我正在尝试按时间绘制音频幅度,我正在用来实现这一点,AudioRecord类,它给了我一个原始音频数组。
new Thread(new Runnable() {
@Override
public void run() {
while (mIsRecording) {
int readSize = mRecorder.read(mBuffer, 0, mBuffer.length);
for (int i = 0; i < readSize; i++) {
long time = mChronometer.getTimeElapsed();
ampArray.add((mBuffer[i]));
timeArray.add(time);
}
}
}
}).start();
}
我用于AudioRecored的参数是:
public static final int SAMPLE_RATE = 8000;
private void initRecorder() {
int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
mBuffer = new short[bufferSize];
mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSize);
}
我得到的结果是这个:
The result i get -----
What i'm looking for
我在这里想念什么吗?
提前致谢。
编辑:绘图方法:
当记录停止时,我将振幅数组中保存的所有值和时间数组中保存的所有值发送到GraphView Api的LineGraphSeries
series = new LineGraphSeries<DataPoint>(generateData(ampArray, timeArray));
graph.addSeries(series);
generateData方法:
double x = 0; int i = 0; short y = 0;
private DataPoint[] generateData(ArrayList<Short> ampArray, ArrayList<Double> timeArray) {
DataPoint[] values = new DataPoint[ampArray.size()];
for (int i=0; i< ampArray.size(); i++) {
x = timeArray.get(i);
y = ampArray.get(i);
DataPoint v = new DataPoint(x, y);
values[i] = v;
}
return values;
}
最佳答案
我将在这里进行有根据的猜测,并建议这与以下两行有关:
long time = mChronometer.getTimeElapsed();
timeArray.add(time);
在我看来,您正在尝试绘制在不同时间范围内发生的样本,并且正在针对当前的CPU时钟进行批量处理,这可以解释您的结果-例如,您可能处理了大量的样本-可以比最初发生的速度快得多-并且它们可能都获得相似的时间轴值。
正确的方法是为样本本身重建时间轴。假设您处理的第一个样本是时间0。如果采样率为48000,则每个样本为1/48000秒。该方法将是这样的:
int sampleNumber = 0;
while (mIsRecording) {
int readSize = mRecorder.read(mBuffer, 0, mBuffer.length);
for (int i = 0; i < readSize; i++) {
ampArray.add((mBuffer[i]));
double time = sampleNumber / SAMPLE_RATE;
timeArray.add(time);
sampleNumber++;
}
}
注意,我将timeArray从int更改为double,因为现在是秒而不是毫秒。如果您希望使用毫秒,则将时间乘以1000并转换为长整数。
另外,您无需为时间轴创建数组,因为您可以根据其在ampArray中的绝对索引确定任何样本的时间。