Android 录音问题?
我一直在摆弄 Android API 的 AudioRecord 功能,并发现了一些奇怪的行为。
背景资料: 我的手机是 HTC Incredible 我正在使用 Eclipse 插件通过模拟器进行 Android 开发。 目标平台或操作系统是 2.2...因为我的手机使用的是它。
一些代码:
bufferSize = AudioRecord.getMinBufferSize(FREQUENCY, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, FREQUENCY, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
这是我用来设置 AudioRecord API 的代码。现在,对于模拟器来说,它希望将 FREQUENCY 设置为 8000 才能正常工作。返回的缓冲区大小为 640。对于手机,我使用 44100。这里的一个问题是,波形的最终 PCM 数据似乎是一个 8 位签名波形。我得到的值从 -127 到 128。我认为值 AudioFormat.ENCODING_PCM_16BIT
会产生不同的结果。
我使用线程处理音频,
public void run() {
while(isRecording) {
audioRecord.startRecording();
byte[] data = new byte[bufferSize];
audioRecord.read(data, 0, bufferSize);
listener.setData(data);
handleData(data);
}
audioRecord.release();
}
我有一种使用 SurfaceView 以图形方式实时显示相应波形的方法。 MIC 中似乎传来很多噪音。我也从模拟器和手机中听到这种噪音。我需要通过某种过滤器运行数据吗?我想使用这些数据来计算一些有趣的 FFT 之类的东西,只是为了玩弄波浪。但我需要以某种方式减少噪音。
还有其他人也经历过这种情况吗?有人有解决办法吗?
我感谢您的时间和回复, 谢谢, dk
I have been messing around with the AudioRecord feature of the Android API and found some strange behaviors with it.
Background info:
My phone is a HTC Incredible
I am using the Eclipse plugin for Android development with the emulator.
Targeted platform or OS is 2.2... Since it is what my phone uses.
Some code:
bufferSize = AudioRecord.getMinBufferSize(FREQUENCY, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, FREQUENCY, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
This is the code I use to setup the AudioRecord API with. Now, for the emulator it likes FREQUENCY to be set to 8000 for it to work. Comes back with a buffer size 640. For the phone I use 44100. One issue here is it seems the resulting PCM data for the wave seems to be an eight bit signed wave. I get values from -127 to 128. I thought the value AudioFormat.ENCODING_PCM_16BIT
would produce something different.
I process the audio with a thread,
public void run() {
while(isRecording) {
audioRecord.startRecording();
byte[] data = new byte[bufferSize];
audioRecord.read(data, 0, bufferSize);
listener.setData(data);
handleData(data);
}
audioRecord.release();
}
I have a way to graphically display to corresponding wave in real time using a SurfaceView
. There seems to be a lot of noise coming from the MIC. I get this noise from the emulator and the phone as well. Do I need to run the data through some sort of filter(s)? I would like to use this data to calculate some fun FFT and stuff just to play around with the wave. But I need to reduce the noise somehow.
Has anyone else experience this as well. Does anyone have a solution?
I appreciated your time and responses,
thanks,
dk
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您从“AudioFormat.ENCODING_PCM_16BIT”流读取字节时,它实际上为您提供每个样本的高字节和低字节作为 2 个连续字节。如果您只是将每个字节作为样本(而不是实际的一半样本),那么这看起来会非常嘈杂,而且第一个字节的签名将是错误的(它是小尾数顺序)。
要从流中获取有意义的数据,请通过 Shorts 读取,例如
When you read bytes from a "AudioFormat.ENCODING_PCM_16BIT" stream, it actually gives you both the upper and lower bytes of each sample as 2 sequential bytes. This will seem extremely noisy if you just take each byte to be a sample (instead of the half sample it actually is), plus the signing will be wrong for the first byte (it's in little endian order).
To get meaningful data out of the stream, read via shorts, e.g.
自从问这个问题以来已经有一段时间了,所以我不知道回答它是否还有意义。
您获得从 -127 到 128 之间的值的原因是您正在读入一个字节数组,每个字节都保存一个有符号的 8 位数字。对于 16 位音频,请读取一组 Shorts。
恐怕我无法解决噪音问题。
It's been a while since this question was asked, so I don't know if answering it is relevant any more.
The reason you're getting values from -127 to 128 is that you're reading into an array of bytes, each of which hold a signed 8-bit number. For 16-bit audio, read into an array of shorts.
I'm afraid I can't help with the noise issue.
我也许能帮上一点忙。不过我的情况和你一样,所以我只能告诉你我的经历。
我相信您可以像这样获得设备的首选采样率:
16 位编码模式是唯一适用于 AudioRecord 的模式。我不确定为什么你会得到类似 8Bit 的输出(对吗?)。也许有人知道。
我也不确定你如何从检索到的字节中提取幅度,你这样做了吗?
最后,我相信您需要使用周期性侦听器函数,如下所示:
这里有两个我无法回答的大问题,我也想知道自己的答案:
我希望我能提供更多帮助。
I might be able to help a tiny bit. However, I am in the same situation as you so I can only tell you about my experiences.
I believe you can get your device's preferred sampleRate like so:
The 16Bit encoding mode is the only one that works with AudioRecord. I am unsure why you are getting 8Bit like output (right?). Maybe someone knows.
I am also unsure how you pull the amplitude from the retrieved bytes, did you do this?
Finally, I believe you need to use the periodic listener functions, like so:
There are two big questions here which I cannot answer and want to know the answer of myself as well:
I wish I could help more.
这个开源项目有大量的帮助器类来帮助您获取音频数据并进行分析实验:
https://github.com/gast-lib/gast-lib
它有一个 AsyncTask
它有一些控制 AudioRecorder
它甚至有一个 简单频率估计算法
This open source project has a good amount of helper classes to help you acquire the audio data and experiment with analyzing it:
https://github.com/gast-lib/gast-lib
It has an AsyncTask
It has something that controls AudioRecorder
It even has a simple frequency estimation algorithm