Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 实时播放来自麦克风的声音_Android_Audio_Real Time_Record_Audio Recording - Fatal编程技术网

Android 实时播放来自麦克风的声音

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

我一直在尝试让我的应用程序录制来自麦克风的声音并(大约)实时播放,但是没有成功

我分别使用AudioRecord和AudioTrack类进行录制和播放。我尝试过不同的方法,我试着录制传入的声音并将其写入文件,效果很好。我也尝试过用AudioTrack播放那个文件中的声音,效果也不错。问题是当我试图实时播放声音时,而不是在写入文件后读取文件

代码如下:

//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。我也有同样的问题。使用较大的缓冲区大小初始化
音频曲目
,解决了该问题。就是你需要的那个。