我正在测试一个Android应用程序的概念,它允许您通过RFCOMM(从PC到手机)传输蓝牙。我可以将音频从我的电脑传输到手机没问题,并开始流式传输音频。问题是音频开始断断续续,我从AudioTrack得到一个缓冲区欠载错误消息。从套接字读取是花费最多时间的。当我计时时,当读取返回时需要≥1000毫秒时发生欠载,而平均需要几百个才能返回。以下是我的代码:
public ConnectedThread(BluetoothSocket socket) {
this.setPriority(MAX_PRIORITY);
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams; using temp objects because
// member streams are final.
try {
tmpIn = socket.getInputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating input stream", e);
}
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating output stream", e);
}
minBuffSize = AudioTrack.getMinBufferSize(48000, CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
m_audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 48000, CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT, minBuffSize /* 1 second buffer */,
AudioTrack.MODE_STREAM);
mmBuffer = new byte[minBuffSize * 2];
mmInStream = tmpIn;
mmOutStream = tmpOut;
// distream = new DataInputStream(new BufferedInputStream(mmInStream, 1000000));
distream = new DataInputStream(mmInStream);
}
public void run() {
int numBytes = 0; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs.
boolean firstRun = true;
while (true) {
try {
final long startTime = System.currentTimeMillis();
distream.readFully(mmBuffer);
final long endTime = System.currentTimeMillis();
int temp = m_audioTrack.write(mmBuffer, 0, mmBuffer.length);
System.out.println("Total execution time: " + (endTime - startTime) );
if (firstRun) {
m_audioTrack.play();
firstRun = false;
}
} catch (IOException e) {
Log.d(TAG, "Input stream was disconnected", e);
break;
}
}
有关如何加快套接字读取或防止欠载的任何建议吗?
答案 0 :(得分:1)
让我们考虑这段代码:
minBuffSize = AudioTrack.getMinBufferSize(48000, CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
m_audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 48000, CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT, minBuffSize /* 1 second buffer */,
AudioTrack.MODE_STREAM);
请注意不一致之处:
AudioTrack.getMinBufferSize()
值调用CHANNEL_OUT_MONO
方法。AudioTrack
值调用CHANNEL_OUT_STEREO
构造函数。请考虑为AudioTrack.getMinBufferSize()
方法调用使用相同的参数,尤其是CHANNEL_OUT_STEREO
值。更好的是,请考虑提取适当的常量或局部变量,以将其重用于两个方法调用:sampleRate
,channelConfig
,audioFormat
。