170 lines
3.6 KiB
C
170 lines
3.6 KiB
C
/*
|
|
* 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 */
|
|
/** @} */
|
|
|