android - Android PCM绘图

标签 android audio pcm

我正在尝试按时间绘制音频幅度,我正在用来实现这一点,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中的绝对索引确定任何样本的时间。

关于android - Android PCM绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34373927/

相关文章:

android - 如何使用特定选项卡启动 Activity ?

javascript - 在 cordova 中安装插件从我的项目中删除了所有文件(index.js 和 index.html 除外)

apache-flex - 如何在mouseEvent情况下仅触发一次函数

c - 如何使用核心音频正确录制 16 位 LittleEndian 签名整数 PCM 格式的音频

java - 如何在我的 Recycler View 的寻呼机上显示点?

android - 更新 Facebook APK 后,FACEBOOK/TWITTER 登录不再适用于 Android 应用程序(登录立即消失!)

ios - Objective-C 中的高性能缓冲区

unix - 通过Skype流式传输音乐或音频文件

c# - 从 WasapiLoopbackCapture 捕获音频,并转换为 muLaw

javascript - 如何将 JavaScript 浮点 PCM 音频数组转换为小端字节字符串?