用 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,现在它工作正常,没有任何噪音!
我正在从服务器套接字获取 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,现在它工作正常,没有任何噪音!