From: Larry on
Hi,

I would like to save the first 1 secondo of audio data from the internal
Microphone. I am doing this to get to know better the waveForm API. this is
the code I've written so far:

<<<main.cpp
#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;
}
<<<end code

I'd like to point out that I am not using any callback function for the
moment...I'd likme to know more about that!

Anyway, is the code right so far? after I call waveInStart(); how can I
actually grab the rwa audio data??

thanks!

From: ScottMcP [MVP] on
On Dec 19, 7:21 am, "Larry" <dontmewit...(a)got.it> wrote:
> Anyway, is the code right so far? after I call waveInStart(); how can I
> actually grab the rwa audio data??
>
> thanks!

You have created a 4096 byte buffer, but 1 second of audio is going to
need 44100*2 bytes. So you better make the buffer big enough to hold
the amount of audio you want!

The wavein device has several ways it can notiify you when the buffer
is filled. Don't lie to it like you are doing by passing
CALLBACK_EVENT. The simplest way for experimenting is to use
CALLBACK_NULL and simply use Sleep(1100) and then assume that the
buffer has been filled when Sleep returns.

If you use CALLBACK_EVENT then create an event with CreateEvent, pass
the event handle in dwCallback, and wait for the recording to finish
by calling WaitForSingleObject with the event handle.
WaitForSingleObject will suspend your code until the buffer has been
filled, then it will return.

From: Larry on

"ScottMcP [MVP]" <scottmcp(a)mvps.org> ha scritto nel messaggio
news:21d670ff-2b7c-48d0-b7f8-fbca49b9aad9(a)x18g2000vbd.googlegroups.com...

> You have created a 4096 byte buffer, but 1 second of audio is going to
> need 44100*2 bytes. So you better make the buffer big enough to hold
> the amount of audio you want!

Ok, we will be continuing about this later as I am very interesting about
buffers and how going about having the work flow the smootesh way.

> The wavein device has several ways it can notiify you when the buffer
> is filled. Don't lie to it like you are doing by passing
> CALLBACK_EVENT. The simplest way for experimenting is to use
> CALLBACK_NULL and simply use Sleep(1100) and then assume that the
> buffer has been filled when Sleep returns.

I don't think CALLBACK_NULL will suit me.

> If you use CALLBACK_EVENT then create an event with CreateEvent, pass
> the event handle in dwCallback, and wait for the recording to finish
> by calling WaitForSingleObject with the event handle.
> WaitForSingleObject will suspend your code until the buffer has been
> filled, then it will return.

Ok, I need to read up on that a little more. By the way, I have just coded
something more by using "CALLBACK_FUNCTION"

<<<main.cpp
#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;
}
}

now it seems to work better...Now, I am in tow minds wheter to use a
CALLBACK_FUNCTION approach or the CALLBACK_EVENET one...

thanks

From: ScottMcP [MVP] on
On Dec 19, 11:32 am, "Larry" <dontmewit...(a)got.it> wrote:
> now it seems to work better...Now, I am in tow minds wheter to use a
> CALLBACK_FUNCTION approach or the CALLBACK_EVENET one...
>
> thanks

If you plan to eventually record continuous audio then
CALLBACK_FUNCTION presents problems. Your callback function cannot do
much. See the waveInProc documentation where is says "Applications
should not call any system-defined functions from inside a callback
function, except ...". There are no such restrictions with
CALLBACK_EVENT and CALLBACK_WINDOW.

Have fun!

From: Larry on

"ScottMcP [MVP]" <scottmcp(a)mvps.org> ha scritto nel messaggio
news:6c4a60a8-e3cc-475b-8088-fafba64e4fa0(a)n31g2000vbt.googlegroups.com...
On Dec 19, 11:32 am, "Larry" <dontmewit...(a)got.it> wrote:
> now it seems to work better...Now, I am in tow minds wheter to use a
> CALLBACK_FUNCTION approach or the CALLBACK_EVENET one...
>
> thanks

> There are no such restrictions with
> CALLBACK_EVENT and CALLBACK_WINDOW.

Ok! So, if I wanted to go for the CALBACK_WINDOW, should I just set up a
regular callback like the following?

LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
lParam);

thanks