mirror of
https://github.com/libretro/RetroArch
synced 2025-02-07 12:39:54 +00:00
Merge pull request #4039 from FIX94/master
(WiiU) continuation of the audio driver changes from yesterday
This commit is contained in:
commit
a79215499e
@ -29,6 +29,7 @@
|
||||
|
||||
#include "wiiu/wiiu_dbg.h"
|
||||
#include "wiiu/system/memory.h"
|
||||
#include "wiiu/multivoice.h"
|
||||
|
||||
#include "audio/audio_driver.h"
|
||||
#include "configuration.h"
|
||||
@ -37,8 +38,7 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AXVoice* voice_l;
|
||||
AXVoice* voice_r;
|
||||
AXMVoice* mvoice;
|
||||
uint16_t* buffer_l;
|
||||
uint16_t* buffer_r;
|
||||
bool nonblocking;
|
||||
@ -72,12 +72,11 @@ AXResult ax_aux_callback(void* data, ax_audio_t* ax)
|
||||
OSUninterruptibleSpinLock_Acquire(&ax->spinlock);
|
||||
//buffer underrun, stop playback to let if fill up
|
||||
if(ax->written < AX_AUDIO_SAMPLE_MIN)
|
||||
{
|
||||
AXSetVoiceState(ax->voice_l, AX_VOICE_STATE_STOPPED);
|
||||
AXSetVoiceState(ax->voice_r, AX_VOICE_STATE_STOPPED);
|
||||
}
|
||||
else //all good, play back frame
|
||||
ax->written -= AX_AUDIO_SAMPLE_COUNT;
|
||||
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_STOPPED);
|
||||
//make sure to update written value if voice is running
|
||||
if(AXIsMultiVoiceRunning(ax->mvoice))
|
||||
ax->written -= (ax->written < AX_AUDIO_SAMPLE_COUNT ? ax->written : AX_AUDIO_SAMPLE_COUNT);
|
||||
|
||||
OSUninterruptibleSpinLock_Release(&ax->spinlock);
|
||||
return AX_RESULT_SUCCESS;
|
||||
}
|
||||
@ -93,10 +92,11 @@ static void* ax_audio_init(const char* device, unsigned rate, unsigned latency)
|
||||
|
||||
AXInitWithParams(&init);
|
||||
|
||||
ax->voice_l = AXAcquireVoice(10, NULL, ax);
|
||||
ax->voice_r = AXAcquireVoice(10, NULL, ax);
|
||||
u16 setup_buf[0x30] = {0};
|
||||
setup_buf[0x25] = 2; //we request 2 channels
|
||||
AXAcquireMultiVoice(31, NULL, 0, setup_buf, &ax->mvoice);
|
||||
|
||||
if (!ax->voice_l || !ax->voice_r)
|
||||
if (!ax->mvoice || ax->mvoice->channels != 2)
|
||||
{
|
||||
free(ax);
|
||||
return NULL;
|
||||
@ -109,37 +109,37 @@ static void* ax_audio_init(const char* device, unsigned rate, unsigned latency)
|
||||
DCFlushRange(ax->buffer_l,AX_AUDIO_SIZE);
|
||||
DCFlushRange(ax->buffer_r,AX_AUDIO_SIZE);
|
||||
|
||||
//shared by both voices
|
||||
AXVoiceOffsets offsets;
|
||||
|
||||
offsets.data = ax->buffer_l;
|
||||
offsets.currentOffset = 0;
|
||||
offsets.loopOffset = 0;
|
||||
offsets.endOffset = AX_AUDIO_COUNT - 1;
|
||||
offsets.loopingEnabled = AX_VOICE_LOOP_ENABLED;
|
||||
offsets.dataType = AX_VOICE_FORMAT_LPCM16;
|
||||
AXSetVoiceOffsets(ax->voice_l, &offsets);
|
||||
|
||||
offsets.data = ax->buffer_l;
|
||||
AXSetVoiceOffsets(ax->mvoice->v[0], &offsets);
|
||||
|
||||
offsets.data = ax->buffer_r;
|
||||
AXSetVoiceOffsets(ax->voice_r, &offsets);
|
||||
AXSetVoiceOffsets(ax->mvoice->v[1], &offsets);
|
||||
|
||||
AXSetMultiVoiceSrcType(ax->mvoice, AX_VOICE_SRC_TYPE_NONE);
|
||||
AXSetMultiVoiceSrcRatio(ax->mvoice, 1.0f);
|
||||
|
||||
AXVoiceVeData ve = {0xF000, 0};
|
||||
AXSetMultiVoiceVe(ax->mvoice, &ve);
|
||||
|
||||
AXSetVoiceSrcType(ax->voice_l, AX_VOICE_SRC_TYPE_NONE);
|
||||
AXSetVoiceSrcType(ax->voice_r, AX_VOICE_SRC_TYPE_NONE);
|
||||
AXSetVoiceSrcRatio(ax->voice_l, 1.0f);
|
||||
AXSetVoiceSrcRatio(ax->voice_r, 1.0f);
|
||||
AXVoiceVeData ve = {0xFFFF, 0};
|
||||
AXSetVoiceVe(ax->voice_l, &ve);
|
||||
AXSetVoiceVe(ax->voice_r, &ve);
|
||||
u32 mix[24] = {0};
|
||||
mix[0] = 0x80000000;
|
||||
AXSetVoiceDeviceMix(ax->voice_l, AX_DEVICE_TYPE_DRC, 0, (AXVoiceDeviceMixData*)mix);
|
||||
AXSetVoiceDeviceMix(ax->voice_l, AX_DEVICE_TYPE_TV, 0, (AXVoiceDeviceMixData*)mix);
|
||||
AXSetVoiceDeviceMix(ax->mvoice->v[0], AX_DEVICE_TYPE_DRC, 0, (AXVoiceDeviceMixData*)mix);
|
||||
AXSetVoiceDeviceMix(ax->mvoice->v[0], AX_DEVICE_TYPE_TV, 0, (AXVoiceDeviceMixData*)mix);
|
||||
|
||||
mix[0] = 0;
|
||||
mix[4] = 0x80000000;
|
||||
AXSetVoiceDeviceMix(ax->voice_r, AX_DEVICE_TYPE_DRC, 0, (AXVoiceDeviceMixData*)mix);
|
||||
AXSetVoiceDeviceMix(ax->voice_r, AX_DEVICE_TYPE_TV, 0, (AXVoiceDeviceMixData*)mix);
|
||||
AXSetVoiceDeviceMix(ax->mvoice->v[1], AX_DEVICE_TYPE_DRC, 0, (AXVoiceDeviceMixData*)mix);
|
||||
AXSetVoiceDeviceMix(ax->mvoice->v[1], AX_DEVICE_TYPE_TV, 0, (AXVoiceDeviceMixData*)mix);
|
||||
|
||||
AXSetVoiceState(ax->voice_l, AX_VOICE_STATE_STOPPED);
|
||||
AXSetVoiceState(ax->voice_r, AX_VOICE_STATE_STOPPED);
|
||||
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_STOPPED);
|
||||
|
||||
ax->pos = 0;
|
||||
ax->written = 0;
|
||||
@ -158,7 +158,7 @@ static void ax_audio_free(void* data)
|
||||
ax_audio_t* ax = (ax_audio_t*)data;
|
||||
|
||||
AXRegisterAuxCallback(AX_DEVICE_TYPE_DRC, 0, 0, NULL, NULL);
|
||||
|
||||
AXFreeMultiVoice(ax->mvoice);
|
||||
MEM1_free(ax->buffer_l);
|
||||
MEM1_free(ax->buffer_r);
|
||||
free(ax);
|
||||
@ -213,6 +213,8 @@ static ssize_t ax_audio_write(void* data, const void* buf, size_t size)
|
||||
count = 0;
|
||||
goto wiiu_audio_end;
|
||||
}
|
||||
if(count > AX_AUDIO_COUNT)
|
||||
count = AX_AUDIO_COUNT;
|
||||
|
||||
size_t countAvail = AX_AUDIO_COUNT - ax->written;
|
||||
if (ax->nonblocking)
|
||||
@ -230,8 +232,8 @@ static ssize_t ax_audio_write(void* data, const void* buf, size_t size)
|
||||
//sync, wait for free memory
|
||||
do {
|
||||
OSYieldThread();
|
||||
countAvail = AX_AUDIO_COUNT - ax->written;
|
||||
} while(AXIsVoiceRunning(ax->voice_l) && countAvail < count);
|
||||
countAvail = AX_AUDIO_COUNT - ax->written;
|
||||
} while(AXIsMultiVoiceRunning(ax->mvoice) && countAvail < count);
|
||||
}
|
||||
|
||||
// ax_audio_buffer_write(ax, buf, count);
|
||||
@ -271,7 +273,7 @@ static ssize_t ax_audio_write(void* data, const void* buf, size_t size)
|
||||
OSUninterruptibleSpinLock_Release(&ax->spinlock);
|
||||
|
||||
//possibly buffer underrun
|
||||
if(!AXIsVoiceRunning(ax->voice_l))
|
||||
if(!AXIsMultiVoiceRunning(ax->mvoice))
|
||||
{
|
||||
//checks if it can be started
|
||||
ax_audio_start(ax);
|
||||
@ -287,15 +289,14 @@ static bool ax_audio_stop(void* data)
|
||||
{
|
||||
ax_audio_t* ax = (ax_audio_t*)data;
|
||||
|
||||
AXSetVoiceState(ax->voice_l, AX_VOICE_STATE_STOPPED);
|
||||
AXSetVoiceState(ax->voice_r, AX_VOICE_STATE_STOPPED);
|
||||
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_STOPPED);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ax_audio_alive(void* data)
|
||||
{
|
||||
ax_audio_t* ax = (ax_audio_t*)data;
|
||||
return AXIsVoiceRunning(ax->voice_l);
|
||||
return AXIsMultiVoiceRunning(ax->mvoice);
|
||||
}
|
||||
|
||||
static bool ax_audio_start(void* data)
|
||||
@ -308,25 +309,9 @@ static bool ax_audio_start(void* data)
|
||||
if (runloop_ctl(RUNLOOP_CTL_IS_SHUTDOWN, NULL))
|
||||
return true;
|
||||
|
||||
//for safety first
|
||||
ax_audio_stop(data);
|
||||
|
||||
//reset offset to last load offset
|
||||
AXVoiceOffsets offsets;
|
||||
uint32_t lastOffset = ((ax->pos - ((ax->written)<<1)) & AX_AUDIO_COUNT_MASK);
|
||||
AXGetVoiceOffsets(ax->voice_l, &offsets);
|
||||
offsets.currentOffset = lastOffset;
|
||||
AXSetVoiceOffsets(ax->voice_l, &offsets);
|
||||
AXGetVoiceOffsets(ax->voice_r, &offsets);
|
||||
offsets.currentOffset = lastOffset;
|
||||
AXSetVoiceOffsets(ax->voice_r, &offsets);
|
||||
|
||||
//set back to playing on enough buffered data
|
||||
if(ax->written > AX_AUDIO_SAMPLE_MIN)
|
||||
{
|
||||
AXSetVoiceState(ax->voice_l, AX_VOICE_STATE_PLAYING);
|
||||
AXSetVoiceState(ax->voice_r, AX_VOICE_STATE_PLAYING);
|
||||
}
|
||||
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_PLAYING);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -337,8 +322,6 @@ static void ax_audio_set_nonblock_state(void* data, bool state)
|
||||
|
||||
if (ax)
|
||||
{
|
||||
if(state != ax->nonblocking)
|
||||
ax_audio_start(data);
|
||||
ax->nonblocking = state;
|
||||
}
|
||||
}
|
||||
|
20
wiiu/multivoice.h
Normal file
20
wiiu/multivoice.h
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
#ifndef _MULTIVOICE_H_
|
||||
#define _MULTIVOICE_H_
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool running;
|
||||
uint32_t channels;
|
||||
AXVoice *v[];
|
||||
} AXMVoice;
|
||||
|
||||
void AXAcquireMultiVoice(uint32_t prio, void *cb, uint32_t cbarg, void *setup, AXMVoice **mvoice);
|
||||
void AXSetMultiVoiceState(AXMVoice *mvoice, AXVoiceState state);
|
||||
void AXSetMultiVoiceVe(AXMVoice *mvoice, AXVoiceVeData *veData);
|
||||
void AXSetMultiVoiceSrcType(AXMVoice *mvoice, AXVoiceSrcType type);
|
||||
void AXSetMultiVoiceSrcRatio(AXMVoice *mvoice, float ratio);
|
||||
bool AXIsMultiVoiceRunning(AXMVoice *mvoice);
|
||||
void AXFreeMultiVoice(AXMVoice *mvoice);
|
||||
|
||||
#endif
|
@ -2,5 +2,12 @@
|
||||
EXPORT_BEGIN(sndcore2.rpl);
|
||||
|
||||
#include "../rpl/libsndcore2/exports.h"
|
||||
EXPORT(AXAcquireMultiVoice);
|
||||
EXPORT(AXSetMultiVoiceState);
|
||||
EXPORT(AXSetMultiVoiceVe);
|
||||
EXPORT(AXSetMultiVoiceSrcType);
|
||||
EXPORT(AXSetMultiVoiceSrcRatio);
|
||||
EXPORT(AXIsMultiVoiceRunning);
|
||||
EXPORT(AXFreeMultiVoice);
|
||||
|
||||
EXPORT_END();
|
||||
|
Loading…
x
Reference in New Issue
Block a user