首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android PCM绘图

Android PCM绘图
EN

Stack Overflow用户
提问于 2015-12-20 02:23:09
回答 1查看 494关注 0票数 2

我正在尝试按时间绘制音频振幅,我使用AudioRecord类来实现这一点,它提供了一个原始音频数组。

代码语言:javascript
复制
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使用的参数是:

代码语言:javascript
复制
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

代码语言:javascript
复制
series = new LineGraphSeries<DataPoint>(generateData(ampArray, timeArray));
graph.addSeries(series);

generateData方法:

代码语言:javascript
复制
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;
}
EN

回答 1

Stack Overflow用户

发布于 2015-12-20 15:20:24

我将在这里进行一个有根据的猜测,并建议它与这两行有关:

代码语言:javascript
复制
long time = mChronometer.getTimeElapsed();
timeArray.add(time);

在我看来,您正在尝试绘制在不同时间范围内发生的样本,并且您正在根据当前CPU时钟批量处理,这将解释您的结果-例如,您可能处理一大块样本-您可以比一开始发生的速度快得多-它们可能都会得到类似的时间轴值。

正确的方法是重建样本本身的时间轴。假设您处理的第一个样本是时间0。如果采样率为48000,则每个采样为1/48000秒。方法是这样的:

代码语言:javascript
复制
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,因为它现在是以秒为单位,而不是毫秒。如果您更喜欢毫秒,那么将time乘以1000并转换为long。

此外,您不需要为时间轴创建数组,因为您可以根据任何样本在ampArray中的绝对索引来确定其时间。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34373927

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档