(Audio) Update audio drivers to make them more uniform

This commit is contained in:
twinaphex 2020-01-04 10:32:03 +01:00
parent 22b789cca6
commit ee7051891b
13 changed files with 206 additions and 183 deletions

View File

@ -245,7 +245,7 @@ static void *coreaudio_init(const char *device,
#else #else
comp = AudioComponentFindNext(NULL, &desc); comp = AudioComponentFindNext(NULL, &desc);
#endif #endif
if (comp == NULL) if (!comp)
goto error; goto error;
#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) #if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))

View File

@ -260,6 +260,23 @@ static bool g_interrupted;
- (ssize_t)writeFloat:(const float *)data samples:(size_t)samples { - (ssize_t)writeFloat:(const float *)data samples:(size_t)samples {
size_t written = 0; size_t written = 0;
if (_nonBlock)
{
if (!g_interrupted && samples > 0)
{
size_t write_avail = rb_avail(&_rb);
if (write_avail > samples)
write_avail = samples;
rb_write_data(&_rb, data, write_avail);
data += write_avail;
written += write_avail;
samples -= write_avail;
}
}
else
{
while (!g_interrupted && samples > 0) while (!g_interrupted && samples > 0)
{ {
size_t write_avail = rb_avail(&_rb); size_t write_avail = rb_avail(&_rb);
@ -271,12 +288,10 @@ static bool g_interrupted;
written += write_avail; written += write_avail;
samples -= write_avail; samples -= write_avail;
if (_nonBlock)
break;
if (write_avail == 0) if (write_avail == 0)
dispatch_semaphore_wait(_sema, DISPATCH_TIME_FOREVER); dispatch_semaphore_wait(_sema, DISPATCH_TIME_FOREVER);
} }
}
return written; return written;
} }

View File

@ -23,7 +23,7 @@
typedef struct typedef struct
{ {
bool nonblocking; bool nonblock;
bool playing; bool playing;
int16_t* l; int16_t* l;
int16_t* r; int16_t* r;
@ -180,7 +180,7 @@ static ssize_t ctr_csnd_audio_write(void *data, const void *buf, size_t size)
(((ctr->pos - ctr->playpos ) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 4)) || (((ctr->pos - ctr->playpos ) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 4)) ||
(((ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK) < (size >> 2))) (((ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK) < (size >> 2)))
{ {
if (ctr->nonblocking) if (ctr->nonblock)
ctr->pos = (ctr->playpos + (CTR_CSND_AUDIO_COUNT >> 1)) & CTR_CSND_AUDIO_COUNT_MASK; ctr->pos = (ctr->playpos + (CTR_CSND_AUDIO_COUNT >> 1)) & CTR_CSND_AUDIO_COUNT_MASK;
else else
{ {
@ -265,7 +265,7 @@ static void ctr_csnd_audio_set_nonblock_state(void *data, bool state)
{ {
ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data; ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data;
if (ctr) if (ctr)
ctr->nonblocking = state; ctr->nonblock = state;
} }
static bool ctr_csnd_audio_use_float(void *data) static bool ctr_csnd_audio_use_float(void *data)

View File

@ -22,7 +22,7 @@
typedef struct typedef struct
{ {
bool nonblocking; bool nonblock;
bool playing; bool playing;
int channel; int channel;
ndspWaveBuf dsp_buf; ndspWaveBuf dsp_buf;
@ -102,7 +102,7 @@ static ssize_t ctr_dsp_audio_write(void *data, const void *buf, size_t size)
(((ctr->pos - sample_pos ) & CTR_DSP_AUDIO_COUNT_MASK) < (CTR_DSP_AUDIO_COUNT >> 4)) || (((ctr->pos - sample_pos ) & CTR_DSP_AUDIO_COUNT_MASK) < (CTR_DSP_AUDIO_COUNT >> 4)) ||
(((sample_pos - ctr->pos) & CTR_DSP_AUDIO_COUNT_MASK) < (size >> 2))) (((sample_pos - ctr->pos) & CTR_DSP_AUDIO_COUNT_MASK) < (size >> 2)))
{ {
if (ctr->nonblocking) if (ctr->nonblock)
ctr->pos = (sample_pos + (CTR_DSP_AUDIO_COUNT >> 1)) & CTR_DSP_AUDIO_COUNT_MASK; ctr->pos = (sample_pos + (CTR_DSP_AUDIO_COUNT >> 1)) & CTR_DSP_AUDIO_COUNT_MASK;
else else
{ {
@ -173,7 +173,7 @@ static void ctr_dsp_audio_set_nonblock_state(void *data, bool state)
{ {
ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data; ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data;
if (ctr) if (ctr)
ctr->nonblocking = state; ctr->nonblock = state;
} }
static bool ctr_dsp_audio_use_float(void *data) static bool ctr_dsp_audio_use_float(void *data)

View File

@ -29,7 +29,8 @@
typedef struct ps2_audio typedef struct ps2_audio
{ {
bool nonblocking; /* TODO/FIXME - nonblock is not implemented */
bool nonblock;
bool running; bool running;
} ps2_audio_t; } ps2_audio_t;
@ -82,15 +83,12 @@ static void ps2_audio_free(void *data)
static ssize_t ps2_audio_write(void *data, const void *buf, size_t size) static ssize_t ps2_audio_write(void *data, const void *buf, size_t size)
{ {
int bytes_sent;
ps2_audio_t* ps2 = (ps2_audio_t*)data; ps2_audio_t* ps2 = (ps2_audio_t*)data;
if (!ps2->running) if (!ps2->running)
return -1; return -1;
bytes_sent = audsrv_play_audio(buf, size); return audsrv_play_audio(buf, size);
return bytes_sent;
} }
static bool ps2_audio_alive(void *data) static bool ps2_audio_alive(void *data)
@ -134,7 +132,7 @@ static void ps2_audio_set_nonblock_state(void *data, bool toggle)
ps2_audio_t* ps2 = (ps2_audio_t*)data; ps2_audio_t* ps2 = (ps2_audio_t*)data;
if (ps2) if (ps2)
ps2->nonblocking = toggle; ps2->nonblock = toggle;
} }
static bool ps2_audio_use_float(void *data) static bool ps2_audio_use_float(void *data)

View File

@ -29,7 +29,7 @@
typedef struct typedef struct
{ {
uint32_t audio_port; uint32_t audio_port;
bool nonblocking; bool nonblock;
bool started; bool started;
volatile bool quit_thread; volatile bool quit_thread;
fifo_buffer_t *buffer; fifo_buffer_t *buffer;
@ -150,7 +150,7 @@ static ssize_t ps3_audio_write(void *data, const void *buf, size_t size)
{ {
ps3_audio_t *aud = data; ps3_audio_t *aud = data;
if (aud->nonblocking) if (aud->nonblock)
{ {
if (fifo_write_avail(aud->buffer) < size) if (fifo_write_avail(aud->buffer) < size)
return 0; return 0;
@ -200,7 +200,7 @@ static void ps3_audio_set_nonblock_state(void *data, bool toggle)
{ {
ps3_audio_t *aud = data; ps3_audio_t *aud = data;
if (aud) if (aud)
aud->nonblocking = toggle; aud->nonblock = toggle;
} }
static void ps3_audio_free(void *data) static void ps3_audio_free(void *data)

View File

@ -44,7 +44,7 @@
typedef struct psp_audio typedef struct psp_audio
{ {
bool nonblocking; bool nonblock;
uint32_t* buffer; uint32_t* buffer;
uint32_t* zeroBuffer; uint32_t* zeroBuffer;
@ -167,7 +167,7 @@ static void *psp_audio_init(const char *device,
psp->cond_lock = slock_new(); psp->cond_lock = slock_new();
psp->cond = scond_new(); psp->cond = scond_new();
psp->nonblocking = false; psp->nonblock = false;
psp->running = true; psp->running = true;
psp->worker_thread = sthread_create(audioMainLoop, psp); psp->worker_thread = sthread_create(audioMainLoop, psp);
@ -209,7 +209,7 @@ static ssize_t psp_audio_write(void *data, const void *buf, size_t size)
if (!psp->running) if (!psp->running)
return -1; return -1;
if (psp->nonblocking) if (psp->nonblock)
{ {
if (AUDIO_BUFFER_SIZE - ((uint16_t) if (AUDIO_BUFFER_SIZE - ((uint16_t)
(psp->write_pos - psp->read_pos) & AUDIO_BUFFER_SIZE_MASK) < size) (psp->write_pos - psp->read_pos) & AUDIO_BUFFER_SIZE_MASK) < size)
@ -287,7 +287,7 @@ static void psp_audio_set_nonblock_state(void *data, bool toggle)
{ {
psp_audio_t* psp = (psp_audio_t*)data; psp_audio_t* psp = (psp_audio_t*)data;
if (psp) if (psp)
psp->nonblocking = toggle; psp->nonblock = toggle;
} }
static bool psp_audio_use_float(void *data) static bool psp_audio_use_float(void *data)

View File

@ -92,9 +92,11 @@ static ssize_t switch_audio_write(void *data, const void *buf, size_t size)
if (!swa->current_buffer) if (!swa->current_buffer)
{ {
if (swa->blocking) /* no buffer, nonblocking... */
{ if (!swa->blocking)
while(swa->current_buffer == NULL) return 0;
while (!swa->current_buffer)
{ {
uint32_t handle_idx = 0; uint32_t handle_idx = 0;
num = 0; num = 0;
@ -110,10 +112,6 @@ static ssize_t switch_audio_write(void *data, const void *buf, size_t size)
#endif #endif
} }
} }
else
/* no buffer, nonblocking... */
return 0;
}
swa->current_buffer->data_size = 0; swa->current_buffer->data_size = 0;
} }
@ -297,7 +295,7 @@ static void *switch_audio_init(const char *device,
swa->buffers[i].data_offset = 0; swa->buffers[i].data_offset = 0;
swa->buffers[i].buffer = memalign(0x1000, switch_audio_buffer_size(NULL)); swa->buffers[i].buffer = memalign(0x1000, switch_audio_buffer_size(NULL));
if (swa->buffers[i].buffer == NULL) if (!swa->buffers[i].buffer)
goto fail_audio_output; goto fail_audio_output;
memset(swa->buffers[i].buffer, 0, switch_audio_buffer_size(NULL)); memset(swa->buffers[i].buffer, 0, switch_audio_buffer_size(NULL));
@ -306,7 +304,7 @@ static void *switch_audio_init(const char *device,
swa->buffers[i].unknown = 0; swa->buffers[i].unknown = 0;
swa->buffers[i].sample_data = alloc_pages(sample_buffer_size, switch_audio_buffer_size(NULL), NULL); swa->buffers[i].sample_data = alloc_pages(sample_buffer_size, switch_audio_buffer_size(NULL), NULL);
if (swa->buffers[i].sample_data == NULL) if (!swa->buffers[i].sample_data)
goto fail_audio_output; goto fail_audio_output;
#endif #endif

View File

@ -42,7 +42,8 @@ static const AudioRendererConfig audio_renderer_config =
.num_mix_buffers = 2, .num_mix_buffers = 2,
}; };
typedef struct { typedef struct
{
AudioDriver drv; AudioDriver drv;
void* mempool; void* mempool;
AudioDriverWaveBuf wavebufs[BUFFER_COUNT]; AudioDriverWaveBuf wavebufs[BUFFER_COUNT];
@ -52,10 +53,11 @@ typedef struct {
size_t buffer_size; size_t buffer_size;
size_t samples; size_t samples;
Mutex update_lock; Mutex update_lock;
bool nonblocking; bool nonblock;
} libnx_audren_t; } libnx_audren_t;
static void *libnx_audren_audio_init(const char *device, unsigned rate, unsigned latency, static void *libnx_audren_audio_init(
const char *device, unsigned rate, unsigned latency,
unsigned block_frames, unsigned block_frames,
unsigned *new_rate) unsigned *new_rate)
{ {
@ -79,7 +81,7 @@ static void *libnx_audren_audio_init(const char *device, unsigned rate, unsigned
real_latency = MAX(5, latency); real_latency = MAX(5, latency);
RARCH_LOG("[Audio]: real_latency is %u\n", real_latency); RARCH_LOG("[Audio]: real_latency is %u\n", real_latency);
aud->nonblocking = !block_frames; aud->nonblock = !block_frames;
aud->buffer_size = (real_latency * sample_rate / 1000); aud->buffer_size = (real_latency * sample_rate / 1000);
aud->samples = (aud->buffer_size / num_channels / sizeof(int16_t)); aud->samples = (aud->buffer_size / num_channels / sizeof(int16_t));
aud->current_size = 0; aud->current_size = 0;
@ -150,9 +152,7 @@ fail:
if (aud) if (aud)
{ {
if (aud->mempool) if (aud->mempool)
{
free(aud->mempool); free(aud->mempool);
}
free(aud); free(aud);
} }
@ -176,18 +176,19 @@ static ssize_t libnx_audren_audio_get_free_wavebuf_idx(libnx_audren_t* aud)
for (i = 0; i < BUFFER_COUNT; i++) for (i = 0; i < BUFFER_COUNT; i++)
{ {
if (aud->wavebufs[i].state == AudioDriverWaveBufState_Free if (
aud->wavebufs[i].state == AudioDriverWaveBufState_Free
|| aud->wavebufs[i].state == AudioDriverWaveBufState_Done) || aud->wavebufs[i].state == AudioDriverWaveBufState_Done)
{
return i; return i;
} }
}
return -1; return -1;
} }
static size_t libnx_audren_audio_append(libnx_audren_t* aud, const void *buf, size_t size) static size_t libnx_audren_audio_append(
libnx_audren_t* aud, const void *buf, size_t size)
{ {
void *dstbuf = NULL;
ssize_t free_idx = -1; ssize_t free_idx = -1;
if (!aud->current_wavebuf) if (!aud->current_wavebuf)
@ -202,11 +203,9 @@ static size_t libnx_audren_audio_append(libnx_audren_t* aud, const void *buf, si
} }
if (size > aud->buffer_size - aud->current_size) if (size > aud->buffer_size - aud->current_size)
{
size = aud->buffer_size - aud->current_size; size = aud->buffer_size - aud->current_size;
}
void *dstbuf = aud->current_pool_ptr + aud->current_size; dstbuf = aud->current_pool_ptr + aud->current_size;
memcpy(dstbuf, buf, size); memcpy(dstbuf, buf, size);
armDCacheFlush(dstbuf, size); armDCacheFlush(dstbuf, size);
@ -231,7 +230,8 @@ static size_t libnx_audren_audio_append(libnx_audren_t* aud, const void *buf, si
return size; return size;
} }
static ssize_t libnx_audren_audio_write(void *data, const void *buf, size_t size) static ssize_t libnx_audren_audio_write(void *data,
const void *buf, size_t size)
{ {
libnx_audren_t *aud = (libnx_audren_t*)data; libnx_audren_t *aud = (libnx_audren_t*)data;
size_t written = 0; size_t written = 0;
@ -239,16 +239,23 @@ static ssize_t libnx_audren_audio_write(void *data, const void *buf, size_t size
if (!aud) if (!aud)
return -1; return -1;
if (aud->nonblock)
{
while(written < size) while(written < size)
{ {
written += libnx_audren_audio_append(aud, buf + written, size - written); written += libnx_audren_audio_append(
aud, buf + written, size - written);
if (written != size) if (written != size)
{
if(aud->nonblocking)
{
break; break;
} }
}
else else
{
while(written < size)
{
written += libnx_audren_audio_append(
aud, buf + written, size - written);
if (written != size)
{ {
mutexLock(&aud->update_lock); mutexLock(&aud->update_lock);
audrvUpdate(&aud->drv); audrvUpdate(&aud->drv);
@ -341,7 +348,7 @@ static void libnx_audren_audio_set_nonblock_state(void *data, bool state)
if (!aud) if (!aud)
return; return;
aud->nonblocking = state; aud->nonblock = state;
} }
audio_driver_t audio_switch_libnx_audren = { audio_driver_t audio_switch_libnx_audren = {

View File

@ -43,13 +43,14 @@ static const AudioRendererConfig audio_renderer_config =
.num_mix_buffers = 2, .num_mix_buffers = 2,
}; };
typedef struct { typedef struct
{
AudioDriver drv; AudioDriver drv;
void* mempool; void* mempool;
AudioDriverWaveBuf wavebufs[BUFFER_COUNT]; AudioDriverWaveBuf wavebufs[BUFFER_COUNT];
size_t buffer_size; size_t buffer_size;
size_t samples; size_t samples;
bool nonblocking; bool nonblock;
fifo_buffer_t* fifo; fifo_buffer_t* fifo;
Mutex fifo_lock; Mutex fifo_lock;
@ -63,6 +64,7 @@ typedef struct {
static void thread_job(void* data) static void thread_job(void* data)
{ {
unsigned i;
libnx_audren_thread_t *aud = (libnx_audren_thread_t*)data; libnx_audren_thread_t *aud = (libnx_audren_thread_t*)data;
size_t available = 0; size_t available = 0;
size_t current_size = 0; size_t current_size = 0;
@ -70,7 +72,6 @@ static void thread_job(void* data)
AudioDriverWaveBuf* current_wavebuf = NULL; AudioDriverWaveBuf* current_wavebuf = NULL;
void* current_pool_ptr = NULL; void* current_pool_ptr = NULL;
void* dstbuf = NULL; void* dstbuf = NULL;
unsigned i;
if (!aud) if (!aud)
return; return;
@ -99,9 +100,7 @@ static void thread_job(void* data)
written_tmp = MIN(available, aud->buffer_size - current_size); written_tmp = MIN(available, aud->buffer_size - current_size);
dstbuf = current_pool_ptr + current_size; dstbuf = current_pool_ptr + current_size;
if (written_tmp > 0) if (written_tmp > 0)
{
fifo_read(aud->fifo, dstbuf, written_tmp); fifo_read(aud->fifo, dstbuf, written_tmp);
}
mutexUnlock(&aud->fifo_lock); mutexUnlock(&aud->fifo_lock);
if (written_tmp > 0) if (written_tmp > 0)
@ -162,12 +161,14 @@ static void *libnx_audren_thread_audio_init(const char *device, unsigned rate, u
aud->running = true; aud->running = true;
aud->paused = false; aud->paused = false;
aud->nonblocking = !block_frames; aud->nonblock = !block_frames;
aud->buffer_size = (real_latency * sample_rate / 1000); aud->buffer_size = (real_latency * sample_rate / 1000);
aud->samples = (aud->buffer_size / num_channels / sizeof(int16_t)); aud->samples = (aud->buffer_size / num_channels / sizeof(int16_t));
mempool_size = (aud->buffer_size * BUFFER_COUNT + (AUDREN_MEMPOOL_ALIGNMENT-1)) &~ (AUDREN_MEMPOOL_ALIGNMENT-1); mempool_size = (aud->buffer_size * BUFFER_COUNT +
(AUDREN_MEMPOOL_ALIGNMENT-1)) &~ (AUDREN_MEMPOOL_ALIGNMENT-1);
aud->mempool = memalign(AUDREN_MEMPOOL_ALIGNMENT, mempool_size); aud->mempool = memalign(AUDREN_MEMPOOL_ALIGNMENT, mempool_size);
if (!aud->mempool) if (!aud->mempool)
{ {
RARCH_ERR("[Audio]: mempool alloc failed\n"); RARCH_ERR("[Audio]: mempool alloc failed\n");
@ -199,7 +200,8 @@ static void *libnx_audren_thread_audio_init(const char *device, unsigned rate, u
mpid = audrvMemPoolAdd(&aud->drv, aud->mempool, mempool_size); mpid = audrvMemPoolAdd(&aud->drv, aud->mempool, mempool_size);
audrvMemPoolAttach(&aud->drv, mpid); audrvMemPoolAttach(&aud->drv, mpid);
audrvDeviceSinkAdd(&aud->drv, AUDREN_DEFAULT_DEVICE_NAME, num_channels, sink_channels); audrvDeviceSinkAdd(&aud->drv, AUDREN_DEFAULT_DEVICE_NAME,
num_channels, sink_channels);
rc = audrenStartAudioRenderer(); rc = audrenStartAudioRenderer();
if (R_FAILED(rc)) if (R_FAILED(rc))
@ -229,7 +231,9 @@ static void *libnx_audren_thread_audio_init(const char *device, unsigned rate, u
mutexInit(&aud->fifo_condlock); mutexInit(&aud->fifo_condlock);
svcGetThreadPriority(&thread_priority, CUR_THREAD_HANDLE); svcGetThreadPriority(&thread_priority, CUR_THREAD_HANDLE);
rc = threadCreate(&aud->thread, &thread_job, (void*)aud, thread_stack_size, thread_priority - 1, thread_preferred_cpu); rc = threadCreate(&aud->thread, &thread_job,
(void*)aud, thread_stack_size,
thread_priority - 1, thread_preferred_cpu);
if (R_FAILED(rc)) if (R_FAILED(rc))
{ {
RARCH_ERR("[Audio]: threadCreate: %x\n", rc); RARCH_ERR("[Audio]: threadCreate: %x\n", rc);
@ -258,9 +262,7 @@ fail:
if (aud) if (aud)
{ {
if (aud->mempool) if (aud->mempool)
{
free(aud->mempool); free(aud->mempool);
}
free(aud); free(aud);
} }
@ -278,7 +280,8 @@ static size_t libnx_audren_thread_audio_buffer_size(void *data)
return aud->buffer_size; return aud->buffer_size;
} }
static ssize_t libnx_audren_thread_audio_write(void *data, const void *buf, size_t size) static ssize_t libnx_audren_thread_audio_write(void *data,
const void *buf, size_t size)
{ {
libnx_audren_thread_t *aud = (libnx_audren_thread_t*)data; libnx_audren_thread_t *aud = (libnx_audren_thread_t*)data;
size_t available, written, written_tmp; size_t available, written, written_tmp;
@ -289,15 +292,13 @@ static ssize_t libnx_audren_thread_audio_write(void *data, const void *buf, size
if (aud->paused) if (aud->paused)
return 0; return 0;
if(aud->nonblocking) if (aud->nonblock)
{ {
mutexLock(&aud->fifo_lock); mutexLock(&aud->fifo_lock);
available = fifo_write_avail(aud->fifo); available = fifo_write_avail(aud->fifo);
written = MIN(available, size); written = MIN(available, size);
if (written > 0) if (written > 0)
{
fifo_write(aud->fifo, buf, written); fifo_write(aud->fifo, buf, written);
}
mutexUnlock(&aud->fifo_lock); mutexUnlock(&aud->fifo_lock);
} }
else else
@ -419,7 +420,7 @@ static void libnx_audren_thread_audio_set_nonblock_state(void *data, bool state)
if (!aud) if (!aud)
return; return;
aud->nonblocking = state; aud->nonblock = state;
} }
audio_driver_t audio_switch_libnx_audren_thread = { audio_driver_t audio_switch_libnx_audren_thread = {

View File

@ -53,7 +53,7 @@ typedef struct
size_t fifoSize; size_t fifoSize;
volatile bool running; volatile bool running;
bool nonblocking; bool nonblock;
bool is_paused; bool is_paused;
compat_audio_out_buffer buffers[AUDIO_BUFFER_COUNT]; compat_audio_out_buffer buffers[AUDIO_BUFFER_COUNT];
@ -152,7 +152,7 @@ static void *switch_thread_audio_init(const char *device, unsigned rate, unsigne
return NULL; return NULL;
swa->running = true; swa->running = true;
swa->nonblocking = true; swa->nonblock = true;
swa->is_paused = true; swa->is_paused = true;
swa->latency = MAX(latency, 8); swa->latency = MAX(latency, 8);
@ -217,7 +217,7 @@ static void *switch_thread_audio_init(const char *device, unsigned rate, unsigne
swa->buffers[i].data_size = swa->buffers[i].buffer_size; swa->buffers[i].data_size = swa->buffers[i].buffer_size;
swa->buffers[i].buffer = memalign(0x1000, swa->buffers[i].buffer_size); swa->buffers[i].buffer = memalign(0x1000, swa->buffers[i].buffer_size);
if (swa->buffers[i].buffer == NULL) if (!swa->buffers[i].buffer)
goto fail; goto fail;
memset(swa->buffers[i].buffer, 0, swa->buffers[i].buffer_size); memset(swa->buffers[i].buffer, 0, swa->buffers[i].buffer_size);
@ -228,7 +228,7 @@ static void *switch_thread_audio_init(const char *device, unsigned rate, unsigne
swa->buffers[i].data_size = swa->buffers[i].buffer_size; swa->buffers[i].data_size = swa->buffers[i].buffer_size;
swa->buffers[i].sample_data = alloc_pages(swa->buffers[i].buffer_size, swa->buffers[i].buffer_size, NULL); swa->buffers[i].sample_data = alloc_pages(swa->buffers[i].buffer_size, swa->buffers[i].buffer_size, NULL);
if (swa->buffers[i].sample_data == NULL) if (!swa->buffers[i].sample_data)
goto fail_audio_output; goto fail_audio_output;
memset(swa->buffers[i].sample_data, 0, swa->buffers[i].buffer_size); memset(swa->buffers[i].sample_data, 0, swa->buffers[i].buffer_size);
@ -345,7 +345,7 @@ static ssize_t switch_thread_audio_write(void *data, const void *buf, size_t siz
if (!swa || !swa->running) if (!swa || !swa->running)
return 0; return 0;
if (swa->nonblocking) if (swa->nonblock)
{ {
compat_mutex_lock(&swa->fifoLock); compat_mutex_lock(&swa->fifoLock);
avail = fifo_write_avail(swa->fifo); avail = fifo_write_avail(swa->fifo);
@ -397,7 +397,7 @@ static void switch_thread_audio_set_nonblock_state(void *data, bool state)
switch_thread_audio_t *swa = (switch_thread_audio_t *)data; switch_thread_audio_t *swa = (switch_thread_audio_t *)data;
if (swa) if (swa)
swa->nonblocking = state; swa->nonblock = state;
} }
static bool switch_thread_audio_use_float(void *data) static bool switch_thread_audio_use_float(void *data)

View File

@ -31,7 +31,7 @@ typedef struct
AXMVoice* mvoice; AXMVoice* mvoice;
uint16_t* buffer_l; uint16_t* buffer_l;
uint16_t* buffer_r; uint16_t* buffer_r;
bool nonblocking; bool nonblock;
uint32_t pos; uint32_t pos;
uint32_t written; uint32_t written;
@ -56,11 +56,13 @@ typedef struct
static volatile ax_audio_t *wiiu_cb_ax = NULL; static volatile ax_audio_t *wiiu_cb_ax = NULL;
void wiiu_ax_callback(void) void wiiu_ax_callback(void)
{ {
ax_audio_t *ax = NULL;
/*possibly called before unregister */ /*possibly called before unregister */
if(wiiu_cb_ax == NULL) if (!wiiu_cb_ax)
return; return;
ax_audio_t *ax = (ax_audio_t*)wiiu_cb_ax; ax = (ax_audio_t*)wiiu_cb_ax;
if (AXIsMultiVoiceRunning(ax->mvoice)) if (AXIsMultiVoiceRunning(ax->mvoice))
{ {
if (OSUninterruptibleSpinLock_Acquire(&ax->spinlock)) if (OSUninterruptibleSpinLock_Acquire(&ax->spinlock))
@ -188,13 +190,14 @@ static bool ax_audio_start(void* data, bool is_shutdown)
AXSetMultiVoiceCurrentOffset(ax->mvoice, ax_audio_limit(ax->pos - ax->written)); AXSetMultiVoiceCurrentOffset(ax->mvoice, ax_audio_limit(ax->pos - ax->written));
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_PLAYING); AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_PLAYING);
} }
return true; return true;
} }
static ssize_t ax_audio_write(void* data, const void* buf, size_t size) static ssize_t ax_audio_write(void* data, const void* buf, size_t size)
{ {
uint32_t i; uint32_t i;
size_t countAvail = 0; size_t count_avail = 0;
ax_audio_t* ax = (ax_audio_t*)data; ax_audio_t* ax = (ax_audio_t*)data;
const uint16_t* src = buf; const uint16_t* src = buf;
size_t count = size >> 2; size_t count = size >> 2;
@ -205,35 +208,35 @@ static ssize_t ax_audio_write(void* data, const void* buf, size_t size)
if (count > AX_AUDIO_MAX_FREE) if (count > AX_AUDIO_MAX_FREE)
count = AX_AUDIO_MAX_FREE; count = AX_AUDIO_MAX_FREE;
countAvail = ((ax->written > AX_AUDIO_MAX_FREE) ? 0 : (AX_AUDIO_MAX_FREE - ax->written)); count_avail = ((ax->written > AX_AUDIO_MAX_FREE) ? 0 : (AX_AUDIO_MAX_FREE - ax->written));
if (ax->nonblocking) if (ax->nonblock)
{ {
/* Not enough available for 3ms of data */ /* Not enough available for 3ms of data */
if(countAvail < AX_AUDIO_SAMPLE_COUNT) if (count_avail < AX_AUDIO_SAMPLE_COUNT)
count = 0; count = 0;
} }
else if(countAvail < count) else if (count_avail < count)
{ {
/* Sync, wait for free memory */ /* Sync, wait for free memory */
while(AXIsMultiVoiceRunning(ax->mvoice) && (countAvail < count)) while(AXIsMultiVoiceRunning(ax->mvoice) && (count_avail < count))
{ {
OSYieldThread(); /* Gives threads with same priority time to run */ OSYieldThread(); /* Gives threads with same priority time to run */
countAvail = (ax->written > AX_AUDIO_MAX_FREE ? 0 : (AX_AUDIO_MAX_FREE - ax->written)); count_avail = (ax->written > AX_AUDIO_MAX_FREE ? 0 : (AX_AUDIO_MAX_FREE - ax->written));
} }
} }
/* Over available space, do as much as possible */ /* Over available space, do as much as possible */
if(count > countAvail) if (count > count_avail)
count = countAvail; count = count_avail;
/* make sure we have input size */ /* make sure we have input size */
if (count > 0) if (count > 0)
{ {
/* write in new data */ /* write in new data */
size_t startPos = ax->pos; size_t start_pos = ax->pos;
int flushP2needed = 0; int flush_p2_needed = 0;
int flushP2 = 0; int flush_p2 = 0;
for (i = 0; i < (count << 1); i += 2) for (i = 0; i < (count << 1); i += 2)
{ {
@ -244,24 +247,25 @@ static ssize_t ax_audio_write(void* data, const void* buf, size_t size)
/* wrapped around, make sure to store cache */ /* wrapped around, make sure to store cache */
if (ax->pos == 0) if (ax->pos == 0)
{ {
flushP2needed = 1; flush_p2_needed = 1;
flushP2 = ((count << 1) - i); flush_p2 = ((count << 1) - i);
DCStoreRangeNoSync(ax->buffer_l+startPos, (AX_AUDIO_COUNT-startPos) << 1); DCStoreRangeNoSync(ax->buffer_l + start_pos,
DCStoreRangeNoSync(ax->buffer_r+startPos, (AX_AUDIO_COUNT-startPos) << 1); (AX_AUDIO_COUNT - start_pos) << 1);
DCStoreRangeNoSync(ax->buffer_r + start_pos, (AX_AUDIO_COUNT - start_pos) << 1);
} }
} }
/* standard cache store case */ /* standard cache store case */
if(!flushP2needed) if (!flush_p2_needed)
{ {
DCStoreRangeNoSync(ax->buffer_l+startPos, count << 1); DCStoreRangeNoSync(ax->buffer_l + start_pos, count << 1);
DCStoreRange(ax->buffer_r+startPos, count << 1); DCStoreRange(ax->buffer_r + start_pos, count << 1);
} }
/* store the rest after wrap */ /* store the rest after wrap */
else if(flushP2 > 0) else if (flush_p2 > 0)
{ {
DCStoreRangeNoSync(ax->buffer_l, flushP2); DCStoreRangeNoSync(ax->buffer_l, flush_p2);
DCStoreRange(ax->buffer_r, flushP2); DCStoreRange(ax->buffer_r, flush_p2);
} }
/* add in new audio data */ /* add in new audio data */
@ -294,7 +298,7 @@ static void ax_audio_set_nonblock_state(void* data, bool state)
ax_audio_t* ax = (ax_audio_t*)data; ax_audio_t* ax = (ax_audio_t*)data;
if (ax) if (ax)
ax->nonblocking = state; ax->nonblock = state;
} }
static bool ax_audio_use_float(void* data) static bool ax_audio_use_float(void* data)