com.tffenterprises.music.tag
Class ID3v1

java.lang.Object
  extended by com.tffenterprises.music.tag.ID3v1
All Implemented Interfaces:
ID3Tag, java.io.Serializable, java.lang.Cloneable
Direct Known Subclasses:
SmartID3v1

public class ID3v1
extends java.lang.Object
implements ID3Tag, java.io.Serializable, java.lang.Cloneable

ID3v1 is an implementation of the so-called ID3v1.1 standard. An object can be constructed from a 125-byte array, from another instance of an ID3 subclass or from scratch. If the construction of the object necessitated any string cleaning and/or data sanitization, the isChanged() method will return true on the fresh object (otherwise it will return false, until a later change is made). The ID3v1 object can output itself as a string or as a 125-byte array ready to be written into a file. Writing the tag into a file at its proper location is not the responsibility of the ID3v1 class; it is the responsibility of the user. (The TaggedFile class is a compliant user). Standard practice for ID3v1.1 tags is to insert the string "TAG" 128 bytes from the end of a file, followed by the 125 bytes of actual information returned by ID3v1.toBytes() method.

Version:
1.0d1 $Date: 2002/10/11 00:57:29 $
Author:
Guillaume Lessard, Daniel M. Zimmerman
See Also:
Serialized Form

Field Summary
private  java.lang.String album
          The name of the album or set from which the track was extracted.
private static int ALBUM_LENGTH
          Byte length of the album-name field in ID3v1.
private static int ALBUM_OFFSET
          Byte offset of the album-name field in ID3v1.
private  java.lang.String artist
          The name of the artist or performer featured on the track.
private static int ARTIST_LENGTH
          Byte length of the artist field in ID3v1.
private static int ARTIST_OFFSET
          Byte offset of the artist field in ID3v1.
private  boolean changed
          Flag indicating whether or not the tag has been changed.
private  java.lang.String comment
          A comment relevant to the track.
private static int COMMENT_LENGTH
          Byte length of the comment field in ID3v1.
private static int COMMENT_OFFSET
          Byte offset of the comment field in ID3v1.
static java.lang.String ENCODING
          The recommended character encoding for an ID3v1 tag
private  byte genre
          A byte representing the genre of the track.
static java.lang.String GENRE_NONE
          A recommended string that means "no genre"
private static int GENRE_OFFSET
          Byte offset of the genre byte in ID3v1.
private static int ID3_11_OFFSET
          Byte offset of the ID3v1.1 marker byte.
static java.lang.String PREFIX
          The string that announces the ID3v1 tag in a tagged file.
static int TAG_LENGTH
          The length of an ID3v1 tag.
private  java.lang.String title
          The title of the track represented by this tag.
private static int TITLE_LENGTH
          Byte length of the title field in ID3v1.
private static int TITLE_OFFSET
          Byte offset of the title field in ID3v1.
private  byte track
          The track's position within the set to which it belongs.
private static int TRACK_OFFSET
          Byte offset of the track byte in ID3v1.1.
private  short year
          The year during which the track was recorded or released.
private static int YEAR_LENGTH
          Byte length of the year field in ID3v1.
private static int YEAR_OFFSET
          Byte offset of the year field in ID3v1.
 
Constructor Summary
ID3v1()
          Default constructor.
ID3v1(byte[] tagBytes)
          Constructor from an array of bytes.
ID3v1(ID3Tag oldTag)
          Constructor copying data from another Tag implementor.
ID3v1(java.io.InputStream in)
          Constructor from an InputStream.
 
Method Summary
static boolean CheckFileForTag(java.io.RandomAccessFile raFile)
          Verify whether a given file contains an ID3v1 tag.
private  java.lang.String cleanString(byte[] bytes, int offset, int length)
          This will return a "proper" substring from the defined portion of the byte array.
private  java.lang.String cleanString(java.lang.String res, int length)
          Returns a "proper" substring of the string passed as an argument, up to a maximum length of length characters.
 java.lang.Object clone()
          Clone the ID3v1 tag
 boolean equals(java.lang.Object obj)
          Compare the ID3v1 tag for equality with another ID3v1 tag.
 java.lang.String getAlbum()
          Return the name of the album or set on which this track can be found
 java.lang.String getArtist()
          Return the name of the artist or performer featured on the track represented by this tag
 byte[] getBytes()
          Get a byte array equivalent to the tag's representation in a file, using the default ID3 string encoding.
 byte[] getBytes(java.lang.String encoding)
          Get a byte array equivalent to the tag's representation in a file, using the given string encoding.
 java.util.zip.Checksum getChecksum()
          Obtain a Checksum object representing this instance.
 java.lang.String getComment()
          Return a comment attached to the track.
 byte getGenre()
          Return a byte representing the genre of the track.
static int GetTagLength(java.io.RandomAccessFile raFile)
          Get the length of the ID3v1 tag in this particular file.
static long GetTagOffset(java.io.RandomAccessFile raFile)
          Obtain the offset at which an ID3v1 would be located if there were one in the given file.
 java.lang.String getTitle()
          Return the title of the track represented by this tag
 byte getTrackNumber()
          Return the track's position out of its set, as an integer.
 short getYear()
          Return the year during which the track was recorded or released, or -1 if there is no such information available.
 int hashCode()
          Obtain a hash code for this ID3v1 tag.
 boolean isChanged()
          Returns whether or not the tag has been changed.
private  void parseBytes(byte[] tagBytes)
          Extract tag information out of a byte array.
 void setAlbum(java.lang.String album)
          Set the title of the album or set of which the track is extracted.
 void setArtist(java.lang.String artist)
          Set the name of the artist or performer featured on the track
 void setChanged(boolean changed)
          Sets or clears the "changed" bit.
 void setComment(java.lang.String comment)
          Attach a comment relevant to the track.
 void setGenre(byte genre)
          Set the byte representing the genre of the track.
 void setGenre(java.lang.String genre)
          Set the byte representing the genre of the track, using the String representation of the genre.
 void setTitle(java.lang.String title)
          Set the title of the track represented by this tag.
 void setTrackNumber(byte track)
          Set the position of the track within its set.
 void setYear(short year)
          Set the year during which the track was recorded or released.
 java.lang.String toString()
          Get a String representation of the tag.
static short ValidateYear(short year)
          Sanitize the year during which the track was recorded or released.
 void writeTo(java.io.OutputStream out)
          Write this tag to an output stream, using the default ID3 string encoding.
 void writeTo(java.io.OutputStream out, java.lang.String encoding)
          Write this tag to an output stream, using the given string encoding.
 
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

PREFIX

public static final java.lang.String PREFIX
The string that announces the ID3v1 tag in a tagged file.

See Also:
Constant Field Values

TAG_LENGTH

public static final int TAG_LENGTH
The length of an ID3v1 tag.

See Also:
Constant Field Values

ENCODING

public static final java.lang.String ENCODING
The recommended character encoding for an ID3v1 tag

See Also:
Constant Field Values

GENRE_NONE

public static final java.lang.String GENRE_NONE
A recommended string that means "no genre"

See Also:
Constant Field Values

TITLE_LENGTH

private static final int TITLE_LENGTH
Byte length of the title field in ID3v1.

See Also:
Constant Field Values

ARTIST_LENGTH

private static final int ARTIST_LENGTH
Byte length of the artist field in ID3v1.

See Also:
Constant Field Values

ALBUM_LENGTH

private static final int ALBUM_LENGTH
Byte length of the album-name field in ID3v1.

See Also:
Constant Field Values

COMMENT_LENGTH

private static final int COMMENT_LENGTH
Byte length of the comment field in ID3v1.

See Also:
Constant Field Values

YEAR_LENGTH

private static final int YEAR_LENGTH
Byte length of the year field in ID3v1.

See Also:
Constant Field Values

TITLE_OFFSET

private static final int TITLE_OFFSET
Byte offset of the title field in ID3v1.

See Also:
Constant Field Values

ARTIST_OFFSET

