From cc2160de5cc05dc3aa77f3a34358e66f6193c8c9 Mon Sep 17 00:00:00 2001 From: Michał Cichoń Date: Tue, 26 Jun 2012 20:35:30 +0200 Subject: Add support for AAC. --- faad2/src/aacDECdrop/wave_out.c | 190 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 faad2/src/aacDECdrop/wave_out.c (limited to 'faad2/src/aacDECdrop/wave_out.c') diff --git a/faad2/src/aacDECdrop/wave_out.c b/faad2/src/aacDECdrop/wave_out.c new file mode 100644 index 0000000..02131ab --- /dev/null +++ b/faad2/src/aacDECdrop/wave_out.c @@ -0,0 +1,190 @@ +/* + * function: Support for playing wave files - Win32 - ONLY + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright (C) 2002 John Edwards + */ + +#include +#include +#include "wave_out.h" + +#define MAX_WAVEBLOCKS 32 + + +static CRITICAL_SECTION cs; +static HWAVEOUT dev = NULL; +static int ScheduledBlocks = 0; +static int PlayedWaveHeadersCount = 0; // free index +static WAVEHDR* PlayedWaveHeaders [MAX_WAVEBLOCKS]; + + +static int +Box ( const char* msg ) +{ + MessageBox ( NULL, msg, "Error Message . . .", MB_OK | MB_ICONEXCLAMATION ); + return -1; +} + + +/* + * This function registers already played WAVE chunks. Freeing is done by free_memory(), + */ + +static void CALLBACK +wave_callback ( HWAVE hWave, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ) +{ + if ( uMsg == WOM_DONE ) + { + EnterCriticalSection ( &cs ); + PlayedWaveHeaders [PlayedWaveHeadersCount++] = (WAVEHDR*) dwParam1; + LeaveCriticalSection ( &cs ); + } +} + + +static void +free_memory ( void ) +{ + WAVEHDR* wh; + HGLOBAL hg; + + EnterCriticalSection ( &cs ); + wh = PlayedWaveHeaders [--PlayedWaveHeadersCount]; + ScheduledBlocks--; // decrease the number of USED blocks + LeaveCriticalSection ( &cs ); + + waveOutUnprepareHeader ( dev, wh, sizeof (WAVEHDR) ); + + hg = GlobalHandle ( wh -> lpData ); // Deallocate the buffer memory + GlobalUnlock (hg); + GlobalFree (hg); + + hg = GlobalHandle ( wh ); // Deallocate the header memory + GlobalUnlock (hg); + GlobalFree (hg); +} + + +Int +Set_WIN_Params ( FILE_T dummyFile , + Ldouble SampleFreq, + Uint BitsPerSample, + Uint Channels ) +{ + WAVEFORMATEX outFormat; + UINT deviceID = WAVE_MAPPER; + + (void) dummyFile; + + if ( waveOutGetNumDevs () == 0 ) + return Box ( "No audio device present." ); + + outFormat.wFormatTag = WAVE_FORMAT_PCM; + outFormat.wBitsPerSample = BitsPerSample; + outFormat.nChannels = Channels; + outFormat.nSamplesPerSec = (unsigned long)(SampleFreq); + outFormat.nBlockAlign = outFormat.nChannels * outFormat.wBitsPerSample/8; + outFormat.nAvgBytesPerSec = outFormat.nSamplesPerSec * outFormat.nChannels * outFormat.wBitsPerSample/8; + + switch ( waveOutOpen ( &dev, deviceID, &outFormat, (DWORD)wave_callback, 0, CALLBACK_FUNCTION ) ) + { + case MMSYSERR_ALLOCATED: return Box ( "Device is already open." ); + case MMSYSERR_BADDEVICEID: return Box ( "The specified device is out of range." ); + case MMSYSERR_NODRIVER: return Box ( "There is no audio driver in this system." ); + case MMSYSERR_NOMEM: return Box ( "Unable to allocate sound memory." ); + case WAVERR_BADFORMAT: return Box ( "This audio format is not supported." ); + case WAVERR_SYNC: return Box ( "The device is synchronous." ); + default: return Box ( "Unknown media error." ); + case MMSYSERR_NOERROR: break; + } + + waveOutReset ( dev ); + InitializeCriticalSection ( &cs ); + SetPriorityClass ( GetCurrentProcess (), HIGH_PRIORITY_CLASS ); +// SetPriorityClass ( GetCurrentProcess (), REALTIME_PRIORITY_CLASS ); + return 0; +} + + +int +WIN_Play_Samples ( const void* data, size_t len ) +{ + HGLOBAL hg; + HGLOBAL hg2; + LPWAVEHDR wh; + void* allocptr; + + do + { + while ( PlayedWaveHeadersCount > 0 ) // free used blocks ... + free_memory (); + + if ( ScheduledBlocks < sizeof(PlayedWaveHeaders)/sizeof(*PlayedWaveHeaders) ) // wait for a free block ... + break; + Sleep (26); + + } while (1); + + if ( (hg2 = GlobalAlloc ( GMEM_MOVEABLE, len )) == NULL ) // allocate some memory for a copy of the buffer + return Box ( "GlobalAlloc failed." ); + + allocptr = GlobalLock (hg2); + CopyMemory ( allocptr, data, len ); // Here we can call any modification output functions we want.... + + if ( (hg = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (WAVEHDR))) == NULL ) // now make a header and WRITE IT! + return -1; + + wh = GlobalLock (hg); + wh->dwBufferLength = len; + wh->lpData = allocptr; + + if ( waveOutPrepareHeader ( dev, wh, sizeof (WAVEHDR)) != MMSYSERR_NOERROR ) + { + GlobalUnlock (hg); + GlobalFree (hg); + return -1; + } + + if ( waveOutWrite ( dev, wh, sizeof (WAVEHDR)) != MMSYSERR_NOERROR ) + { + GlobalUnlock (hg); + GlobalFree (hg); + return -1; + } + + EnterCriticalSection ( &cs ); + ScheduledBlocks++; + LeaveCriticalSection ( &cs ); + + return len; +} + + +int +WIN_Audio_close ( void ) +{ + if ( dev != NULL ) + { + while ( ScheduledBlocks > 0 ) + { + Sleep (ScheduledBlocks); + while ( PlayedWaveHeadersCount > 0 ) // free used blocks ... + free_memory (); + } + + waveOutReset (dev); // reset the device + waveOutClose (dev); // close the device + dev = NULL; + } + + DeleteCriticalSection ( &cs ); + ScheduledBlocks = 0; + return 0; +} + + +/******************************** end of wave_out.c ********************************/ + -- cgit v1.2.3