diff --git a/drivers/audio/Win32/gaudout_lld.c b/drivers/audio/Win32/gaudout_lld.c index 9581fa45..fd70c80b 100644 --- a/drivers/audio/Win32/gaudout_lld.c +++ b/drivers/audio/Win32/gaudout_lld.c @@ -64,7 +64,10 @@ static bool_t senddata(WAVEHDR *pwh) { GAudioData *paud; // Get the next data block to send - if (!(paud = gaudoutGetDataBlockI())) + gfxSystemLock(); + paud = gaudoutGetDataBlockI(); + gfxSystemUnlock(); + if (!paud) return FALSE; // Prepare the wave header for Windows @@ -104,7 +107,9 @@ static DWORD WINAPI waveProc(LPVOID arg) { waveOutUnprepareHeader(ah, pwh, sizeof(WAVEHDR)); // Give the buffer back to the Audio Free List + gfxSystemLock(); gaudoutReleaseDataBlockI((GAudioData *)pwh->dwUser); + gfxSystemUnlock(); pwh->lpData = 0; nQueuedBuffers--; @@ -131,9 +136,12 @@ void gaudout_lld_deinit() { } } -bool_t gaudout_lld_init(uint16_t channel, uint32_t frequency) { +bool_t gaudout_lld_init(uint16_t channel, uint32_t frequency, ArrayDataFormat format) { WAVEFORMATEX wfx; + if (format != ARRAY_DATA_8BITUNSIGNED && format != ARRAY_DATA_16BITSIGNED) + return FALSE; + if (!waveThread) { if (!(waveThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)waveProc, 0, 0, &threadID))) { fprintf(stderr, "GAUDOUT: Can't create WAVE play-back thread\n"); @@ -145,9 +153,9 @@ bool_t gaudout_lld_init(uint16_t channel, uint32_t frequency) { wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = channel == GAUDOUT_STEREO ? 2 : 1; wfx.nSamplesPerSec = frequency; - wfx.nBlockAlign = wfx.nChannels * sizeof(audout_sample_t); + wfx.nBlockAlign = wfx.nChannels * (format == ARRAY_DATA_8BITUNSIGNED ? 1 : 2); wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; - wfx.wBitsPerSample = sizeof(audout_sample_t) * 8; + wfx.wBitsPerSample = (format == ARRAY_DATA_8BITUNSIGNED ? 8 : 16); wfx.cbSize = 0; if (waveOutOpen(&ah, WAVE_MAPPER, &wfx, (DWORD_PTR)threadID, 0, CALLBACK_THREAD)) { diff --git a/src/gaudout/driver.h b/src/gaudout/driver.h index cd9ab01b..8e72dff4 100644 --- a/src/gaudout/driver.h +++ b/src/gaudout/driver.h @@ -62,12 +62,13 @@ void gaudoutReleaseDataBlockI(GAudioData *paud); * * @param[in] channel The channel to use (see the driver for the available channels provided) * @param[in] frequency The sample frequency to use + * @param[in] format The sample format * * @note The driver will always have been stopped and de-init before this is called. * * @api */ -bool_t gaudout_lld_init(uint16_t channel, uint32_t frequency); +bool_t gaudout_lld_init(uint16_t channel, uint32_t frequency, ArrayDataFormat format); /** * @brief De-Initialise the driver diff --git a/src/gaudout/gaudout.c b/src/gaudout/gaudout.c index c0d673a0..275677c8 100644 --- a/src/gaudout/gaudout.c +++ b/src/gaudout/gaudout.c @@ -94,10 +94,10 @@ GAudioData *gaudioGetBuffer(delaytime_t ms) { return (GAudioData *)gfxQueueGSyncGet(&freelist, ms); } -bool_t gaudioPlayInit(uint16_t channel, uint32_t frequency) { +bool_t gaudioPlayInit(uint16_t channel, uint32_t frequency, ArrayDataFormat format) { gaudioPlayStop(); gaudout_lld_deinit(); - return gaudout_lld_init(channel, frequency); + return gaudout_lld_init(channel, frequency, format); } void gaudioPlay(GAudioData *paud) { @@ -127,11 +127,11 @@ bool_t gaudioPlaySetVolume(uint8_t vol) { */ GAudioData *gaudoutGetDataBlockI(void) { - return (GAudioData *)gfxQueueASyncGet(&playlist); + return (GAudioData *)gfxQueueASyncGetI(&playlist); } void gaudoutReleaseDataBlockI(GAudioData *paud) { - gfxQueueGSyncPut(&freelist, (gfxQueueGSyncItem *)paud); + gfxQueueGSyncPutI(&freelist, (gfxQueueGSyncItem *)paud); } diff --git a/src/gaudout/sys_defs.h b/src/gaudout/sys_defs.h index c3745b8c..4f09678b 100644 --- a/src/gaudout/sys_defs.h +++ b/src/gaudout/sys_defs.h @@ -39,7 +39,7 @@ typedef struct GAudioData { gfxQueueASyncItem next; // @< Used for queuing the buffers size_t size; // @< The size of the buffer area following this structure (in bytes) - size_t len; // @< The length of the data in the buffer area (in samples) + size_t len; // @< The length of the data in the buffer area (in bytes) } GAudioData; /*===========================================================================*/ @@ -92,13 +92,14 @@ void gaudioReleaseBuffer(GAudioData *paud); * * @param[in] channel The audio output channel to use. * @param[in] frequency The audio sample rate in samples per second + * @param[in] format The audio sample format * * @note Some channels are mono, and some are stereo. See your driver config file * to determine which channels to use and whether they are stereo or not. * * @api */ -bool_t gaudioPlayInit(uint16_t channel, uint32_t frequency); +bool_t gaudioPlayInit(uint16_t channel, uint32_t frequency, ArrayDataFormat format); /** * @brief Play the specified sample data. @@ -109,8 +110,7 @@ bool_t gaudioPlayInit(uint16_t channel, uint32_t frequency); * * @note Calling this will cancel any pause. * @note Before calling this function the len field of the GAudioData structure must be - * specified. While the buffer size is specified in bytes, this length is specified in samples - * and must be even for stereo channels. + * specified (in bytes). * @note For stereo channels the sample data is interleaved in the buffer. * @note This call returns before the data has completed playing. Subject to available buffers (which * can be obtained from the free-list), any number of buffers may be played. They will be queued