private static final int ARTIST_OFFSET
Byte offset of the artist field in ID3v1.

See Also:
Constant Field Values

ALBUM_OFFSET

private static final int ALBUM_OFFSET
Byte offset of the album-name field in ID3v1.

See Also:
Constant Field Values

YEAR_OFFSET

private static final int YEAR_OFFSET
Byte offset of the year field in ID3v1.

See Also:
Constant Field Values

COMMENT_OFFSET

private static final int COMMENT_OFFSET
Byte offset of the comment field in ID3v1.

See Also:
Constant Field Values

ID3_11_OFFSET

private static final int ID3_11_OFFSET
Byte offset of the ID3v1.1 marker byte.

See Also:
Constant Field Values

TRACK_OFFSET

private static final int TRACK_OFFSET
Byte offset of the track byte in ID3v1.1.

See Also:
Constant Field Values

GENRE_OFFSET

private static final int GENRE_OFFSET
Byte offset of the genre byte in ID3v1.

See Also:
Constant Field Values

title

private java.lang.String title
The title of the track represented by this tag.


artist

private java.lang.String artist
The name of the artist or performer featured on the track.


album

private java.lang.String album
The name of the album or set from which the track was extracted.


year

private short year
The year during which the track was recorded or released.


comment

private java.lang.String comment
A comment relevant to the track.


track

private byte track
The track's position within the set to which it belongs.


genre

private byte genre
A byte representing the genre of the track.


changed

private boolean changed
Flag indicating whether or not the tag has been changed.

Constructor Detail

ID3v1

public ID3v1()
Default constructor. All the strings will be set to the empty string, and all numerical values will be set to -1 (the "unknown" value).


ID3v1

public ID3v1(ID3Tag oldTag)
Constructor copying data from another Tag implementor. The tag values will be copied from it (up to their maximum length for ID3v1).

Parameters:
oldTag - the ID3 instance from which to copy this ID3v1 object.

ID3v1

public ID3v1(byte[] tagBytes)
      throws java.lang.IllegalArgumentException
Constructor from an array of bytes. Note that the array of bytes passed to this constructor will neither be retained nor modified.

Parameters:
tagBytes - an array of 125 bytes containing the data from which the ID3v1 tag is to be extracted.
Throws:
java.lang.IllegalArgumentException - if the array is not 125 bytes long.

ID3v1

public ID3v1(java.io.InputStream in)
      throws java.lang.IllegalArgumentException,
             java.io.IOException
Constructor from an InputStream. The InputStream needs to be correctly positioned after the "TAG" indicator in the file.

Parameters:
in - a correctly-positioned instance of InputStream from which the ID3v1 tag is to be extracted.
Throws:
java.lang.IllegalArgumentException - if there are less than 125 bytes left in stream.
java.io.IOException - if an I/O error occurs during the parsing.
Method Detail

CheckFileForTag

public static boolean CheckFileForTag(java.io.RandomAccessFile raFile)
                               throws java.io.IOException
Verify whether a given file contains an ID3v1 tag.

Parameters:
raFile - the file to check for the presence of a tag.
Returns:
a boolean indicating the presence of an ID3v1 tag.
Throws:
java.io.IOException - if an I/O error occurs during the parsing.

GetTagOffset

public static long GetTagOffset(java.io.RandomAccessFile raFile)
                         throws java.io.IOException
Obtain the offset at which an ID3v1 would be located if there were one in the given file.

Parameters:
raFile - the file from which to extract the offset.
Returns:
the offset at which the ID3v1 information should be found.
Throws:
java.io.IOException - if an I/O error occurs during the parsing.

GetTagLength

public static int GetTagLength(java.io.RandomAccessFile raFile)
Get the length of the ID3v1 tag in this particular file. Note that ID3v1 tags are always 125 bytes long (excluding the "TAG" bytes); this method exists for consistency with other Tag subclasses.

Parameters:
raFile - the file for which to get the tag length.
Returns:
the length of the ID3v1 tag.

setTitle

public void setTitle(java.lang.String title)
Set the title of the track represented by this tag.

