PDA

Visualizza la versione completa : [C++ Win32] waveInStart


gianvituzzi
19-12-2009, 14:13
Salve,

ho scritto quello che dovrebbe essere il codice base per catturare un primo chunk di 4096 bytes di audio dal microfono del pc:



#include <windows.h>
#pragma comment (lib, "winmm.lib")
#include <mmsystem.h>
#include <iostream>
#include <stdlib.h> // Define "system" function
#define system_buf_len 4096

LRESULT CALLBACK mycallback(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

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)mycallback,
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);
system("pause");
return 0;
}

LRESULT CALLBACK mycallback(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
MessageBox(NULL, LPCTSTR(message), "Caption", MB_OK);
return 0;
}


Dopo la chiamata waveInStart() credevo che dovessi aspettare una chiamata da parte del sistema alla callback (mycallback) quando l'intero buffer era pieno, per questo ho settato in maniera molto semplice la callback per vedere se veniva chiamata dal sistema (a limite stampando il valore di "message" che in teoria dovrebbe ritornare la costante MM_WIM_DATA). Tuttavia il codice viene eseguito senza errori da parte del compilatore ma la callback non viene richiamata!

A questo punto mi domando se la callback scritta nella forma corretta

oregon
19-12-2009, 14:30
Un "Evento" un oggetto di Windows non una funzione

http://msdn.microsoft.com/en-us/library/ms535863(VS.85).aspx

Non cos che si usa quella API ...

Dai un'occhiata a

http://www.relisoft.com/freeware/recorder.html

gianvituzzi
19-12-2009, 14:46
Ok, grazie per il link, anche se mi sarebbe piaciuto approfondire dove dice:


Once the buffer is full, Windows notifies the client, who is supposed to process the bufferful of data. There are several notification options.The second option is to get notifications in the form of a Windows messages.

oregon
19-12-2009, 14:55
Se vuoi utilizzare una "funzione di callback" (non un evento) allora devi indicare la costante

CALLBACK_FUNCTION

nella open e utilizzare una funzione del tipo


void CALLBACK waveInProc(
HWAVEIN hwi,
UINT uMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2
)

Tramite il campo uMsg gestirai i messaggi in arrivo.

gianvituzzi
19-12-2009, 15:41
ok, ma c' una cosa che non capisco la struttura della callback :



void CALLBACK waveInProc(
HWAVEIN hwi,
UINT uMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2
)


ma quando aspetto MM_WIM_DATA non mi sembra che i parametti corrispondano alla callback:



MM_WIM_DATA
wParam = (WPARAM) hInputDev
lParam = (LONG) lpwvhdr


come ottego wParam e lParam??

gianvituzzi
19-12-2009, 15:44
cmq ho provato ad eseguire questo codice:



#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");
return 0;
}

void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
{
MessageBox(NULL, LPCTSTR(uMsg), "Caption", MB_OK);
}


ed ottengo un errore /unhandle exception/ il seguente:


waveinxxx.exe!waveInProc(HWAVEIN__ * hwi=0x004448c8, unsigned int uMsg=958, unsigned long dwInstance=0, unsigned long dwParam1=0, unsigned long dwParam2=0) Line 63 + 0x15 bytes C++

oregon
19-12-2009, 17:05
Originariamente inviato da gianvituzzi

... ed ottengo un errore ...


Beh ... per forza ... se scrivi

MessageBox(NULL, LPCTSTR(uMsg), "Caption", MB_OK);

... cosa intendevi fare?

uMsg un numero intero ... non puoi passarlo come se fosse un indirizzo di una stringa!

Ma tu hai chiaro il concetto di "messaggio" per Windows ?

gianvituzzi
19-12-2009, 17:10
assolutamente, solo che volevo fare una cosa tipo:



std::cout << uMsg << std::endl;


ovvero stampare un numero...

oregon
19-12-2009, 17:14
Dato che la messagebox accetta un dato di tipo stringa (quelle del C), dovrai prima trasformare il valore numerico in stringa ...

Dovrai quindi allocare lo spazio per una stringa e utilizzarlo per memorizzarci il valore di uMsg ... puoi usare la funzione sprintf ...

XWolverineX
19-12-2009, 17:21
Quanti wave quest'oggi.

Loading