Android - 如何将自己的音频编解码器添加到AudioRecord?

5

我目前拥有一个用于测试Android设备音频的回环程序。

它使用AudioRecord和AudioTrack从麦克风录制PCM音频,并将PCM音频通过听筒播放出来。

以下是代码:

public class Record extends Thread
  {

          static final int bufferSize = 200000;
          final short[] buffer = new short[bufferSize];
          short[] readBuffer = new short[bufferSize];

          public void run() {  
            isRecording = true;
            android.os.Process.setThreadPriority
            (android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

            int buffersize = AudioRecord.getMinBufferSize(11025,
            AudioFormat.CHANNEL_CONFIGURATION_MONO,
            AudioFormat.ENCODING_PCM_16BIT);

                           arec = new AudioRecord(MediaRecorder.AudioSource.MIC,
                                           11025,
                                           AudioFormat.CHANNEL_CONFIGURATION_MONO,
                                           AudioFormat.ENCODING_PCM_16BIT,
                                           buffersize);

                           atrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
                                           11025,
                                           AudioFormat.CHANNEL_CONFIGURATION_MONO,
                                           AudioFormat.ENCODING_PCM_16BIT,
                                           buffersize,
                                           AudioTrack.MODE_STREAM);


                           atrack.setPlaybackRate(11025);

                           byte[] buffer = new byte[buffersize];
                           arec.startRecording();
                           atrack.play();

                           while(isRecording) {

                                   arec.read(buffer, 0, buffersize);
                                   atrack.write(buffer, 0, buffer.length);
                           }  
          }
  }

正如您在创建AudioTrack和AudioRecord时所看到的,编码是通过AudioFormat提供的,但这仅允许16位或8位PCM。

我现在有自己的G711编解码器实现,并希望能够对来自麦克风的音频进行编码并对进入EarPiece的音频进行解码,因此我有encode(short lin[], int offset, byte enc[], int frames)decode(byte enc[], short lin[], int frames)方法,但我不确定如何使用它们来对AudioRecord和AudioTrack中的音频进行编码和解码。

有人可以帮助我或指点我方向吗?


嗨,唐纳尔,你能更新一下这个问题,告诉我们最终的实现吗?我已经试了好几天在 G711 中编码/解码,但一直没有成功。如果我们能看到你是如何做的那就太棒了……我遇到了很多与此问题相关的问题。谢谢。 - Juan Pedro Martinez
嗨Juan,恐怕我已经没有最终解决方案了,那是我早就离开的项目的一部分,我已经没有或无法记住解决方案的代码,十分抱歉。 - Donal Rafferty
2个回答

2
将您的arec.read(buffer, 0, buffersize)调用更改为使用AudioRecord中的Bytebuffer read()方法。
一旦您将字节输入到ByteBuffer对象中,您就可以插入G711实现调用编码并使用ByteBuffer.asShortBuffer()方法将捕获的PCM数据传递给编码器。
这样就可以解决您最初的问题,而无需引入第三方库来为您完成这项工作。(此答案是为以后遇到此问题的人准备的)。
我的问题是为什么?
在您上面的代码中,您从麦克风捕获PCM数据,并直接将其写入缓冲区以进行播放。
在您的实现中,按照PCM -> G711(编码) -> G711(解码) -> PCM的路径是没有意义的。这只是引入了不必要的处理和延迟。现在,如果您要将编码数据写入文件而不是尝试通过耳机播放它,那将是另一回事,但是您当前的代码似乎并没有将PCM数据编码的实际用途。
在这里引入自己的编解码器只有在将压缩的语音数据写入文件(例如记录通话数据)或通过网络发送时才有意义。

0

我知道这是一个相当老的帖子。你能够让你自己的G711工作吗?我的初始想法是使用为内核编译的库并使用JNI来调用它。


请在原问题下使用评论来提出这种类型的问题。在获得更多细节之前,请不要创建答案。祝你好运! :) - Fabian Fagerholm
嗨,Chris,我确实使用了第三方库来实现这个。 - Donal Rafferty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接