Deshman
April 19th, 2005, 09:56 AM
I am new to Visual C++ so try not to flame me. I am actually programming in C and need a way to stream audio from the sound card so i can encode it and send to via serial comm to another PC. I just dont know how to access the raw PCM stream from the sound card. I would then need to convert PCM to WAV inorder to convert or is there a codec native to windows that can get ~4:1 compression. I am using Win2000 Pro and only using input from a mic.
Thanks,
Ashley
croman7
April 19th, 2005, 11:23 AM
Look after waveInOpen() in MSDN.
darwen
April 19th, 2005, 06:03 PM
Have a look at DirectShow. It will require you to know COM though.
It's part of the DirectX SDK.
Darwen.
mmscg
April 19th, 2005, 11:02 PM
This code will record 10 seconds of microphone input (actually anything going thru soundcard)
using the wavein and mmio apis.
The buffer size can easily be changed to accomodate longer record times.
For very long record times you will probably want to set up a circular buffer system to save memory.
To do the encoding to a format other than PCM you will need to use ACM (Audio Compression Manager).
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
HWND hBtn01;
hBtn01 = CreateWindow("button","Record",WS_CHILD|WS_VISIBLE|WS_TABSTOP,
125,110,70,25,hWnd,(HMENU)IDB_RECORD,GetModuleHandle(NULL),NULL);
break;
case MM_WIM_DATA:
{
waveInUnprepareHeader(WaveHandle,&WaveHeader,sizeof(WAVEHDR));
SaveWaveFile();
waveInClose(WaveHandle);
WaveHeader.lpData=0;
if(WaveData)
{
delete[] WaveData;
WaveData=0;
}
waveInReset(WaveHandle);
return 0;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case 100:
{
WaveFormat.wFormatTag = WAVE_FORMAT_PCM;
WaveFormat.nChannels = 2;
WaveFormat.nSamplesPerSec = 44100;
WaveFormat.wBitsPerSample = 16;
WaveFormat.nAvgBytesPerSec = 176400;
WaveFormat.nBlockAlign = 4;
WaveFormat.cbSize = 0;
int Res=waveInOpen(&WaveHandle,WAVE_MAPPER,&WaveFormat,0,0,WAVE_FORMAT_QUERY);
CheckWaveError(Res);
if(Res==WAVERR_BADFORMAT) return 0;
Res=waveInOpen(&WaveHandle,WAVE_MAPPER,&WaveFormat,(DWORD)hWnd,0,CALLBACK_WINDOW);
CheckWaveError(Res);
int buffer = 1764000;
if(WaveData)delete[] WaveData;
WaveData = new char[buffer];
WaveHeader.dwBufferLength = buffer;
WaveHeader.dwFlags = 0;
WaveHeader.lpData = WaveData;
Res=waveInPrepareHeader(WaveHandle,&WaveHeader,sizeof(WAVEHDR));
CheckWaveError(Res);
Res=waveInAddBuffer(WaveHandle,&WaveHeader,sizeof(WAVEHDR));
CheckWaveError(Res);
if(Res!=0)
{
waveInUnprepareHeader(WaveHandle,&WaveHeader,sizeof(WAVEHDR));
delete[] WaveData;
WaveData=0;
return 0;
}
Res=waveInStart(WaveHandle);
CheckWaveError(Res);
return 0;
}
}
}
case WM_CLOSE:
if(WaveData)delete[] WaveData;
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//---------------------------------------------------------------------------
void SaveWaveFile()
{
MMCKINFO ChunkInfo;
MMCKINFO FormatChunkInfo;
MMCKINFO DataChunkInfo;
HMMIO handle = mmioOpen("test.wav",0,MMIO_CREATE|MMIO_WRITE);
if(!handle)
{
MessageBox(0,"Error creating file.","Error Message",0);
return;
}
memset(&ChunkInfo,0,sizeof(MMCKINFO));
ChunkInfo.fccType=mmioStringToFOURCC("WAVE",0);
DWORD Res=mmioCreateChunk(handle,&ChunkInfo,MMIO_CREATERIFF);
CheckMMIOError(Res);
FormatChunkInfo.ckid=mmioStringToFOURCC("fmt ",0);
FormatChunkInfo.cksize=sizeof(WAVEFORMATEX);
Res=mmioCreateChunk(handle,&FormatChunkInfo,0);
CheckMMIOError(Res);
mmioWrite(handle,(char*)&WaveFormat,sizeof(WaveFormat));
Res=mmioAscend(handle,&FormatChunkInfo,0);
CheckMMIOError(Res);
DataChunkInfo.ckid=mmioStringToFOURCC("data",0);
DataSize=WaveHeader.dwBytesRecorded;
char X[100];
sprintf(X,"Record finished - %u bytes recorded.",WaveHeader.dwBytesRecorded);
MessageBox(0,X,"SaveWaveFile",MB_OK);
DataChunkInfo.cksize=DataSize;
Res=mmioCreateChunk(handle,&DataChunkInfo,0);
CheckMMIOError(Res);
Res=mmioWrite(handle,(char*)WaveHeader.lpData,DataSize);
mmioAscend(handle,&DataChunkInfo,0);
mmioAscend(handle,&ChunkInfo,0);
mmioClose(handle,0);
}
//---------------------------------------------------------------------------
void CheckWaveError(DWORD code)
{
if(code==0)return;
char buff[256];
waveInGetErrorText(code,buff,sizeof(buff));
MessageBox(hWndMain,buff,"CheckWaveError",MB_OK);
}
//---------------------------------------------------------------------------
void CheckMMIOError(DWORD code)
{
if(code==0)return;
char buff[256];
wsprintf(buff,"MMIO Error!!!->Error Code: %d",code);
MessageBox(hWndMain,buff,"CheckMMIOError",MB_OK);
}
//---------------------------------------------------------------------------