抱歉,我说英语不好。
我做了两个项目(QT,c ++,mingw32)。
使用RTP(ortp-0.20.0)发送/接收音频流。
但收到的声音是扭曲的。 (输出声音很糟糕。)
有人可以帮忙吗?
RTPSend.cpp
#include <ortp/ortp.h> // ortp-0.20.0
RtpSession *session;
unsigned char buffer[160];
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define BS 8000
int sampleRate = 8000; // 8000, 11025, 16000, 22050, 24000, 32000, 44100
int NUMPTS = sampleRate * 10; // 10 seconds
short int waveIn[BS];
HWAVEIN hWaveIn;
WAVEHDR WaveInHdr;
MMRESULT result;
WAVEFORMATEX pFormat;
uint32_t user_ts = 0;
void CALLBACK waveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
WAVEHDR *pHdr=NULL;
WAVEHDR pHdr2;
switch(uMsg)
{
case WIM_CLOSE:
cout << "waveInProc()... WIM_CLOSE" << endl;
break;
case WIM_DATA:
{
pHdr = (WAVEHDR *)dwParam1;
pHdr2.lpData = (LPSTR)pHdr->lpData;
pHdr2.dwBufferLength = pHdr->dwBufferLength;
pHdr2.dwBytesRecorded = pHdr->dwBytesRecorded;
pHdr2.dwUser = 0;
pHdr2.dwFlags = 0;
pHdr2.dwLoops = 0;
cout << "waveInProc()... WIM_DATA : " << "pHdr->dwBufferLength:" << pHdr->dwBufferLength << " pHdr->dwBytesRecorded:" << pHdr->dwBytesRecorded<< endl;
int len = pHdr->dwBytesRecorded;
for(int i=0; i<len;) {
int length = 160;
if(len-i < 160) length=len-i;
memcpy(buffer, pHdr->lpData+i, length);
rtp_session_send_with_ts(session, buffer, length, user_ts);
user_ts+=160;
i+=length;
}
waveInPrepareHeader(hwi, pHdr, sizeof(WAVEHDR));
waveInAddBuffer(hwi, pHdr, sizeof(WAVEHDR));
}
break;
case WIM_OPEN:
cout << "waveInProc()... WIM_OPEN" << endl;
break;
default:
break;
}
}
int main(int argv, char **args)
{
ortp_init();
ortp_scheduler_init();
ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR);
session=rtp_session_new(RTP_SESSION_SENDONLY);
rtp_session_set_scheduling_mode(session,1);
rtp_session_set_blocking_mode(session,1);
rtp_session_set_connected_mode(session,TRUE);
rtp_session_set_remote_addr(session,"192.168.0.181",61610);
rtp_session_set_payload_type(session,0);
pFormat.wFormatTag = WAVE_FORMAT_PCM;
pFormat.nChannels = 1;
pFormat.nSamplesPerSec = sampleRate;
pFormat.nAvgBytesPerSec = 2 * sampleRate;
pFormat.nBlockAlign = 2;
pFormat.wBitsPerSample = 16;
pFormat.cbSize = 0;
result = waveInOpen(&hWaveIn, WAVE_MAPPER, &pFormat, (DWORD_PTR)waveInProc, NULL, CALLBACK_FUNCTION);
if(result) {
cout << "Failed to open waveform input device." << endl;
return -1;
}
WaveInHdr.lpData = (LPSTR)waveIn;
WaveInHdr.dwBufferLength = BS;
WaveInHdr.dwBytesRecorded = 0;
WaveInHdr.dwUser = 0;
WaveInHdr.dwFlags = 0;
WaveInHdr.dwLoops = 0;
waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
result = waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
if(result) {
cout << "Failed to read block from device" << endl;
return -1;
}
result = waveInStart(hWaveIn);
if(result) {
cout << "Failed to start recording" << endl;
return -1;
}
cout << "Recording..." << endl;
Sleep((NUMPTS/sampleRate) * 1000);
waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
// waveInClose(hWaveIn);
rtp_session_destroy(session);
ortp_exit();
ortp_global_stats_display();
return 0;
}
RTPRecv.cpp
#include <ortp/ortp.h> // ortp-0.20.0
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int sampleRate = 8000; // 8000, 11025, 16000, 22050, 24000, 32000, 44100
WAVEHDR WaveOutHdr;
MMRESULT result;
HWAVEOUT hWaveOut;
WAVEFORMATEX pFormat;
int main(int argv, char **args)
{
pFormat.wFormatTag = WAVE_FORMAT_PCM;
pFormat.nChannels = 1;
pFormat.nSamplesPerSec = sampleRate;
pFormat.nAvgBytesPerSec = 2 * sampleRate;
pFormat.nBlockAlign = 2;
pFormat.wBitsPerSample = 16;
pFormat.cbSize = 0;
if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT))
{
MessageBoxA(NULL, "Failed to replay", NULL, MB_OK | MB_ICONEXCLAMATION );
}
RtpSession *session;
int jittcomp=40;
bool_t adapt=TRUE;
ortp_init();
ortp_scheduler_init();
ortp_set_log_level_mask(ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR);
session=rtp_session_new(RTP_SESSION_RECVONLY);
rtp_session_set_scheduling_mode(session,1);
rtp_session_set_blocking_mode(session,1);
rtp_session_set_local_addr(session,"0.0.0.0",61610);
rtp_session_set_connected_mode(session,TRUE);
rtp_session_set_symmetric_rtp(session,TRUE);
rtp_session_enable_adaptive_jitter_compensation(session,adapt);
rtp_session_set_jitter_compensation(session,jittcomp);
rtp_session_set_payload_type(session,0);
rtp_session_signal_connect(session,"ssrc_changed",(RtpCallback)rtp_session_reset,0);
unsigned char buffer[160];
int have_more;
int err;
uint32_t ts=0;
int stream_received=0;
while(1) {
have_more=1;
while (have_more){
err=rtp_session_recv_with_ts(session, buffer, 160, ts, &have_more);
if (err>0) stream_received=1;
if ((stream_received) && (err>0)) {
WaveOutHdr.lpData = (LPSTR)buffer;
WaveOutHdr.dwBufferLength = 160;
WaveOutHdr.dwBytesRecorded = 160;
WaveOutHdr.dwUser = 0;
WaveOutHdr.dwFlags = 0;
WaveOutHdr.dwLoops = 0;
waveOutPrepareHeader(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR));
waveOutWrite(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR));
}
}
ts+=160;
}
waveOutUnprepareHeader(hWaveOut, &WaveOutHdr, sizeof(WAVEHDR));
waveOutClose(hWaveOut);
rtp_session_destroy(session);
ortp_exit();
ortp_global_stats_display();
return 0;
}
答案 0 :(得分:0)
您可以在客户端制作一个大缓冲区。例如:缓冲区持有10秒。尝试接收小缓冲区并将其添加到自waveOutGetPosition()
以来的大缓冲区并连续释放主缓冲区,然后在waveOutWrite()
消息后WOM_DONE
。