#include #include "parameters.h" #include "sound.h" #include "os_generic.h" #include #include #include #if defined(WIN32) #pragma comment(lib,"winmm.lib") #endif #define BUFFS 2 struct SoundDriverWin { void (*CloseFn)( struct SoundDriverWin * object ); int (*SoundStateFn)( struct SoundDriverWin * object ); SoundCBType callback; int channelsPlay; int spsPlay; int channelsRec; int spsRec; int buffer; int isEnding; int GOBUFF; int recording; HWAVEIN hMyWave; WAVEHDR WavBuff[BUFFS]; }; static struct SoundDriverWin * w; void CloseSoundWin( struct SoundDriverWin * r ) { int i; if( r ) { waveInStop(r->hMyWave); waveInReset(r->hMyWave); for ( i=0;ihMyWave,&(r->WavBuff[i]),sizeof(WAVEHDR)); free ((r->WavBuff[i]).lpData); } waveInClose(r->hMyWave); free( r ); } } int SoundStateWin( struct SoundDriverWin * soundobject ) { return soundobject->recording; } void CALLBACK HANDLEMIC(HWAVEIN hwi,UINT umsg, DWORD dwi, DWORD hdr, DWORD dwparm) { int ctr; int ob; long cValue; unsigned int maxWave=0; float buffer[w->buffer*w->channelsRec]; if (w->isEnding) return; switch (umsg) { case MM_WIM_OPEN: printf( "Mic Open.\n" ); w->recording = 1; break; case MM_WIM_DATA: // printf( "Mic Data.\n"); ob = (w->GOBUFF+(BUFFS))%BUFFS; // waveInPrepareHeader(w->hMyWave,&(w->WavBuff[w->Cbuff]),sizeof(WAVEHDR)); for (ctr=0;ctrbuffer * w->channelsRec;ctr++) { float cv = (uint16_t)(((uint8_t)w->WavBuff[ob].lpData[ctr*2+1])*256+((uint8_t)w->WavBuff[ob].lpData[ctr*2])+32768)-32768; cv /= 32768; // if( ctr < 3 ) cv = -1; // buffer[(w->buffer * w->channelsRec)-ctr-1] = cv; buffer[ctr] = cv; } waveInAddBuffer(w->hMyWave,&(w->WavBuff[w->GOBUFF]),sizeof(WAVEHDR)); w->GOBUFF = ( w->GOBUFF + 1 ) % BUFFS; int playbacksamples; //Unused w->callback( 0, buffer, w->buffer, &playbacksamples, (struct SoundDriver*)w ); } } static struct SoundDriverWin * InitWinSound( struct SoundDriverWin * r ) { int i; WAVEFORMATEX wfmt; if( GetParameterI( "play", 0 ) ) { fprintf( stderr, "Error: This Windows Sound Driver does not support playback.\n" ); exit( -1 ); } w = r; printf( "WFMT: %d %d %d\n", r->channelsRec, r->spsRec, r->spsRec * r->channelsRec ); wfmt.wFormatTag = WAVE_FORMAT_PCM; wfmt.nChannels = r->channelsRec; wfmt.nSamplesPerSec = r->spsRec; wfmt.nAvgBytesPerSec = r->spsRec * r->channelsRec; wfmt.nBlockAlign = r->channelsRec * 2; wfmt.wBitsPerSample = 16; wfmt.cbSize = 0; long dwdevice; dwdevice = GetParameterI( "wininput", WAVE_MAPPER ); printf( "Wave Devs: %d; WAVE_MAPPER: %d; Selected Input: %d\n", waveInGetNumDevs(), WAVE_MAPPER, dwdevice ); printf( "waveInOpen: %p, %p\n", &r->hMyWave, &wfmt ); int p = waveInOpen(&r->hMyWave, dwdevice, &wfmt,(DWORD)(void*)(&HANDLEMIC) , 0, CALLBACK_FUNCTION); printf( "WIO: %d\n", p ); //On real windows, returns 11 for ( i=0;iWavBuff[i]), 0, sizeof(r->WavBuff[i]) ); (r->WavBuff[i]).dwBufferLength = r->buffer*2*r->channelsRec; (r->WavBuff[i]).dwLoops = 1; (r->WavBuff[i]).lpData=(char*) malloc(r->buffer*r->channelsRec*2); waveInPrepareHeader(r->hMyWave,&(r->WavBuff[i]),sizeof(WAVEHDR)); waveInAddBuffer(r->hMyWave,&(r->WavBuff[i]),sizeof(WAVEHDR)); } p = waveInStart(r->hMyWave); printf( "WIS: %d\n", p ); //On real windows returns 5. return r; } void * InitSoundWin( SoundCBType cb ) { struct SoundDriverWin * r = malloc( sizeof( struct SoundDriverWin ) ); r->CloseFn = CloseSoundWin; r->SoundStateFn = SoundStateWin; r->callback = cb; r->spsRec = GetParameterI( "samplerate", 44100 ); r->channelsRec = GetParameterI( "channels", 2 ); r->buffer = GetParameterI( "buffer", 384 ); r->recording = 0; r->isEnding = 0; printf( "Buffer: %d\n", r->buffer ); r->GOBUFF=0; return InitWinSound(r); } EXECUTE_AT_BOOT( WinSoundReg, RegSound( 10, "WIN", InitSoundWin ) );