Some fixes and tidyup

This commit is contained in:
UnknownShadow200 2025-06-10 21:51:48 +10:00
parent dbec9e8c76
commit 0b3a20be2d
14 changed files with 83 additions and 181 deletions

View File

@ -14,6 +14,9 @@ struct AudioContext {
#include "_AudioBase.h"
static int channelIDs;
#define MAX_AUDIO_VOICES 24
#define AudioBuf_InUse(buf) ((buf)->status == NDSP_WBUF_QUEUED || (buf)->status == NDSP_WBUF_PLAYING)
// See https://github.com/devkitPro/3ds-examples/blob/master/audio/README.md
// To get audio to work in Citra, just create a 0 byte file in sdmc/3ds named dspfirm.cdca
@ -39,7 +42,7 @@ void AudioBackend_Free(void) { }
cc_result Audio_Init(struct AudioContext* ctx, int buffers) {
int chanID = -1;
for (int i = 0; i < 24; i++)
for (int i = 0; i < MAX_AUDIO_VOICES; i++)
{
// channel in use
if (channelIDs & (1 << i)) continue;
@ -96,7 +99,7 @@ cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk) {
for (int i = 0; i < ctx->count; i++)
{
buf = &ctx->bufs[i];
if (buf->status == NDSP_WBUF_QUEUED || buf->status == NDSP_WBUF_PLAYING)
if (AudioBuf_InUse(buf))
continue;
buf->data_pcm16 = chunk->data;
@ -109,8 +112,6 @@ cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk) {
return ERR_INVALID_ARGUMENT;
}
cc_result Audio_Play(struct AudioContext* ctx) { return 0; }
cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
ndspWaveBuf* buf;
int count = 0;
@ -118,7 +119,7 @@ cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
for (int i = 0; i < ctx->count; i++)
{
buf = &ctx->bufs[i];
if (buf->status == NDSP_WBUF_QUEUED || buf->status == NDSP_WBUF_PLAYING) {
if (AudioBuf_InUse(buf)) {
count++; continue;
}
}
@ -140,35 +141,11 @@ cc_result StreamContext_Enqueue(struct AudioContext* ctx, struct AudioChunk* chu
}
cc_result StreamContext_Play(struct AudioContext* ctx) {
return Audio_Play(ctx);
return 0;
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {
return Audio_Poll(ctx, inUse);
}
/*########################################################################################################################*
*------------------------------------------------------Stream context-----------------------------------------------------*
*#########################################################################################################################*/
cc_result StreamContext_SetFormat(struct AudioContext* ctx, int channels, int sampleRate, int playbackRate) {
return Audio_SetFormat(ctx, channels, sampleRate, playbackRate);
}
cc_result StreamContext_Enqueue(struct AudioContext* ctx, struct AudioChunk* chunk) {
return Audio_QueueChunk(ctx, chunk);
}
cc_result StreamContext_Play(struct AudioContext* ctx) {
return Audio_Play(ctx);
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {
@ -188,17 +165,14 @@ cc_result SoundContext_PlayData(struct AudioContext* ctx, struct AudioData* data
if ((res = Audio_SetFormat(ctx, data->channels, data->sampleRate, data->rate))) return res;
if ((res = Audio_QueueChunk(ctx, &data->chunk))) return res;
if ((res = Audio_Play(ctx))) return res;
return 0;
}
cc_result SoundContext_PollBusy(struct AudioContext* ctx, cc_bool* isBusy) {
int inUse = 1;
cc_result res;
if ((res = Audio_Poll(ctx, &inUse))) return res;
ndspWaveBuf* buf = &ctx->bufs[0];
*isBusy = inUse > 0;
*isBusy = AudioBuf_InUse(buf);
return 0;
}

View File

@ -151,7 +151,7 @@ cc_result StreamContext_Play(struct AudioContext* ctx) {
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {

View File

@ -158,7 +158,7 @@ cc_result StreamContext_Play(struct AudioContext* ctx) {
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {

View File

@ -17,50 +17,30 @@ cc_result Audio_Init(struct AudioContext* ctx, int buffers) {
void Audio_Close(struct AudioContext* ctx) { }
cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sampleRate, int playbackRate) {
return ERR_NOT_SUPPORTED;
}
void Audio_SetVolume(struct AudioContext* ctx, int volume) { }
cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk) {
return ERR_NOT_SUPPORTED;
}
cc_result Audio_Play(struct AudioContext* ctx) {
return ERR_NOT_SUPPORTED;
}
cc_result Audio_Pause(struct AudioContext* ctx) {
return ERR_NOT_SUPPORTED;
}
cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
return ERR_NOT_SUPPORTED;
}
/*########################################################################################################################*
*------------------------------------------------------Stream context-----------------------------------------------------*
*#########################################################################################################################*/
cc_result StreamContext_SetFormat(struct AudioContext* ctx, int channels, int sampleRate, int playbackRate) {
return Audio_SetFormat(ctx, channels, sampleRate, playbackRate);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Enqueue(struct AudioContext* ctx, struct AudioChunk* chunk) {
return Audio_QueueChunk(ctx, chunk);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Play(struct AudioContext* ctx) {
return Audio_Play(ctx);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {
return Audio_Poll(ctx, inUse);
return ERR_NOT_SUPPORTED;
}

View File

@ -189,7 +189,7 @@ cc_result StreamContext_Play(struct AudioContext* ctx) {
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {

View File

@ -66,6 +66,7 @@ struct AudioContext {
#define AUDIO_COMMON_ALLOC
#include "_AudioBase.h"
#include "Funcs.h"
static void* audio_device;
static void* audio_context;
@ -223,18 +224,6 @@ cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk) {
return 0;
}
cc_result Audio_Play(struct AudioContext* ctx) {
_alSourcePlay(ctx->source);
return _alGetError();
}
cc_result Audio_Pause(struct AudioContext* ctx) {
if (!_alSourcePause) return ERR_NOT_SUPPORTED;
_alSourcePause(ctx->source);
return _alGetError();
}
cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
ALint processed = 0;
ALuint buffer;
@ -269,11 +258,15 @@ cc_result StreamContext_Enqueue(struct AudioContext* ctx, struct AudioChunk* chu
}
cc_result StreamContext_Play(struct AudioContext* ctx) {
return Audio_Play(ctx);
_alSourcePlay(ctx->source);
return _alGetError();
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
if (!_alSourcePause) return ERR_NOT_SUPPORTED;
_alSourcePause(ctx->source);
return _alGetError();
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {
@ -294,9 +287,9 @@ cc_result SoundContext_PlayData(struct AudioContext* ctx, struct AudioData* data
if ((res = Audio_SetFormat(ctx, data->channels, data->sampleRate, data->rate))) return res;
if ((res = Audio_QueueChunk(ctx, &data->chunk))) return res;
if ((res = Audio_Play(ctx))) return res;
_alSourcePlay(ctx->source);
return 0;
return _alGetError();
}
cc_result SoundContext_PollBusy(struct AudioContext* ctx, cc_bool* isBusy) {

View File

@ -4,6 +4,7 @@
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include "ExtMath.h"
#include "Funcs.h"
static SLObjectItf slEngineObject;
static SLEngineItf slEngineEngine;
@ -204,14 +205,6 @@ cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk) {
return (*ctx->playerQueue)->Enqueue(ctx->playerQueue, chunk->data, chunk->size);
}
cc_result Audio_Pause(struct AudioContext* ctx) {
return (*ctx->playerPlayer)->SetPlayState(ctx->playerPlayer, SL_PLAYSTATE_PAUSED);
}
cc_result Audio_Play(struct AudioContext* ctx) {
return (*ctx->playerPlayer)->SetPlayState(ctx->playerPlayer, SL_PLAYSTATE_PLAYING);
}
cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
SLBufferQueueState state = { 0 };
cc_result res = 0;
@ -236,11 +229,11 @@ cc_result StreamContext_Enqueue(struct AudioContext* ctx, struct AudioChunk* chu
}
cc_result StreamContext_Play(struct AudioContext* ctx) {
return Audio_Play(ctx);
return (*ctx->playerPlayer)->SetPlayState(ctx->playerPlayer, SL_PLAYSTATE_PLAYING);
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
return (*ctx->playerPlayer)->SetPlayState(ctx->playerPlayer, SL_PLAYSTATE_PAUSED);
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {
@ -257,13 +250,11 @@ cc_bool SoundContext_FastPlay(struct AudioContext* ctx, struct AudioData* data)
cc_result SoundContext_PlayData(struct AudioContext* ctx, struct AudioData* data) {
cc_result res;
Audio_SetVolume(ctx, data->volume);
if ((res = Audio_SetFormat(ctx, data->channels, data->sampleRate, data->rate))) return res;
if ((res = Audio_QueueChunk(ctx, &data->chunk))) return res;
if ((res = Audio_Play(ctx))) return res;
return 0;
return (*ctx->playerPlayer)->SetPlayState(ctx->playerPlayer, SL_PLAYSTATE_PLAYING);
}
cc_result SoundContext_PollBusy(struct AudioContext* ctx, cc_bool* isBusy) {

View File

@ -19,6 +19,10 @@ AudioDriver drv;
bool switchAudio = false;
void* audrv_mutex;
#define MAX_AUDIO_VOICES 24
#define AudioBuf_InUse(buf) ((buf)->state == AudioDriverWaveBufState_Queued || (buf)->state == AudioDriverWaveBufState_Playing || (buf)->state == AudioDriverWaveBufState_Waiting)
cc_bool AudioBackend_Init(void) {
if (switchAudio) return true;
switchAudio = true;
@ -28,7 +32,7 @@ cc_bool AudioBackend_Init(void) {
static const AudioRendererConfig arConfig =
{
.output_rate = AudioRendererOutputRate_48kHz,
.num_voices = 24,
.num_voices = MAX_AUDIO_VOICES,
.num_effects = 0,
.num_sinks = 1,
.num_mix_objs = 1,
@ -55,7 +59,8 @@ void AudioBackend_Tick(void) {
}
void AudioBackend_Free(void) {
for (int i = 0; i < 24; i++) {
for (int i = 0; i < MAX_AUDIO_VOICES; i++)
{
audrvVoiceStop(&drv, i);
}
audrvUpdate(&drv);
@ -64,7 +69,7 @@ void AudioBackend_Free(void) {
cc_result Audio_Init(struct AudioContext* ctx, int buffers) {
int chanID = -1;
for (int i = 0; i < 24; i++)
for (int i = 0; i < MAX_AUDIO_VOICES; i++)
{
// channel in use
if (channelIDs & (1 << i)) continue;
@ -130,10 +135,9 @@ cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk) {
for (int i = 0; i < ctx->count; i++)
{
buf = &ctx->bufs[i];
int state = buf->state;
cc_uint32 endOffset = chunk->size / (sizeof(cc_int16) * ((ctx->channels == 2) ? 2 : 1));
if (state == AudioDriverWaveBufState_Queued || state == AudioDriverWaveBufState_Playing || state == AudioDriverWaveBufState_Waiting)
if (AudioBuf_InUse(buf->state))
continue;
buf->data_pcm16 = chunk->data;
@ -152,11 +156,6 @@ cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk) {
return ERR_INVALID_ARGUMENT;
}
cc_result Audio_Play(struct AudioContext* ctx) {
audrvVoiceStart(&drv, ctx->chanID);
return 0;
}
cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
AudioDriverWaveBuf* buf;
int count = 0;
@ -164,7 +163,7 @@ cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
for (int i = 0; i < ctx->count; i++)
{
buf = &ctx->bufs[i];
if (buf->state == AudioDriverWaveBufState_Queued || buf->state == AudioDriverWaveBufState_Playing || buf->state == AudioDriverWaveBufState_Waiting) {
if (AudioBuf_InUse(buf)) {
count++; continue;
}
}
@ -186,11 +185,12 @@ cc_result StreamContext_Enqueue(struct AudioContext* ctx, struct AudioChunk* chu
}
cc_result StreamContext_Play(struct AudioContext* ctx) {
return Audio_Play(ctx);
audrvVoiceStart(&drv, ctx->chanID);
return 0;
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {
@ -210,17 +210,15 @@ cc_result SoundContext_PlayData(struct AudioContext* ctx, struct AudioData* data
if ((res = Audio_SetFormat(ctx, data->channels, data->sampleRate, data->rate))) return res;
if ((res = Audio_QueueChunk(ctx, &data->chunk))) return res;
if ((res = Audio_Play(ctx))) return res;
audrvVoiceStart(&drv, ctx->chanID);
return 0;
}
cc_result SoundContext_PollBusy(struct AudioContext* ctx, cc_bool* isBusy) {
int inUse = 1;
cc_result res;
if ((res = Audio_Poll(ctx, &inUse))) return res;
AudioDriverWaveBuf* buf = &ctx->bufs[0];
*isBusy = inUse > 0;
*isBusy = AudioBuf_InUse(buf);
return 0;
}

View File

@ -312,35 +312,6 @@ cc_result Audio_Play(struct AudioContext* ctx) {
return err;
}
cc_result Audio_Pause(struct AudioContext* ctx) {
ctx->stream->Stop();
return 0;
}
cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
struct AudioBuffer* buf;
int count = 0;
// FIXME: music thread check
if (ctx->count == AUDIO_MAX_BUFFERS) {
// Process background tasks in music thread
RThread thread;
TInt error = KErrNone;
while (thread.RequestCount()) {
CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle);
User::WaitForAnyRequest();
}
}
for (int i = 0; i < ctx->count; i++) {
buf = &ctx->bufs[i];
if (!buf->available) count++;
}
*inUse = count;
return 0;
}
cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sampleRate, int playbackRate) {
int sampleRateNew = Audio_AdjustSampleRate(sampleRate, playbackRate);
@ -374,11 +345,30 @@ cc_result StreamContext_Play(struct AudioContext* ctx) {
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
ctx->stream->Stop();
return 0;
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {
return Audio_Poll(ctx, inUse);
struct AudioBuffer* buf;
int i, count = 0;
// Process background tasks in music thread
RThread thread;
TInt error = KErrNone;
while (thread.RequestCount()) {
CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle);
User::WaitForAnyRequest();
}
for (i = 0; i < ctx->count; i++)
{
buf = &ctx->bufs[i];
if (!buf->available) count++;
}
*inUse = count;
return 0;
}
@ -402,11 +392,7 @@ cc_result SoundContext_PlayData(struct AudioContext* ctx, struct AudioData* data
}
cc_result SoundContext_PollBusy(struct AudioContext* ctx, cc_bool* isBusy) {
int inUse = 1;
cc_result res;
if ((res = Audio_Poll(ctx, &inUse))) return res;
*isBusy = inUse > 0;
*isBusy = !&ctx->bufs[0].available;
return 0;
}

View File

@ -1,11 +1,12 @@
#include "Core.h"
#if defined CC_BUILD_WEBAUDIO
struct AudioContext { int contextID, count, rate; void* data; };
struct AudioContext { int contextID, count; void* data; };
#define AUDIO_OVERRIDE_SOUNDS
#define AUDIO_OVERRIDE_ALLOC
#include "_AudioBase.h"
#include "Funcs.h"
extern int interop_InitAudio(void);
extern int interop_AudioCreate(void);
@ -28,7 +29,6 @@ cc_result Audio_Init(struct AudioContext* ctx, int buffers) {
ctx->count = buffers;
ctx->contextID = interop_AudioCreate();
ctx->data = NULL;
ctx->rate = 100;
return 0;
}
@ -38,48 +38,32 @@ void Audio_Close(struct AudioContext* ctx) {
ctx->count = 0;
}
cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sampleRate, int playbackRate) {
ctx->rate = playbackRate; return 0;
}
void Audio_SetVolume(struct AudioContext* ctx, int volume) {
interop_AudioVolume(ctx->contextID, volume);
}
cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk) {
ctx->data = chunk->data; return 0;
}
cc_result Audio_Play(struct AudioContext* ctx) {
return interop_AudioPlay(ctx->contextID, ctx->data, ctx->rate);
}
cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
return interop_AudioPoll(ctx->contextID, inUse);
}
/*########################################################################################################################*
*------------------------------------------------------Stream context-----------------------------------------------------*
*#########################################################################################################################*/
cc_result StreamContext_SetFormat(struct AudioContext* ctx, int channels, int sampleRate, int playbackRate) {
return Audio_SetFormat(ctx, channels, sampleRate, playbackRate);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Enqueue(struct AudioContext* ctx, struct AudioChunk* chunk) {
return Audio_QueueChunk(ctx, chunk);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Play(struct AudioContext* ctx) {
return Audio_Play(ctx);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {
return Audio_Poll(ctx, inUse);
return ERR_NOT_SUPPORTED;
}
@ -98,7 +82,7 @@ cc_result SoundContext_PlayData(struct AudioContext* ctx, struct AudioData* data
cc_result SoundContext_PollBusy(struct AudioContext* ctx, cc_bool* isBusy) {
int inUse = 1;
cc_result res;
if ((res = Audio_Poll(ctx, &inUse))) return res;
if ((res = interop_AudioPoll(ctx->contextID, &inUse))) return res;
*isBusy = inUse > 0;
return 0;

View File

@ -72,7 +72,7 @@ cc_result StreamContext_Play(struct AudioContext* ctx) {
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {

View File

@ -123,8 +123,6 @@ cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk) {
return ERR_INVALID_ARGUMENT;
}
cc_result Audio_Play(struct AudioContext* ctx) { return 0; }
cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
cc_result res = 0;
WAVEHDR* hdr;
@ -156,11 +154,11 @@ cc_result StreamContext_Enqueue(struct AudioContext* ctx, struct AudioChunk* chu
}
cc_result StreamContext_Play(struct AudioContext* ctx) {
return Audio_Play(ctx);
return 0;
}
cc_result StreamContext_Pause(struct AudioContext* ctx) {
return Audio_Pause(ctx);
return ERR_NOT_SUPPORTED;
}
cc_result StreamContext_Update(struct AudioContext* ctx, int* inUse) {

View File

@ -564,7 +564,7 @@ static cc_bool ParseIPv6(const char* ip, int port, cc_sockaddr* dst) {
INT size = sizeof(*addr6);
if (!_WSAStringToAddressA) return false;
if (!_WSAStringToAddressA(ip, AF_INET6, NULL, addr6, &size)) {
if (!_WSAStringToAddressA((char*)ip, AF_INET6, NULL, addr6, &size)) {
addr6->sin6_port = _htons(port);
dst->size = size;

View File

@ -1,7 +1,6 @@
#include "Audio.h"
#include "String.h"
#include "Logger.h"
#include "Funcs.h"
#include "Errors.h"
#include "Utils.h"
#include "Platform.h"
@ -17,7 +16,6 @@ static cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sam
static cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk);
static cc_result Audio_Play(struct AudioContext* ctx);
static cc_result Audio_Poll(struct AudioContext* ctx, int* inUse);
static cc_result Audio_Pause(struct AudioContext* ctx);
/*########################################################################################################################*