From e762e91bd5d5347071c3b43fbdb021376584c267 Mon Sep 17 00:00:00 2001 From: inmarket Date: Wed, 5 Mar 2014 13:45:37 +1000 Subject: Updates to GAUDOUT. Add Events to the GAUDOUT api. --- src/gaudout/driver.h | 10 ++++++++++ src/gaudout/gaudout.c | 53 ++++++++++++++++++++++++++++++++++++++------------ src/gaudout/sys_defs.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/gaudout/driver.h b/src/gaudout/driver.h index 8e72dff4..bd00d06d 100644 --- a/src/gaudout/driver.h +++ b/src/gaudout/driver.h @@ -56,6 +56,16 @@ GAudioData *gaudoutGetDataBlockI(void); */ void gaudoutReleaseDataBlockI(GAudioData *paud); +/** + * @brief Signal that all playing has now stopped + * + * @note Defined in the high level GAUDOUT code for use by the GAUDOUT drivers. + * + * @iclass + * @notapi + */ +void gaudoutDoneI(void); + /** * @brief Initialise the driver * @return TRUE if the channel and frequency are valid. diff --git a/src/gaudout/gaudout.c b/src/gaudout/gaudout.c index 275677c8..00b01e91 100644 --- a/src/gaudout/gaudout.c +++ b/src/gaudout/gaudout.c @@ -21,32 +21,33 @@ static gfxQueueASync playlist; static gfxQueueGSync freelist; -static uint16_t audFlags; - #define AUDOUTFLG_RUNNING 0x0001 - #define AUDOUTFLG_USE_EVENTS 0x0002 +static uint16_t PlayFlags; + #define PLAYFLG_USEEVENTS 0x0001 + #define PLAYFLG_PLAYING 0x0002 #if GFX_USE_GEVENT - static GTimer AudGTimer; + static GTimer PlayTimer; - static void AudGTimerCallback(void *param) { + static void PlayTimerCallback(void *param) { (void) param; GSourceListener *psl; - GEventADC *pe; + GEventAudioOut *pe; psl = 0; while ((psl = geventGetSourceListener((GSourceHandle)(&aud), psl))) { - if (!(pe = (GEventAudioIn *)geventGetEventBuffer(psl))) { + if (!(pe = (GEventAudioOut *)geventGetEventBuffer(psl))) { // This listener is missing - save this. - psl->srcflags |= GAUDIN_LOSTEVENT; + psl->srcflags |= GAUDOUT_LOSTEVENT; continue; } - pe->type = GEVENT_AUDIO_IN; - pe->channel = aud.channel; - pe->count = lastcount; - pe->buffer = lastbuffer; + pe->type = GEVENT_AUDIO_OUT; pe->flags = psl->srcflags; psl->srcflags = 0; + if ((PlayFlags & PLAYFLG_PLAYING)) + pe->flags |= GAUDOUT_PLAYING; + if (!gfxQueueGSyncIsEmpty(&freelist)) + pe->flags |= GAUDOUT_FREEBLOCK; geventSendEvent(psl); } } @@ -57,11 +58,17 @@ void _gaudoutInit(void) { gfxQueueASyncInit(&playlist); gfxQueueGSyncInit(&freelist); + #if GFX_USE_GEVENT + gtimerInit(&PlayTimer); + #endif } void _gaudoutDeinit(void) { /* ToDo */ + #if GFX_USE_GEVENT + gtimerDeinit(&PlayTimer); + #endif } bool_t gaudioAllocBuffers(unsigned num, size_t size) { @@ -103,6 +110,7 @@ bool_t gaudioPlayInit(uint16_t channel, uint32_t frequency, ArrayDataFormat form void gaudioPlay(GAudioData *paud) { if (paud) gfxQueueASyncPut(&playlist, (gfxQueueASyncItem *)paud); + PlayFlags |= PLAYFLG_PLAYING; gaudout_lld_start(); } @@ -116,12 +124,22 @@ void gaudioPlayStop(void) { gaudout_lld_stop(); while((paud = (GAudioData *)gfxQueueASyncGet(&playlist))) gfxQueueGSyncPut(&freelist, (gfxQueueGSyncItem *)paud); + PlayFlags &= ~PLAYFLG_PLAYING; } bool_t gaudioPlaySetVolume(uint8_t vol) { return gaudout_lld_set_volume(vol); } +#if GFX_USE_GEVENT || defined(__DOXYGEN__) + GSourceHandle gaudioPlayGetSource(void) { + if (!gtimerIsActive(&PlayTimer)) + gtimerStart(&PlayTimer, PlayTimerCallback, 0, TRUE, TIME_INFINITE); + PlayFlags |= PLAYFLG_USEEVENTS; + return (GSourceHandle)&PlayFlags; + } +#endif + /** * Routines provided for use by drivers. */ @@ -132,8 +150,19 @@ GAudioData *gaudoutGetDataBlockI(void) { void gaudoutReleaseDataBlockI(GAudioData *paud) { gfxQueueGSyncPutI(&freelist, (gfxQueueGSyncItem *)paud); + #if GFX_USE_GEVENT + if (PlayFlags & PLAYFLG_USEEVENTS) + gtimerJabI(&PlayTimer); + #endif } +void gaudoutDoneI(void) { + PlayFlags &= ~PLAYFLG_PLAYING; + #if GFX_USE_GEVENT + if (PlayFlags & PLAYFLG_USEEVENTS) + gtimerJabI(&PlayTimer); + #endif +} #endif /* GFX_USE_GAUDOUT */ /** @} */ diff --git a/src/gaudout/sys_defs.h b/src/gaudout/sys_defs.h index 4f09678b..75cda243 100644 --- a/src/gaudout/sys_defs.h +++ b/src/gaudout/sys_defs.h @@ -42,6 +42,36 @@ typedef struct GAudioData { size_t len; // @< The length of the data in the buffer area (in bytes) } GAudioData; + +// Event types for GAUDOUT +#define GEVENT_AUDIO_OUT (GEVENT_GAUDOUT_FIRST+0) + +/** + * @brief The Audio output event structure. + * @{ + */ +typedef struct GEventAudioOut_t { + #if GFX_USE_GEVENT || defined(__DOXYGEN__) + /** + * @brief The type of this event (GEVENT_AUDIO_OUT) + */ + GEventType type; + #endif + /** + * @brief The event flags + */ + uint16_t flags; + /** + * @brief The event flag values. + * @{ + */ + #define GAUDOUT_LOSTEVENT 0x0001 /**< @brief The last GEVENT_AUDIO_OUT event was lost */ + #define GAUDOUT_PLAYING 0x0002 /**< @brief The audio out system is currently playing */ + #define GAUDOUT_FREEBLOCK 0x0004 /**< @brief An audio buffer has been freed */ + /** @} */ +} GEventAudioOut; +/** @} */ + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ @@ -96,6 +126,8 @@ void gaudioReleaseBuffer(GAudioData *paud); * * @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. + * @note Only one channel can be playing at a time. Calling this will stop any + * currently playing channel. * * @api */ @@ -155,6 +187,25 @@ void gaudioPlayStop(void); */ bool_t gaudioPlaySetVolume(uint8_t vol); +#if GFX_USE_GEVENT || defined(__DOXYGEN__) + /** + * @brief Turn on sending results to the GEVENT sub-system. + * @details Returns a GSourceHandle to listen for GEVENT_AUDIO_OUT events. + * + * @note The audio output will not use the GEVENT system unless this is + * called first. This saves processing time if the application does + * not want to use the GEVENT sub-system for audio output. + * Once turned on it can only be turned off by calling @p gaudioPlayInit() again. + * @note The audio output is capable of signalling via this method and other methods + * at the same time. + * + * @return The GSourceHandle + * + * @api + */ + GSourceHandle gaudioPlayGetSource(void); +#endif + #ifdef __cplusplus } #endif -- cgit v1.2.3