/**
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not,
* you can get a copy from http://www.opensource.org/licenses/lgpl-license.php or write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
package org.jaudiotagger.tag.datatype;
import org.jaudiotagger.tag.InvalidDataTypeException;
import org.jaudiotagger.tag.id3.AbstractTagFrameBody;
import org.jaudiotagger.tag.id3.ID3Tags;
/**
* Represents a {@link org.jaudiotagger.tag.id3.framebody.FrameBodySYTC} tempo code.
*
* The tempo is in BPM described with one or two bytes. If the
* first byte has the value $FF, one more byte follows, which is added
* to the first giving a range from 2 - 510 BPM, since $00 and $01 is
* reserved. $00 is used to describe a beat-free time period, which is
* not the same as a music-free time period. $01 is used to indicate one
* single beat-stroke followed by a beat-free period.
*
* @author <a href="mailto:hs@tagtraum.com">Hendrik Schreiber</a>
* @version $Id:$
*/
public class TempoCode extends AbstractDataType
{
private static final int MINIMUM_NO_OF_DIGITS = 1;
private static final int MAXIMUM_NO_OF_DIGITS = 2;
public TempoCode(final TempoCode copy)
{
super(copy);
}
public TempoCode(final String identifier, final AbstractTagFrameBody frameBody)
{
super(identifier, frameBody, 0);
}
public TempoCode(final String identifier, final AbstractTagFrameBody frameBody, final Object value) {
super(identifier, frameBody, value);
}
@Override
public int getSize()
{
if (value == null)
{
return 0;
}
else
{
return ID3Tags.getWholeNumber(value) < 0xFF ? MINIMUM_NO_OF_DIGITS : MAXIMUM_NO_OF_DIGITS;
}
}
@Override
public boolean equals(final Object that)
{
return that instanceof TempoCode && super.equals(that);
}
@Override
public void readByteArray(final byte[] arr, final int offset) throws InvalidDataTypeException
{
if (arr == null)
{
throw new NullPointerException("Byte array is null");
}
if (offset < 0)
{
throw new IllegalArgumentException("negative offset into an array offset:" + offset);
}
if (offset >= arr.length)
{
throw new InvalidDataTypeException("Offset to byte array is out of bounds: offset = " + offset + ", array.length = " + arr.length);
}
long lvalue = 0;
lvalue += (arr[offset] & 0xff);
if (lvalue == 0xFF)
{
lvalue += (arr[offset+1] & 0xff);
}
value = lvalue;
}
@Override
public byte[] writeByteArray()
{
final int size = getSize();
final byte[] arr = new byte[size];
long temp = ID3Tags.getWholeNumber(value);
int offset = 0;
if (temp >= 0xFF)
{
arr[offset] = (byte)0xFF;
offset++;
temp -= 0xFF;
}
arr[offset] = (byte) (temp & 0xFF);
return arr;
}
@Override
public String toString()
{
return value == null ? "" : value.toString();
}
}