package org.farng.mp3.id3;
import org.farng.mp3.InvalidTagException;
import org.farng.mp3.object.AbstractMP3Object;
import org.farng.mp3.object.ObjectGroupRepeated;
import org.farng.mp3.object.ObjectNumberFixedLength;
import org.farng.mp3.object.ObjectNumberHashMap;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* <h3>4.5. Event timing codes</h3>
* <p/>
* <p> This frame allows synchronisation with key events in the audio. The<br> header is:</p>
* <p/>
* <p> <Header for 'Event timing codes', ID: "ETCO"><br>
* <p/>
* Time stamp format $xx</p>
* <p/>
* <p> Where time stamp format is:</p>
* <p/>
* <p> $01 Absolute time, 32 bit sized, using MPEG [MPEG] frames as unit<br>
* $02 Absolute time, 32 bit sized, using milliseconds as unit</p>
* <p/>
* <p> Absolute time means that every stamp contains the time from the<br> beginning of the
* file.</p>
* <p/>
* <p> Followed by a list of key events in the following format:</p>
* <p/>
* <p> Type of event $xx<br>
* <p/>
* Time stamp $xx (xx ...)</p>
* <p/>
* <p> The 'Time stamp' is set to zero if directly at the beginning of the<br> sound or after
* the previous event. All events MUST be sorted in<br> chronological order. The type of event is as
* follows:</p>
* <p/>
* <p> $00 padding (has no meaning)<br> $01 end of initial
* silence<br> $02 intro start<br>
* <p/>
* $03 main part start<br> $04 outro start<br>
* $05 outro end<br>
* <p/>
* $06 verse start<br> $07 refrain start<br>
* $08 interlude start<br>
* <p/>
* $09 theme start<br> $0A variation start<br>
* $0B key change<br>
* <p/>
* $0C time change<br> $0D momentary unwanted noise (Snap,
* Crackle & Pop)<br> $0E sustained noise<br>
* <p/>
* $0F sustained noise end<br> $10 intro end<br>
* $11 main part end<br>
* <p/>
* $12 verse end<br> $13 refrain end<br>
* $14 theme end<br>
* <p/>
* $15 profanity<br> $16 profanity end</p>
* <p/>
* <p> $17-$DF reserved for future use</p>
* <p/>
* <p> $E0-$EF not predefined synch 0-F</p>
* <p/>
* <p> $F0-$FC reserved for future use</p>
* <p/>
* <p> $FD audio end (start of silence)<br>
* <p/>
* $FE audio file ends<br> $FF one more byte of events
* follows (all the following bytes with<br> the value $FF have
* the same function)</p>
* <p/>
* <p> Terminating the start events such as "intro start" is OPTIONAL. The<br> 'Not
* predefined synch's ($E0-EF) are for user events. You might want<br> to synchronise your music to
* something, like setting off an explosion<br> on-stage, activating a screensaver etc.</p>
* <p/>
* <p> There may only be one "ETCO" frame in each tag.<br> </p>
*
* @author Eric Farng
* @version $Revision: 1.4 $
*/
public class FrameBodyETCO extends AbstractID3v2FrameBody {
/**
* Creates a new FrameBodyETCO object.
*/
public FrameBodyETCO() {
super();
}
/**
* Creates a new FrameBodyETCO object.
*/
public FrameBodyETCO(final FrameBodyETCO body) {
super(body);
}
/**
* Creates a new FrameBodyETCO object.
*/
public FrameBodyETCO(final byte timeStampFormat, final byte event, final int timeStamp) {
setObject("Time Stamp Format", new Long(timeStampFormat));
this.addGroup(event, timeStamp);
}
/**
* Creates a new FrameBodyETCO object.
*/
public FrameBodyETCO(final RandomAccessFile file) throws IOException, InvalidTagException {
this.read(file);
}
public String getIdentifier() {
return "ETCO" + ((char) 0) + getOwner();
}
public String getOwner() {
return (String) getObject("Owner");
}
public void getOwner(final String description) {
setObject("Owner", description);
}
public void addGroup(final byte event, final int timeStamp) {
final ObjectGroupRepeated group = (ObjectGroupRepeated) this.getObject("Data");
final AbstractMP3Object ev = new ObjectNumberHashMap("Type Of Event", 1);
final AbstractMP3Object ts = new ObjectNumberFixedLength("Time Stamp", 4);
group.addObject(ev);
group.addObject(ts);
setObject("Data", group);
}
protected void setupObjectList() {
appendToObjectList(new ObjectNumberHashMap("Time Stamp Format", 1));
final ObjectGroupRepeated group = new ObjectGroupRepeated("Data");
group.addProperty(new ObjectNumberHashMap("Type Of Event", 1));
group.addProperty(new ObjectNumberFixedLength("Time Stamp", 4));
appendToObjectList(group);
}
}