Specified by:
setTitle in interface ID3Tag
Parameters:
title - the title of the track represented by this tag.

getTitle

public java.lang.String getTitle()
Return the title of the track represented by this tag

Specified by:
getTitle in interface ID3Tag
Returns:
the title of the track represented by this tag

setArtist

public void setArtist(java.lang.String artist)
Set the name of the artist or performer featured on the track

Specified by:
setArtist in interface ID3Tag
Parameters:
artist - the name of the artist or performer featured on the track.

getArtist

public java.lang.String getArtist()
Return the name of the artist or performer featured on the track represented by this tag

Specified by:
getArtist in interface ID3Tag
Returns:
the name of the artist or performer featured on the track

setAlbum

public void setAlbum(java.lang.String album)
Set the title of the album or set of which the track is extracted.

Specified by:
setAlbum in interface ID3Tag
Parameters:
album - the title of the album or set of which the track is extracted.

getAlbum

public java.lang.String getAlbum()
Return the name of the album or set on which this track can be found

Specified by:
getAlbum in interface ID3Tag
Returns:
the name of the album or set on which this track can be found

setComment

public void setComment(java.lang.String comment)
Attach a comment relevant to the track.

Specified by:
setComment in interface ID3Tag
Parameters:
comment - a comment relevant to the track.

getComment

public java.lang.String getComment()
Return a comment attached to the track.

Specified by:
getComment in interface ID3Tag
Returns:
a comment attached to the track.

setTrackNumber

public void setTrackNumber(byte track)
Set the position of the track within its set. This value can be cleared by passing the value -1 as a track number.

Specified by:
setTrackNumber in interface ID3Tag
Parameters:
track - the position of the track within its set.

getTrackNumber

public byte getTrackNumber()
Return the track's position out of its set, as an integer. If this information is unknown, return -1.

Specified by:
getTrackNumber in interface ID3Tag
Returns:
the track's position out of its set, as an integer. If there is no such information, return -1.

setGenre

public void setGenre(byte genre)
Set the byte representing the genre of the track. To clear the genre without setting a new one, pass a byte whose value is -1.

Specified by:
setGenre in interface ID3Tag
Parameters:
genre - the byte representing the genre of the track.

setGenre

public void setGenre(java.lang.String genre)
Set the byte representing the genre of the track, using the String representation of the genre. If the String parameter does not correspond to a genre, it will be set to -1.

Parameters:
genre - the String representing the genre of the track.

getGenre

public byte getGenre()
Return a byte representing the genre of the track. If there is no such information, return -1.

Specified by:
getGenre in interface ID3Tag
Returns:
a byte representing the genre of the track. If there is no such information, return -1.

setYear

public void setYear(short year)
Set the year during which the track was recorded or released.

Specified by:
setYear in interface ID3Tag
Parameters:
year - the year during which the track was recorded or released.

getYear

public short getYear()
Return the year during which the track was recorded or released, or -1 if there is no such information available.

Specified by:
getYear in interface ID3Tag
Returns:
the year during which the track was recorded or released. If there is no such information, return -1.

isChanged

public boolean isChanged()
Returns whether or not the tag has been changed.

Specified by:
isChanged in interface ID3Tag
Returns:
whether or not the tag has been changed.

setChanged

public void setChanged(boolean changed)
Sets or clears the "changed" bit.

Specified by:
setChanged in interface ID3Tag
Parameters:
changed - true to set the changed bit, false to unset it.

getBytes

public byte[] getBytes()
Get a byte array equivalent to the tag's representation in a file, using the default ID3 string encoding.

Specified by:
getBytes in interface ID3Tag
Returns:
a byte array equivalent to the tag's representation in a file.

getBytes

public byte[] getBytes(java.lang.String encoding)
                throws java.io.UnsupportedEncodingException
Get a byte array equivalent to the tag's representation in a file, using the given string encoding.

The implementation of this method assumes a 1-byte encoding, but then again so does the ID3v1 so-called standard. This should not be considered as a bug, but it should be taken into consideration.

