Updates to GAUDOUT to allow specification of the sample format.
Fix threading issues.
This commit is contained in:
parent
17f1f9d799
commit
43527de2c0
4 changed files with 22 additions and 13 deletions
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue