(GX) Reimplement audio driver
This commit is contained in:
parent
e9243a5ab4
commit
17b69cbc29
|
@ -40,26 +40,28 @@ typedef struct
|
||||||
bool nonblock;
|
bool nonblock;
|
||||||
} gx_audio_t;
|
} gx_audio_t;
|
||||||
|
|
||||||
static gx_audio_t *g_audio;
|
|
||||||
|
|
||||||
static void dma_callback(void)
|
static void dma_callback(void)
|
||||||
{
|
{
|
||||||
|
gx_audio_t *wa = (gx_audio_t*)driver.audio_data;
|
||||||
// erase last chunk to avoid repeating audio
|
// erase last chunk to avoid repeating audio
|
||||||
memset(g_audio->data[g_audio->dma_busy], 0, CHUNK_SIZE);
|
memset(wa->data[wa->dma_busy], 0, CHUNK_SIZE);
|
||||||
|
|
||||||
g_audio->dma_busy = g_audio->dma_next;
|
wa->dma_busy = wa->dma_next;
|
||||||
g_audio->dma_next = (g_audio->dma_next + 1) & (BLOCKS - 1);
|
wa->dma_next = (wa->dma_next + 1) & (BLOCKS - 1);
|
||||||
|
|
||||||
DCFlushRange(g_audio->data[g_audio->dma_next], CHUNK_SIZE);
|
DCFlushRange(wa->data[wa->dma_next], CHUNK_SIZE);
|
||||||
AUDIO_InitDMA((u32)g_audio->data[g_audio->dma_next], CHUNK_SIZE);
|
AUDIO_InitDMA((uint32_t)wa->data[wa->dma_next], CHUNK_SIZE);
|
||||||
|
|
||||||
LWP_ThreadSignal(g_audio->cond);
|
LWP_ThreadSignal(wa->cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *gx_audio_init(const char *device, unsigned rate, unsigned latency)
|
static void *gx_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||||
{
|
{
|
||||||
if (g_audio)
|
gx_audio_t *wa = (gx_audio_t*)memalign(32, sizeof(*wa));
|
||||||
return g_audio;
|
if (!wa)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memset(wa, 0, sizeof(*wa));
|
||||||
|
|
||||||
AUDIO_Init(NULL);
|
AUDIO_Init(NULL);
|
||||||
AUDIO_RegisterDMACallback(dma_callback);
|
AUDIO_RegisterDMACallback(dma_callback);
|
||||||
|
@ -75,26 +77,14 @@ static void *gx_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||||
g_settings.audio.out_rate = 48000;
|
g_settings.audio.out_rate = 48000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_audio)
|
LWP_InitQueue(&wa->cond);
|
||||||
{
|
|
||||||
g_audio = memalign(32, sizeof(*g_audio));
|
|
||||||
memset(g_audio, 0, sizeof(*g_audio));
|
|
||||||
LWP_InitQueue(&g_audio->cond);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(g_audio->data, 0, sizeof(g_audio->data));
|
|
||||||
g_audio->dma_busy = g_audio->dma_next = 0;
|
|
||||||
g_audio->write_ptr = 0;
|
|
||||||
g_audio->nonblock = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_audio->dma_write = BLOCKS - 1;
|
wa->dma_write = BLOCKS - 1;
|
||||||
DCFlushRange(g_audio->data, sizeof(g_audio->data));
|
DCFlushRange(wa->data, sizeof(wa->data));
|
||||||
AUDIO_InitDMA((u32)g_audio->data[g_audio->dma_next], CHUNK_SIZE);
|
AUDIO_InitDMA((uint32_t)wa->data[wa->dma_next], CHUNK_SIZE);
|
||||||
AUDIO_StartDMA();
|
AUDIO_StartDMA();
|
||||||
|
|
||||||
return g_audio;
|
return wa;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wii uses silly R, L, R, L interleaving ...
|
// Wii uses silly R, L, R, L interleaving ...
|
||||||
|
@ -141,16 +131,16 @@ static ssize_t gx_audio_write(void *data, const void *buf_, size_t size)
|
||||||
|
|
||||||
static bool gx_audio_stop(void *data)
|
static bool gx_audio_stop(void *data)
|
||||||
{
|
{
|
||||||
(void)data;
|
gx_audio_t *wa = (gx_audio_t*)data;
|
||||||
AUDIO_StopDMA();
|
AUDIO_StopDMA();
|
||||||
memset(g_audio->data, 0, sizeof(g_audio->data));
|
memset(wa->data, 0, sizeof(wa->data));
|
||||||
DCFlushRange(g_audio->data, sizeof(g_audio->data));
|
DCFlushRange(wa->data, sizeof(wa->data));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gx_audio_set_nonblock_state(void *data, bool state)
|
static void gx_audio_set_nonblock_state(void *data, bool state)
|
||||||
{
|
{
|
||||||
gx_audio_t *wa = data;
|
gx_audio_t *wa = (gx_audio_t*)data;
|
||||||
wa->nonblock = state;
|
wa->nonblock = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,21 +153,22 @@ static bool gx_audio_start(void *data)
|
||||||
|
|
||||||
static void gx_audio_free(void *data)
|
static void gx_audio_free(void *data)
|
||||||
{
|
{
|
||||||
|
gx_audio_t *wa = (gx_audio_t*)data;
|
||||||
AUDIO_StopDMA();
|
AUDIO_StopDMA();
|
||||||
AUDIO_RegisterDMACallback(NULL);
|
AUDIO_RegisterDMACallback(NULL);
|
||||||
if (g_audio && g_audio->cond)
|
if (wa && wa->cond)
|
||||||
{
|
{
|
||||||
LWP_CloseQueue(g_audio->cond);
|
LWP_CloseQueue(wa->cond);
|
||||||
g_audio->cond = 0;
|
wa->cond = 0;
|
||||||
}
|
}
|
||||||
if (data)
|
if (data)
|
||||||
free(data);
|
free(data);
|
||||||
g_audio = NULL;
|
wa = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t gx_audio_write_avail(void *data)
|
static size_t gx_audio_write_avail(void *data)
|
||||||
{
|
{
|
||||||
gx_audio_t *wa = data;
|
gx_audio_t *wa = (gx_audio_t*)data;
|
||||||
return ((wa->dma_busy - wa->dma_write + BLOCKS) & (BLOCKS - 1)) * CHUNK_SIZE;
|
return ((wa->dma_busy - wa->dma_write + BLOCKS) & (BLOCKS - 1)) * CHUNK_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue