Salve,
in questo momento per capire meglio il concetto di classe e programmazione orientata agli oggetti in C++ sto scrivendo una classe per usare in modo più semplice la waveForm API di windows.
la classe si chiama waveCapture ed è composta naturalmente da due files:
waveCapture.h
waveCapture.cpp
I metodi della classe sono i seguenti:
// Costruttori e distruttore
waveCapture();
waveCapture(DWORD dwSamplePerSec, WORD wBitsPerSample, WORD nChannels);
~waveCapture();
// Start Capturing WAVE
BOOL start();
BOOL start(WORD uDevice);
BOOL start(WORD uDevice, DWORD dwBufferLength, DWORD dwNumBuffers);
// Get Buffer (return bytes captured)
DWORD getBuffer(PBYTE pWAVBuffer);
// Stop Capturing
BOOL stop();
di seguito mostro come si usa la classe in main()
codice:
#include "waveCapture.h"
int main()
{
waveCapture* pwc = new waveCapture(); // Default: 44100, 16 (bit), 2 (STEREO)
pwc->start(0, 176400, 3); // (microfono interno, 176400 bytes, 3 buffers)
PBYTE pWAVBuffer = new BYTE[176400];
DWORD dwBytesRecorded = 0;
dwBytesRecorded = pwc->getBuffer(pWAVBuffer);
dwBytesRecorded = pwc->getBuffer(pWAVBuffer);
//...etc...oppure:
while( dwBytesRecorded = pwc->getBuffer(pWAVBuffer) > 0 )
{
//...do something with pWAVBuffer...
}
pwc->stop();
return 0;
}
Quindi ogni volta che chiamo getBuffer(); passo un puntatore ad un blocco di memoria BYTE che verrà riempito dalla fun<ione. La funzione poi ritornerà il numero di bytes realmente catturati. La funzione è bloccante e ritorna il primo buffer pronto. (all'interno viene usata la CALLBACK_EVENT)
questa è la struttura della classe nel file header:
codice:
class waveCapture
{
public:
// Constructors:
waveCapture();
~waveCapture();
waveCapture(DWORD, WORD, WORD);
// Methods:
BOOL start();
BOOL start(WORD);
BOOL start(WORD, DWORD, DWORD);
BOOL stop();
DWORD getBuffer(PBYTE);
private:
HANDLE hevent;
HWAVEIN hwi;
WAVEFORMATEX wf;
WAVEHDR *buff;
DWORD _dwBufferCount;
DWORD dwTotalBufferLength;
}
il lavoro è svolto per la maggior parte da start() e getBuffer() che hanno in comune /WAVEHDR *buff/, /HWAVEIN hwi/ e sopratutto /WAVEHDR *buff/
Ora vi mostro la funzione membro getBuffer() che è quella che mi da problemi (in quanto ritorna 0 e un puntatore vuoto):
codice:
DWORD waveCapture::getBuffer(PBYTE pWAVBuffer)
{
DWORD _dwBytesRecorded = 0;
// CALLBACK EVENT
WaitForSingleObject(hevent, INFINITE);
if(buff[_dwBufferCount].dwFlags & WHDR_DONE)
{
_dwBytesRecorded = buff[_dwBufferCount].dwBytesRecorded;
pWAVBuffer = (PBYTE)buff[_dwBufferCount].lpData;
waveInAddBuffer(hwi, &buff[_dwBufferCount], sizeof(WAVEHDR));
}
if(_dwBufferCount == __dwNumBuffers -1)
{
_dwBufferCount = 0;
} else {
_dwBufferCount++;
}
dwTotalBufferLength += _dwBytesRecorded;
return _dwBytesRecorded;
}
volevo sapere se sto facendo bene il casting:
codice:
PBYTE pWAVBuffer = (PBYTE)buff[_dwBufferCount].lpData;
in quanto buff.lpData è nativo in LPSTR ed io dovrei portarlo a PBYTE
per completezza posto anche il codice della funzione membro start() (sintetizzata)
codice:
BOOL waveCapture::start()
{
// ...let's get straight to the gist...
// Define WAVEFORMATEX Structure (WAVEFORMATEX wf)
(...)
// Create event:
hevent = CreateEvent(NULL,0,0,NULL);
// WaveInOpen
waveInOpen(&hwi,uDevice,(LPWAVEFORMATEX)&wf,(DWORD)hevent,0,CALLBACK_EVENT);
// Define WAVEHDR Structure:
buff = new WAVEHDR[dwNumBuffers];
// Push buffers:
waveInPrepareHeader(hwi, &buff[i], sizeof(WAVEHDR));
waveInAddBuffer(hwi, &buff[i], sizeof(WAVEHDR));
// Start capturing...
waveInStart(hwi);
_dwBufferCount = 0;
return true;
}
forse sono andato un pò troppo per le lunghe...
grazie