Parameters:
encoding - the string encoding to be used in converting the tag to bytes.
Returns:
a byte array equivalent to the tag's representation in a file.
Throws:
java.io.UnsupportedEncodingException - if the encoding is unsupported.

writeTo

public void writeTo(java.io.OutputStream out)
             throws java.io.IOException
Write this tag to an output stream, using the default ID3 string encoding. The OutputStream must be correctly positioned *after* the TAG marker.

Parameters:
out - the OutputStream instance to which this tag will be written.
Throws:
java.io.IOException - if an I/O error occurs.

writeTo

public void writeTo(java.io.OutputStream out,
                    java.lang.String encoding)
             throws java.io.UnsupportedEncodingException,
                    java.io.IOException
Write this tag to an output stream, using the given string encoding. The stream must be correctly positioned *after* the TAG marker.

The implementation of this method assumes a 1-byte encoding, but then again so does the ID3v1 so-called standard. This should not be considered as a bug, but it should be taken into consideration.

Parameters:
out - the OutputStream instance to which this tag will be written.
encoding - the character encoding to be used.
Throws:
java.io.IOException - if an I/O error occurs.
java.io.UnsupportedEncodingException - if the named encoding isn't supported.

getChecksum

public java.util.zip.Checksum getChecksum()
Obtain a Checksum object representing this instance.

This method is used by the hashCode() method. A subclass only needs to update the checksum with its extra data. The name of the class is already taken into account.

Returns:
a Checksum object representing tihs instance.

toString

public java.lang.String toString()
Get a String representation of the tag.

Specified by:
toString in interface ID3Tag
Overrides:
toString in class java.lang.Object
Returns:
a String representation of the tag.

clone

public java.lang.Object clone()
Clone the ID3v1 tag

Overrides:
clone in class java.lang.Object
Returns:
a clone of the object

equals

public boolean equals(java.lang.Object obj)
Compare the ID3v1 tag for equality with another ID3v1 tag.

Overrides:
equals in class java.lang.Object
Parameters:
obj - another ID3v1 tag to be compared
Returns:
true if the two objects are equal.

hashCode

public final int hashCode()
Obtain a hash code for this ID3v1 tag.

The implementation of this method utilises the getChecksum() method of ID3v1. Subclasses should override the getChecksum() method and update the checksum with their local data. The changes will be reflected in the returned hash code.

Overrides:
hashCode in class java.lang.Object
Returns:
a hash code for this ID3v1 tag.

parseBytes

private void parseBytes(byte[] tagBytes)
                 throws java.lang.IllegalArgumentException
Extract tag information out of a byte array.

Parameters:
tagBytes - a byte array from which to read the tag information.
Throws:
java.lang.IllegalArgumentException - if the byte array has an incorrect size.

cleanString

private java.lang.String cleanString(byte[] bytes,
                                     int offset,
                                     int length)
This will return a "proper" substring from the defined portion of the byte array.

Parameters:
bytes - the bytes being converted to characters.
offset - index of the first byte to convert.
length - number of Bytes to convert.
Returns:
a substring from the specified portion of the byte array.

cleanString

private java.lang.String cleanString(java.lang.String res,
                                     int length)
Returns a "proper" substring of the string passed as an argument, up to a maximum length of length characters.

Parameters:
res - the String to be cleaned up. If this parameter is null, an empty string is returned.
length - the maximum length of the resulting String.
Returns:
a "clean" substring from the String passed as a parameter.

ValidateYear

public static short ValidateYear(short year)
Sanitize the year during which the track was recorded or released. This method will return a sanitized version of the value it received, or -1 if it didn't make any sense.

Given that Edison invented recording in 1877, no value prior to that makes sense given what the "Year" field of ID3v1 is supposed to mean.

Turning to probable values, we will assume that people are not using shortcuts for very distant dates. Thus, values smaller than 25 will be interpreted as being later than 1999, while values from 26 to 99 will be interpreted as being during the twentieth century.

Parameters:
year - a year number, as input by a user.
Returns:
a sanitized version of the year number