用 AudioTrack 播放 PCM 有点吵

Playing PCM with AudioTrack is a little noisy

我正在从服务器套接字获取 GSM 字节数组中的音频数据,我正在使用 this GSMDecoder 将其解码为 PCM 并播放。解码器在长度为 33 的字节数组和长度为 160 的 returns int 数组中获取 gsm 数据。

首先(在 for 循环中)我将 GSM 字节数组切割成 33 的长度并将其提供给解码器。解码器的返回值是 pcm int 数组,然后我将每个解码块 (pcmChunk) 添加到名为 AudioStream 的自定义 InputStream:

 int x = 33; 

 //p is the GSM bytearray
 int len = p.length;

 byte[] gsmChunk;
 int[] pcmChunk;


 for (int i = 0; i < len - x + 1; i += x) {
      gsmChunk= Arrays.copyOfRange(p, i, i + x);
      pcmChunk= gsmDecoder.decode(gsmChunk);
      audioStream.addData(pcmChunk);
 }

 if (len % x != 0) {//end of array
      gsmChunk= Arrays.copyOfRange(p, len - len % x, len);
      pcmChunk= gsmDecoder.decode(gsmChunk);
      audioStream.addData(pcmChunk);
 }

 writeToAudioTrack(audioStream);

然后将包含 pcm 数据的 audioStream 传递给 writeToAudioTrack() 方法进行播放。

private void writeToAudioTrack(InputStream is) throws IOException {
    int i;
    byte[] s = new byte[BUFFER_SIZE]; //BUFFER_SIZE = 64

    while ((i = is.read(s, 0, BUFFER_SIZE)) > -1) {
        audioTrack.write(s, 0, i);

    }

}

AudioTrack 已经设置:

    int sampleRate = 4200;
    int minBufferSize = AudioTrack.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);

AudioStream.java:

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;


    public class AudioStream extends InputStream {


    private ArrayList<Integer> pcm;


    public AudioStream() {
        pcm = new ArrayList<>();
    }

    public void addData(int data[]){
        for(int i=0 ; i<data.length ; i++){
            pcm.add(data[i]);
        }
    }

    @Override
    public int read() throws IOException {
        if(pcm.size()>0) {
            int r= pcm.remove(0);

            return (r>>4) & 0xFF;
        }
        return -1;
    }
}

AudioStream的read()方法返回值:

12-17 18:59:20.788  : 247
12-17 18:59:20.788  : 249
12-17 18:59:20.788  : 252
12-17 18:59:20.788  : 0
12-17 18:59:20.788  : 3
12-17 18:59:20.788  : 247
12-17 18:59:20.788  : 241
12-17 18:59:20.788  : 249
12-17 18:59:20.788  : 6
12-17 18:59:20.788  : 11
12-17 18:59:20.788  : 5
12-17 18:59:20.788  : 249
12-17 18:59:20.788  : 242
12-17 18:59:20.788  : 249
12-17 18:59:20.788  : 5
12-17 18:59:20.788  : 9
12-17 18:59:20.788  : 3
12-17 18:59:20.788  : 247
12-17 18:59:20.788  : 244
12-17 18:59:20.788  : 252
12-17 18:59:20.788  : 3
12-17 18:59:20.788  : 6
12-17 18:59:20.788  : 0
12-17 18:59:20.788  : 252
12-17 18:59:20.788  : 252
12-17 18:59:20.788  : 0
12-17 18:59:20.788  : 1
12-17 18:59:20.788  : 255
12-17 18:59:20.788  : 253
12-17 18:59:20.788  : 252
12-17 18:59:20.788  : 254
12-17 18:59:20.788  : 1
12-17 18:59:20.788  : 5
12-17 18:59:20.788  : 3
12-17 18:59:20.788  : 254
12-17 18:59:20.788  : 0
12-17 18:59:20.788  : 3
12-17 18:59:20.788  : 2
12-17 18:59:20.788  : 4
12-17 18:59:20.788  : 2
12-17 18:59:20.788  : 253
12-17 18:59:20.788  : 253
12-17 18:59:20.788  : 0
12-17 18:59:20.788  : 3
12-17 18:59:20.788  : 10
12-17 18:59:20.788  : 5
12-17 18:59:20.788  : 250
12-17 18:59:20.793  : 250
12-17 18:59:20.793  : 253
12-17 18:59:20.793  : 2
12-17 18:59:20.793  : 12
12-17 18:59:20.793  : 6
12-17 18:59:20.793  : 248
12-17 18:59:20.793  : 248
12-17 18:59:20.793  : 2
12-17 18:59:20.793  : 9
12-17 18:59:20.793  : 19
12-17 18:59:20.793  : 13
12-17 18:59:20.793  : 249
12-17 18:59:20.793  : 244
12-17 18:59:20.793  : 254
12-17 18:59:20.793  : 8
12-17 18:59:20.793  : 15
12-17 18:59:20.793  : 9
12-17 18:59:20.793  : 249
12-17 18:59:20.793  : 245
12-17 18:59:20.793  : 252
12-17 18:59:20.793  : 7
12-17 18:59:20.793  : 14
12-17 18:59:20.793  : 11
12-17 18:59:20.793  : 253

