mirror of
https://github.com/libretro/RetroArch
synced 2025-01-31 06:32:48 +00:00
Merge pull request #7877 from fjtrujy/feature/PS2AudioSupport
PS2 Audio Support
This commit is contained in:
commit
56bf1c53ca
24
Makefile.ps2
24
Makefile.ps2
@ -2,11 +2,10 @@ BUILD_PRX = 0
|
||||
DEBUG = 0
|
||||
HAVE_KERNEL_PRX = 0
|
||||
HAVE_LOGGER = 0
|
||||
HAVE_FILE_LOGGER = 1
|
||||
HAVE_FILE_LOGGER = 0
|
||||
HAVE_THREADS = 0
|
||||
BIG_STACK = 0
|
||||
WHOLE_ARCHIVE_LINK = 0
|
||||
PS2_IP = 192.168.2.150
|
||||
PS2_IP = 192.168.1.150
|
||||
|
||||
#Configuration for IRX
|
||||
EE_BIN2O = bin2o
|
||||
@ -22,29 +21,23 @@ else
|
||||
OPTIMIZE_LV := -O2
|
||||
endif
|
||||
|
||||
ifeq ($(WHOLE_ARCHIVE_LINK), 1)
|
||||
WHOLE_START := -Wl,--whole-archive
|
||||
WHOLE_END := -Wl,--no-whole-archive
|
||||
endif
|
||||
|
||||
INCDIR = -I$(PS2DEV)/gsKit/include -I$(PS2SDK)/ports/include
|
||||
INCDIR += -Ips2 -Ips2/include -Ilibretro-common/include
|
||||
INCDIR += -Ideps -Ideps/stb -Ideps/libz -Ideps/7zip -Ideps/pthreads -Ideps/pthreads/platform/ps2 -Ideps/pthreads/platform/helper
|
||||
GPVAL = -G0
|
||||
CFLAGS = $(OPTIMIZE_LV) -ffast-math -fsingle-precision-constant
|
||||
CFLAGS = $(OPTIMIZE_LV) -ffast-math -fsingle-precision-constant
|
||||
ASFLAGS = $(CFLAGS)
|
||||
|
||||
RARCH_DEFINES += -DPS2 -DUSE_IOP_CTYPE_MACRO -D_MIPS_ARCH_R5900 -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DWANT_ZLIB
|
||||
RARCH_DEFINES += -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_IMAGEVIEWER -DHAVE_7ZIP -DHAVE_CC_RESAMPLER
|
||||
RARCH_DEFINES += -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -DHAVE_CC_RESAMPLER
|
||||
|
||||
LIBDIR =
|
||||
LDFLAGS = -L$(PS2SDK)/ports/lib -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ee/lib -L. -s
|
||||
LIBS += $(WHOLE_START) -lretro_ps2 $(WHOLE_END)
|
||||
LIBS += -lgskit -ldmakit -lpad -lmc -lhdd -lsdl -lc -lfileXio -lpatches -lpoweroff -ldebug -lc
|
||||
LIBS += -lretro_ps2 -lgskit -ldmakit -laudsrv -lpad -lmc -lhdd -lsdl -lfileXio -lpatches -lpoweroff
|
||||
|
||||
#IRX modules
|
||||
# IRX modules - modules have to be in IRX_DIR
|
||||
IRX = iomanX.irx fileXio.irx usbd.irx usbhdfsd.irx freesd.irx audsrv.irx poweroff.irx ps2dev9.irx ps2atad.irx ps2hdd.irx ps2fs.irx
|
||||
IRX = iomanX.irx fileXio.irx mcman.irx mcserv.irx usbd.irx usbhdfsd.irx freesd.irx audsrv.irx poweroff.irx ps2dev9.irx ps2atad.irx ps2hdd.irx ps2fs.irx
|
||||
IRX_OBJ = $(IRX:.irx=.o)
|
||||
EE_OBJS += $(IRX_OBJ)
|
||||
|
||||
@ -108,10 +101,7 @@ $(EE_IRX_OBJ):
|
||||
include $(PS2SDK)/samples/Makefile.pref
|
||||
include $(PS2SDK)/samples/Makefile.eeglobal
|
||||
|
||||
|
||||
#Linking with C++
|
||||
$(EE_BIN): $(EE_OBJS) $(PS2SDK)/ee/startup/crt0.o
|
||||
$(EE_CXX) $(EE_NO_CRT) -T$(PS2SDK)/ee/startup/linkfile $(EE_CXXFLAGS) \
|
||||
-o $(EE_BIN) $(PS2SDK)/ee/startup/crt0.o $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(EE_OBJS) $(CRTEND_OBJ) $(CRTN_OBJ) $(EE_LDFLAGS) $(EE_LIBS)
|
||||
|
||||
|
||||
|
@ -122,6 +122,9 @@ static const audio_driver_t *audio_drivers[] = {
|
||||
#if defined(PSP) || defined(VITA)
|
||||
&audio_psp,
|
||||
#endif
|
||||
#if defined(PS2)
|
||||
&audio_ps2,
|
||||
#endif
|
||||
#ifdef _3DS
|
||||
&audio_ctr_csnd,
|
||||
&audio_ctr_dsp,
|
||||
|
269
audio/drivers/ps2_audio.c
Normal file
269
audio/drivers/ps2_audio.c
Normal file
@ -0,0 +1,269 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2014-2017 - Francisco Javier Trujillo Mata
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <kernel.h>
|
||||
#include <audsrv.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
|
||||
typedef struct ps2_audio {
|
||||
fifo_buffer_t* buffer;
|
||||
bool nonblocking;
|
||||
volatile bool running;
|
||||
int worker_thread;
|
||||
int lock;
|
||||
int cond_lock;
|
||||
|
||||
} ps2_audio_t;
|
||||
|
||||
static ps2_audio_t *backup_ps2;
|
||||
static u8 audioThreadStack[4 * 1024] __attribute__ ((aligned(16)));
|
||||
|
||||
#define AUDIO_OUT_BUFFER 2 * 1024
|
||||
#define AUDIO_BUFFER 64 * 1024
|
||||
#define AUDIO_CHANNELS 2
|
||||
#define AUDIO_BITS 16
|
||||
#define AUDIO_PRIORITY 0x7F /* LOWER VALUE GRATHER PRIORITY*/
|
||||
|
||||
|
||||
static void audioMainLoop(void *data) {
|
||||
char out_tmp[AUDIO_OUT_BUFFER];
|
||||
ps2_audio_t* ps2 = backup_ps2;
|
||||
|
||||
while (ps2->running) {
|
||||
WaitSema(ps2->lock);
|
||||
size_t size = MIN(fifo_read_avail(ps2->buffer), sizeof(out_tmp));
|
||||
fifo_read(ps2->buffer, out_tmp, size);
|
||||
iSignalSema(ps2->lock);
|
||||
iSignalSema(ps2->cond_lock);
|
||||
|
||||
audsrv_wait_audio(size);
|
||||
audsrv_play_audio(out_tmp, size);
|
||||
}
|
||||
|
||||
audsrv_stop_audio();
|
||||
ExitDeleteThread();
|
||||
}
|
||||
|
||||
|
||||
static void audioCreateThread(ps2_audio_t *ps2) {
|
||||
int ret;
|
||||
ee_thread_t thread;
|
||||
|
||||
thread.func=&audioMainLoop;
|
||||
thread.stack=audioThreadStack;
|
||||
thread.stack_size=sizeof(audioThreadStack);
|
||||
thread.gp_reg=&_gp;
|
||||
thread.initial_priority=AUDIO_PRIORITY;
|
||||
thread.attr=thread.option=0;
|
||||
|
||||
/*Backup the PS2 content to be used in the thread */
|
||||
backup_ps2 = ps2;
|
||||
|
||||
ps2->running = true;
|
||||
ps2->worker_thread = CreateThread(&thread);
|
||||
if (ps2->worker_thread >= 0) {
|
||||
ret = StartThread(ps2->worker_thread, NULL);
|
||||
if (ret < 0) {
|
||||
printf("sound_init: StartThread returned %d\n", ret);
|
||||
}
|
||||
} else {
|
||||
printf("CreateThread failed: %d\n", ps2->worker_thread);
|
||||
}
|
||||
}
|
||||
|
||||
static void audioStopNDeleteThread(ps2_audio_t *ps2) {
|
||||
ps2->running = false;
|
||||
if (ps2->worker_thread) {
|
||||
ps2->worker_thread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void audioConfigure(ps2_audio_t *ps2, unsigned rate) {
|
||||
int err;
|
||||
struct audsrv_fmt_t format;
|
||||
format.bits = AUDIO_BITS;
|
||||
format.freq = rate;
|
||||
format.channels = AUDIO_CHANNELS;
|
||||
|
||||
err = audsrv_set_format(&format);
|
||||
if (err) {
|
||||
printf("set format returned %d\n", err);
|
||||
printf("audsrv returned error string: %s\n", audsrv_get_error_string());
|
||||
}
|
||||
|
||||
audsrv_set_volume(MAX_VOLUME);
|
||||
}
|
||||
|
||||
static void audioCreateSemas(ps2_audio_t *ps2) {
|
||||
ee_sema_t lock_info;
|
||||
lock_info.max_count = 1;
|
||||
lock_info.init_count = 1;
|
||||
lock_info.option = 0;
|
||||
ps2->lock = CreateSema(&lock_info);
|
||||
|
||||
ee_sema_t cond_lock_info;
|
||||
cond_lock_info.init_count = 1;
|
||||
cond_lock_info.max_count = 1;
|
||||
cond_lock_info.option = 0;
|
||||
ps2->cond_lock = CreateSema(&cond_lock_info);
|
||||
}
|
||||
|
||||
static void *ps2_audio_init(const char *device,
|
||||
unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
{
|
||||
ps2_audio_t *ps2 = (ps2_audio_t*)calloc(1, sizeof(ps2_audio_t));
|
||||
|
||||
if (ps2) {
|
||||
ps2->buffer = fifo_new(AUDIO_BUFFER);
|
||||
audioConfigure(ps2, rate);
|
||||
audioCreateSemas(ps2);
|
||||
audioCreateThread(ps2);
|
||||
}
|
||||
|
||||
return ps2;
|
||||
}
|
||||
|
||||
static void ps2_audio_free(void *data) {
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
if(!ps2)
|
||||
return;
|
||||
|
||||
if(ps2->running){
|
||||
audioStopNDeleteThread(ps2);
|
||||
|
||||
if (ps2->lock) {
|
||||
iDeleteSema(ps2->lock);
|
||||
ps2->lock = 0;
|
||||
}
|
||||
|
||||
if (ps2->cond_lock) {
|
||||
iDeleteSema(ps2->cond_lock);
|
||||
ps2->cond_lock = 0;
|
||||
}
|
||||
|
||||
}
|
||||
fifo_free(ps2->buffer);
|
||||
free(ps2);
|
||||
}
|
||||
|
||||
static ssize_t ps2_audio_write(void *data, const void *buf, size_t size) {
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if (!ps2->running)
|
||||
return -1;
|
||||
|
||||
if (ps2->nonblocking) {
|
||||
if (fifo_write_avail(ps2->buffer) < size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (fifo_write_avail(ps2->buffer) < size) {
|
||||
WaitSema(ps2->cond_lock);
|
||||
}
|
||||
|
||||
WaitSema(ps2->lock);
|
||||
fifo_write(ps2->buffer, buf, size);
|
||||
iSignalSema(ps2->lock);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static bool ps2_audio_alive(void *data) {
|
||||
bool alive = false;
|
||||
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
if (ps2) {
|
||||
alive = ps2->running;
|
||||
}
|
||||
|
||||
return alive;
|
||||
}
|
||||
|
||||
static bool ps2_audio_stop(void *data) {
|
||||
bool stop = true;
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if (ps2) {
|
||||
audioStopNDeleteThread(ps2);
|
||||
audsrv_stop_audio();
|
||||
}
|
||||
|
||||
return stop;
|
||||
}
|
||||
|
||||
static bool ps2_audio_start(void *data, bool is_shutdown) {
|
||||
bool start = true;
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if(ps2) {
|
||||
if (!ps2->running && !ps2->worker_thread) {
|
||||
audioCreateThread(ps2);
|
||||
}
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
static void ps2_audio_set_nonblock_state(void *data, bool toggle) {
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
if (ps2) {
|
||||
ps2->nonblocking = toggle;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ps2_audio_use_float(void *data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static size_t ps2_audio_write_avail(void *data) {
|
||||
size_t size = 0;
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if (ps2 && ps2->running) {
|
||||
WaitSema(ps2->lock);
|
||||
size_t size = AUDIO_BUFFER - fifo_read_avail(ps2->buffer);
|
||||
iSignalSema(ps2->lock);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static size_t ps2_audio_buffer_size(void *data) {
|
||||
return AUDIO_BUFFER ;
|
||||
}
|
||||
|
||||
audio_driver_t audio_ps2 = {
|
||||
ps2_audio_init,
|
||||
ps2_audio_write,
|
||||
ps2_audio_stop,
|
||||
ps2_audio_start,
|
||||
ps2_audio_alive,
|
||||
ps2_audio_set_nonblock_state,
|
||||
ps2_audio_free,
|
||||
ps2_audio_use_float,
|
||||
"ps2",
|
||||
NULL,
|
||||
NULL,
|
||||
ps2_audio_write_avail,
|
||||
ps2_audio_buffer_size
|
||||
};
|
@ -20,12 +20,11 @@
|
||||
#include <loadfile.h>
|
||||
#include <unistd.h>
|
||||
#include <sbv_patches.h>
|
||||
#include <fileXio_rpc.h>
|
||||
#include <audsrv.h>
|
||||
#include <sifrpc.h>
|
||||
#include <iopcontrol.h>
|
||||
#include <libpwroff.h>
|
||||
#include <SDL/SDL.h>
|
||||
#include <audsrv.h>
|
||||
|
||||
|
||||
enum BootDeviceIDs{
|
||||
@ -73,6 +72,12 @@ extern unsigned int usbd_irx_size;
|
||||
extern unsigned char usbhdfsd_irx_start[];
|
||||
extern unsigned int usbhdfsd_irx_size;
|
||||
|
||||
extern unsigned char mcman_irx_start[];
|
||||
extern unsigned int mcman_irx_size;
|
||||
|
||||
extern unsigned char mcserv_irx_start[];
|
||||
extern unsigned int mcserv_irx_size;
|
||||
|
||||
static unsigned char HDDModulesLoaded=0;
|
||||
|
||||
char eboot_path[512];
|
||||
@ -306,26 +311,33 @@ static void frontend_ps2_init(void *data)
|
||||
SifInitRpc(0);
|
||||
sbv_patch_enable_lmb();
|
||||
|
||||
// Controllers
|
||||
SifLoadModule("rom0:SIO2MAN", 0, NULL);
|
||||
SifLoadModule("rom0:PADMAN", 0, NULL);
|
||||
|
||||
// I/O Files
|
||||
SifExecModuleBuffer(iomanX_irx_start, iomanX_irx_size, 0, NULL, NULL);
|
||||
SifExecModuleBuffer(fileXio_irx_start, fileXio_irx_size, 0, NULL, NULL);
|
||||
|
||||
// Memory Card
|
||||
SifExecModuleBuffer(mcman_irx_start, mcman_irx_size, 0, NULL, NULL);
|
||||
SifExecModuleBuffer(mcserv_irx_start, mcserv_irx_size, 0, NULL, NULL);
|
||||
|
||||
SifLoadModule("rom0:SIO2MAN", 0, NULL);
|
||||
SifLoadModule("rom0:MCMAN", 0, NULL);
|
||||
SifLoadModule("rom0:MCSERV", 0, NULL);
|
||||
SifLoadModule("rom0:PADMAN", 0, NULL);
|
||||
|
||||
// USB
|
||||
SifExecModuleBuffer(usbd_irx_start, usbd_irx_size, 0, NULL, NULL);
|
||||
SifExecModuleBuffer(usbhdfsd_irx_start, usbhdfsd_irx_size, 0, NULL, NULL);
|
||||
|
||||
// Audio
|
||||
SifExecModuleBuffer(freesd_irx_start, freesd_irx_size, 0, NULL, NULL);
|
||||
SifExecModuleBuffer(audsrv_irx_start, audsrv_irx_size, 0, NULL, NULL);
|
||||
|
||||
fileXioInit();
|
||||
audsrv_init();
|
||||
|
||||
SDL_Init(SDL_INIT_TIMER);
|
||||
|
||||
//Initializes audsrv library
|
||||
if(audsrv_init()) {
|
||||
RARCH_ERR("audsrv library not initalizated\n");
|
||||
}
|
||||
|
||||
retro_sleep(100);
|
||||
|
||||
#if defined(HAVE_FILE_LOGGER)
|
||||
retro_main_log_file_init("retroarch.log");
|
||||
|
@ -25,6 +25,9 @@
|
||||
#define GS_TEXT GS_SETREG_RGBAQ(0x80,0x80,0x80,0x80,0x00) // turn white GS Screen
|
||||
#define GS_BLACK GS_SETREG_RGBAQ(0x00,0x00,0x00,0x00,0x00) // turn white GS Screen
|
||||
|
||||
#define NTSC_WIDTH 640
|
||||
#define NTSC_HEIGHT 448
|
||||
|
||||
typedef struct ps2_video
|
||||
{
|
||||
GSGLOBAL *gsGlobal;
|
||||
@ -44,11 +47,17 @@ typedef struct ps2_video
|
||||
static GSGLOBAL *init_GSGlobal(void) {
|
||||
GSGLOBAL *gsGlobal = gsKit_init_global();
|
||||
|
||||
gsGlobal->PSM = GS_PSM_CT16;
|
||||
gsGlobal->Mode = GS_MODE_NTSC;
|
||||
gsGlobal->Interlace = GS_INTERLACED;
|
||||
gsGlobal->Field = GS_FIELD;
|
||||
gsGlobal->Width = NTSC_WIDTH;
|
||||
gsGlobal->Height = NTSC_HEIGHT;
|
||||
|
||||
gsGlobal->PSM = GS_PSM_CT16;
|
||||
gsGlobal->PSMZ = GS_PSMZ_16;
|
||||
gsGlobal->DoubleBuffering = GS_SETTING_OFF;
|
||||
gsGlobal->ZBuffering = GS_SETTING_OFF;
|
||||
gsGlobal->PrimAlphaEnable = GS_SETTING_OFF;
|
||||
gsGlobal->PrimAlphaEnable = GS_SETTING_OFF;
|
||||
|
||||
dmaKit_init(D_CTRL_RELE_OFF,D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC,
|
||||
D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF);
|
||||
|
@ -773,7 +773,7 @@ AUDIO
|
||||
#elif defined(PSP) || defined(VITA)
|
||||
#include "../audio/drivers/psp_audio.c"
|
||||
#elif defined(PS2)
|
||||
// #include "../audio/drivers/ps2_audio.c"
|
||||
#include "../audio/drivers/ps2_audio.c"
|
||||
#elif defined(_3DS)
|
||||
#include "../audio/drivers/ctr_csnd_audio.c"
|
||||
#include "../audio/drivers/ctr_dsp_audio.c"
|
||||
|
@ -294,7 +294,7 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, uns
|
||||
*/
|
||||
/* TODO: this is only useful for a few platforms, find which and add ifdef */
|
||||
stream->fp = fp;
|
||||
#if !defined(PS2)
|
||||
#if !defined(PS2) // TODO: PS2 IMPROVEMENT
|
||||
stream->buf = (char*)calloc(1, 0x4000);
|
||||
setvbuf(stream->fp, stream->buf, _IOFBF, 0x4000);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user