Android 实时播放来自麦克风的声音
我一直在尝试让我的应用程序录制来自麦克风的声音并(大约)实时播放,但是没有成功 我分别使用AudioRecord和AudioTrack类进行录制和播放。我尝试过不同的方法,我试着录制传入的声音并将其写入文件,效果很好。我也尝试过用AudioTrack播放那个文件中的声音,效果也不错。问题是当我试图实时播放声音时,而不是在写入文件后读取文件 代码如下:Android 实时播放来自麦克风的声音,android,audio,real-time,record,audio-recording,Android,Audio,Real Time,Record,Audio Recording,我一直在尝试让我的应用程序录制来自麦克风的声音并(大约)实时播放,但是没有成功 我分别使用AudioRecord和AudioTrack类进行录制和播放。我尝试过不同的方法,我试着录制传入的声音并将其写入文件,效果很好。我也尝试过用AudioTrack播放那个文件中的声音,效果也不错。问题是当我试图实时播放声音时,而不是在写入文件后读取文件 代码如下: //variables private int audioSource = MediaRecorder.AudioSource.MIC; priv
//variables
private int audioSource = MediaRecorder.AudioSource.MIC;
private int samplingRate = 44100; /* in Hz*/
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private int bufferSize = AudioRecord.getMinBufferSize(samplingRate, channelConfig, audioFormat);
private int sampleNumBits = 16;
private int numChannels = 1;
// …
AudioRecord recorder = new AudioRecord(audioSource, samplingRate, channelConfig, audioFormat, bufferSize);
recorder.startRecording();
isRecording = true;
AudioTrack audioPlayer = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSize, AudioTrack.MODE_STREAM);
if(audioPlayer.getPlayState() != AudioTrack.PLAYSTATE_PLAYING)
audioPlayer.play();
//capture data and record to file
int readBytes=0, writtenBytes=0;
do{
readBytes = recorder.read(data, 0, bufferSize);
if(AudioRecord.ERROR_INVALID_OPERATION != readBytes){
writtenBytes += audioPlayer.write(data, 0, readBytes);
}
}
while(isRecording);
它抛出一个java.lang.IllegalStateException,原因是“在未初始化的音轨上调用play()”
但是,如果我将AudioTrack初始化更改为使用采样率8000Hz和采样格式8位(而不是16位),它将不再引发异常,应用程序将运行,尽管它会产生可怕的噪音
当我播放一个文件中的AudioTrack时,AudioTrack的初始化没有问题,我尝试了44100和16位,它工作正常,产生了正确的声音
有什么帮助吗?所有本机Android音频都是。您只能实时播放格式,或者使用特殊的编解码器,我认为这在Android上并不微不足道 关键是,如果你想同时录制/播放音频,你必须创建自己的音频缓冲区并将原始PCM编码的音频样本存储在那里(我不确定你是否在想duh!或者这是否是你的全部想法,所以我会尽量弄清楚,但不要嚼自己的口香糖) PCM是模拟信号的数字表示,其中音频是原始声波的一组“快照”。因为所有聪明的数学家和工程师都看到了减少数据位数的潜力,他们想出了各种各样的方法。编码(压缩)信号的表示与原始PCM信号非常不同,必须进行解码(en coder+dec oder=编解码器)。除非您使用特殊算法和媒体流编解码器,否则不可能像您尝试的那样播放编码信号,因为它不是逐样本编码的,而是逐帧编码的,您需要整个样本帧(如果不是完整的信号)来解码此帧 方法是手动存储来自麦克风缓冲区的音频样本,并手动将其输入输出缓冲区。你必须为此做一些编码,但我相信有一些开源应用程序你可以看看,并在它们的源代码上达到顶峰(当然,除非你以后愿意出售你的应用程序,但这是一个完全不同的讨论) 如果您正在为Android 2.3或更高版本开发,并且不太害怕在中编程,您可以尝试使用。下面列出了OpenSL ES的Android特定功能。该平台允许您更灵活地处理音频,如果您的应用程序高度依赖音频处理,您可能会找到您所需要的 将抛出一个java.lang.IllegalStateException,原因如下 由“在未初始化的音轨上调用play()”引起
这是因为缓冲区太小。我尝试了“bufferSize+=2048;”,然后就没事了。我遇到了类似的问题,我通过将此权限添加到清单文件中解决了这个问题:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
确保您的var数据足以进行采样
例如:如果将samplingRate用作44100,则数据字节数组的长度应为44101或更大+1。我也有同样的问题。使用较大的缓冲区大小初始化
音频曲目
,解决了该问题。就是你需要的那个。