diff --git a/build/vs2010/Lol.Core.Vars.props b/build/vs2010/Lol.Core.Vars.props index 9e655b35..d3426f28 100644 --- a/build/vs2010/Lol.Core.Vars.props +++ b/build/vs2010/Lol.Core.Vars.props @@ -80,7 +80,8 @@ libsysmodule_stub.a;libsysutil_stub.a;libresc_stub.a; libpngdec_stub.a; - libio_stub.a;libusbd_stub.a;libpadfilter.a + libio_stub.a;libusbd_stub.a;libpadfilter.a; + libaudio_stub.a;libspurs_stub.a;libmstreamSPURSMP3.a $(XboxDefines) diff --git a/configure.ac b/configure.ac index 215ca73b..db9ac96e 100644 --- a/configure.ac +++ b/configure.ac @@ -226,6 +226,8 @@ AC_CHECK_LIB(sysmodule_stub, cellSysmoduleLoadModule, LOL_LIBS="${LOL_LIBS} -lpngdec_stub" dnl For the pad library LOL_LIBS="${LOL_LIBS} -lio_stub -lusbd_stub -lpadfilter" + dnl For the audio library + LOL_LIBS="${LOL_LIBS} -laudio_stub -lspurs_stub -lmstreamSPURSMP3" dnl Disable this warning, it's too verbose with vector.h AM_CXXFLAGS="${AM_CXXFLAGS} -Wno-sign-compare" AC_PATH_PROG(MAKE_FSELF, make_fself, no) diff --git a/src/platform/ps3/ps3app.cpp b/src/platform/ps3/ps3app.cpp index 1f281f88..1e40a820 100644 --- a/src/platform/ps3/ps3app.cpp +++ b/src/platform/ps3/ps3app.cpp @@ -18,6 +18,12 @@ # include /* SYS_HOST_ROOT */ # include # include + +# include /* multistream */ + +# include /* SPURS */ +# include +# include #endif #include "core.h" @@ -32,6 +38,9 @@ namespace lol * PS3 App implementation class */ +/* FIXME: this shouldn't be a global */ +static unsigned int port_num; + class Ps3AppData { friend class Ps3App; @@ -43,6 +52,27 @@ private: if (status == CELL_SYSUTIL_REQUEST_EXITGAME) Ticker::Shutdown(); } + + static void MultiStreamThread(uint64_t param) + { + Timer t; + cellAudioPortStart(port_num); + /* FIXME: quit gracefully if needed */ + while (true) + { + if (!cellMSSystemSignalSPU()) + { + t.Get(); + t.Wait(1.f / 60.f / 32); + } + + cellMSSystemGenerateCallbacks(); + } + cellAudioPortStop(port_num); + sys_ppu_thread_exit(0); + } + + CellSpurs m_spurs __attribute__((aligned (128))); #endif }; @@ -133,6 +163,75 @@ Ps3App::Ps3App(char const *title, ivec2 res, float fps) : //psglLoadShaderLibrary("/shaders.bin"); psglResetCurrentContext(); + /* Create audio device */ + cellSysmoduleLoadModule(CELL_SYSMODULE_IO); + cellSysmoduleLoadModule(CELL_SYSMODULE_AUDIO); + cellSysmoduleLoadModule(CELL_SYSMODULE_RESC); + cellSysmoduleLoadModule(CELL_SYSMODULE_SPURS); + + int ret = cellMSSystemConfigureSysUtilEx(CELL_MS_AUDIOMODESELECT_SUPPORTSLPCM + | CELL_MS_AUDIOMODESELECT_SUPPORTSDOLBY + | CELL_MS_AUDIOMODESELECT_SUPPORTSDTS + | CELL_MS_AUDIOMODESELECT_PREFERDOLBY); + int num_chans = ret & 0xf; + int has_dolby = (ret & 0x10) >> 4; + int has_dts = (ret & 0x20) >> 5; + + Log::Debug("audio channels %d, dolby %d, DTS %d\n", + num_chans, has_dolby, has_dts); + ret = cellAudioInit(); + + CellAudioPortParam ap; + memset(&ap, 0, sizeof(ap)); + ap.nChannel = CELL_AUDIO_PORT_8CH; + ap.nBlock = CELL_AUDIO_BLOCK_8; + ret = cellAudioPortOpen(&ap, &port_num); + Log::Debug("audio port %d\n", port_num); + + CellAudioPortConfig pc; + ret = cellAudioGetPortConfig(port_num, &pc); + + cellMSSystemConfigureLibAudio(&ap, &pc); + + CellMSSystemConfig cfg; + cfg.channelCount = 400; /* Maximum number of streams */ + cfg.subCount = 31; /* ? */ + cfg.dspPageCount = 5; + cfg.flags = CELL_MS_NOFLAGS; + + uint8_t const prios[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; + int mem_needed = cellMSSystemGetNeededMemorySize(&cfg); + void *ms_mem = memalign(128, mem_needed); + sys_ppu_thread_t tid; + sys_ppu_thread_get_id(&tid); + int tprio; + sys_ppu_thread_get_priority(tid, &tprio); + cellSpursInitialize(&data->m_spurs, 1, 250 /* thread group priority */, + tprio - 1, false); + cellMSSystemInitSPURS(ms_mem, &cfg, &data->m_spurs, &prios[0]); + + float const bus_vols[64] = + { + 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, + }; + + sys_ppu_thread_t thread; + ret = sys_ppu_thread_create(&thread, Ps3AppData::MultiStreamThread, + NULL, 0 /* Server prio */, + 0x4000 /* 16 KiB stack */, + SYS_PPU_THREAD_CREATE_JOINABLE, + "Audio Thread"); + + cellMSCoreSetVolume64(CELL_MS_SUBBUS_1, CELL_MS_DRY, bus_vols); + cellMSCoreSetVolume64(CELL_MS_MASTER_BUS, CELL_MS_DRY, bus_vols); + /* Initialise everything */ Ticker::Setup(fps); Video::Setup(newres); @@ -165,6 +264,12 @@ Ps3App::~Ps3App() { #if defined __CELLOS_LV2__ glFinish(); + + /* Unload audio modules */ + cellSysmoduleUnloadModule(CELL_SYSMODULE_IO); + cellSysmoduleUnloadModule(CELL_SYSMODULE_AUDIO); + cellSysmoduleUnloadModule(CELL_SYSMODULE_RESC); + cellSysmoduleUnloadModule(CELL_SYSMODULE_SPURS); #endif delete data; }