diff --git a/Makefile.ctr b/Makefile.ctr index cb1aa30512..4fc2261928 100644 --- a/Makefile.ctr +++ b/Makefile.ctr @@ -87,7 +87,8 @@ else OBJS += audio/drivers_resampler/cc_resampler.o OBJS += camera/drivers/nullcamera.o OBJS += location/drivers/nulllocation.o - OBJS += audio/drivers/ctr_audio.o + OBJS += audio/drivers/ctr_csnd_audio.o + OBJS += audio/drivers/ctr_dsp_audio.o OBJS += audio/drivers/nullaudio.o OBJS += gfx/video_driver.o OBJS += gfx/video_common.o diff --git a/audio/audio_driver.c b/audio/audio_driver.c index 7f07bfe6e5..42137d04e7 100644 --- a/audio/audio_driver.c +++ b/audio/audio_driver.c @@ -120,7 +120,8 @@ static const audio_driver_t *audio_drivers[] = { &audio_psp, #endif #ifdef _3DS - &audio_ctr, + &audio_ctr_csnd, + &audio_ctr_dsp, #endif &audio_null, NULL, diff --git a/audio/audio_driver.h b/audio/audio_driver.h index df5f265b71..b9cf548f51 100644 --- a/audio/audio_driver.h +++ b/audio/audio_driver.h @@ -89,7 +89,8 @@ extern audio_driver_t audio_xenon360; extern audio_driver_t audio_ps3; extern audio_driver_t audio_gx; extern audio_driver_t audio_psp; -extern audio_driver_t audio_ctr; +extern audio_driver_t audio_ctr_csnd; +extern audio_driver_t audio_ctr_dsp; extern audio_driver_t audio_rwebaudio; extern audio_driver_t audio_null; diff --git a/audio/drivers/ctr_audio.c b/audio/drivers/ctr_csnd_audio.c similarity index 58% rename from audio/drivers/ctr_audio.c rename to audio/drivers/ctr_csnd_audio.c index ebd4de82bc..05969c8b5d 100644 --- a/audio/drivers/ctr_audio.c +++ b/audio/drivers/ctr_csnd_audio.c @@ -32,26 +32,26 @@ typedef struct uint32_t playpos; uint64_t cpu_ticks_last; -} ctr_audio_t; +} ctr_csnd_audio_t; -#define CTR_AUDIO_COUNT (1u << 11u) -#define CTR_AUDIO_COUNT_MASK (CTR_AUDIO_COUNT - 1u) -#define CTR_AUDIO_SIZE (CTR_AUDIO_COUNT * sizeof(int16_t)) -#define CTR_AUDIO_SIZE_MASK (CTR_AUDIO_SIZE - 1u) +#define CTR_CSND_AUDIO_COUNT (1u << 11u) +#define CTR_CSND_AUDIO_COUNT_MASK (CTR_CSND_AUDIO_COUNT - 1u) +#define CTR_CSND_AUDIO_SIZE (CTR_CSND_AUDIO_COUNT * sizeof(int16_t)) +#define CTR_CSND_AUDIO_SIZE_MASK (CTR_CSND_AUDIO_SIZE - 1u) -#define CTR_AUDIO_RATE 32730 +#define CTR_CSND_AUDIO_RATE 32730 #define CTR_CSND_TICKS_PER_SAMPLE 2048 -#define CTR_CPU_TICKS_PER_SAMPLE (CTR_CSND_TICKS_PER_SAMPLE * 4) +#define CTR_CSND_CPU_TICKS_PER_SAMPLE (CTR_CSND_TICKS_PER_SAMPLE * 4) -static void ctr_audio_update_playpos(ctr_audio_t* ctr) +static void ctr_csnd_audio_update_playpos(ctr_csnd_audio_t* ctr) { uint32_t samples_played; uint64_t current_tick; current_tick = svcGetSystemTick(); - samples_played = (current_tick - ctr->cpu_ticks_last) / CTR_CPU_TICKS_PER_SAMPLE; - ctr->playpos = (ctr->playpos + samples_played) & CTR_AUDIO_COUNT_MASK; - ctr->cpu_ticks_last += samples_played * CTR_CPU_TICKS_PER_SAMPLE; + samples_played = (current_tick - ctr->cpu_ticks_last) / CTR_CSND_CPU_TICKS_PER_SAMPLE; + ctr->playpos = (ctr->playpos + samples_played) & CTR_CSND_AUDIO_COUNT_MASK; + ctr->cpu_ticks_last += samples_played * CTR_CSND_CPU_TICKS_PER_SAMPLE; } @@ -96,9 +96,9 @@ Result csndPlaySound_custom(int chn, u32 flags, float vol, float pan, void* data return 0; } -static void *ctr_audio_init(const char *device, unsigned rate, unsigned latency) +static void *ctr_csnd_audio_init(const char *device, unsigned rate, unsigned latency) { - ctr_audio_t *ctr = (ctr_audio_t*)calloc(1, sizeof(ctr_audio_t)); + ctr_csnd_audio_t *ctr = (ctr_csnd_audio_t*)calloc(1, sizeof(ctr_csnd_audio_t)); settings_t *settings = config_get_ptr(); if (!ctr) @@ -108,26 +108,26 @@ static void *ctr_audio_init(const char *device, unsigned rate, unsigned latency) (void)rate; (void)latency; - settings->audio.out_rate = CTR_AUDIO_RATE; + settings->audio.out_rate = CTR_CSND_AUDIO_RATE; - ctr->l = linearAlloc(CTR_AUDIO_SIZE); - ctr->r = linearAlloc(CTR_AUDIO_SIZE); + ctr->l = linearAlloc(CTR_CSND_AUDIO_SIZE); + ctr->r = linearAlloc(CTR_CSND_AUDIO_SIZE); - memset(ctr->l, 0, CTR_AUDIO_SIZE); - memset(ctr->r, 0, CTR_AUDIO_SIZE); + memset(ctr->l, 0, CTR_CSND_AUDIO_SIZE); + memset(ctr->r, 0, CTR_CSND_AUDIO_SIZE); ctr->l_paddr = osConvertVirtToPhys((u32)ctr->l); ctr->r_paddr = osConvertVirtToPhys((u32)ctr->r); ctr->pos = 0; - GSPGPU_FlushDataCache(ctr->l_paddr, CTR_AUDIO_SIZE); - GSPGPU_FlushDataCache(ctr->r_paddr, CTR_AUDIO_SIZE); + GSPGPU_FlushDataCache(ctr->l_paddr, CTR_CSND_AUDIO_SIZE); + GSPGPU_FlushDataCache(ctr->r_paddr, CTR_CSND_AUDIO_SIZE); csndPlaySound_custom(0x8, SOUND_LOOPMODE(CSND_LOOPMODE_NORMAL)| SOUND_FORMAT(CSND_ENCODING_PCM16), - 1.0, -1.0, ctr->l, ctr->l, CTR_AUDIO_SIZE); + 1.0, -1.0, ctr->l, ctr->l, CTR_CSND_AUDIO_SIZE); csndPlaySound_custom(0x9, SOUND_LOOPMODE(CSND_LOOPMODE_NORMAL)| SOUND_FORMAT(CSND_ENCODING_PCM16), - 1.0, 1.0, ctr->r, ctr->r, CTR_AUDIO_SIZE); + 1.0, 1.0, ctr->r, ctr->r, CTR_CSND_AUDIO_SIZE); csndExecCmds(true); ctr->playpos = 0; @@ -137,9 +137,9 @@ static void *ctr_audio_init(const char *device, unsigned rate, unsigned latency) return ctr; } -static void ctr_audio_free(void *data) +static void ctr_csnd_audio_free(void *data) { - ctr_audio_t* ctr = (ctr_audio_t*)data; + ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data; // csndExit(); CSND_SetPlayState(0x8, 0); @@ -152,14 +152,14 @@ static void ctr_audio_free(void *data) free(ctr); } -static ssize_t ctr_audio_write(void *data, const void *buf, size_t size) +static ssize_t ctr_csnd_audio_write(void *data, const void *buf, size_t size) { int i; uint32_t samples_played = 0; uint64_t current_tick = 0; static struct retro_perf_counter ctraudio_f = {0}; const uint16_t *src = buf; - ctr_audio_t *ctr = (ctr_audio_t*)data; + ctr_csnd_audio_t *ctr = (ctr_csnd_audio_t*)data; (void)data; (void)buf; @@ -169,22 +169,22 @@ static ssize_t ctr_audio_write(void *data, const void *buf, size_t size) rarch_perf_init(&ctraudio_f, "ctraudio_f"); retro_perf_start(&ctraudio_f); - ctr_audio_update_playpos(ctr); + ctr_csnd_audio_update_playpos(ctr); - if((((ctr->playpos - ctr->pos) & CTR_AUDIO_COUNT_MASK) < (CTR_AUDIO_COUNT >> 2)) || - (((ctr->pos - ctr->playpos ) & CTR_AUDIO_COUNT_MASK) < (CTR_AUDIO_COUNT >> 4)) || - (((ctr->playpos - ctr->pos) & CTR_AUDIO_COUNT_MASK) < (size >> 2))) + if((((ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 2)) || + (((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))) { if (ctr->nonblocking) - ctr->pos = (ctr->playpos + (CTR_AUDIO_COUNT >> 1)) & CTR_AUDIO_COUNT_MASK; + ctr->pos = (ctr->playpos + (CTR_CSND_AUDIO_COUNT >> 1)) & CTR_CSND_AUDIO_COUNT_MASK; else { do{ /* todo: compute the correct sleep period */ retro_sleep(1); - ctr_audio_update_playpos(ctr); - }while (((ctr->playpos - ctr->pos) & CTR_AUDIO_COUNT_MASK) < (CTR_AUDIO_COUNT >> 1) - || (((ctr->pos - ctr->playpos) & CTR_AUDIO_COUNT_MASK) < (CTR_AUDIO_COUNT >> 4))); + ctr_csnd_audio_update_playpos(ctr); + }while (((ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 1) + || (((ctr->pos - ctr->playpos) & CTR_CSND_AUDIO_COUNT_MASK) < (CTR_CSND_AUDIO_COUNT >> 4))); } } @@ -193,20 +193,20 @@ static ssize_t ctr_audio_write(void *data, const void *buf, size_t size) ctr->l[ctr->pos] = src[i]; ctr->r[ctr->pos] = src[i + 1]; ctr->pos++; - ctr->pos &= CTR_AUDIO_COUNT_MASK; + ctr->pos &= CTR_CSND_AUDIO_COUNT_MASK; } - GSPGPU_FlushDataCache(ctr->l, CTR_AUDIO_SIZE); - GSPGPU_FlushDataCache(ctr->r, CTR_AUDIO_SIZE); + GSPGPU_FlushDataCache(ctr->l, CTR_CSND_AUDIO_SIZE); + GSPGPU_FlushDataCache(ctr->r, CTR_CSND_AUDIO_SIZE); retro_perf_stop(&ctraudio_f); return size; } -static bool ctr_audio_stop(void *data) +static bool ctr_csnd_audio_stop(void *data) { - ctr_audio_t* ctr = (ctr_audio_t*)data; + ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data; /* using SetPlayState would make tracking the playback * position more difficult */ @@ -228,15 +228,15 @@ static bool ctr_audio_stop(void *data) return true; } -static bool ctr_audio_alive(void *data) +static bool ctr_csnd_audio_alive(void *data) { - ctr_audio_t* ctr = (ctr_audio_t*)data; + ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data; return ctr->playing; } -static bool ctr_audio_start(void *data) +static bool ctr_csnd_audio_start(void *data) { - ctr_audio_t* ctr = (ctr_audio_t*)data; + ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data; rarch_system_info_t *system = rarch_system_info_get_ptr(); /* Prevents restarting audio when the menu @@ -260,44 +260,44 @@ static bool ctr_audio_start(void *data) return true; } -static void ctr_audio_set_nonblock_state(void *data, bool state) +static void ctr_csnd_audio_set_nonblock_state(void *data, bool state) { - ctr_audio_t* ctr = (ctr_audio_t*)data; + ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data; if (ctr) ctr->nonblocking = state; } -static bool ctr_audio_use_float(void *data) +static bool ctr_csnd_audio_use_float(void *data) { (void)data; return false; } -static size_t ctr_audio_write_avail(void *data) +static size_t ctr_csnd_audio_write_avail(void *data) { - ctr_audio_t* ctr = (ctr_audio_t*)data; + ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data; - ctr_audio_update_playpos(ctr); - return (ctr->playpos - ctr->pos) & CTR_AUDIO_COUNT_MASK; + ctr_csnd_audio_update_playpos(ctr); + return (ctr->playpos - ctr->pos) & CTR_CSND_AUDIO_COUNT_MASK; } -static size_t ctr_audio_buffer_size(void *data) +static size_t ctr_csnd_audio_buffer_size(void *data) { (void)data; - return CTR_AUDIO_COUNT; + return CTR_CSND_AUDIO_COUNT; } -audio_driver_t audio_ctr = { - ctr_audio_init, - ctr_audio_write, - ctr_audio_stop, - ctr_audio_start, - ctr_audio_alive, - ctr_audio_set_nonblock_state, - ctr_audio_free, - ctr_audio_use_float, - "ctr", - ctr_audio_write_avail, - ctr_audio_buffer_size +audio_driver_t audio_ctr_csnd = { + ctr_csnd_audio_init, + ctr_csnd_audio_write, + ctr_csnd_audio_stop, + ctr_csnd_audio_start, + ctr_csnd_audio_alive, + ctr_csnd_audio_set_nonblock_state, + ctr_csnd_audio_free, + ctr_csnd_audio_use_float, + "csnd", + ctr_csnd_audio_write_avail, + ctr_csnd_audio_buffer_size }; diff --git a/audio/drivers/ctr_dsp_audio.c b/audio/drivers/ctr_dsp_audio.c new file mode 100644 index 0000000000..bdf51aa7d6 --- /dev/null +++ b/audio/drivers/ctr_dsp_audio.c @@ -0,0 +1,281 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2014-2015 - Ali Bouhlel + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include <3ds.h> +#include "../../general.h" +#include "../../driver.h" +#include "../../performance.h" + + +#define CTR_DSP_BUFFERS_COUNT (1u << 4u) +#define CTR_DSP_BUFFERS_MASK (CTR_DSP_BUFFERS_COUNT - 1) + +typedef struct +{ + bool nonblocking; + bool playing; + + int channel; + ndspWaveBuf dsp_buf[CTR_DSP_BUFFERS_COUNT]; + uint32_t dsp_buf_id; + uint8_t* linear_buffer; + +} ctr_dsp_audio_t; + +#define CTR_DSP_AUDIO_COUNT (1u << 11u) +#define CTR_DSP_AUDIO_COUNT_MASK (CTR_DSP_AUDIO_COUNT - 1u) +#define CTR_DSP_AUDIO_SIZE (CTR_DSP_AUDIO_COUNT * sizeof(int16_t) * 2) +#define CTR_DSP_AUDIO_SIZE_MASK (CTR_DSP_AUDIO_SIZE - 1u) + + +#ifndef DEBUG_HOLD +void wait_for_input(void); +#define PRINTFPOS(X,Y) "\x1b["#X";"#Y"H" +#define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0) +#define DEBUG_VAR(X) printf( "%-20s: 0x%08X\n", #X, (u32)(X)) +#define DEBUG_VAR64(X) printf( #X"\r\t\t\t\t : 0x%016llX\n", (u64)(X)) +#endif + + +static uint32_t ctr_get_queued_samples(ctr_dsp_audio_t* ctr) +{ + uint32_t sample_pos, sample_count; + uint16_t buf_seq; + + buf_seq = ndspChnGetWaveBufSeq(ctr->channel); + + if(!buf_seq) + return 0; + + sample_pos = ndspChnGetSamplePos(ctr->channel); + sample_count = 0; + + int buf_id = ctr->dsp_buf_id; + do + { + buf_id++; + buf_id&= CTR_DSP_BUFFERS_MASK; + } + while(ctr->dsp_buf[buf_id].sequence_id != buf_seq); + ndspWaveBuf* current = &ctr->dsp_buf[buf_id]; + + sample_count = current->nsamples - sample_pos; + while((current = current->next)) + { + sample_count += current->nsamples; + } + return sample_count; +} + + + +static void *ctr_dsp_audio_init(const char *device, unsigned rate, unsigned latency) +{ + ctr_dsp_audio_t *ctr; + settings_t *settings = config_get_ptr(); + + (void)device; + (void)rate; + (void)latency; + + if (ndspInit() < 0) + return NULL; + + ctr = (ctr_dsp_audio_t*)calloc(1, sizeof(ctr_dsp_audio_t)); + + if (!ctr) + return NULL; + +// memset(ctr, 0, sizeof(*ctr)); + + settings->audio.out_rate = 32730; + + ctr->channel = 0; + ctr->dsp_buf_id = 0; + + ndspSetOutputMode(NDSP_OUTPUT_STEREO); + ndspSetClippingMode(NDSP_CLIP_SOFT); //?? +// ndspSetClippingMode(NDSP_CLIP_NORMAL); //?? + ndspSetOutputCount(CTR_DSP_BUFFERS_COUNT); + ndspChnReset(ctr->channel); +// ndspChnInitParams(ctr->channel); + ndspChnSetFormat(ctr->channel, NDSP_FORMAT_STEREO_PCM16); + ndspChnSetInterp(ctr->channel, NDSP_INTERP_NONE); +// ndspChnSetInterp(ctr->channel, NDSP_INTERP_LINEAR); +// ndspChnSetInterp(ctr->channel, NDSP_INTERP_POLYPHASE); + ndspChnSetRate(ctr->channel, 32728.0f); +// ndspChnSetRate(ctr->channel, CTR_DSP_AUDIO_RATE); +// ndspChnSetRate(ctr->channel, 0x7F00); +// ndspChnSetMix(ctr->channel, (float[12]){1.0, 1.0, 0.0}); + ndspChnWaveBufClear(ctr->channel); + + ctr->linear_buffer = linearAlloc(CTR_DSP_BUFFERS_COUNT * CTR_DSP_AUDIO_SIZE); + + int i; + for (i = 0; i < CTR_DSP_BUFFERS_COUNT; i++) + ctr->dsp_buf[i].data_pcm16 = (uint16_t*)(ctr->linear_buffer + i * CTR_DSP_AUDIO_SIZE); + + return ctr; +} + +static void ctr_dsp_audio_free(void *data) +{ + ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data; + + linearFree(ctr->linear_buffer); + free(ctr); + ndspExit(); +} + +static ssize_t ctr_dsp_audio_write(void *data, const void *buf, size_t size) +{ + static struct retro_perf_counter ctraudio_dsp_f = {0}; + ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data; + + ndspWaveBuf* current_buf = &ctr->dsp_buf[ctr->dsp_buf_id]; + static int dropped=0; + uint32_t queued = ctr_get_queued_samples(ctr); + + if(size > CTR_DSP_AUDIO_SIZE) + { + DEBUG_VAR(size); + ctr_dsp_audio_write(ctr, buf, CTR_DSP_AUDIO_SIZE); + buf = (const void*)((u32)buf + CTR_DSP_AUDIO_SIZE); + size = size - CTR_DSP_AUDIO_SIZE; + } + + dropped++; + if(ctr->nonblocking) + { + if((current_buf->status == NDSP_WBUF_QUEUED) || (current_buf->status == NDSP_WBUF_PLAYING)) + return size; + + if((queued + (size>>2)) > 0x2000) + return size; + } + else + { + if(queued > (0x1000 + (size>>2))) + { +// printf(PRINTFPOS(24,0)"queued :0x%08X \n", ctr_get_queued_samples(ctr)); + while(ctr_get_queued_samples(ctr) > 160 ) + svcSleepThread(100000); + } + } + dropped--; + + + rarch_perf_init(&ctraudio_dsp_f, "ctraudio_dsp_f"); + retro_perf_start(&ctraudio_dsp_f); + + memcpy(current_buf->data_pcm16, buf, size); + current_buf->nsamples = size>>2; + + DSP_FlushDataCache(current_buf->data_pcm16, size); + DSP_FlushDataCache(ctr->dsp_buf, sizeof(ctr->dsp_buf)); + gfxFlushBuffers(); + + ndspChnWaveBufAdd(ctr->channel, current_buf); + retro_perf_stop(&ctraudio_dsp_f); + +// printf(PRINTFPOS(25,0)"dropped:0x%08X queued :0x%08X \n", dropped, queued); +// printf(PRINTFPOS(26,0)"current:0x%08X nsamples:0x%08X \n", ctr->dsp_buf_id, current_buf->nsamples); +// printf(PRINTFPOS(27,0)"dropped:0x%08X count :0x%08X \n", ndspGetDroppedFrames(), ndspGetFrameCount()); +// printf(PRINTFPOS(28,0)"Pos :0x%08X Seq :0x%08X \n", ndspChnGetSamplePos(ctr->channel), ndspChnGetWaveBufSeq(ctr->channel)); + + ctr->dsp_buf_id++; + ctr->dsp_buf_id &= CTR_DSP_BUFFERS_MASK; + + return size; +} + +static bool ctr_dsp_audio_stop(void *data) +{ + ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data; + + ndspChnWaveBufClear(ctr->channel); + ctr->playing = false; + int i; + memset(ctr->dsp_buf, 0, sizeof(ctr->dsp_buf)); + for (i = 0; i < CTR_DSP_BUFFERS_COUNT; i++) + ctr->dsp_buf[i].data_pcm16 = (uint16_t*)(ctr->linear_buffer + i * CTR_DSP_AUDIO_SIZE); + + return true; +} + +static bool ctr_dsp_audio_alive(void *data) +{ + ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data; + return ctr->playing; +} + +static bool ctr_dsp_audio_start(void *data) +{ + ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data; + rarch_system_info_t *system = rarch_system_info_get_ptr(); + + /* Prevents restarting audio when the menu + * is toggled off on shutdown */ + + if (system->shutdown) + return true; + + ctr->playing = true; + + return true; +} + +static void ctr_dsp_audio_set_nonblock_state(void *data, bool state) +{ + ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data; + if (ctr) + ctr->nonblocking = state; +} + +static bool ctr_dsp_audio_use_float(void *data) +{ + (void)data; + return false; +} + +static size_t ctr_dsp_audio_write_avail(void *data) +{ + ctr_dsp_audio_t* ctr = (ctr_dsp_audio_t*)data; + uint32_t queued_samples = ctr_get_queued_samples(ctr); + + return queued_samples < 0x1000 ? 0x1000 - queued_samples : 0; +} + +static size_t ctr_dsp_audio_buffer_size(void *data) +{ + (void)data; + return 0x1000; +} + + +audio_driver_t audio_ctr_dsp = { + ctr_dsp_audio_init, + ctr_dsp_audio_write, + ctr_dsp_audio_stop, + ctr_dsp_audio_start, + ctr_dsp_audio_alive, + ctr_dsp_audio_set_nonblock_state, + ctr_dsp_audio_free, + ctr_dsp_audio_use_float, + "dsp", + ctr_dsp_audio_write_avail, + ctr_dsp_audio_buffer_size +}; + diff --git a/configuration.c b/configuration.c index 4605a6b774..4f0499c7bb 100644 --- a/configuration.c +++ b/configuration.c @@ -121,7 +121,7 @@ const char *config_get_default_audio(void) return "psp"; #endif case AUDIO_CTR: - return "ctr"; + return "csnd"; case AUDIO_RWEBAUDIO: return "rwebaudio"; default: diff --git a/ctr/ctr_config.c b/ctr/ctr_config.c index e1e7504797..21cc60022d 100644 --- a/ctr/ctr_config.c +++ b/ctr/ctr_config.c @@ -15,4 +15,4 @@ int __stacksize__ = CTR_STACK_SIZE; unsigned int __linear_heap_size = CTR_LINEAR_HEAP_SIZE; -unsigned int __heap_size = CTR_MAX_HEAP_SIZE; +unsigned int __heap_size = CTR_MAX_HEAP_SIZE + CTR_STACK_SIZE; diff --git a/ctr/tools/template.rsf b/ctr/tools/template.rsf index c3d42b6f6a..7f3590ed8d 100644 --- a/ctr/tools/template.rsf +++ b/ctr/tools/template.rsf @@ -152,6 +152,7 @@ AccessControlInfo: - cam:u - cecd:u - csnd:SND + - dsp::DSP - frd:u - http:C - ir:USER diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index 6a523c33cc..d99cc6c895 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -29,6 +29,7 @@ #include "../../general.h" #include "retroarch.h" +#include "audio/audio_driver.h" #ifdef IS_SALAMANDER #include "../../file_ext.h" @@ -40,9 +41,11 @@ const char* elf_path_cst = "sdmc:/retroarch/test.3dsx"; #ifndef DEBUG_HOLD void wait_for_input(void); +void dump_result_value(Result val); #define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0) #define DEBUG_VAR(X) printf( "%-20s: 0x%08X\n", #X, (u32)(X)) #define DEBUG_VAR64(X) printf( #X"\r\t\t\t\t : 0x%016llX\n", (u64)(X)) +#define DEBUG_ERROR(X) do{if(X)dump_result_value(X)}while(0) #endif #define CTR_APPMEMALLOC_PTR ((u32*)0x1FF80040) @@ -118,8 +121,6 @@ void __attribute__((noreturn)) __libctru_exit(int rc) svcExitProcess(); } - - static void frontend_ctr_get_environment_settings(int *argc, char *argv[], void *args, void *params_data) { @@ -160,6 +161,8 @@ static void frontend_ctr_get_environment_settings(int *argc, char *argv[], *argc = 0; + *argc=0; + #ifndef IS_SALAMANDER #if 0 if (argv[1] && (argv[1][0] != '\0')) @@ -224,16 +227,9 @@ static void frontend_ctr_deinit(void *data) } exitCfgu(); - csndExit(); + ndspExit(); + csndExit(); gfxExit(); - -#if 0 - sdmcExit(); - fsExit(); - hidExit(); - aptExit(); - srvExit(); -#endif #endif } @@ -253,21 +249,22 @@ static void frontend_ctr_init(void *data) global->verbosity = true; #if 0 - srvInit(); - aptInit(); - hidInit(); - fsInit(); - sdmcInit(); - APT_SetAppCpuTimeLimit(NULL, 80); - gfxInitDefault(); #endif osSetSpeedupEnable(true); gfxInit(GSP_BGR8_OES,GSP_RGB565_OES,false); - csndInit(); - initCfgu(); gfxSet3D(false); consoleInit(GFX_BOTTOM, NULL); + audio_driver_t* dsp_audio_driver = &audio_ctr_dsp; + if(csndInit() != 0) + { + dsp_audio_driver = &audio_ctr_csnd; + audio_ctr_csnd = audio_ctr_dsp; + audio_ctr_dsp = audio_null; + } + if(ndspInit() != 0) + *dsp_audio_driver = audio_null; + initCfgu(); #endif } @@ -279,6 +276,145 @@ static int frontend_ctr_get_rating(void) bool select_pressed = false; +typedef union{ + struct + { + unsigned description : 10; + unsigned module : 8; + unsigned : 3; + unsigned summary : 6; + unsigned level : 5; + }; + Result val; +}ctr_result_value; + +void dump_result_value(Result val) +{ + ctr_result_value res; + res.val = val; + printf("result : 0x%08X\n", val); + printf("description : %u\n", res.description); + printf("module : %u\n", res.module); + printf("summary : %u\n", res.summary); + printf("level : %u\n", res.level); +} +#if 0 +static void ctr_crawl_memory(uint32_t* total_size, uint32_t size) +{ + void* tmp = malloc(size); + if(tmp) + *total_size += size; + else + size >>= 1; + + if (size > 4) + ctr_crawl_memory(total_size, size); + + free(tmp); +} + +void ctr_get_memory_info(uint32_t* available, uint32_t* max_block) +{ + *available = 0; + + ctr_crawl_memory(available, 1<<27); + + void* tmp; + *max_block = 0; + int i; + for (i=27; i>2; i--) + { + tmp = malloc(*max_block + (1 << i)); + if(tmp) + { + *max_block += 1 << i; + free(tmp); + } + } + + +} + +uint32_t malloc_calls = 0; +uint32_t min_malloc_addr = 0xFFFFFFFF; +uint32_t max_malloc_addr = 0x0; + +void* malloc(size_t nbytes) +{ + void* ret = _malloc_r (_REENT, nbytes); + + if (ret) + { + if(max_malloc_addr < ((uint32_t)ret + nbytes)) + max_malloc_addr = ((uint32_t)ret + nbytes); + + if(min_malloc_addr > (uint32_t)ret) + min_malloc_addr = (uint32_t)ret; + } + + malloc_calls++; + return ret; +} + +void free (void* aptr) +{ + _free_r (_REENT, aptr); +} + +uint32_t sbrk_calls = 0; +uint32_t sbrk_max_incr = 0; +uint32_t sbrk_total_incr = 0; +uint32_t sbrk_heap_start = 0; +uint32_t sbrk_heap_end = 0; + +#include "errno.h" +extern char *fake_heap_end; +extern char *fake_heap_start; + +/* Register name faking - works in collusion with the linker. */ +register char * stack_ptr asm ("sp"); + +void * _sbrk_r (struct _reent *ptr, ptrdiff_t incr) { + extern char end asm ("__end__"); /* Defined by the linker. */ + static char * heap_start; + + char * prev_heap_start; + char * heap_end; + + if (heap_start == NULL) { + if (fake_heap_start == NULL) { + heap_start = &end; + } else { + heap_start = fake_heap_start; + } + } + + prev_heap_start = heap_start; + + if (fake_heap_end == NULL) { + heap_end = stack_ptr; + } else { + heap_end = fake_heap_end; + } + + if (heap_start + incr > heap_end) { + ptr->_errno = ENOMEM; + return (caddr_t) -1; + } + + heap_start += incr; + + sbrk_calls++; + if ((incr > 0) && (sbrk_max_incr < incr)) + sbrk_max_incr = incr; + sbrk_total_incr += incr; + sbrk_heap_start = (uint32_t) heap_start; + sbrk_heap_end = (uint32_t) heap_end; + + return (caddr_t) prev_heap_start; +} +#endif + void wait_for_input(void) { printf("\n\nPress Start.\n\n"); diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index be6086584d..24a6ff03ad 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -461,12 +461,30 @@ static bool ctr_frame(void* data, const void* frame, frames = 0; } -// extern u32 __linear_heap_size; +#if 0 // extern u32 gpuCmdBufOffset; -// extern u32 __heap_size; -// printf("0x%08X 0x%08X 0x%08X\r", __heap_size, gpuCmdBufOffset, (__linear_heap_size - linearSpaceFree() +0x3FF) & ~0x3FF); -// printf("fps: %8.4f frames: %i (%X)\r", fps, total_frames++, (__linear_heap_size - linearSpaceFree())); - printf("fps: %8.4f frames: %i\r", fps, total_frames++); + +// if(!(frames & 0x3F)) +// { +// u32 available,max_block; +// void ctr_get_memory_info(u32* available, u32* max_block); + +// ctr_get_memory_info(&available, &max_block); +// printf(PRINTFPOS(28,0)"u:0x%08X f:0x%08X b:0x%08X\n", __heap_size - available, available, max_block); +// } + + extern u32 __linear_heap_size; + extern u32 __heap_size; + + extern uint32_t sbrk_calls, sbrk_max_incr, sbrk_total_incr, sbrk_heap_start, sbrk_heap_end; + printf(PRINTFPOS(25,0)"c:0x%08X m:0x%08X c:0x%08X\n", sbrk_calls, sbrk_max_incr, sbrk_total_incr); + printf(PRINTFPOS(26,0)"s:0x%08X e:0x%08X \n", sbrk_heap_start, sbrk_heap_end); + extern uint32_t malloc_calls, min_malloc_addr, max_malloc_addr; + printf(PRINTFPOS(27,0)"n:0x%08X l:0x%08X h:0x%08X\n", malloc_calls, min_malloc_addr, max_malloc_addr); + printf(PRINTFPOS(28,0)"0x%08X 0x%08X 0x%08X\r", __heap_size, gpuCmdBufOffset, (__linear_heap_size - linearSpaceFree() +0x3FF) & ~0x3FF); +#endif +// printf(PRINTFPOS(29,0)"fps: %8.4f frames: %i (%X)\r", fps, total_frames++, (__linear_heap_size - linearSpaceFree())); + printf(PRINTFPOS(29,0)"fps: %8.4f frames: %i\r", fps, total_frames++); fflush(stdout); rarch_perf_init(&ctrframe_f, "ctrframe_f"); diff --git a/gfx/drivers/ctr_gu.h b/gfx/drivers/ctr_gu.h index 363a4c80b4..6eea2c3b87 100644 --- a/gfx/drivers/ctr_gu.h +++ b/gfx/drivers/ctr_gu.h @@ -61,6 +61,7 @@ #ifndef DEBUG_HOLD void wait_for_input(void); +#define PRINTFPOS(X,Y) "\x1b["#X";"#Y"H" #define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0) #define DEBUG_VAR(X) printf( "%-20s: 0x%08X\n", #X, (u32)(X)) #define DEBUG_VAR64(X) printf( #X"\r\t\t\t\t : 0x%016llX\n", (u64)(X)) diff --git a/griffin/griffin.c b/griffin/griffin.c index e5c12fe4c7..a443a740f0 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -501,7 +501,8 @@ AUDIO #elif defined(PSP) || defined(VITA) #include "../audio/drivers/psp_audio.c" #elif defined(_3DS) -#include "../audio/drivers/ctr_audio.c" +#include "../audio/drivers/ctr_csnd_audio.c" +#include "../audio/drivers/ctr_dsp_audio.c" #endif #ifdef HAVE_DSOUND