-
May 14th, 2008, 10:03 PM
#1
waveInStart audio is very choppy
I am writing an application to send audio over a socket, problem is, its very very choppy! my buffer size is 1000 bytes, I tried 500, 4096, 8000, all of which exhibit very choppy sound! can someone help? what do I need to do to stream PCM audio without choppy sound? my settings are...
WAVEFORMATEX wfx;
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 1; //1: mono, 2, stereo
wfx.nSamplesPerSec = 11025; //11025,22050,44100
wfx.wBitsPerSample = 8; //8,16
this is what Im doing...
---to send audio from the microphone---
waveInPrepareHeader
waveInAddBuffer
waveInStart
//wait for MM_WIM_DATA
//I make a heap copy of WAVEHDR's lpData , and post to another thread
//(done just for testing purpose, will send over socket eventually)
waveInStop
waveInUnprepareHeader
-repeats
--to receive the audio---
thread receives the message
waveOutPause
waveOutUnprepareHeader
waveOutPrepareHeader
waveOutWrite
waveOutRestart
//wait for next message
-
May 15th, 2008, 04:23 AM
#2
Re: waveInStart audio is very choppy
Have you tried recording the audio and playing it back on the same machine without sockets? As in, the recording side places audio in a buffer, which is then used by the playback side.
When you try that, does that sound choppy as well?
Streaming live audio over a network is not trivial. You need to match the audio clock rates at both ends of the connection, and you need to counteract any networking jitter. The easy fix for the last option is a larger receive buffer, which will then of course increase latency.
-
May 15th, 2008, 09:28 AM
#3
Re: waveInStart audio is very choppy
Thanks for you response! I did end up figuring it out last night!
The problem was, I did not have enough buffers flowing to the sound devices.
I increased my buffers to 10 x 1000, and this is the method am using now, and its really smooth!....
---to send audio from the microphone---
{create WAVEHDR on heap, waveInPrepareHeader, waveInAddBuffer}
//loop previous line 10 times to make a nice buffer for mic
waveInStart
//on MM_WIM_DATA we used a buffer, so add another one, then cleanup
//the one we just rcv'ed (after sending it of course)...
{create WAVEHDR on heap, waveInPrepareHeader, waveInAddBuffer}
{waveInUnprepareHeader passed by MM_WIM_DATA, send lpData,
delete WAVEHDR, and then lpData}
---to play audio---
rcv lpData, waveOutPrepareHeader, waveOutWrite
on MM_WOM_DONE message, I cleanup the WAVEHDR
this method works perfect, and is not choppy at all!
-
May 15th, 2008, 04:12 PM
#4
Re: waveInStart audio is very choppy
Glad to hear you got it sorted, and also thank you for posting your solution here!
-
December 19th, 2009, 07:43 AM
#5
Re: waveInStart audio is very choppy
Hi,
I'm sorry to bring this up after along while... I would like to save the first one second of audio data from the internal Microphone. I am doing this in order to get to know better the waveForm API. this is the code I've written so far:
Code:
#include <windows.h>
#pragma comment (lib, "winmm.lib")
#include <mmsystem.h>
#include <iostream>
#define system_buf_len 4096
BOOL CALLBACK myCallback();
int main()
{
// Definisco la struttura WAVEFORMATEX
WAVEFORMATEX waveFormat;
waveFormat.wFormatTag = WAVE_FORMAT_PCM;
waveFormat.wBitsPerSample = 16;
waveFormat.nChannels = 1;
waveFormat.nSamplesPerSec = 44100;
waveFormat.nBlockAlign = waveFormat.nChannels *
waveFormat.wBitsPerSample / 8;
waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec *
waveFormat.nBlockAlign;
waveFormat.cbSize = 0;
MMRESULT mmres; // ...
HWAVEIN phvi; // Handle for the input device
UINT uDevice = 0; // Device id "Gruppo Microfoni"
// waveInOpen
mmres = waveInOpen(&phvi,
uDevice,
(LPWAVEFORMATEX)&waveFormat,
0,
0,
CALLBACK_EVENT
);
// Prepare Buffer
char *buf = (char *)malloc(system_buf_len);
WAVEHDR buffer;
buffer.lpData = buf;
buffer.dwBufferLength = system_buf_len;
buffer.dwBytesRecorded = 0;
buffer.dwUser = 0;
buffer.dwFlags = 0;
buffer.dwLoops = 0;
// waveInPrepareHeader
waveInPrepareHeader(phvi, &buffer, sizeof(WAVEHDR));
// waveInAddBuffer
waveInAddBuffer(phvi, &buffer, sizeof(WAVEHDR));
//waveInStart;
waveInStart(phvi);
return 0;
}
I'd like to point out that I am not using any callback function for the
moment...I'd like to know more about that by the way!
Anyway, is the code right so far? after I call waveInStart(); how can I
actually grab the rwa audio data??
thanks!
-
December 19th, 2009, 09:47 AM
#6
Re: waveInStart audio is very choppy
I've never used the callback method with the waveXXX functions so I don't know too much about it. I found this article:
http://www.codeproject.com/KB/audio-...recording.aspx
that discusses issues involved with callback processing. I was looking for a project that I'd used in the past when I ran across the article above. Here's the class I've used before (after hacking it all to hell):
http://www.codeproject.com/KB/audio-video/fister.aspx
-
December 19th, 2009, 11:39 AM
#7
Re: waveInStart audio is very choppy
ok thanks...I am going to check out those links. Anyway...this is something more I have coded so far:
Code:
#include <windows.h>
#pragma comment (lib, "winmm.lib")
#include <mmsystem.h>
#include <iostream>
#include <stdlib.h> // Define "system" function
#define system_buf_len 4096
void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD
dwParam1,DWORD dwParam2);
int main()
{
// Definisco la struttura WAVEFORMATEX
WAVEFORMATEX waveFormat;
waveFormat.wFormatTag = WAVE_FORMAT_PCM;
waveFormat.wBitsPerSample = 16;
waveFormat.nChannels = 1;
waveFormat.nSamplesPerSec = 44100;
waveFormat.nBlockAlign = waveFormat.nChannels *
waveFormat.wBitsPerSample / 8;
waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec *
waveFormat.nBlockAlign;
waveFormat.cbSize = 0;
MMRESULT mmres; // ...
HWAVEIN phvi; // Handle for the input device
UINT uDevice = 0; // Device id "Gruppo Microfoni"
// waveInOpen
mmres = waveInOpen(&phvi,
uDevice,
(LPWAVEFORMATEX)&waveFormat,
(DWORD)waveInProc,
0,
CALLBACK_FUNCTION
);
// Prepare Buffer
char *buf = (char *)malloc(system_buf_len);
WAVEHDR buffer;
buffer.lpData = buf;
buffer.dwBufferLength = system_buf_len;
buffer.dwBytesRecorded = 0;
buffer.dwUser = 0;
buffer.dwFlags = 0;
buffer.dwLoops = 0;
// waveInPrepareHeader
waveInPrepareHeader(phvi, &buffer, sizeof(WAVEHDR));
// waveInAddBuffer
waveInAddBuffer(phvi, &buffer, sizeof(WAVEHDR));
//waveInStart;
waveInStart(phvi);
//
system("pause");
//waveInClose;
waveInClose(phvi);
return 0;
}
void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD
dwParam1,DWORD dwParam2)
{
switch(uMsg)
{
case WIM_DATA:
MessageBox(0,"WIN_DATA","waveInProc",MB_OK);
break;
case WIM_OPEN:
MessageBox(0,"WIN_OPEN","waveInProc",MB_OK);
break;
case WIM_CLOSE:
MessageBox(0,"WIN_CLOSE","waveInProc",MB_OK);
break;
}
}
it basically uses the CALLBACK_FUNCTION
-
December 19th, 2009, 08:02 PM
#8
Re: waveInStart audio is very choppy
I coded the callback function like the following:
Code:
void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
{
WAVEHDR* pWaveHdr;
switch(uMsg)
{
case MM_WIM_DATA:
pWaveHdr = ((WAVEHDR*)dwParam1 );
std::cout << "MM_WIN_DATA" << std::endl;
std::cout << "dwFlags: " << pWaveHdr->dwFlags << std::endl;
std::cout << "dwBytesRecorded: " << pWaveHdr->dwBytesRecorded << std::endl;
std::cout << "lpData: " << &pWaveHdr->lpData << std::endl;
break;
case MM_WIM_OPEN:
std::cout << "MM_WIN_OPEN" << std::endl;
break;
case MM_WIM_CLOSE:
std::cout << "MM_WIN_CLOSE" << std::endl;
break;
}
}
I am getting it working great. yet, I wonder how I can access the actual buffer data! I'd like to save it on a binary file (yep, just 4096 bytes)
thanks
-
December 22nd, 2009, 09:14 PM
#9
Re: waveInStart audio is very choppy
this is some new code...how can I put the recording into a infinite loop? do I have to use threads?
Code:
#include <windows.h>
#pragma comment (lib, "winmm.lib")
#include <mmsystem.h>
#include <iostream>
#include <stdlib.h> // Define "system" function
#include <string>
#define system_buf_len 32768
void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
bool addbuffer(WAVEHDR *pWaveHdr);
int main()
{
// Definisco la struttura WAVEFORMATEX
WAVEFORMATEX waveFormat;
waveFormat.wFormatTag = WAVE_FORMAT_PCM;
waveFormat.wBitsPerSample = 16;
waveFormat.nChannels = 1;
waveFormat.nSamplesPerSec = 44100;
waveFormat.nBlockAlign = (waveFormat.nChannels * waveFormat.wBitsPerSample) / 8;
waveFormat.nAvgBytesPerSec = (waveFormat.nSamplesPerSec * waveFormat.nBlockAlign);
waveFormat.cbSize = 0;
MMRESULT mmres; // ...
HWAVEIN phvi; // Handle for the input device
UINT uDevice = 0; // Device id "Gruppo Microfoni"
// waveInOpen
mmres = waveInOpen(&phvi,
uDevice,
(LPWAVEFORMATEX)&waveFormat,
(DWORD)waveInProc,
0,
CALLBACK_FUNCTION
);
// Prepare Buffer
int i=0;
int num_buff = 20;
WAVEHDR *buffer = (WAVEHDR *) malloc(sizeof(WAVEHDR)*num_buff);
for (i=0; i<num_buff; i++)
{
buffer[i].lpData = (LPSTR) malloc(system_buf_len);
buffer[i].dwBufferLength = system_buf_len;
buffer[i].dwBytesRecorded = 0;
buffer[i].dwUser = 0;
buffer[i].dwFlags = 0;
buffer[i].dwLoops = 0;
waveInPrepareHeader(phvi, &buffer[i], sizeof(WAVEHDR));
waveInAddBuffer(phvi, &buffer[i], sizeof(WAVEHDR));
}
//waveInStart;
waveInStart(phvi);
//waveInClose;
waveInClose(phvi);
system("pause");
return 0;
}
void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
{
WAVEHDR* pWaveHdr;
switch(uMsg)
{
case MM_WIM_DATA:
pWaveHdr = ((WAVEHDR*)dwParam1);
if (pWaveHdr && hwi)
{
if (pWaveHdr->dwFlags && WHDR_DONE == WHDR_DONE)
{
pWaveHdr->dwFlags = 0;
waveInUnprepareHeader(hwi, pWaveHdr, sizeof(WAVEHDR));
if (pWaveHdr->dwBytesRecorded > 0)
{
addbuffer(pWaveHdr);
}
delete[] pWaveHdr->lpData;
pWaveHdr->lpData = NULL;
}
}
break;
case MM_WIM_OPEN:
std::cout << "MM_WIN_OPEN" << std::endl;
break;
case MM_WIM_CLOSE:
std::cout << "MM_WIN_CLOSE" << std::endl;
break;
}
}
bool addbuffer(WAVEHDR *pWaveHdr)
{
std::cout << pWaveHdr->dwBytesRecorded << std::endl;
std::cout << pWaveHdr->lpData << std::endl;
return true;
}
thanks
-
December 20th, 2012, 10:25 AM
#10
Re: waveInStart audio is very choppy
Hi Guys,
you guys are good! i having a question about waveform audio functions as well. and i am wondering how could i code the input signal and play it the output sound at the same time? is there any idea guys?
here the code is the usually code founded anywhere and works find.
#include <iostream>
#include <Windows.h>
#include <MMSystem.h>
using namespace std;
#pragma comment(lib,”libwinmm.a”)//this will make the linker links
//with this library
int main()
{
const int NUMPTS = 44100 * 10;
int sampleRate = 44100;
short int waveIn[NUMPTS];
HWAVEIN hWaveIn;
WAVEHDR WaveInHdr;
MMRESULT result;
HWAVEOUT hWaveOut;
WAVEFORMATEX pFormat;
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, 0, 0, WAVE_FORMAT_DIRECT);
if(result)
{
char fault[256];
waveInGetErrorTextA(result, fault, 256);
MessageBoxA(NULL, fault, "Failed to open waveform input device.", MB_OK | MB_ICONEXCLAMATION);
return 1;
}
WaveInHdr.lpData = (LPSTR)waveIn;
WaveInHdr.dwBufferLength = 2 * NUMPTS;
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)
{
MessageBoxA(NULL, "Failed to read block from device", NULL, MB_OK | MB_ICONEXCLAMATION);
return 1;
}
result = waveInStart(hWaveIn);
if(result)
{
MessageBoxA(NULL, "Failed to start recording", NULL, MB_OK | MB_ICONEXCLAMATION);
return 1;
}
cout << "Recording..." << endl;
Sleep((NUMPTS/sampleRate) * 1000); //Sleep while recording
cout << "Playing..." << endl;
if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT))
{
MessageBoxA(NULL, "Failed to replay", NULL, MB_OK | MB_ICONEXCLAMATION );
}
waveOutWrite(hWaveOut, &WaveInHdr, sizeof(WaveInHdr)); //<-- The line I forgot before
Sleep((NUMPTS/sampleRate) * 1000); //Sleep for as long as there was recorded
waveOutUnprepareHeader(hWaveOut, &WaveInHdr, sizeof(WAVEHDR));
waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
waveInClose(hWaveIn);
waveOutClose(hWaveOut);
return 0;
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|