【发布时间】:2013-05-19 23:03:10
【问题描述】:
我想将音频流从 PC(C++ 应用程序,使用 FMOD-API 解码音频数据并通过 UDP 套接字发送)发送到 Android 设备。通信已经开始,我可以在 android 上听到“声音”(100 毫秒的声音,然后是 900 毫秒的静音,交替)。
我不知道为什么声音会断断续续 - 在 PC 上,相同的音频流可以很好地播放质量。我认为问题出在android上..
代码如下:
DatagramSocket sock = new DatagramSocket(12345);
byte []bSockBuffer = new byte[1024];
byte []bRecvBufTmp;
int iAudioBufSize, iCurAudioBufPos = 0;
sock.setReceiveBufferSize(bSockBuffer.length);
// Audio Stream initialisieren:
iAudioBufSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT, iAudioBufSize, AudioTrack.MODE_STREAM);
track.play();
while (true)
{
DatagramPacket pack = new DatagramPacket(bSockBuffer, bSockBuffer.length);
// Paket empfangen:
sock.receive(pack);
track.write(pack.getData(), 0, pack.getLength());
}
我确定正确设置了“AudioTrack”对象,设置与我在 c++ 应用程序中的设置进行比较。
另一个步骤是在临时“byte[]”变量中预缓冲接收到的套接字数据,并在达到缓冲区“iAudioBufSize”的大小时将其写入 AudioTrack 对象。 这没有帮助。
有什么想法吗? 谢谢
[编辑] C++ 应用程序代码,使用了 FMOD API 示例的示例“手动解码”:
FMOD_RESULT F_CALLBACK pcmreadcallback(FMOD_SOUND *sound, void *data, unsigned int datalen)
{
CCtrlSocket *cClientTmp = /* Obtaining target client sock here */;
FMOD_RESULT result;
unsigned int read, uSentTmp, uSizeTmp;
EnterCriticalSection(&decodecrit);
if (!decodesound)
return (FMOD_ERR_FILE_EOF);
result = decodesound->readData(data, datalen, &read);
if (result == FMOD_ERR_FILE_EOF)
{
// Handle looping:
decodesound->seekData(0);
datalen -= read;
result = decodesound->readData((char*) data + read, datalen, &read);
}
// Split package in multiple parts:
uSentTmp = 0;
do
{
uSizeTmp = (read - uSentTmp);
if (uSizeTmp > 1024)
uSizeTmp = 1024;
uSentTmp += cClientTmp->SendAudioData((char*) data + uSentTmp, uSizeTmp);
} while (uSentTmp < read);
LeaveCriticalSection(&decodecrit);
return (FMOD_OK);
}
【问题讨论】:
-
您知道 UDP 数据报可能大于 1024 字节,对吧?实际数据包大小是多少?
-
我已经将我的 c++ 应用程序中每个发送的包都切割成 1024 字节的片段。我还比较了我发送和接收的尺寸 - 它很合身。
-
您应该尝试更改缓冲区大小。 socket 和 AudioTrack 播放器都将当前值乘以 2 或 3 并检查是否有变化
-
我已经尝试过尺寸..
-
改变 AudioTrack-buffer 的大小会改变静音的持续时间。我还尝试了 Thread.sleep([various timings]);在 track.write() 之后; - 改变了沉默的持续时间......
标签: android sockets stream udp audiotrack