如果我将 r>>4 更改为 r>>8,结果会更加嘈杂:

12-17 19:21:36.043  : 1
12-17 19:21:36.043  : 254
12-17 19:21:36.043  : 252
12-17 19:21:36.043  : 255
12-17 19:21:36.043  : 1
12-17 19:21:36.043  : 1
12-17 19:21:36.043  : 0
12-17 19:21:36.043  : 253
12-17 19:21:36.043  : 251
12-17 19:21:36.043  : 255
12-17 19:21:36.043  : 1
12-17 19:21:36.043  : 2
12-17 19:21:36.043  : 2
12-17 19:21:36.043  : 1
12-17 19:21:36.043  : 254
12-17 19:21:36.043  : 253
12-17 19:21:36.043  : 254
12-17 19:21:36.043  : 254
12-17 19:21:36.043  : 0
12-17 19:21:36.043  : 2
12-17 19:21:36.043  : 1
12-17 19:21:36.043  : 255
12-17 19:21:36.043  : 253
12-17 19:21:36.043  : 251
12-17 19:21:36.043  : 254
12-17 19:21:36.043  : 2
12-17 19:21:36.043  : 4
12-17 19:21:36.043  : 1
12-17 19:21:36.043  : 254
12-17 19:21:36.043  : 250
12-17 19:21:36.043  : 251
12-17 19:21:36.043  : 0
12-17 19:21:36.043  : 4
12-17 19:21:36.043  : 4
12-17 19:21:36.043  : 0
12-17 19:21:36.043  : 252
12-17 19:21:36.043  : 251
12-17 19:21:36.043  : 255
12-17 19:21:36.043  : 4
12-17 19:21:36.043  : 4
12-17 19:21:36.043  : 0
12-17 19:21:36.048  : 251
12-17 19:21:36.048  : 250
12-17 19:21:36.048  : 255
12-17 19:21:36.048  : 4
12-17 19:21:36.048  : 5
12-17 19:21:36.048  : 1
12-17 19:21:36.048  : 251
12-17 19:21:36.048  : 249
12-17 19:21:36.048  : 253
12-17 19:21:36.048  : 3
12-17 19:21:36.048  : 5
12-17 19:21:36.048  : 2
12-17 19:21:36.048  : 253
12-17 19:21:36.048  : 251
12-17 19:21:36.048  : 253
12-17 19:21:36.048  : 2
12-17 19:21:36.048  : 3
12-17 19:21:36.048  : 1
12-17 19:21:36.048  : 253
12-17 19:21:36.048  : 251
12-17 19:21:36.048  : 254
12-17 19:21:36.048  : 2
12-17 19:21:36.048  : 3
12-17 19:21:36.048  : 1
12-17 19:21:36.048  : 1
12-17 19:21:36.048  : 0
12-17 19:21:36.048  : 254
12-17 19:21:36.048  : 254
12-17 19:21:36.048  : 255
12-17 19:21:36.048  : 255

我想这是字节顺序问题。

我切换到 this decoder,现在它工作正常,没有任何噪音!