diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gaudin/driver.h | 102 | ||||
-rw-r--r-- | src/gaudin/gaudin.c | 158 | ||||
-rw-r--r-- | src/gaudin/sys_defs.h | 174 | ||||
-rw-r--r-- | src/gaudin/sys_make.mk | 1 | ||||
-rw-r--r-- | src/gaudin/sys_options.h | 32 | ||||
-rw-r--r-- | src/gaudin/sys_rules.h | 30 | ||||
-rw-r--r-- | src/gaudio/driver_play.h (renamed from src/gaudout/driver.h) | 58 | ||||
-rw-r--r-- | src/gaudio/driver_record.h | 108 | ||||
-rw-r--r-- | src/gaudio/gaudio.c | 318 | ||||
-rw-r--r-- | src/gaudio/sys_defs.h | 340 | ||||
-rw-r--r-- | src/gaudio/sys_make.mk | 1 | ||||
-rw-r--r-- | src/gaudio/sys_options.h | 44 | ||||
-rw-r--r-- | src/gaudio/sys_rules.h | 54 | ||||
-rw-r--r-- | src/gaudout/gaudout.c | 169 | ||||
-rw-r--r-- | src/gaudout/sys_defs.h | 217 | ||||
-rw-r--r-- | src/gaudout/sys_make.mk | 1 | ||||
-rw-r--r-- | src/gaudout/sys_options.h | 32 | ||||
-rw-r--r-- | src/gaudout/sys_rules.h | 44 | ||||
-rw-r--r-- | src/gevent/sys_defs.h | 3 | ||||
-rw-r--r-- | src/gfx.c | 22 |
20 files changed, 897 insertions, 1011 deletions
diff --git a/src/gaudin/driver.h b/src/gaudin/driver.h deleted file mode 100644 index b534e2a5..00000000 --- a/src/gaudin/driver.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gaudin/driver.h - * @brief GAUDIN - Audio Input driver header file. - * - * @defgroup Driver Driver - * @ingroup GAUDIN - * @{ - */ - -#ifndef _GAUDIN_LLD_H -#define _GAUDIN_LLD_H - -#include "gfx.h" - -#if GFX_USE_GAUDIN || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Type definitions */ -/*===========================================================================*/ - -/** - * @brief The structure passed to start a audio conversion - * @note We use the structure instead of parameters purely to save - * interrupt stack space which is very limited in some platforms. - * @{ - */ -typedef struct gaudin_params_t { - uint16_t channel; - uint32_t frequency; - audin_sample_t *buffer; - size_t bufcount; - size_t samplesPerEvent; - } gaudin_params; -/** @} */ - -/** - * @brief These routines are the callbacks that the driver uses. - * @details Defined in the high level GAUDIN code. - * - * @iclass - * @notapi - * - * @{ - */ - -/** - * @param[in] buffer The buffer - * @param[in] n The amount of samples - * */ -extern void GAUDIN_ISR_CompleteI(audin_sample_t *buffer, size_t n); - -extern void GAUDIN_ISR_ErrorI(void); -/** - * @} - */ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initialise the driver - * - * @param[in] paud Initialisation parameters - * - * @api - */ -void gaudin_lld_init(const gaudin_params *paud); - -/** - * @brief Start the audio input sampling - * - * @api - */ -void gaudin_lld_start(void); - -/** - * @brief Stop the audio input sampling - * - * @api - */ -void gaudin_lld_stop(void); - -#ifdef __cplusplus -} -#endif - -#endif /* GFX_USE_GADC */ - -#endif /* _GADC_LLD_H */ -/** @} */ diff --git a/src/gaudin/gaudin.c b/src/gaudin/gaudin.c deleted file mode 100644 index 2e3507ef..00000000 --- a/src/gaudin/gaudin.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gaudin/gaudin.c - * @brief GAUDIN sub-system code. - * - * @addtogroup GAUDIN - * @{ - */ -#include "gfx.h" - -#if GFX_USE_GAUDIN - -/* Include the driver defines */ -#include "src/gaudin/driver.h" - -static gaudin_params aud; -static gfxSem *paudSem; -static GEventAudioIn *paudEvent; -static audin_sample_t *lastbuffer; -static size_t lastcount; -static uint16_t audFlags; - #define AUDFLG_RUNNING 0x0001 - #define AUDFLG_USE_EVENTS 0x0002 - -#if GFX_USE_GEVENT - static GTimer AudGTimer; - - static void AudGTimerCallback(void *param) { - (void) param; - GSourceListener *psl; - GEventADC *pe; - - psl = 0; - while ((psl = geventGetSourceListener((GSourceHandle)(&aud), psl))) { - if (!(pe = (GEventAudioIn *)geventGetEventBuffer(psl))) { - // This listener is missing - save this. - psl->srcflags |= GAUDIN_LOSTEVENT; - continue; - } - - pe->type = GEVENT_AUDIO_IN; - pe->channel = aud.channel; - pe->count = lastcount; - pe->buffer = lastbuffer; - pe->flags = psl->srcflags; - psl->srcflags = 0; - geventSendEvent(psl); - } - } -#endif - -void GAUDIN_ISR_CompleteI(audin_sample_t *buffer, size_t n) { - /* Save the details */ - lastcount = n; - lastbuffer = buffer; - - /* Signal the user with the data */ - if (paudEvent) { - #if GFX_USE_GEVENT - paudEvent->type = GEVENT_AUDIO_IN; - #endif - paudEvent->channel = aud.channel; - paudEvent->count = lastcount; - paudEvent->buffer = lastbuffer; - paudEvent->flags = 0; - } - - /* Our two signalling mechanisms */ - if (paudSem) - gfxSemSignalI(paudSem); - - #if GFX_USE_GEVENT - if (audFlags & AUDFLG_USE_EVENTS) - gtimerJabI(&AudGTimer); - #endif -} - -void GAUDIN_ISR_ErrorI(void) { - /* Ignore any errors for now */ -} - -void _gaudinInit(void) -{ - #if GFX_USE_GEVENT - gtimerInit(&AudGTimer); - #endif -} - -void _gaudinDeinit(void) -{ - // Commented stuff still ToDo - #if GFX_USE_GEVENT - gtimerDeinit(&AudGTimer); - #endif -} - -bool_t gaudinInit(uint16_t channel, uint32_t frequency, audin_sample_t *buffer, size_t bufcount, size_t samplesPerEvent) { - /* Check the channel is valid */ - if (channel >= GAUDIN_NUM_CHANNELS || frequency > GAUDIN_MAX_SAMPLE_FREQUENCY) - return FALSE; - - /* Stop any existing transfers */ - if ((audFlags & AUDFLG_RUNNING)) - gaudin_lld_stop(); - audFlags = 0; - - /* Initialise everything */ - aud.channel = channel; - aud.frequency = frequency; - aud.buffer = buffer; - aud.bufcount = bufcount; - aud.samplesPerEvent = samplesPerEvent; - paudSem = 0; - paudEvent = 0; - - /* Set up the low level driver */ - gaudin_lld_init(&aud); - return TRUE; -} - -#if GFX_USE_GEVENT - GSourceHandle gaudinGetSource(void) { - if (!gtimerIsActive(&AudGTimer)) - gtimerStart(&AudGTimer, AudGTimerCallback, 0, TRUE, TIME_INFINITE); - audFlags |= AUDFLG_USE_EVENTS; - return (GSourceHandle)&aud; - } -#endif - -void gaudinSetBSem(gfxSem *pbsem, GEventAudioIn *pEvent) { - gfxSystemLock(); - paudSem = pbsem; - paudEvent = pEvent; - gfxSystemUnlock(); -} - -void gaudinStart(void) { - if (!(audFlags & AUDFLG_RUNNING)) { - audFlags |= AUDFLG_RUNNING; - gaudin_lld_start(); - } -} - -void gaudinStop(void) { - if ((audFlags & AUDFLG_RUNNING)) { - gaudin_lld_stop(); - audFlags &= ~AUDFLG_RUNNING; - } -} - -#endif /* GFX_USE_GAUDIN */ -/** @} */ diff --git a/src/gaudin/sys_defs.h b/src/gaudin/sys_defs.h deleted file mode 100644 index c65a69c1..00000000 --- a/src/gaudin/sys_defs.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gaudin/sys_defs.h - * - * @addtogroup GAUDIN - * - * @brief Module to read audio inputs - * - * @{ - */ - -#ifndef _GAUDIN_H -#define _GAUDIN_H - -#include "gfx.h" - -#if GFX_USE_GAUDIN || defined(__DOXYGEN__) - -/* Include the driver defines */ -#include "gaudin_lld_config.h" - -/*===========================================================================*/ -/* Type definitions */ -/*===========================================================================*/ - -// Event types for GAUDIN -#define GEVENT_AUDIO_IN (GEVENT_GAUDIN_FIRST+0) - -/** - * @brief The Audio Input event structure. - * @{ - */ -typedef struct GEventAudioIn_t { - #if GFX_USE_GEVENT || defined(__DOXYGEN__) - /** - * @brief The type of this event (GEVENT_AUDIO_IN) - */ - GEventType type; - #endif - /** - * @brief The current channel - */ - uint16_t channel; - /** - * @brief The event flags - */ - uint16_t flags; - /** - * @brief The event flag values. - * @{ - */ - #define GAUDIN_LOSTEVENT 0x0001 /**< @brief The last GEVENT_AUDIO_IN event was lost */ - /** @} */ - /** - * @brief The number of audio samples in the buffer - */ - size_t count; - /** - * @brief The buffer containing the audio samples - */ - audin_sample_t *buffer; -} GEventAudioIn; -/** @} */ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initialise (but not start) the Audio Input Subsystem. - * @details Returns FALSE for an invalid channel or other invalid parameter. - * - * @param[in] channel The channel to convert. Can be set from 0 to GAUDIN_NUM_CHANNELS - 1. - * @param[in] frequency The sample frequency - * @param[in] buffer The static buffer to put the samples into. - * @param[in] bufcount The total number of conversions that will fit in the buffer. - * @param[in] samplesPerEvent The number of conversions to do before returning an event. - * - * @note Only one channel is active at a time. If an audio input is running it will be stopped. - * The Event subsystem is disconnected from the audio subsystem and any binary semaphore - * event is forgotten. - * @note Some channels may be stereo channels which return twice as much sample data with - * the left and right channel data interleaved. Other channels may be mono channels. - * Where stereo channels exist it would be common for the low level driver to also - * offer the left and right channels separately. - * @note Due to a bug in Chibi-OS countPerEvent must be even if using the GADC low level audio driver. - * If bufcount is not evenly divisable by countPerEvent, the remainder must also be even. - * This requirement may not apply to other GAUDIN drivers. - * @note The number of samples for stereo devices will be double the number of conversions. - * Make sure you allocate your buffers large enough. Each channel is then interleaved - * into the provided buffer. Note 'bufcount' and 'countPerEvent' parameters describe the - * number of conversions not the number of samples. - * @note The buffer is circular. When the end of the buffer is reached it will start - * putting data into the beginning of the buffer again. - * @note The event listener must process the event (and the data in it) before the - * next event occurs. If not, the following event will be lost. - * @note If bufcount is evenly divisable by countPerEvent, then every event will return - * countPerEvent conversions. If bufcount is not evenly divisable, it will return - * a block of samples containing less than countPerEvent samples when it reaches the - * end of the buffer. - * - * @return FALSE if invalid channel or parameter - * - * @api - */ -bool_t gaudinInit(uint16_t channel, uint32_t frequency, audin_sample_t *buffer, size_t bufcount, size_t samplesPerEvent); - -#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_IN events. - * - * @note The audio input 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 input. - * Once turned on it can only be turned off by calling @p gaudinInit() again. - * @note The audio input is capable of signalling via this method and a binary semaphore - * at the same time. - * - * @return The GSourceHandle - * - * @api - */ - GSourceHandle gaudinGetSource(void); -#endif - -/** - * @brief Allow retrieving of results from the audio input using a Binary Semaphore and a static event buffer. - * - * @param[in] pbsem The semaphore is signaled when data is available. - * @param[in] pEvent The static event buffer to place the result information. - * - * @note Passing a NULL for pbsem or pEvent will turn off signalling via this method. - * @note The audio input is capable of signalling via this method and the GEVENT - * sub-system at the same time. - * - * @api - */ -void gaudinSetBSem(gfxSem *pbsem, GEventAudioIn *pEvent); - -/** - * @brief Start the audio input conversions. - * @pre It must have been initialised first with @p gaudinInit() - * - * @api - */ -void gaudinStart(void); - -/** - * @brief Stop the audio input conversions. - * - * @api - */ -void gaudinStop(void); - -#ifdef __cplusplus -} -#endif - -#endif /* GFX_USE_GAUDIN */ - -#endif /* _GAUDIN_H */ -/** @} */ - diff --git a/src/gaudin/sys_make.mk b/src/gaudin/sys_make.mk deleted file mode 100644 index 16bb33b7..00000000 --- a/src/gaudin/sys_make.mk +++ /dev/null @@ -1 +0,0 @@ -GFXSRC += $(GFXLIB)/src/gaudin/gaudin.c diff --git a/src/gaudin/sys_options.h b/src/gaudin/sys_options.h deleted file mode 100644 index 305a6f8d..00000000 --- a/src/gaudin/sys_options.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gaudin/sys_options.h - * @brief GAUDIN - Audio Input subsystem options header file. - * - * @addtogroup GAUDIN - * @{ - */ - -#ifndef _GAUDIN_OPTIONS_H -#define _GAUDIN_OPTIONS_H - -/** - * @name GAUDIN Functionality to be included - * @{ - */ -/** - * @} - * - * @name GAUDIN Optional Sizing Parameters - * @{ - */ -/** @} */ - -#endif /* _GAUDIN_OPTIONS_H */ -/** @} */ diff --git a/src/gaudin/sys_rules.h b/src/gaudin/sys_rules.h deleted file mode 100644 index 21d2552f..00000000 --- a/src/gaudin/sys_rules.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gaudin/sys_rules.h - * @brief GAUDIN safety rules header file. - * - * @addtogroup GAUDIN - * @{ - */ - -#ifndef _GAUDIN_RULES_H -#define _GAUDIN_RULES_H - -#if GFX_USE_GAUDIN - #if GFX_USE_GEVENT && !GFX_USE_GTIMER - #if GFX_DISPLAY_RULE_WARNINGS - #warning "GAUDIN: GFX_USE_GTIMER is required if GFX_USE_GAUDIN and GFX_USE_GEVENT are TRUE. It has been turned on for you." - #endif - #undef GFX_USE_GTIMER - #define GFX_USE_GTIMER TRUE - #endif -#endif - -#endif /* _GAUDIN_RULES_H */ -/** @} */ diff --git a/src/gaudout/driver.h b/src/gaudio/driver_play.h index bd00d06d..72ad4747 100644 --- a/src/gaudout/driver.h +++ b/src/gaudio/driver_play.h @@ -6,20 +6,20 @@ */ /** - * @file src/gaudout/driver.h - * @brief GAUDOUT - Audio Output driver header file. + * @file src/gaudio/driver_play.h + * @brief GAUDIO - Audio play driver header file. * * @defgroup Driver Driver - * @ingroup GAUDOUT + * @ingroup GAUDIO * @{ */ -#ifndef _GAUDOUT_LLD_H -#define _GAUDOUT_LLD_H +#ifndef _GAUDIO_PLAY_LLD_H +#define _GAUDIO_PLAY_LLD_H #include "gfx.h" -#if GFX_USE_GAUDOUT || defined(__DOXYGEN__) +#if (GFX_USE_GAUDIO && GAUDIO_NEED_PLAY) || defined(__DOXYGEN__) /*===========================================================================*/ /* Type definitions */ @@ -37,38 +37,38 @@ extern "C" { * @brief Get a block of audio data to play * @return A pointer to the GAaudioData structure or NULL if none is currently available * - * @note Defined in the high level GAUDOUT code for use by the GAUDOUT drivers. + * @note Defined in the high level GAUDIO code for use by the GAUDIO play drivers. * * @iclass * @notapi */ -GAudioData *gaudoutGetDataBlockI(void); +GAudioData *gaudioPlayGetDataBlockI(void); /** - * @brief Release a block of audio data after playing + * @brief Release a block of audio data to the free list * * @param[in] paud The GAudioData block to be released. * - * @note Defined in the high level GAUDOUT code for use by the GAUDOUT drivers. + * @note Defined in the high level GAUDIO code for use by the GAUDIO play drivers. * * @iclass * @notapi */ -void gaudoutReleaseDataBlockI(GAudioData *paud); +void gaudioPlayReleaseDataBlockI(GAudioData *paud); /** * @brief Signal that all playing has now stopped * - * @note Defined in the high level GAUDOUT code for use by the GAUDOUT drivers. + * @note Defined in the high level GAUDIO code for use by the GAUDIO play drivers. * * @iclass * @notapi */ -void gaudoutDoneI(void); +void gaudioPlayDoneI(void); /** - * @brief Initialise the driver - * @return TRUE if the channel and frequency are valid. + * @brief Initialise the play driver + * @return TRUE if the channel, frequency and format are valid. * * @param[in] channel The channel to use (see the driver for the available channels provided) * @param[in] frequency The sample frequency to use @@ -78,38 +78,30 @@ void gaudoutDoneI(void); * * @api */ -bool_t gaudout_lld_init(uint16_t channel, uint32_t frequency, ArrayDataFormat format); - -/** - * @brief De-Initialise the driver - * - * @note The audio output will always have been stopped first by the high level layer. - * @note This may be called before a @p gaudout_lld_init() has occurred. - * - * @api - */ -void gaudout_lld_deinit(void); +bool_t gaudio_play_lld_init(uint16_t channel, uint32_t frequency, ArrayDataFormat format); /** * @brief Start the audio output playing * * @note This may be called at any stage including while the driver * is already playing. The driver should check for data blocks - * to play using @p gaudoutGetDataBlockI(). + * to play using @p gaudioPlayGetDataBlockI(). * * @api */ -void gaudout_lld_start(void); +void gaudio_play_lld_start(void); /** * @brief Stop the audio output playing. * * @note Some drivers may only stop playing at a data block boundary. - * @note This may be called before a @p gaudout_lld_init() has occurred. + * @note It is possible but unlikely for it to be called when playing has already stopped. + * @note It should not return until all active buffers (currently in use by the driver) + * have been returned to the free-list and @p gaudioPlayDoneI() has been called. * * @api */ -void gaudout_lld_stop(void); +void gaudio_play_lld_stop(void); /** * @brief Set the output volume. @@ -122,13 +114,13 @@ void gaudout_lld_stop(void); * * @api */ -bool_t gaudout_lld_set_volume(uint8_t vol); +bool_t gaudio_play_lld_set_volume(uint8_t vol); #ifdef __cplusplus } #endif -#endif /* GFX_USE_GAUDOUT */ +#endif /* GFX_USE_GAUDIO && GAUDIO_NEED_PLAY */ -#endif /* _GAUDOUT_LLD_H */ +#endif /* _GAUDIO_PLAY_LLD_H */ /** @} */ diff --git a/src/gaudio/driver_record.h b/src/gaudio/driver_record.h new file mode 100644 index 00000000..252cae5c --- /dev/null +++ b/src/gaudio/driver_record.h @@ -0,0 +1,108 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gaudio/driver_record.h + * @brief GAUDIO - Audio Recording driver header file. + * + * @defgroup Driver Driver + * @ingroup GAUDIO + * @{ + */ + +#ifndef _GAUDIO_RECORD_LLD_H +#define _GAUDIO_RECORD_LLD_H + +#include "gfx.h" + +#if (GFX_USE_GAUDIO && GAUDIO_NEED_RECORD) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Type definitions */ +/*===========================================================================*/ + +/** + * @brief Get a free block of audio data that we can record into + * @return A pointer to the GAaudioData structure or NULL if none is currently available + * + * @note Defined in the high level GAUDIO code for use by the GAUDIO record drivers. + * + * @iclass + * @notapi + */ +GAudioData *gaudioRecordGetFreeBlockI(void); + +/** + * @brief Save a block of recorded audio data ready for the application + * + * @param[in] paud The GAudioData block with data. + * + * @note Defined in the high level GAUDIO code for use by the GAUDIO record drivers. + * + * @iclass + * @notapi + */ +void gaudioRecordSaveDataBlockI(GAudioData *paud); + +/** + * @brief Signal that all recording has now stopped + * + * @note Defined in the high level GAUDIO code for use by the GAUDIO record drivers. + * + * @iclass + * @notapi + */ +void gaudioRecordDoneI(void); + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialise the record driver + * @return TRUE if the channel, frequency and format are valid. + * + * @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 gaudio_record_lld_init(uint16_t channel, uint32_t frequency, ArrayDataFormat format); + +/** + * @brief Start the audio recording + * + * @api + */ +void gaudio_record_lld_start(void); + +/** + * @brief Stop the audio recording. + * + * @note Some drivers may only stop recording at a data block boundary. + * @note This routine should not return until any currently active buffers have been + * saved (even if with zero length) and @p gaudioRecordDoneI() has been called. + * + * @api + */ +void gaudio_record_lld_stop(void); + +#ifdef __cplusplus +} +#endif + +#endif /* GFX_USE_GAUDIO && GAUDIO_NEED_RECORD */ + +#endif /* _GAUDIO_RECORD_LLD_H */ +/** @} */ diff --git a/src/gaudio/gaudio.c b/src/gaudio/gaudio.c new file mode 100644 index 00000000..a83dcd85 --- /dev/null +++ b/src/gaudio/gaudio.c @@ -0,0 +1,318 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gaudio/gaudio.c + * @brief GAUDIO sub-system code. + * + * @addtogroup GAUDIO + * @{ + */ +#include "gfx.h" + +#if GFX_USE_GAUDIO + +static gfxQueueGSync freeList; + +#if GAUDIO_NEED_PLAY + #include "src/gaudio/driver_play.h" + + static gfxQueueASync playList; + static gfxSem playComplete; + static uint16_t playFlags; + #define PLAYFLG_USEEVENTS 0x0001 + #define PLAYFLG_PLAYING 0x0002 + #define PLAYFLG_ISINIT 0x0004 + #if GFX_USE_GEVENT + static GTimer playTimer; + static void PlayTimerCallback(void *param); + #endif +#endif + +#if GAUDIO_NEED_RECORD + #include "src/gaudio/driver_record.h" + + static gfxQueueGSync recordList; + static uint16_t recordFlags; + #define RECORDFLG_USEEVENTS 0x0001 + #define RECORDFLG_RECORDING 0x0002 + #define RECORDFLG_STALLED 0x0004 + #define RECORDFLG_ISINIT 0x0008 + #if GFX_USE_GEVENT + static GTimer recordTimer; + static void RecordTimerCallback(void *param); + #endif +#endif + + +void _gaudioInit(void) +{ + gfxQueueGSyncInit(&freeList); + #if GAUDIO_NEED_PLAY + gfxQueueASyncInit(&playList); + #if GFX_USE_GEVENT + gtimerInit(&playTimer); + #endif + gfxSemInit(&playComplete, 0, 0); + #endif + #if GAUDIO_NEED_RECORD + gfxQueueGSyncInit(&recordList); + #if GFX_USE_GEVENT + gtimerInit(&recordTimer); + #endif + #endif +} + +void _gaudioDeinit(void) +{ + #if GAUDIO_NEED_PLAY + #if GFX_USE_GEVENT + gtimerDeinit(&playTimer); + #endif + gfxSemDestroy(&playComplete); + #endif + #if GAUDIO_NEED_RECORD + #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) { + gaudioPlayStop(); + playFlags &= ~PLAYFLG_ISINIT; + if (!gaudio_play_lld_init(channel, frequency, format)) + return FALSE; + playFlags |= PLAYFLG_ISINIT; + return TRUE; + } + + void gaudioPlay(GAudioData *paud) { + if (!(playFlags & PLAYFLG_ISINIT)) { + // Oops - init failed - return it directly to the free-list + if (paud) { + gfxQueueGSyncPut(&freeList, (gfxQueueGSyncItem *)paud); + gfxYield(); // Make sure we get no endless cpu hogging loops + } + return; + } + + if (paud) + gfxQueueASyncPut(&playList, (gfxQueueASyncItem *)paud); + playFlags |= PLAYFLG_PLAYING; + gaudio_play_lld_start(); + } + + void gaudioPlayPause(void) { + if ((playFlags & (PLAYFLG_ISINIT|PLAYFLG_PLAYING)) == (PLAYFLG_ISINIT|PLAYFLG_PLAYING)) + gaudio_play_lld_stop(); + } + + void gaudioPlayStop(void) { + GAudioData *paud; + + if (playFlags & PLAYFLG_PLAYING) + gaudio_play_lld_stop(); + while((paud = (GAudioData *)gfxQueueASyncGet(&playList))) + gfxQueueGSyncPut(&freeList, (gfxQueueGSyncItem *)paud); + } + + bool_t gaudioPlaySetVolume(uint8_t vol) { + return gaudio_play_lld_set_volume(vol); + } + + bool_t gaudioPlayWait(delaytime_t ms) { + if (!(playFlags & PLAYFLG_PLAYING)) + return TRUE; + return gfxSemWait(&playComplete, ms); + } + + #if GFX_USE_GEVENT + static void PlayTimerCallback(void *param) { + (void) param; + GSourceListener *psl; + GEventAudioPlay *pe; + + psl = 0; + while ((psl = geventGetSourceListener((GSourceHandle)&playTimer, psl))) { + if (!(pe = (GEventAudioPlay *)geventGetEventBuffer(psl))) { + // This listener is missing - save this. + psl->srcflags |= GAUDIO_PLAY_LOSTEVENT; + continue; + } + + pe->type = GEVENT_AUDIO_PLAY; + pe->flags = psl->srcflags; + psl->srcflags = 0; + if ((playFlags & PLAYFLG_PLAYING)) + pe->flags |= GAUDIO_PLAY_PLAYING; + if (!gfxQueueGSyncIsEmpty(&freeList)) + pe->flags |= GAUDIO_PLAY_FREEBLOCK; + geventSendEvent(psl); + } + } + + GSourceHandle gaudioPlayGetSource(void) { + if (!gtimerIsActive(&playTimer)) + gtimerStart(&playTimer, PlayTimerCallback, 0, TRUE, TIME_INFINITE); + playFlags |= PLAYFLG_USEEVENTS; + return (GSourceHandle)&playTimer; + } + #endif + + /** + * Routines provided for use by drivers. + */ + + GAudioData *gaudioPlayGetDataBlockI(void) { + return (GAudioData *)gfxQueueASyncGetI(&playList); + } + + void gaudioPlayReleaseDataBlockI(GAudioData *paud) { + gfxQueueGSyncPutI(&freeList, (gfxQueueGSyncItem *)paud); + #if GFX_USE_GEVENT + if (playFlags & PLAYFLG_USEEVENTS) + gtimerJabI(&playTimer); + #endif + } + + void gaudioPlayDoneI(void) { + playFlags &= ~PLAYFLG_PLAYING; + #if GFX_USE_GEVENT + if (playFlags & PLAYFLG_USEEVENTS) + gtimerJabI(&playTimer); + #endif + gfxSemSignalI(&playComplete); // This should really be gfxSemSignalAllI(&playComplete); + } +#endif + +#if GAUDIO_NEED_RECORD + bool_t gaudioRecordInit(uint16_t channel, uint32_t frequency, ArrayDataFormat format) { + gaudioRecordStop(); + recordFlags &= ~RECORDFLG_ISINIT; + if (!gaudio_record_lld_init(channel, frequency, format)) + return FALSE; + recordFlags |= RECORDFLG_ISINIT; + return TRUE; + } + + void gaudioRecordStart(void) { + if (!(recordFlags & RECORDFLG_ISINIT)) + return; // Oops - init failed + + recordFlags |= RECORDFLG_RECORDING; + recordFlags &= ~RECORDFLG_STALLED; + gaudio_record_lld_start(); + } + + void gaudioRecordStop(void) { + GAudioData *paud; + + 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); + } + + GAudioData *gaudioRecordGetData(delaytime_t ms) { + return (GAudioData *)gfxQueueGSyncGet(&recordList, ms); + } + + #if GFX_USE_GEVENT + static void RecordTimerCallback(void *param) { + (void) param; + GSourceListener *psl; + GEventAudioRecord *pe; + + psl = 0; + while ((psl = geventGetSourceListener((GSourceHandle)&recordTimer, psl))) { + if (!(pe = (GEventAudioRecord *)geventGetEventBuffer(psl))) { + // This listener is missing - save this. + psl->srcflags |= GAUDIO_RECORD_LOSTEVENT; + continue; + } + pe->type = GEVENT_AUDIO_RECORD; + pe->flags = psl->srcflags; + psl->srcflags = 0; + if ((recordFlags & RECORDFLG_RECORDING)) + pe->flags |= GAUDIO_RECORD_RECORDING; + if ((recordFlags & RECORDFLG_STALLED)) + pe->flags |= GAUDIO_RECORD_STALL; + if (!gfxQueueGSyncIsEmpty(&recordList)) + pe->flags |= GAUDIO_RECORD_GOTBLOCK; + geventSendEvent(psl); + } + } + + GSourceHandle gaudioRecordGetSource(void) { + if (!gtimerIsActive(&recordTimer)) + gtimerStart(&recordTimer, RecordTimerCallback, 0, TRUE, TIME_INFINITE); + recordFlags |= RECORDFLG_USEEVENTS; + return (GSourceHandle)&recordTimer; + } + #endif + + /** + * Routines provided for use by drivers. + */ + + GAudioData *gaudioRecordGetFreeBlockI(void) { + return (GAudioData *)gfxQueueGSyncGetI(&freeList); + } + + void gaudioRecordSaveDataBlockI(GAudioData *paud) { + gfxQueueGSyncPutI(&recordList, (gfxQueueGSyncItem *)paud); + #if GFX_USE_GEVENT + if (recordFlags & RECORDFLG_USEEVENTS) + gtimerJabI(&recordTimer); + #endif + } + + void gaudioRecordDoneI(void) { + recordFlags |= RECORDFLG_STALLED; + #if GFX_USE_GEVENT + if (recordFlags & RECORDFLG_USEEVENTS) + gtimerJabI(&recordTimer); + #endif + } +#endif + +#endif /* GFX_USE_GAUDIO */ +/** @} */ diff --git a/src/gaudio/sys_defs.h b/src/gaudio/sys_defs.h new file mode 100644 index 00000000..a9a951b7 --- /dev/null +++ b/src/gaudio/sys_defs.h @@ -0,0 +1,340 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gaudio/sys_defs.h + * + * @addtogroup GAUDIO + * + * @brief Module to handle audio recording and play-back + * + * @{ + */ + +#ifndef _GAUDIO_H +#define _GAUDIO_H + +#include "gfx.h" + +#if GFX_USE_GAUDIO || defined(__DOXYGEN__) + +/* Include the driver defines */ +#if GAUDIO_NEED_PLAY + #include "gaudio_play_config.h" +#endif +#if GAUDIO_NEED_RECORD + #include "gaudio_record_config.h" +#endif + +/*===========================================================================*/ +/* 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) + +#if GFX_USE_GEVENT || defined(__DOXYGEN__) + /** + * @brief The Audio play event structure. + * @{ + */ + typedef struct GEventAudioPlay_t { + /** + * @brief The type of this event (GEVENT_AUDIO_PLAY) + */ + GEventType type; + /** + * @brief The event flags + */ + uint16_t flags; + /** + * @brief The event flag values. + * @{ + */ + #define GAUDIO_PLAY_LOSTEVENT 0x0001 /**< @brief The last GEVENT_AUDIO_PLAY event was lost */ + #define GAUDIO_PLAY_PLAYING 0x0002 /**< @brief The audio out system is currently playing */ + #define GAUDIO_PLAY_FREEBLOCK 0x0004 /**< @brief An audio buffer has been freed */ + /** @} */ + } GEventAudioPlay; + /** @} */ + + /** + * @brief The Audio record event structure. + * @{ + */ + typedef struct GEventAudioRecord_t { + /** + * @brief The type of this event (GEVENT_AUDIO_RECORD) + */ + GEventType type; + /** + * @brief The event flags + */ + uint16_t flags; + /** + * @brief The event flag values. + * @{ + */ + #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_STALL 0x0008 /**< @brief The recording process has stalled due to no free buffers */ + /** @} */ + } GEventAudioRecord; + /** @} */ +#endif + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +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 + * sample frequency. + * @return TRUE is successful, FALSE if the driver doesn't accept those parameters. + * + * @param[in] channel The audio output channel to use. Can be set from 0 to GAUDIO_PLAY_NUM_CHANNELS - 1 + * @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. + * @note Only one channel can be playing at a time. Calling this will stop any + * currently playing channel. + * + * @api + */ + bool_t gaudioPlayInit(uint16_t channel, uint32_t frequency, ArrayDataFormat format); + + /** + * @brief Play the specified sample data. + * @details The sample data is output to the audio channel. On completion the buffer is returned to the free-list. + * @pre @p gaudioPlayInit must have been called first to set the channel and sample frequency. + * + * @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 + * 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 + * for playing in the order they are supplied to this routine and played when previous buffers are + * complete. In this way continuous playing can be obtained without audio gaps. + * + * @api + */ + void gaudioPlay(GAudioData *paud); + + /** + * @brief Pause any currently playing sounds. + * + * @note If nothing is currently playing this routine does nothing. To restart playing call @p gaudioPlay() + * with or without a new sample buffer. + * @note Some drivers will not respond until a buffer boundary. + * + * @api + */ + void gaudioPlayPause(void); + + /** + * @brief Stop any currently playing sounds. + * + * @note This stops any playing sounds and returns any currently queued buffers back to the free-list. + * @note Some drivers will not respond until a buffer boundary. + * + * @api + */ + void gaudioPlayStop(void); + + /** + * @brief Set the output volume. + * @return TRUE if successful. + * + * @param[in] 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. + * + * @api + */ + 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 signaling via this method and other methods + * at the same time. + * + * @return The GSourceHandle + * + * @api + */ + GSourceHandle gaudioPlayGetSource(void); + #endif + + /** + * @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. + * + * @api + */ + bool_t gaudioPlayWait(delaytime_t ms); +#endif + +#if GAUDIO_NEED_RECORD || defined(__DOXYGEN__) + /** + * @brief Initialise (but not start) the Audio Recording sub-system. + * @details Returns FALSE for an invalid channel or other invalid parameter. + * + * @param[in] channel The channel to convert. Can be set from 0 to GAUDIO_RECORD_NUM_CHANNELS - 1 + * @param[in] frequency The sample frequency + * @param[in] format The audio sample format requested + * + * @note Only one channel is active at a time. If an audio input is running it will be stopped. + * The Event subsystem is disconnected from the audio subsystem and any binary semaphore + * event is forgotten. + * @note Some channels may be stereo channels which return twice as much sample data with + * the left and right channel data interleaved. Other channels may be mono channels. + * Where stereo channels exist the low level driver may also + * offer the left and right channels separately. + * @note Due to a bug in Chibi-OS each buffer on the free-list must contain an even number of + * samples and for stereo devices it must hold a number of samples that is evenly divisible by 4. + * This requirement applies only to ChibiOS where the audio driver uses + * a ChibiOS hal driver like the cpu ADC driver. This applies even it is used indirectly via + * the uGFX GADC driver. + * @note The number of samples for stereo devices will be double the number of conversions. + * Make sure you allocate your buffers large enough. Each channel is then interleaved + * into the provided buffer. + * + * @return FALSE if invalid channel or parameter + * + * @api + */ + bool_t gaudioRecordInit(uint16_t channel, uint32_t frequency, ArrayDataFormat format); + + /** + * @brief Start the audio recording. + * @pre It must have been initialised first with @p gaudioRecordInit() + * + * @api + */ + void gaudioRecordStart(void); + + /** + * @brief Stop the audio recording. + * + * @note All audio recording data that has not yet been retrieved is automatically + * returned to the free-list. + * @api + */ + void gaudioRecordStop(void); + + /** + * @brief Get a filled audio buffer from the recording 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 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(). + * @api + */ + GAudioData *gaudioRecordGetData(delaytime_t ms); + + #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_RECORD events. + * + * @note Audio recording 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 recording. + * Once turned on it can only be turned off by calling @p gaudioRecordInit() again. + * @note The audio input is capable of signaling via this and other methods + * at the same time. + * + * @return The GSourceHandle + * + * @api + */ + GSourceHandle gaudioRecordGetSource(void); + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* GFX_USE_GAUDIO */ + +#endif /* _GAUDIO_H */ +/** @} */ + diff --git a/src/gaudio/sys_make.mk b/src/gaudio/sys_make.mk new file mode 100644 index 00000000..438892c0 --- /dev/null +++ b/src/gaudio/sys_make.mk @@ -0,0 +1 @@ +GFXSRC += $(GFXLIB)/src/gaudio/gaudio.c diff --git a/src/gaudio/sys_options.h b/src/gaudio/sys_options.h new file mode 100644 index 00000000..1363d703 --- /dev/null +++ b/src/gaudio/sys_options.h @@ -0,0 +1,44 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gaudio/sys_options.h + * @brief GAUDIO - Audio subsystem options header file. + * + * @addtogroup GAUDIO + * @{ + */ + +#ifndef _GAUDIO_OPTIONS_H +#define _GAUDOUT_OPTIONS_H + +/** + * @name GAUDIO Functionality to be included + * @{ + */ + /** + * @brief Audio Play capability is needed + */ + #ifndef GAUDIO_NEED_PLAY + #define GAUDIO_NEED_PLAY FALSE + #endif + /** + * @brief Audio Recording capability is needed + */ + #ifndef GAUDIO_NEED_RECORD + #define GAUDIO_NEED_RECORD FALSE + #endif +/** + * @} + * + * @name GAUDIO Optional Sizing Parameters + * @{ + */ +/** @} */ + +#endif /* _GAUDIO_OPTIONS_H */ +/** @} */ diff --git a/src/gaudio/sys_rules.h b/src/gaudio/sys_rules.h new file mode 100644 index 00000000..a3f0dffc --- /dev/null +++ b/src/gaudio/sys_rules.h @@ -0,0 +1,54 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gaudio/sys_rules.h + * @brief GAUDIO safety rules header file. + * + * @addtogroup GAUDIO + * @{ + */ + +#ifndef _GAUDIO_RULES_H +#define _GAUDIO_RULES_H + +#if GFX_USE_GAUDIO + #if !GAUDIO_NEED_PLAY && !GAUDIO_NEED_RECORD + #error "GAUDIO: GAUDIO_NEED_PLAY and/or GAUDIO_NEED_RECORD is required if GFX_USE_GAUDIO is TRUE" + #endif + #if !GFX_USE_GQUEUE + #if GFX_DISPLAY_RULE_WARNINGS + #warning "GAUDIO: GFX_USE_GQUEUE is required if GFX_USE_GAUDIO is TRUE. It has been turned on for you." + #endif + #undef GFX_USE_GQUEUE + #define GFX_USE_GQUEUE TRUE + #endif + #if !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." + #endif + #undef GQUEUE_NEED_ASYNC + #define GQUEUE_NEED_ASYNC TRUE + #endif + #if !GQUEUE_NEED_GSYNC + #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." + #endif + #undef GQUEUE_NEED_GSYNC + #define GQUEUE_NEED_GSYNC TRUE + #endif + #if GFX_USE_GEVENT && !GFX_USE_GTIMER + #if GFX_DISPLAY_RULE_WARNINGS + #warning "GAUDIO: GFX_USE_GTIMER is required if GFX_USE_GAUDIO and GFX_USE_GEVENT are TRUE. It has been turned on for you." + #endif + #undef GFX_USE_GTIMER + #define GFX_USE_GTIMER TRUE + #endif +#endif + +#endif /* _GAUDIO_RULES_H */ +/** @} */ diff --git a/src/gaudout/gaudout.c b/src/gaudout/gaudout.c deleted file mode 100644 index 00b01e91..00000000 --- a/src/gaudout/gaudout.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gaudout/gaudout.c - * @brief GAUDOUT sub-system code. - * - * @addtogroup GAUDOUT - * @{ - */ -#include "gfx.h" - -#if GFX_USE_GAUDOUT || defined(__DOXYGEN__) - -#include "src/gaudout/driver.h" - -static gfxQueueASync playlist; -static gfxQueueGSync freelist; - -static uint16_t PlayFlags; - #define PLAYFLG_USEEVENTS 0x0001 - #define PLAYFLG_PLAYING 0x0002 - -#if GFX_USE_GEVENT - static GTimer PlayTimer; - - static void PlayTimerCallback(void *param) { - (void) param; - GSourceListener *psl; - GEventAudioOut *pe; - - psl = 0; - while ((psl = geventGetSourceListener((GSourceHandle)(&aud), psl))) { - if (!(pe = (GEventAudioOut *)geventGetEventBuffer(psl))) { - // This listener is missing - save this. - psl->srcflags |= GAUDOUT_LOSTEVENT; - continue; - } - - 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); - } - } -#endif - - -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) { - 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); -} - -bool_t gaudioPlayInit(uint16_t channel, uint32_t frequency, ArrayDataFormat format) { - gaudioPlayStop(); - gaudout_lld_deinit(); - return gaudout_lld_init(channel, frequency, format); -} - -void gaudioPlay(GAudioData *paud) { - if (paud) - gfxQueueASyncPut(&playlist, (gfxQueueASyncItem *)paud); - PlayFlags |= PLAYFLG_PLAYING; - gaudout_lld_start(); -} - -void gaudioPlayPause(void) { - gaudout_lld_stop(); -} - -void gaudioPlayStop(void) { - GAudioData *paud; - - 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. - */ - -GAudioData *gaudoutGetDataBlockI(void) { - return (GAudioData *)gfxQueueASyncGetI(&playlist); -} - -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 deleted file mode 100644 index 75cda243..00000000 --- a/src/gaudout/sys_defs.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gaudout/sys_defs.h - * - * @addtogroup GAUDOUT - * - * @brief Module to output audio data (under development) - * - * @{ - */ - -#ifndef _GAUDOUT_H -#define _GAUDOUT_H - -#include "gfx.h" - -#if GFX_USE_GAUDOUT || defined(__DOXYGEN__) - -/* Include the driver defines */ -#include "gaudout_lld_config.h" - - -/*===========================================================================*/ -/* 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 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. */ -/*===========================================================================*/ - -#ifdef __cplusplus -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); - -/** - * @brief Set the audio device to play on the specified channel and with the specified - * sample frequency. - * @return TRUE is successful, FALSE if the driver doesn't accept those parameters. - * - * @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. - * @note Only one channel can be playing at a time. Calling this will stop any - * currently playing channel. - * - * @api - */ -bool_t gaudioPlayInit(uint16_t channel, uint32_t frequency, ArrayDataFormat format); - -/** - * @brief Play the specified sample data. - * @details The sample data is output to the audio channel. On completion the buffer is returned to the free-list. - * @pre @p gaudioPlayInit must have been called first to set the channel and sample frequency. - * - * @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 - * 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 - * for playing in the order they are supplied to this routine and played when previous buffers are - * complete. In this way continuous playing can be obtained without audio gaps. - * - * @api - */ -void gaudioPlay(GAudioData *paud); - -/** - * @brief Pause any currently playing sounds. - * - * @note If nothing is currently playing this routine does nothing. To restart playing call @p gaudioPlay() - * with or without a new sample buffer. - * @note Some drivers will not respond until a buffer boundary. - * - * @api - */ -void gaudioPlayPause(void); - -/** - * @brief Stop any currently playing sounds. - * - * @note This stops any playing sounds and returns any currently queued buffers back to the free-list. - * @note Some drivers will not respond until a buffer boundary. - * - * @api - */ -void gaudioPlayStop(void); - -/** - * @brief Set the output volume. - * @return TRUE if successful. - * - * @param[in] 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. - * - * @api - */ -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 - -#endif /* GFX_USE_GAUDOUT */ - -#endif /* _GAUDOUT_H */ -/** @} */ - diff --git a/src/gaudout/sys_make.mk b/src/gaudout/sys_make.mk deleted file mode 100644 index 14f5bac3..00000000 --- a/src/gaudout/sys_make.mk +++ /dev/null @@ -1 +0,0 @@ -GFXSRC += $(GFXLIB)/src/gaudout/gaudout.c diff --git a/src/gaudout/sys_options.h b/src/gaudout/sys_options.h deleted file mode 100644 index 929bb42a..00000000 --- a/src/gaudout/sys_options.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gaudout/sys_options.h - * @brief GAUDOUT - Audio Output subsystem options header file. - * - * @addtogroup GAUDOUT - * @{ - */ - -#ifndef _GAUDOUT_OPTIONS_H -#define _GAUDOUT_OPTIONS_H - -/** - * @name GAUDOUT Functionality to be included - * @{ - */ -/** - * @} - * - * @name GAUDOUT Optional Sizing Parameters - * @{ - */ -/** @} */ - -#endif /* _GAUDOUT_OPTIONS_H */ -/** @} */ diff --git a/src/gaudout/sys_rules.h b/src/gaudout/sys_rules.h deleted file mode 100644 index 8274e031..00000000 --- a/src/gaudout/sys_rules.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gaudout/sys_rules.h - * @brief GAUDOUT safety rules header file. - * - * @addtogroup GAUDOUT - * @{ - */ - -#ifndef _GAUDOUT_RULES_H -#define _GAUDOUT_RULES_H - -#if GFX_USE_GAUDOUT - #if !GFX_USE_GQUEUE - #if GFX_DISPLAY_RULE_WARNINGS - #warning "GAUDOUT: GFX_USE_GQUEUE is required if GFX_USE_GAUDOUT is TRUE. It has been turned on for you." - #endif - #undef GFX_USE_GQUEUE - #define GFX_USE_GQUEUE TRUE - #endif - #if !GQUEUE_NEED_ASYNC - #if GFX_DISPLAY_RULE_WARNINGS - #warning "GAUDOUT: GQUEUE_NEED_ASYNC is required if GFX_USE_GAUDOUT 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 GFX_DISPLAY_RULE_WARNINGS - #warning "GAUDOUT: GQUEUE_NEED_GSYNC is required if GFX_USE_GAUDOUT is TRUE. It has been turned on for you." - #endif - #undef GQUEUE_NEED_GSYNC - #define GQUEUE_NEED_GSYNC TRUE - #endif -#endif - -#endif /* _GAUDOUT_RULES_H */ -/** @} */ diff --git a/src/gevent/sys_defs.h b/src/gevent/sys_defs.h index 0e656145..c50dc5ae 100644 --- a/src/gevent/sys_defs.h +++ b/src/gevent/sys_defs.h @@ -38,8 +38,7 @@ typedef uint16_t GEventType; #define GEVENT_GINPUT_FIRST 0x0100 // GINPUT events range from 0x0100 to 0x01FF #define GEVENT_GWIN_FIRST 0x0200 // GWIN events range from 0x0200 to 0x02FF #define GEVENT_GADC_FIRST 0x0300 // GADC events range from 0x0300 to 0x033F - #define GEVENT_GAUDIN_FIRST 0x0340 // GAUDIN events range from 0x0340 to 0x037F - #define GEVENT_GAUDOUT_FIRST 0x0380 // GAUDOUT events range from 0x0380 to 0x03BF + #define GEVENT_GAUDIO_FIRST 0x0340 // GAUDIO events range from 0x0340 to 0x037F #define GEVENT_USER_FIRST 0x8000 // Any application defined events start at 0x8000 // This object can be typecast to any GEventXxxxx type to allow any sub-system (or the application) to create events. @@ -44,13 +44,9 @@ extern void _gosDeinit(void); extern void _gadcInit(void); extern void _gadcDeinit(void); #endif -#if GFX_USE_GAUDIN - extern void _gaudinInit(void); - extern void _gaudinDeinit(void); -#endif -#if GFX_USE_GAUDOUT - extern void _gaudoutInit(void); - extern void _gaudoutDeinit(void); +#if GFX_USE_GAUDIO + extern void _gaudioInit(void); + extern void _gaudioDeinit(void); #endif #if GFX_USE_GMISC extern void _gmiscInit(void); @@ -88,11 +84,8 @@ void gfxInit(void) #if GFX_USE_GADC _gadcInit(); #endif - #if GFX_USE_GAUDIN - _gaudinInit(); - #endif - #if GFX_USE_GAUDOUT - _gaudoutInit(); + #if GFX_USE_GAUDIO + _gaudioInit(); #endif } @@ -103,11 +96,8 @@ void gfxDeinit(void) initDone = FALSE; // We deinitialise the opposite way as we initialised - #if GFX_USE_GAUDOUT - _gaudoutDeinit(); - #endif #if GFX_USE_GAUDIN - _gaudinDeinit(); + _gaudioDeinit(); #endif #if GFX_USE_GADC _gadcDeinit(); |