1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18package android.media.videoeditor;
19
20import java.io.File;
21import java.io.FileInputStream;
22import java.io.IOException;
23
24/**
25 * Class which describes the waveform data of an audio track. The gain values
26 * represent the average gain for an audio frame. For audio codecs which do not
27 * operate on a per frame bases (eg. ALAW, ULAW) a reasonable audio frame
28 * duration will be assumed (eg. 50ms).
29 * {@hide}
30 */
31public class WaveformData {
32    /*
33     *  Instance variables
34     */
35    private final int mFrameDurationMs;
36    private final int mFramesCount;
37    private final short[] mGains;
38
39    /*
40     * This constructor shall not be used
41     */
42    @SuppressWarnings("unused")
43    private WaveformData() throws IOException {
44        mFrameDurationMs = 0;
45        mFramesCount = 0;
46        mGains = null;
47    }
48
49    /*
50     * Constructor
51     *
52     * @param audioWaveformFilename The name of the audio waveform file
53     *
54     * The file format is as following:
55     * <ul>
56     *  <li>first 4 bytes provide the number of samples for each value, as
57     *  big-endian signed</li>
58     *  <li>4 following bytes is the total number of values in the file, as
59     *  big-endian signed</li>
60     *  <li>then, all values follow as bytes</li>
61     * </ul>
62     *
63     * @throws IOException on failure of file input stream operations
64     * @throws IllegalArgumentException if audioWaveformFilename is null
65     */
66    WaveformData(String audioWaveformFilename) throws IOException {
67
68        if (audioWaveformFilename == null) {
69            throw new IllegalArgumentException("WaveformData : filename is null");
70        }
71
72        FileInputStream audioGraphFileReadHandle = null;
73
74        try {
75            final File audioGraphFileContext = new File(audioWaveformFilename);
76
77            audioGraphFileReadHandle = new FileInputStream(audioGraphFileContext);
78            /*
79             * Read frame duration
80             */
81            final byte tempFrameDuration[] = new byte[4];
82
83            audioGraphFileReadHandle.read(tempFrameDuration, 0, 4);
84
85            int tempFrameDurationMs = 0;
86            int tempFramesCounter = 0;
87            for (int i = 0; i < 4; i++) {
88                tempFrameDurationMs = (tempFrameDurationMs << 8);
89                tempFrameDurationMs = (tempFrameDurationMs | (tempFrameDuration[i] & 0xff));
90            }
91            mFrameDurationMs = tempFrameDurationMs;
92
93            /*
94             * Read count
95             */
96            final byte tempFramesCount[] = new byte[4];
97
98            audioGraphFileReadHandle.read(tempFramesCount, 0, 4);
99            for (int i = 0; i < 4; i++) {
100                tempFramesCounter = (tempFramesCounter << 8);
101                tempFramesCounter = (tempFramesCounter | (tempFramesCount[i] & 0xff));
102            }
103            mFramesCount = tempFramesCounter;
104
105            /*
106             *  Capture the graph values
107             */
108            mGains = new short[mFramesCount];
109
110            for (int i = 0; i < mFramesCount; i++) {
111                mGains[i] = (short)audioGraphFileReadHandle.read();
112            }
113        } finally {
114            if (audioGraphFileReadHandle != null) {
115                audioGraphFileReadHandle.close();
116            }
117        }
118    }
119
120    /**
121     * @return The duration of a frame in milliseconds
122     */
123    public int getFrameDuration() {
124        return mFrameDurationMs;
125    }
126
127    /**
128     * @return The number of frames within the waveform data
129     */
130    public int getFramesCount() {
131        return mFramesCount;
132    }
133
134    /**
135     * @return The array of frame gains. The size of the array is the frames
136     *         count. The values of the frame gains range from 0 to 255.
137     */
138    public short[] getFrameGains() {
139        return mGains;
140    }
141}
142