android - android系统中各种音源有什么区别?

标签 android audio audiorecord audiotrack

我正在尝试在 Android 中构建一个实时降噪程序
我使用 AudioRecord 获取原始输入声音数据,并使用 AudioTrack 播放它。
在初始化 Audiorecord 时,我使用代码

record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, min);  

回放时我使用代码

track = new AudioTrack(AudioManager.MODE_IN_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);   

这些设置非常适合我的 Nexus 7 平板电脑(非手机),但是当我尝试在 LG Optimus(或任何其他手机)上运行它时,输出音量非常低,即使在硬件的最大音量下也是如此。如果我将AudioManager.MODE_IN_COMMUNICATION改成其他值,有时根本没有输出,或者有时第一次执行程序时输出很大,然后在后续运行时没有输出。这个问题在 Nexus 7 中没有出现(虽然某些选项在 Nexus 7 中也会导致没有声音输出)

(我对原始音频数据进行FFT,然后通过降噪算法函数运行它,计算FFT后每个频率分量的增益值,并将最终输出与这个增益值相乘。我已经能够弄清楚每当扬声器没有输出时,通常是由于这些增益值获得了 NaN 值,但这是一个不同的问题)。

我想知道的是,Audiomanager中定义的各种类型的音频输出源,如AudioManager.MODE_IN_COMMUNICATION和音频输入的区别到底是什么MediaRecorder.AudioSource 中的来源?为什么他们的某些选项会导致平板电脑和手机出现不同的行为?

--- 编辑 ---
另外最近听说,在手机里,执行这个程序后,手机里的输出声音很小,退出程序后,手机正常运行的声音一直停留在那个小音量。一旦程序终止,我如何确保所有相关的声音(或任何其他手机资源)恢复到原来的设置?

--- 编辑 2 ---
旧的初始化代码:

int min = AudioRecord.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, min);
int maxJitter = AudioTrack.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
am.setMode(AudioManager.MODE_IN_COMMUNICATION); // ORIGINAL   AudioManager.MODE_IN_COMMUNICATION  

--- 编辑 3 ---
当前初始化方案

am.setMode(AudioManager.MODE_IN_COMMUNICATION); // ADDED LATER: DELETE THIS LINE IF IT CAUSES PROBLEMS
int min = AudioRecord.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, min);
int maxJitter = AudioTrack.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);

--- 编辑 4 ---
onResume() 中的代码

am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
currentAudioManagerMode = am.getMode();  
... // (function with initialization code from EDIT 3)  

onPause() 中的代码

am.setMode(currentAudioManagerMode);  

最佳答案

如果您需要 SDK API documentation 中提供的更多信息, 那么我可以建议您引用相应的 source code ?同样,您可以对 MediaRecorder 类执行相同的操作。

关于您在运行应用程序后音频设置发生更改的问题,我建议您在启动应用程序时先阅读模式(在硬件资源上使用相应的 getMode() 方法) ) 并保存它们并在您退出/进入后台应用程序时恢复它们(在硬件资源上使用相应的 setMode() 方法)。这里的硬件资源是MediaRecorder和AudioManager。

HTH.

关于android - android系统中各种音源有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19417541/

相关文章:

安卓 list : configChanges:screenSize is not available

android - 当用户单击 Urban Airship 通知时重新启动 android 应用程序

android - 存储游戏数据的合适方式是什么?

html - 如何在网络上播放音频文件但未启用下载?

java - Android 的 AudioRecord 类以什么顺序存储音频样本?

android - AudioRecord 没有足够的内存用于 AudioTrack

android - RuntimeException:自定义 TextView 加载字体无法制作原生字体或内存泄漏

html - 基于 Web 的广播和音频流服务是否使用 Web Audio API 进行播放?

android - 如何在 Android 上合成乐器的声音(钢琴、鼓、吉他等...)

java - AudioRecord 在 Android 5.01 上产生零间隙