EMMA Coverage Report (generated Tue Mar 14 21:50:42 EST 2006)
[all classes][org.farng.mp3.id3]

COVERAGE SUMMARY FOR SOURCE FILE [FrameBodyASPI.java]

nameclass, %method, %block, %line, %
FrameBodyASPI.java0%   (0/1)0%   (0/11)0%   (0/277)0%   (0/53)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class FrameBodyASPI0%   (0/1)0%   (0/11)0%   (0/277)0%   (0/53)
FrameBodyASPI (): void 0%   (0/1)0%   (0/18)0%   (0/7)
FrameBodyASPI (FrameBodyASPI): void 0%   (0/1)0%   (0/41)0%   (0/12)
FrameBodyASPI (RandomAccessFile): void 0%   (0/1)0%   (0/21)0%   (0/8)
FrameBodyASPI (int, int, int, int, short []): void 0%   (0/1)0%   (0/43)0%   (0/13)
equals (): void 0%   (0/1)0%   (0/5)0%   (0/1)
getIdentifier (): String 0%   (0/1)0%   (0/2)0%   (0/1)
getSize (): int 0%   (0/1)0%   (0/8)0%   (0/1)
read (RandomAccessFile): void 0%   (0/1)0%   (0/69)0%   (0/15)
setupObjectList (): void 0%   (0/1)0%   (0/1)0%   (0/1)
toString (): String 0%   (0/1)0%   (0/34)0%   (0/1)
write (RandomAccessFile): void 0%   (0/1)0%   (0/35)0%   (0/8)

1package org.farng.mp3.id3;
2 
3import org.farng.mp3.InvalidTagException;
4 
5import java.io.IOException;
6import java.io.RandomAccessFile;
7 
8/**
9 * <h3>4.30.&nbsp;&nbsp; Audio seek point index</h3>
10 * <p/>
11 * <p>&nbsp;&nbsp; Audio files with variable bit rates are intrinsically difficult to<br> &nbsp;&nbsp; deal with in the
12 * case of seeking within the file. The ASPI frame<br> &nbsp;&nbsp; makes seeking easier by providing a list a seek
13 * points within the<br> &nbsp;&nbsp; audio file. The seek points are a fractional offset within the audio<br>
14 * &nbsp;&nbsp; data, providing a starting point from which to find an appropriate<br>
15 * <p/>
16 * &nbsp;&nbsp; point to start decoding. The presence of an ASPI frame requires the<br> &nbsp;&nbsp; existence of a TLEN
17 * frame, indicating the duration of the file in<br> &nbsp;&nbsp; milliseconds. There may only be one 'audio seek point
18 * index' frame in<br> &nbsp;&nbsp; a tag.</p>
19 * <p/>
20 * <p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;Header for 'Seek Point Index', ID: &quot;ASPI&quot;&gt;<br> &nbsp;&nbsp;&nbsp;&nbsp;
21 * Indexed data start (S)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $xx xx xx xx<br> &nbsp;&nbsp;&nbsp;&nbsp;
22 * Indexed data length (L)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $xx xx xx xx<br> &nbsp;&nbsp;&nbsp;&nbsp; Number of
23 * index points (N)&nbsp;&nbsp;&nbsp;&nbsp; $xx xx<br>
24 * <p/>
25 * &nbsp;&nbsp;&nbsp;&nbsp; Bits per index point (b)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $xx</p>
26 * <p/>
27 * <p>&nbsp;&nbsp; Then for every index point the following data is included;</p>
28 * <p/>
29 * <p>&nbsp;&nbsp;&nbsp;&nbsp; Fraction at index (Fi)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $xx
30 * (xx)</p>
31 * <p/>
32 * <p>&nbsp;&nbsp; 'Indexed data start' is a byte offset from the beginning of the file.<br> &nbsp;&nbsp; 'Indexed data
33 * length' is the byte length of the audio data being<br> &nbsp;&nbsp; indexed. 'Number of index points' is the number
34 * of index points, as<br> &nbsp;&nbsp; the name implies. The recommended number is 100. 'Bits per index<br>
35 * &nbsp;&nbsp; point' is 8 or 16, depending on the chosen precision. 8 bits works<br>
36 * <p/>
37 * &nbsp;&nbsp; well for short files (less than 5 minutes of audio), while 16 bits is<br> &nbsp;&nbsp; advantageous for
38 * long files. 'Fraction at index' is the numerator of<br> &nbsp;&nbsp; the fraction representing a relative position in
39 * the data. The<br> &nbsp;&nbsp; denominator is 2 to the power of b.</p>
40 * <p/>
41 * <p>&nbsp;&nbsp; Here are the algorithms to be used in the calculation. The known data<br> &nbsp;&nbsp; must be the
42 * offset of the start of the indexed data (S), the offset<br> &nbsp;&nbsp; of the end of the indexed data (E), the
43 * number of index points (N),<br> &nbsp;&nbsp; the offset at index i (Oi). We calculate the fraction at index i<br>
44 * &nbsp;&nbsp; (Fi).</p>
45 * <p/>
46 * <p>&nbsp;&nbsp; Oi is the offset of the frame whose start is soonest after the point<br> &nbsp;&nbsp; for which the
47 * time offset is (i/N * duration).</p>
48 * <p/>
49 * <p>&nbsp;&nbsp; The frame data should be calculated as follows:</p>
50 * <p/>
51 * <p>&nbsp;&nbsp;&nbsp;&nbsp; Fi = Oi/L * 2^b&nbsp;&nbsp;&nbsp; (rounded down to the nearest integer)</p>
52 * <p/>
53 * <p>&nbsp;&nbsp; Offset calculation should be calculated as follows from data in the<br> &nbsp;&nbsp; frame:</p>
54 * <p/>
55 * <p>&nbsp;&nbsp;&nbsp;&nbsp; Oi = (Fi/2^b)*L&nbsp;&nbsp;&nbsp; (rounded up to the nearest integer)<br> </p>
56 *
57 * @author Eric Farng
58 * @version $Revision: 1.5 $
59 */
60public class FrameBodyASPI extends AbstractID3v2FrameBody {
61 
62    private short[] fraction = null;
63    private int bitsPerPoint = 0;
64    private int dataLength = 0;
65    private int dataStart = 0;
66    private int indexPoints = 0;
67 
68    /**
69     * Creates a new FrameBodyASPI object.
70     */
71    public FrameBodyASPI() {
72        super();
73    }
74 
75    /**
76     * Creates a new FrameBodyASPI object.
77     */
78    public FrameBodyASPI(final FrameBodyASPI copyObject) {
79        super(copyObject);
80        fraction = (short[]) copyObject.fraction.clone();
81        bitsPerPoint = copyObject.bitsPerPoint;
82        dataLength = copyObject.dataLength;
83        dataStart = copyObject.dataStart;
84        indexPoints = copyObject.indexPoints;
85    }
86 
87    /**
88     * Creates a new FrameBodyASPI object.
89     */
90    public FrameBodyASPI(final int dataStart,
91                         final int dataLength,
92                         final int indexPoints,
93                         final int bitsPerPoint,
94                         final short[] fraction) {
95        super();
96        this.dataStart = dataStart;
97        this.dataLength = dataLength;
98        this.indexPoints = indexPoints;
99        this.bitsPerPoint = bitsPerPoint;
100        this.fraction = new short[fraction.length];
101        System.arraycopy(fraction, 0, this.fraction, 0, fraction.length);
102    }
103 
104    /**
105     * Creates a new FrameBodyASPI object.
106     */
107    public FrameBodyASPI(final RandomAccessFile file) throws IOException, InvalidTagException {
108        super();
109        read(file);
110    }
111 
112    public String getIdentifier() {
113        return "ASPI";
114    }
115 
116    public int getSize() {
117        return 4 + 4 + 2 + 1 + fraction.length << 1;
118    }
119 
120    /**
121     * This method is not yet supported.
122     *
123     * @throws UnsupportedOperationException This method is not yet supported
124     */
125    public void equals() {
126        // todo Implement this java.lang.Object method
127        throw new UnsupportedOperationException("Method equals() not yet implemented.");
128    }
129 
130    protected void setupObjectList() {
131//        throw new UnsupportedOperationException();
132    }
133 
134    public void read(final RandomAccessFile file) throws IOException, InvalidTagException {
135        final int size = readHeader(file);
136        if (size == 0) {
137            throw new InvalidTagException("Empty Frame");
138        }
139        dataStart = file.readInt();
140        dataLength = file.readInt();
141        indexPoints = (int) file.readShort();
142        bitsPerPoint = (int) file.readByte();
143        fraction = new short[indexPoints];
144        for (int i = 0; i < indexPoints; i++) {
145            if (bitsPerPoint == 8) {
146                fraction[i] = (short) file.readByte();
147            } else if (bitsPerPoint == 16) {
148                fraction[i] = file.readShort();
149            } else {
150                throw new InvalidTagException("ASPI bits per point wasn't 8 or 16");
151            }
152        }
153    }
154 
155    public String toString() {
156        return getIdentifier() + ' ' + this
157                .dataStart + ' ' + this
158                .dataLength + ' ' + this
159                .indexPoints + ' ' + this
160                .bitsPerPoint + ' ' + this.fraction
161                .toString();
162    }
163 
164    public void write(final RandomAccessFile file) throws IOException {
165        writeHeader(file, getSize());
166        file.writeInt(dataStart);
167        file.writeInt(dataLength);
168        file.writeShort(indexPoints);
169        file.writeByte(16);
170        for (int i = 0; i < indexPoints; i++) {
171            file.writeShort((int) fraction[i]);
172        }
173    }
174}

[all classes][org.farng.mp3.id3]
EMMA 2.0.5312 (C) Vladimir Roubtsov