diff options
author | Joel Bodenmann <joel@unormal.org> | 2014-04-30 13:41:34 +0200 |
---|---|---|
committer | Joel Bodenmann <joel@unormal.org> | 2014-04-30 13:41:34 +0200 |
commit | 33c721c009465dd30d4e96e055a051480c567b57 (patch) | |
tree | 5a6744a79b7469d80bae474d4314b47d4cd6d44d /src/gaudio | |
parent | 58cf2d2b35542166f1a4e50a83bcf28ff33574a5 (diff) | |
parent | a394e2c35dde67241bea69409bcae9f46dcfc089 (diff) | |
download | uGFX-33c721c009465dd30d4e96e055a051480c567b57.tar.gz uGFX-33c721c009465dd30d4e96e055a051480c567b57.tar.bz2 uGFX-33c721c009465dd30d4e96e055a051480c567b57.zip |
Merge branch 'master' into freertos
Diffstat (limited to 'src/gaudio')
-rw-r--r-- | src/gaudio/driver_play.h | 8 | ||||
-rw-r--r-- | src/gaudio/driver_record.h | 6 | ||||
-rw-r--r-- | src/gaudio/gaudio.c | 79 | ||||
-rw-r--r-- | src/gaudio/sys_defs.h | 71 | ||||
-rw-r--r-- | src/gaudio/sys_rules.h | 10 |
5 files changed, 49 insertions, 125 deletions
diff --git a/src/gaudio/driver_play.h b/src/gaudio/driver_play.h index 72ad4747..343a0fed 100644 --- a/src/gaudio/driver_play.h +++ b/src/gaudio/driver_play.h @@ -42,19 +42,19 @@ extern "C" { * @iclass * @notapi */ -GAudioData *gaudioPlayGetDataBlockI(void); +GDataBuffer *gaudioPlayGetDataBlockI(void); /** * @brief Release a block of audio data to the free list * - * @param[in] paud The GAudioData block to be released. + * @param[in] paud The GDataBuffer block to be released. * * @note Defined in the high level GAUDIO code for use by the GAUDIO play drivers. * * @iclass * @notapi */ -void gaudioPlayReleaseDataBlockI(GAudioData *paud); +void gaudioPlayReleaseDataBlockI(GDataBuffer *paud); /** * @brief Signal that all playing has now stopped @@ -107,7 +107,7 @@ void gaudio_play_lld_stop(void); * @brief Set the output volume. * @return TRUE if successful. * - * @param[in] 0->255 (0 = muted) + * @param[in] vol 0->255 (0 = muted) * * @note Some drivers may not support this. They will return FALSE. * @note For stereo devices, both channels are set to the same volume. diff --git a/src/gaudio/driver_record.h b/src/gaudio/driver_record.h index 252cae5c..20136dd7 100644 --- a/src/gaudio/driver_record.h +++ b/src/gaudio/driver_record.h @@ -34,19 +34,19 @@ * @iclass * @notapi */ -GAudioData *gaudioRecordGetFreeBlockI(void); +#define gaudioRecordGetFreeBlockI() gfxBufferGetI() /** * @brief Save a block of recorded audio data ready for the application * - * @param[in] paud The GAudioData block with data. + * @param[in] paud The GDataBuffer block with data. * * @note Defined in the high level GAUDIO code for use by the GAUDIO record drivers. * * @iclass * @notapi */ -void gaudioRecordSaveDataBlockI(GAudioData *paud); +void gaudioRecordSaveDataBlockI(GDataBuffer *paud); /** * @brief Signal that all recording has now stopped diff --git a/src/gaudio/gaudio.c b/src/gaudio/gaudio.c index a83dcd85..ab1f95ee 100644 --- a/src/gaudio/gaudio.c +++ b/src/gaudio/gaudio.c @@ -16,8 +16,6 @@ #if GFX_USE_GAUDIO -static gfxQueueGSync freeList; - #if GAUDIO_NEED_PLAY #include "src/gaudio/driver_play.h" @@ -51,7 +49,6 @@ static gfxQueueGSync freeList; void _gaudioInit(void) { - gfxQueueGSyncInit(&freeList); #if GAUDIO_NEED_PLAY gfxQueueASyncInit(&playList); #if GFX_USE_GEVENT @@ -70,48 +67,20 @@ void _gaudioInit(void) void _gaudioDeinit(void) { #if GAUDIO_NEED_PLAY + gfxQueueASyncDeinit(&playList); #if GFX_USE_GEVENT gtimerDeinit(&playTimer); #endif gfxSemDestroy(&playComplete); #endif #if GAUDIO_NEED_RECORD + gfxQueueGSyncDeinit(&recordList); #if GFX_USE_GEVENT gtimerDeinit(&recordTimer); #endif #endif } -bool_t gaudioAllocBuffers(unsigned num, size_t size) { - GAudioData *paud; - - if (num < 1) - return FALSE; - - // Round up to a multiple of 4 to prevent problems with structure alignment - size = (size + 3) & ~0x03; - - // Allocate the memory - if (!(paud = gfxAlloc((size+sizeof(GAudioData)) * num))) - return FALSE; - - // Add each of them to our free list - for(;num--; paud = (GAudioData *)((char *)(paud+1)+size)) { - paud->size = size; - gfxQueueGSyncPut(&freeList, (gfxQueueGSyncItem *)paud); - } - - return TRUE; -} - -void gaudioReleaseBuffer(GAudioData *paud) { - gfxQueueGSyncPut(&freeList, (gfxQueueGSyncItem *)paud); -} - -GAudioData *gaudioGetBuffer(delaytime_t ms) { - return (GAudioData *)gfxQueueGSyncGet(&freeList, ms); -} - #if GAUDIO_NEED_PLAY bool_t gaudioPlayInit(uint16_t channel, uint32_t frequency, ArrayDataFormat format) { @@ -123,18 +92,18 @@ GAudioData *gaudioGetBuffer(delaytime_t ms) { return TRUE; } - void gaudioPlay(GAudioData *paud) { + void gaudioPlay(GDataBuffer *pd) { if (!(playFlags & PLAYFLG_ISINIT)) { // Oops - init failed - return it directly to the free-list - if (paud) { - gfxQueueGSyncPut(&freeList, (gfxQueueGSyncItem *)paud); + if (pd) { + gfxBufferRelease(pd); gfxYield(); // Make sure we get no endless cpu hogging loops } return; } - if (paud) - gfxQueueASyncPut(&playList, (gfxQueueASyncItem *)paud); + if (pd) + gfxQueueASyncPut(&playList, (gfxQueueASyncItem *)pd); playFlags |= PLAYFLG_PLAYING; gaudio_play_lld_start(); } @@ -145,12 +114,12 @@ GAudioData *gaudioGetBuffer(delaytime_t ms) { } void gaudioPlayStop(void) { - GAudioData *paud; + GDataBuffer *pd; if (playFlags & PLAYFLG_PLAYING) gaudio_play_lld_stop(); - while((paud = (GAudioData *)gfxQueueASyncGet(&playList))) - gfxQueueGSyncPut(&freeList, (gfxQueueGSyncItem *)paud); + while((pd = (GDataBuffer *)gfxQueueASyncGet(&playList))) + gfxBufferRelease(pd); } bool_t gaudioPlaySetVolume(uint8_t vol) { @@ -182,7 +151,7 @@ GAudioData *gaudioGetBuffer(delaytime_t ms) { psl->srcflags = 0; if ((playFlags & PLAYFLG_PLAYING)) pe->flags |= GAUDIO_PLAY_PLAYING; - if (!gfxQueueGSyncIsEmpty(&freeList)) + if (gfxBufferIsAvailable()) pe->flags |= GAUDIO_PLAY_FREEBLOCK; geventSendEvent(psl); } @@ -200,12 +169,12 @@ GAudioData *gaudioGetBuffer(delaytime_t ms) { * Routines provided for use by drivers. */ - GAudioData *gaudioPlayGetDataBlockI(void) { - return (GAudioData *)gfxQueueASyncGetI(&playList); + GDataBuffer *gaudioPlayGetDataBlockI(void) { + return (GDataBuffer *)gfxQueueASyncGetI(&playList); } - void gaudioPlayReleaseDataBlockI(GAudioData *paud) { - gfxQueueGSyncPutI(&freeList, (gfxQueueGSyncItem *)paud); + void gaudioPlayReleaseDataBlockI(GDataBuffer *pd) { + gfxBufferReleaseI(pd); #if GFX_USE_GEVENT if (playFlags & PLAYFLG_USEEVENTS) gtimerJabI(&playTimer); @@ -242,17 +211,17 @@ GAudioData *gaudioGetBuffer(delaytime_t ms) { } void gaudioRecordStop(void) { - GAudioData *paud; + GDataBuffer *pd; if ((recordFlags & (RECORDFLG_RECORDING|RECORDFLG_STALLED)) == RECORDFLG_RECORDING) gaudio_record_lld_stop(); recordFlags &= ~(RECORDFLG_RECORDING|RECORDFLG_STALLED); - while((paud = (GAudioData *)gfxQueueGSyncGet(&recordList, TIME_IMMEDIATE))) - gfxQueueGSyncPut(&freeList, (gfxQueueGSyncItem *)paud); + while((pd = (GDataBuffer *)gfxQueueGSyncGet(&recordList, TIME_IMMEDIATE))) + gfxBufferRelease(pd); } - GAudioData *gaudioRecordGetData(delaytime_t ms) { - return (GAudioData *)gfxQueueGSyncGet(&recordList, ms); + GDataBuffer *gaudioRecordGetData(delaytime_t ms) { + return (GDataBuffer *)gfxQueueGSyncGet(&recordList, ms); } #if GFX_USE_GEVENT @@ -276,7 +245,7 @@ GAudioData *gaudioGetBuffer(delaytime_t ms) { if ((recordFlags & RECORDFLG_STALLED)) pe->flags |= GAUDIO_RECORD_STALL; if (!gfxQueueGSyncIsEmpty(&recordList)) - pe->flags |= GAUDIO_RECORD_GOTBLOCK; + pe->flags |= GAUDIO_RECORD_GOTBUFFER; geventSendEvent(psl); } } @@ -293,11 +262,7 @@ GAudioData *gaudioGetBuffer(delaytime_t ms) { * Routines provided for use by drivers. */ - GAudioData *gaudioRecordGetFreeBlockI(void) { - return (GAudioData *)gfxQueueGSyncGetI(&freeList); - } - - void gaudioRecordSaveDataBlockI(GAudioData *paud) { + void gaudioRecordSaveDataBlockI(GDataBuffer *paud) { gfxQueueGSyncPutI(&recordList, (gfxQueueGSyncItem *)paud); #if GFX_USE_GEVENT if (recordFlags & RECORDFLG_USEEVENTS) diff --git a/src/gaudio/sys_defs.h b/src/gaudio/sys_defs.h index a9a951b7..5a43af18 100644 --- a/src/gaudio/sys_defs.h +++ b/src/gaudio/sys_defs.h @@ -34,19 +34,6 @@ /* Type definitions */ /*===========================================================================*/ -/** - * @brief Contains Audio Data Samples - * @note This structure is followed immediately by the sample data itself. - * When allocating the buffers for the sample data put this structure - * at the beginning of the buffer. - */ -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 bytes) -} GAudioData; - - // Event types for GAUDIO #define GEVENT_AUDIO_PLAY (GEVENT_GAUDIO_FIRST+0) #define GEVENT_AUDIO_RECORD (GEVENT_GAUDIO_FIRST+1) @@ -95,7 +82,7 @@ typedef struct GAudioData { */ #define GAUDIO_RECORD_LOSTEVENT 0x0001 /**< @brief The last GEVENT_AUDIO_IN event was lost */ #define GAUDIO_RECORD_RECORDING 0x0002 /**< @brief The audio recording system is currently recording */ - #define GAUDIO_RECORD_GOTBLOCK 0x0004 /**< @brief An audio buffer is ready for processing */ + #define GAUDIO_RECORD_GOTBUFFER 0x0004 /**< @brief An audio buffer is ready for processing */ #define GAUDIO_RECORD_STALL 0x0008 /**< @brief The recording process has stalled due to no free buffers */ /** @} */ } GEventAudioRecord; @@ -110,41 +97,6 @@ typedef struct GAudioData { extern "C" { #endif -/** - * @brief Allocate some audio buffers and put them on the free list - * @return TRUE is it succeeded. FALSE on allocation failure. - * - * @param[in] num The number of buffers to allocate - * @param[in] size The size (in bytes) of each buffer - * - * @api - */ -bool_t gaudioAllocBuffers(unsigned num, size_t size); - -/** - * @brief Get an audio buffer from the free list - * @return A GAudioData pointer or NULL if the timeout is exceeded - * - * @params[in] ms The maximum amount of time in milliseconds to wait for a buffer if one is not available. - * - * @api - */ -GAudioData *gaudioGetBuffer(delaytime_t ms); - -/** - * @brief Release a buffer back to the free list - * - * @param[in] paud The buffer to put (back) on the free-list. - * - * @note This call should be used to return any buffers that were taken from - * the free-list once they have been finished with. It can also be used - * to put new buffers onto the free-list. Just make sure the "size" field - * of the GAudioData structure has been filled in first. - * - * @api - */ -void gaudioReleaseBuffer(GAudioData *paud); - #if GAUDIO_NEED_PLAY || defined(__DOXYGEN__) /** * @brief Set the audio device to play on the specified channel and with the specified @@ -172,7 +124,7 @@ void gaudioReleaseBuffer(GAudioData *paud); * @param[in] paud The audio sample buffer to play. It can be NULL (used to restart paused audio) * * @note Calling this will cancel any pause. - * @note Before calling this function the len field of the GAudioData structure must be + * @note Before calling this function the len field of the GDataBuffer structure must be * 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 @@ -182,7 +134,7 @@ void gaudioReleaseBuffer(GAudioData *paud); * * @api */ - void gaudioPlay(GAudioData *paud); + void gaudioPlay(GDataBuffer *paud); /** * @brief Pause any currently playing sounds. @@ -209,7 +161,7 @@ void gaudioReleaseBuffer(GAudioData *paud); * @brief Set the output volume. * @return TRUE if successful. * - * @param[in] 0->255 (0 = muted) + * @param[in] vol 0->255 (0 = muted) * * @note Some drivers may not support this. They will return FALSE. * @note For stereo devices, both channels are set to the same volume. @@ -241,7 +193,7 @@ void gaudioReleaseBuffer(GAudioData *paud); * @brief Wait for any currently playing sounds to complete * @return TRUE if there is now nothing playing or FALSE if the timeout is exceeded * - * @params[in] ms The maximum amount of time in milliseconds to wait for playing to complete. + * @param[in] ms The maximum amount of time in milliseconds to wait for playing to complete. * * @api */ @@ -298,16 +250,21 @@ void gaudioReleaseBuffer(GAudioData *paud); /** * @brief Get a filled audio buffer from the recording list - * @return A GAudioData pointer or NULL if the timeout is exceeded + * @return A GDataBuffer pointer or NULL if the timeout is exceeded * - * @params[in] ms The maximum amount of time in milliseconds to wait for data if some is not currently available. + * @param[in] ms The maximum amount of time in milliseconds to wait for data if some is not currently available. * * @note After processing the audio data, your application must return the buffer to the free-list so that * it can be used to record more audio into. This can be done via the play list using @p gaudioPlay() or - * directly using @p gaudioReleaseBuffer(). + * directly using @p gfxBufferRelease(). + * @note A buffer may be returned to the free-list before you have finished processing it provided you finish + * processing it before GADC re-uses it. This is useful when RAM usage is critical to reduce the number + * of buffers required. It works before the free list is a FIFO queue and therefore buffers are kept + * in the queue as long as possible before they are re-used. + * * @api */ - GAudioData *gaudioRecordGetData(delaytime_t ms); + GDataBuffer *gaudioRecordGetData(delaytime_t ms); #if GFX_USE_GEVENT || defined(__DOXYGEN__) /** diff --git a/src/gaudio/sys_rules.h b/src/gaudio/sys_rules.h index a3f0dffc..4786fa5f 100644 --- a/src/gaudio/sys_rules.h +++ b/src/gaudio/sys_rules.h @@ -27,17 +27,19 @@ #undef GFX_USE_GQUEUE #define GFX_USE_GQUEUE TRUE #endif - #if !GQUEUE_NEED_ASYNC + #if GAUDIO_NEED_PLAY && !GQUEUE_NEED_ASYNC #if GFX_DISPLAY_RULE_WARNINGS - #warning "GAUDIO: GQUEUE_NEED_ASYNC is required if GFX_USE_GAUDIO is TRUE. It has been turned on for you." + #warning "GAUDIO: GQUEUE_NEED_ASYNC is required if GAUDIO_NEED_PLAY is TRUE. It has been turned on for you." #endif #undef GQUEUE_NEED_ASYNC #define GQUEUE_NEED_ASYNC TRUE #endif - #if !GQUEUE_NEED_GSYNC + #if !GQUEUE_NEED_GSYNC || !GQUEUE_NEED_BUFFERS #if GFX_DISPLAY_RULE_WARNINGS - #warning "GAUDIO: GQUEUE_NEED_GSYNC is required if GFX_USE_GAUDIO is TRUE. It has been turned on for you." + #warning "GAUDIO: GQUEUE_NEED_BUFFERS and GQUEUE_NEED_GSYNC are required if GFX_USE_GAUDIO is TRUE. They have been turned on for you." #endif + #undef GQUEUE_NEED_BUFFERS + #define GQUEUE_NEED_BUFFERS TRUE #undef GQUEUE_NEED_GSYNC #define GQUEUE_NEED_GSYNC TRUE #endif |