mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-08 07:51:28 +12:00
First step to help refactor Module management. Add every module in the static ModuleInfo list. Module without id are assigned to 0xffff. The init function is called after constructor and take a pointer to Module as an input. This pointer is used to set the Module's global pointer in its file.
1212 lines
29 KiB
C++
1212 lines
29 KiB
C++
#include "stdafx.h"
|
|
#include "Emu/Memory/Memory.h"
|
|
#include "Emu/System.h"
|
|
#include "Emu/SysCalls/Modules.h"
|
|
#include "Emu/SysCalls/Callback.h"
|
|
|
|
#include "Emu/CPU/CPUThreadManager.h"
|
|
#include "Emu/Audio/cellAudio.h"
|
|
#include "libmixer.h"
|
|
|
|
Module *libmixer = nullptr;
|
|
|
|
CellSurMixerConfig surMixer;
|
|
|
|
#define SUR_PORT (7)
|
|
vm::ptr<CellSurMixerNotifyCallbackFunction> surMixerCb;
|
|
vm::ptr<void> surMixerCbArg;
|
|
std::mutex mixer_mutex;
|
|
float mixdata[8*256];
|
|
u64 mixcount;
|
|
|
|
std::vector<SSPlayer> ssp;
|
|
|
|
int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr<float> addr, u32 samples)
|
|
{
|
|
libmixer->Log("cellAANAddData(handle=%d, port=%d, offset=0x%x, addr=0x%x, samples=%d)",
|
|
aan_handle, aan_port, offset, addr.addr(), samples);
|
|
|
|
u32 type = aan_port >> 16;
|
|
u32 port = aan_port & 0xffff;
|
|
|
|
switch (type)
|
|
{
|
|
case CELL_SURMIXER_CHSTRIP_TYPE1A:
|
|
if (port >= surMixer.chStrips1) type = 0; break;
|
|
case CELL_SURMIXER_CHSTRIP_TYPE2A:
|
|
if (port >= surMixer.chStrips2) type = 0; break;
|
|
case CELL_SURMIXER_CHSTRIP_TYPE6A:
|
|
if (port >= surMixer.chStrips6) type = 0; break;
|
|
case CELL_SURMIXER_CHSTRIP_TYPE8A:
|
|
if (port >= surMixer.chStrips8) type = 0; break;
|
|
default:
|
|
type = 0; break;
|
|
}
|
|
|
|
if (aan_handle != 0x11111111 || samples != 256 || !type || offset != 0)
|
|
{
|
|
libmixer->Error("cellAANAddData(handle=%d, port=%d, offset=0x%x, addr=0x%x, samples=%d): invalid parameters",
|
|
aan_handle, aan_port, offset, addr, samples);
|
|
return CELL_LIBMIXER_ERROR_INVALID_PARAMATER;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
if (type == CELL_SURMIXER_CHSTRIP_TYPE1A)
|
|
{
|
|
// mono upmixing
|
|
for (u32 i = 0; i < samples; i++)
|
|
{
|
|
const float center = addr[i];
|
|
mixdata[i * 8 + 0] += center;
|
|
mixdata[i * 8 + 1] += center;
|
|
}
|
|
}
|
|
else if (type == CELL_SURMIXER_CHSTRIP_TYPE2A)
|
|
{
|
|
// stereo upmixing
|
|
for (u32 i = 0; i < samples; i++)
|
|
{
|
|
const float left = addr[i * 2 + 0];
|
|
const float right = addr[i * 2 + 1];
|
|
mixdata[i * 8 + 0] += left;
|
|
mixdata[i * 8 + 1] += right;
|
|
}
|
|
}
|
|
else if (type == CELL_SURMIXER_CHSTRIP_TYPE6A)
|
|
{
|
|
// 5.1 upmixing
|
|
for (u32 i = 0; i < samples; i++)
|
|
{
|
|
const float left = addr[i * 6 + 0];
|
|
const float right = addr[i * 6 + 1];
|
|
const float center = addr[i * 6 + 2];
|
|
const float low_freq = addr[i * 6 + 3];
|
|
const float rear_left = addr[i * 6 + 4];
|
|
const float rear_right = addr[i * 6 + 5];
|
|
mixdata[i * 8 + 0] += left;
|
|
mixdata[i * 8 + 1] += right;
|
|
mixdata[i * 8 + 2] += center;
|
|
mixdata[i * 8 + 3] += low_freq;
|
|
mixdata[i * 8 + 4] += rear_left;
|
|
mixdata[i * 8 + 5] += rear_right;
|
|
}
|
|
}
|
|
else if (type == CELL_SURMIXER_CHSTRIP_TYPE8A)
|
|
{
|
|
// 7.1
|
|
for (u32 i = 0; i < samples * 8; i++)
|
|
{
|
|
mixdata[i] += addr[i];
|
|
}
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo)
|
|
{
|
|
libmixer->Warning("cellAANConnect(receive=%d, receivePortNo=%d, source=%d, sourcePortNo=%d)",
|
|
receive, receivePortNo, source, sourcePortNo);
|
|
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
if (source >= ssp.size() || !ssp[source].m_created)
|
|
{
|
|
libmixer->Error("cellAANConnect(): invalid source (%d)", source);
|
|
return CELL_LIBMIXER_ERROR_INVALID_PARAMATER;
|
|
}
|
|
|
|
ssp[source].m_connected = true;
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo)
|
|
{
|
|
libmixer->Warning("cellAANDisconnect(receive=%d, receivePortNo=%d, source=%d, sourcePortNo=%d)",
|
|
receive, receivePortNo, source, sourcePortNo);
|
|
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
if (source >= ssp.size() || !ssp[source].m_created)
|
|
{
|
|
libmixer->Error("cellAANDisconnect(): invalid source (%d)", source);
|
|
return CELL_LIBMIXER_ERROR_INVALID_PARAMATER;
|
|
}
|
|
|
|
ssp[source].m_connected = false;
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSSPlayerCreate(vm::ptr<be_t<u32>> handle, vm::ptr<CellSSPlayerConfig> config)
|
|
{
|
|
libmixer->Warning("cellSSPlayerCreate(handle_addr=0x%x, config_addr=0x%x)",
|
|
handle.addr(), config.addr());
|
|
|
|
if (config->outputMode != 0 || config->channels - 1 >= 2)
|
|
{
|
|
libmixer->Error("cellSSPlayerCreate(config.outputMode=%d, config.channels=%d): invalid parameters",
|
|
(u32)config->outputMode, (u32)config->channels);
|
|
return CELL_LIBMIXER_ERROR_INVALID_PARAMATER;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
SSPlayer p;
|
|
p.m_created = true;
|
|
p.m_connected = false;
|
|
p.m_active = false;
|
|
p.m_channels = config->channels;
|
|
|
|
ssp.push_back(p);
|
|
*handle = (u32)ssp.size() - 1;
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSSPlayerRemove(u32 handle)
|
|
{
|
|
libmixer->Warning("cellSSPlayerRemove(handle=%d)", handle);
|
|
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
if (handle >= ssp.size() || !ssp[handle].m_created)
|
|
{
|
|
libmixer->Error("cellSSPlayerRemove(): SSPlayer not found (%d)", handle);
|
|
return CELL_LIBMIXER_ERROR_INVALID_PARAMATER;
|
|
}
|
|
|
|
ssp[handle].m_active = false;
|
|
ssp[handle].m_created = false;
|
|
ssp[handle].m_connected = false;
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSSPlayerSetWave(u32 handle, vm::ptr<CellSSPlayerWaveParam> waveInfo, vm::ptr<CellSSPlayerCommonParam> commonInfo)
|
|
{
|
|
libmixer->Warning("cellSSPlayerSetWave(handle=%d, waveInfo_addr=0x%x, commonInfo_addr=0x%x)",
|
|
handle, waveInfo.addr(), commonInfo.addr());
|
|
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
if (handle >= ssp.size() || !ssp[handle].m_created)
|
|
{
|
|
libmixer->Error("cellSSPlayerSetWave(): SSPlayer not found (%d)", handle);
|
|
return CELL_LIBMIXER_ERROR_INVALID_PARAMATER;
|
|
}
|
|
|
|
// TODO: check parameters
|
|
|
|
ssp[handle].m_addr = waveInfo->addr;
|
|
ssp[handle].m_samples = waveInfo->samples;
|
|
ssp[handle].m_loop_start = waveInfo->loopStartOffset - 1;
|
|
ssp[handle].m_loop_mode = commonInfo ? (u32)commonInfo->loopMode : CELL_SSPLAYER_ONESHOT;
|
|
ssp[handle].m_position = waveInfo->startOffset - 1;
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSSPlayerPlay(u32 handle, vm::ptr<CellSSPlayerRuntimeInfo> info)
|
|
{
|
|
libmixer->Warning("cellSSPlayerPlay(handle=%d, info_addr=0x%x)", handle, info.addr());
|
|
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
if (handle >= ssp.size() || !ssp[handle].m_created)
|
|
{
|
|
libmixer->Error("cellSSPlayerPlay(): SSPlayer not found (%d)", handle);
|
|
return CELL_LIBMIXER_ERROR_INVALID_PARAMATER;
|
|
}
|
|
|
|
// TODO: check parameters
|
|
|
|
ssp[handle].m_active = true;
|
|
ssp[handle].m_level = info->level;
|
|
ssp[handle].m_speed = info->speed;
|
|
ssp[handle].m_x = info->position.x;
|
|
ssp[handle].m_y = info->position.y;
|
|
ssp[handle].m_z = info->position.z;
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSSPlayerStop(u32 handle, u32 mode)
|
|
{
|
|
libmixer->Warning("cellSSPlayerStop(handle=%d, mode=0x%x)", handle, mode);
|
|
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
if (handle >= ssp.size() || !ssp[handle].m_created)
|
|
{
|
|
libmixer->Error("cellSSPlayerStop(): SSPlayer not found (%d)", handle);
|
|
return CELL_LIBMIXER_ERROR_INVALID_PARAMATER;
|
|
}
|
|
|
|
// TODO: transition to stop state
|
|
|
|
ssp[handle].m_active = false;
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSSPlayerSetParam(u32 handle, vm::ptr<CellSSPlayerRuntimeInfo> info)
|
|
{
|
|
libmixer->Warning("cellSSPlayerSetParam(handle=%d, info_addr=0x%x)", handle, info.addr());
|
|
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
if (handle >= ssp.size() || !ssp[handle].m_created)
|
|
{
|
|
libmixer->Error("cellSSPlayerSetParam(): SSPlayer not found (%d)", handle);
|
|
return CELL_LIBMIXER_ERROR_INVALID_PARAMATER;
|
|
}
|
|
|
|
// TODO: check parameters
|
|
|
|
ssp[handle].m_level = info->level;
|
|
ssp[handle].m_speed = info->speed;
|
|
ssp[handle].m_x = info->position.x;
|
|
ssp[handle].m_y = info->position.y;
|
|
ssp[handle].m_z = info->position.z;
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSSPlayerGetState(u32 handle)
|
|
{
|
|
libmixer->Warning("cellSSPlayerGetState(handle=%d)", handle);
|
|
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
if (handle >= ssp.size() || !ssp[handle].m_created)
|
|
{
|
|
libmixer->Warning("cellSSPlayerGetState(): SSPlayer not found (%d)", handle);
|
|
return CELL_SSPLAYER_STATE_ERROR;
|
|
}
|
|
|
|
if (ssp[handle].m_active)
|
|
{
|
|
return CELL_SSPLAYER_STATE_ON;
|
|
}
|
|
|
|
return CELL_SSPLAYER_STATE_OFF;
|
|
}
|
|
|
|
int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
|
|
{
|
|
libmixer->Warning("cellSurMixerCreate(config_addr=0x%x)", config.addr());
|
|
|
|
surMixer = *config;
|
|
|
|
AudioPortConfig& port = m_config.m_ports[SUR_PORT];
|
|
|
|
if (port.m_is_audio_port_opened)
|
|
{
|
|
return CELL_LIBMIXER_ERROR_FULL;
|
|
}
|
|
|
|
port.channel = 8;
|
|
port.block = 16;
|
|
port.attr = 0;
|
|
port.level = 1.0f;
|
|
|
|
libmixer->Warning("*** audio port opened(default)");
|
|
|
|
port.m_is_audio_port_opened = true;
|
|
port.tag = 0;
|
|
m_config.m_port_in_use++;
|
|
|
|
libmixer->Warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)",
|
|
(u32)surMixer.chStrips1, (u32)surMixer.chStrips2, (u32)surMixer.chStrips6, (u32)surMixer.chStrips8);
|
|
|
|
mixcount = 0;
|
|
surMixerCb.set(0);
|
|
|
|
thread t("Surmixer Thread", []()
|
|
{
|
|
AudioPortConfig& port = m_config.m_ports[SUR_PORT];
|
|
|
|
PPUThread& cb_thread = *(PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
|
cb_thread.SetName("Surmixer Callback Thread");
|
|
cb_thread.SetEntry(0);
|
|
cb_thread.SetPrio(1001);
|
|
cb_thread.SetStackSize(0x10000);
|
|
cb_thread.InitStack();
|
|
cb_thread.InitRegs();
|
|
cb_thread.DoRun();
|
|
|
|
while (port.m_is_audio_port_opened)
|
|
{
|
|
if (Emu.IsStopped())
|
|
{
|
|
libmixer->Warning("Surmixer aborted");
|
|
break;
|
|
}
|
|
|
|
if (mixcount > (port.tag + 0)) // adding positive value (1-15): preemptive buffer filling (hack)
|
|
{
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
continue;
|
|
}
|
|
|
|
if (port.m_is_audio_port_started)
|
|
{
|
|
//u64 stamp0 = get_system_time();
|
|
|
|
memset(mixdata, 0, sizeof(mixdata));
|
|
if (surMixerCb)
|
|
{
|
|
surMixerCb.call(cb_thread, surMixerCbArg, mixcount, 256);
|
|
}
|
|
|
|
//u64 stamp1 = get_system_time();
|
|
|
|
{
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
for (auto& p : ssp) if (p.m_active && p.m_created)
|
|
{
|
|
auto v = vm::lptrl<s16>::make(p.m_addr); // 16-bit LE audio data
|
|
float left = 0.0f;
|
|
float right = 0.0f;
|
|
float speed = fabs(p.m_speed);
|
|
float fpos = 0.0f;
|
|
for (int i = 0; i < 256; i++) if (p.m_active)
|
|
{
|
|
u32 pos = p.m_position;
|
|
int pos_inc = 0;
|
|
if (p.m_speed > 0.0f) // select direction
|
|
{
|
|
pos_inc = 1;
|
|
}
|
|
else if (p.m_speed < 0.0f)
|
|
{
|
|
pos_inc = -1;
|
|
}
|
|
int shift = i - (int)fpos; // change playback speed (simple and rough)
|
|
if (shift > 0)
|
|
{
|
|
// slow playback
|
|
pos_inc = 0; // duplicate one sample at this time
|
|
fpos += 1.0f;
|
|
fpos += speed;
|
|
}
|
|
else if (shift < 0)
|
|
{
|
|
// fast playback
|
|
i--; // mix two sample into one at this time
|
|
fpos -= 1.0f;
|
|
}
|
|
else
|
|
{
|
|
fpos += speed;
|
|
}
|
|
p.m_position += (u32)pos_inc;
|
|
if (p.m_channels == 1) // get mono data
|
|
{
|
|
left = right = (float)v[pos] / 0x8000 * p.m_level;
|
|
}
|
|
else if (p.m_channels == 2) // get stereo data
|
|
{
|
|
left = (float)v[pos * 2 + 0] / 0x8000 * p.m_level;
|
|
right = (float)v[pos * 2 + 1] / 0x8000 * p.m_level;
|
|
}
|
|
if (p.m_connected) // mix
|
|
{
|
|
// TODO: m_x, m_y, m_z ignored
|
|
mixdata[i * 8 + 0] += left;
|
|
mixdata[i * 8 + 1] += right;
|
|
}
|
|
if ((p.m_position == p.m_samples && p.m_speed > 0.0f) ||
|
|
(p.m_position == ~0 && p.m_speed < 0.0f)) // loop or stop
|
|
{
|
|
if (p.m_loop_mode == CELL_SSPLAYER_LOOP_ON)
|
|
{
|
|
p.m_position = p.m_loop_start;
|
|
}
|
|
else if (p.m_loop_mode == CELL_SSPLAYER_ONESHOT_CONT)
|
|
{
|
|
p.m_position -= (u32)pos_inc; // restore position
|
|
}
|
|
else // oneshot
|
|
{
|
|
p.m_active = false;
|
|
p.m_position = p.m_loop_start; // TODO: check value
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//u64 stamp2 = get_system_time();
|
|
|
|
auto buf = vm::get_ptr<be_t<float>>(m_config.m_buffer + (128 * 1024 * SUR_PORT) + (mixcount % port.block) * port.channel * 256 * sizeof(float));
|
|
|
|
for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i++)
|
|
{
|
|
// reverse byte order
|
|
buf[i] = mixdata[i];
|
|
}
|
|
|
|
//u64 stamp3 = get_system_time();
|
|
|
|
//ConLog.Write("Libmixer perf: start=%lld (cb=%lld, ssp=%lld, finalize=%lld)", stamp0 - m_config.start_time, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2);
|
|
}
|
|
|
|
mixcount++;
|
|
}
|
|
|
|
{
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
ssp.clear();
|
|
}
|
|
|
|
Emu.GetCPU().RemoveThread(cb_thread.GetId());
|
|
surMixerCb.set(0);
|
|
});
|
|
t.detach();
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerGetAANHandle(vm::ptr<be_t<u32>> handle)
|
|
{
|
|
libmixer->Warning("cellSurMixerGetAANHandle(handle_addr=0x%x) -> %d", handle.addr(), 0x11111111);
|
|
*handle = 0x11111111;
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerChStripGetAANPortNo(vm::ptr<be_t<u32>> port, u32 type, u32 index)
|
|
{
|
|
libmixer->Warning("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x) -> 0x%x", port.addr(), type, index, (type << 16) | index);
|
|
*port = (type << 16) | index;
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerSetNotifyCallback(vm::ptr<CellSurMixerNotifyCallbackFunction> func, vm::ptr<void> arg)
|
|
{
|
|
libmixer->Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func.addr(), arg.addr());
|
|
|
|
if (surMixerCb)
|
|
{
|
|
libmixer->Error("cellSurMixerSetNotifyCallback: surMixerCb already set (addr=0x%x)", surMixerCb.addr());
|
|
}
|
|
surMixerCb = func;
|
|
surMixerCbArg = arg;
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerRemoveNotifyCallback(vm::ptr<CellSurMixerNotifyCallbackFunction> func)
|
|
{
|
|
libmixer->Warning("cellSurMixerRemoveNotifyCallback(func_addr=0x%x)", func.addr());
|
|
|
|
if (surMixerCb.addr() != func.addr())
|
|
{
|
|
libmixer->Error("cellSurMixerRemoveNotifyCallback: surMixerCb had different value (addr=0x%x)", surMixerCb.addr());
|
|
}
|
|
else
|
|
{
|
|
surMixerCb.set(0);
|
|
}
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerStart()
|
|
{
|
|
libmixer->Warning("cellSurMixerStart()");
|
|
|
|
AudioPortConfig& port = m_config.m_ports[SUR_PORT];
|
|
|
|
if (port.m_is_audio_port_opened)
|
|
{
|
|
port.m_is_audio_port_started = true;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerSetParameter(u32 param, float value)
|
|
{
|
|
declCPU();
|
|
libmixer->Todo("cellSurMixerSetParameter(param=0x%x, value=%f, FPR[1]=%f, FPR[2]=%f)", param, value, (float&)CPU.FPR[1], (float&)CPU.FPR[2]);
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerFinalize()
|
|
{
|
|
libmixer->Warning("cellSurMixerFinalize()");
|
|
|
|
AudioPortConfig& port = m_config.m_ports[SUR_PORT];
|
|
|
|
if (port.m_is_audio_port_opened)
|
|
{
|
|
port.m_is_audio_port_started = false;
|
|
port.m_is_audio_port_opened = false;
|
|
m_config.m_port_in_use--;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerSurBusAddData(u32 busNo, u32 offset, u32 addr, u32 samples)
|
|
{
|
|
if (busNo < 8 && samples == 256 && offset == 0)
|
|
{
|
|
libmixer->Log("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples);
|
|
}
|
|
else
|
|
{
|
|
libmixer->Todo("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples);
|
|
return CELL_OK;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
|
|
|
for (u32 i = 0; i < samples; i++)
|
|
{
|
|
// reverse byte order and mix
|
|
u32 v = vm::read32(addr + i * sizeof(float));
|
|
mixdata[i*8+busNo] += (float&)v;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerChStripSetParameter(u32 type, u32 index, vm::ptr<CellSurMixerChStripParam> param)
|
|
{
|
|
libmixer->Todo("cellSurMixerChStripSetParameter(type=%d, index=%d, param_addr=0x%x)", type, index, param.addr());
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerPause(u32 type)
|
|
{
|
|
libmixer->Warning("cellSurMixerPause(type=%d)", type);
|
|
|
|
AudioPortConfig& port = m_config.m_ports[SUR_PORT];
|
|
|
|
if (port.m_is_audio_port_opened)
|
|
{
|
|
port.m_is_audio_port_started = false;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerGetCurrentBlockTag(vm::ptr<be_t<u64>> tag)
|
|
{
|
|
libmixer->Log("cellSurMixerGetCurrentBlockTag(tag_addr=0x%x)", tag.addr());
|
|
|
|
*tag = mixcount;
|
|
return CELL_OK;
|
|
}
|
|
|
|
int cellSurMixerGetTimestamp(u64 tag, vm::ptr<be_t<u64>> stamp)
|
|
{
|
|
libmixer->Log("cellSurMixerGetTimestamp(tag=0x%llx, stamp_addr=0x%x)", tag, stamp.addr());
|
|
|
|
*stamp = m_config.start_time + (tag) * 256000000 / 48000; // ???
|
|
return CELL_OK;
|
|
}
|
|
|
|
void cellSurMixerBeep(u32 arg)
|
|
{
|
|
libmixer->Todo("cellSurMixerBeep(arg=%d)", arg);
|
|
return;
|
|
}
|
|
|
|
void cellSurMixerUtilGetLevelFromDB(float dB)
|
|
{
|
|
// not hooked, probably unnecessary
|
|
libmixer->Todo("cellSurMixerUtilGetLevelFromDB(dB=%f)", dB);
|
|
declCPU();
|
|
(float&)CPU.FPR[0] = 0.0f;
|
|
}
|
|
|
|
void cellSurMixerUtilGetLevelFromDBIndex(int index)
|
|
{
|
|
// not hooked, probably unnecessary
|
|
libmixer->Todo("cellSurMixerUtilGetLevelFromDBIndex(index=%d)", index);
|
|
declCPU();
|
|
(float&)CPU.FPR[0] = 0.0f;
|
|
}
|
|
|
|
void cellSurMixerUtilNoteToRatio(u8 refNote, u8 note)
|
|
{
|
|
// not hooked, probably unnecessary
|
|
libmixer->Todo("cellSurMixerUtilNoteToRatio(refNote=%d, note=%d)", refNote, note);
|
|
declCPU();
|
|
(float&)CPU.FPR[0] = 0.0f;
|
|
}
|
|
|
|
void libmixer_init(Module *pxThis)
|
|
{
|
|
libmixer = pxThis;
|
|
|
|
REG_SUB(libmixer, "surmxAAN", cellAANAddData,
|
|
0xffffffff7c691b78,
|
|
0xffffffff7c0802a6,
|
|
0xfffffffff821ff91,
|
|
0xfffffffff8010080,
|
|
0xffffffff7c802378,
|
|
0xffffffff7caa2b78,
|
|
0xffffffff81690000,
|
|
0xffffffff7c050378,
|
|
0xffffffff7cc43378,
|
|
0x78630020, // clrldi r3,r3,32
|
|
0xffffffff7d465378,
|
|
0xffffffff812b0030,
|
|
0xffffffff80090000,
|
|
0xfffffffff8410028,
|
|
0xffffffff7c0903a6,
|
|
0xffffffff80490004,
|
|
0xffffffff4e800421,
|
|
0xffffffffe8410028,
|
|
0xffffffffe8010080,
|
|
0xffffffff7c6307b4,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff38210070,
|
|
0xffffffff4e800020
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmxAAN", cellAANConnect,
|
|
0xfffffffff821ff71,
|
|
0xffffffff7c0802a6,
|
|
0xffffffff2f830000,
|
|
0xfffffffff80100a0,
|
|
0xffffffff3c008031,
|
|
0xffffffff7c691b78,
|
|
0xffffffff7c8a2378,
|
|
0xffffffff60000003,
|
|
0xffffff00409e0018, // bne
|
|
0xffffffff7c0307b4,
|
|
0xffffffffe80100a0,
|
|
0xffffffff38210090,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff4e800020,
|
|
0xffffffff2f850000,
|
|
0xffffffff78630020,
|
|
0xffffffff38810070,
|
|
0xffffff00419effe0, // beq
|
|
0xffffffff81690000,
|
|
0xffffffff38000001,
|
|
0xffffffff91210074,
|
|
0xffffffff90a10070,
|
|
0xffffffff90c10078,
|
|
0xffffffff9141007c,
|
|
0xffffffff812b0018, // difference
|
|
0xffffffff90010080,
|
|
0xffffffff80090000,
|
|
0xfffffffff8410028,
|
|
0xffffffff7c0903a6,
|
|
0xffffffff80490004,
|
|
0xffffffff4e800421,
|
|
0xffffffffe8410028,
|
|
0xffffffff7c601b78,
|
|
0xffffffff7c0307b4,
|
|
0xffffffffe80100a0,
|
|
0xffffffff38210090,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff4e800020
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmxAAN", cellAANDisconnect,
|
|
0xfffffffff821ff71,
|
|
0xffffffff7c0802a6,
|
|
0xffffffff2f830000,
|
|
0xfffffffff80100a0,
|
|
0xffffffff3c008031,
|
|
0xffffffff7c691b78,
|
|
0xffffffff7c8a2378,
|
|
0xffffffff60000003,
|
|
0xffffff00409e0018, // bne
|
|
0xffffffff7c0307b4,
|
|
0xffffffffe80100a0,
|
|
0xffffffff38210090,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff4e800020,
|
|
0xffffffff2f850000,
|
|
0xffffffff78630020,
|
|
0xffffffff38810070,
|
|
0xffffff00419effe0, // beq
|
|
0xffffffff81690000,
|
|
0xffffffff38000001,
|
|
0xffffffff91210074,
|
|
0xffffffff90a10070,
|
|
0xffffffff90c10078,
|
|
0xffffffff9141007c,
|
|
0xffffffff812b001c, // difference
|
|
0xffffffff90010080,
|
|
0xffffffff80090000,
|
|
0xfffffffff8410028,
|
|
0xffffffff7c0903a6,
|
|
0xffffffff80490004,
|
|
0xffffffff4e800421,
|
|
0xffffffffe8410028,
|
|
0xffffffff7c601b78,
|
|
0xffffffff7c0307b4,
|
|
0xffffffffe80100a0,
|
|
0xffffffff38210090,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff4e800020
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerCreate,
|
|
0xffffffff2f830000,
|
|
0xffffffff7c0802a6,
|
|
0xfffffffff821ff51,
|
|
0xfffffffffbc100a0,
|
|
0xfffffffffb210078,
|
|
0xfffffffffb410080,
|
|
0xfffffffffb610088,
|
|
0xfffffffffb810090,
|
|
0xfffffffffba10098,
|
|
0xfffffffffbe100a8,
|
|
0xfffffffff80100c0,
|
|
0xffffffff7c7e1b78,
|
|
0xf000000040000000, // bne
|
|
0xffffffff3fe08031,
|
|
0xffffffff63ff0003,
|
|
0xffffffffe80100c0,
|
|
0xffffffff7fe307b4,
|
|
0xffffffffeb210078,
|
|
0xffffffffeb410080,
|
|
0xffffffff7c0803a6,
|
|
0xffffffffeb610088,
|
|
0xffffffffeb810090,
|
|
0xffffffffeba10098,
|
|
0xffffffffebc100a0,
|
|
0xffffffffebe100a8,
|
|
0xffffffff382100b0
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerGetAANHandle,
|
|
0xff00000081428250, // lwz
|
|
0xffffffff3d607fce,
|
|
0xffffffff616bfffe,
|
|
0xffffffff812a0018,
|
|
0xffffffff7d2afe70,
|
|
0xffffffff91230000,
|
|
0xffffffff7d404a78,
|
|
0xffffffff7c005050,
|
|
0xffffffff7c00fe70,
|
|
0xffffffff7c035838,
|
|
0xffffffff3c638031,
|
|
0xffffffff38630002,
|
|
0xffffffff7c6307b4,
|
|
0xffffffff4e800020
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerChStripGetAANPortNo,
|
|
0xff00000081228250, // lwz
|
|
0xffffffff7c661b78,
|
|
0xffffffff3c608031,
|
|
0xffffffff78c60020,
|
|
0xffffffff78840020,
|
|
0xffffffff60630002,
|
|
0xffffffff80090018,
|
|
0xffffffff78a50020,
|
|
0xffffffff2f800000,
|
|
0xffffffff4d9e0020,
|
|
0xffffffff78030020,
|
|
0xf000000040000000 // b
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerSetNotifyCallback,
|
|
0xff00000081428250, // lwz
|
|
0xffffffff7c0802a6,
|
|
0xfffffffff821ff81,
|
|
0xfffffffff8010090,
|
|
0xffffffff7c6b1b78,
|
|
0xffffffff3c608031,
|
|
0xffffffff812a0018,
|
|
0xffffffff7c882378,
|
|
0xffffffff60630003,
|
|
0xffffffff2f890000,
|
|
0xffffffff2f0b0000,
|
|
0xffffff00409e0020, // bne
|
|
0xffffffff3c608031,
|
|
0xffffffff60630002,
|
|
0xffffffffe8010090,
|
|
0xffffffff7c6307b4,
|
|
0xffffffff38210080,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff4e800020,
|
|
0xffffff00419affec, // beq
|
|
0xf0000000800a001c, // lwz
|
|
0xffffffff79290020,
|
|
0xffffffff38810070,
|
|
0xffffffff2f800000,
|
|
0xffffffff7d234b78
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerRemoveNotifyCallback,
|
|
0xff00000081628250, // lwz
|
|
0xffffffff7c0802a6,
|
|
0xfffffffff821ff81,
|
|
0xfffffffff8010090,
|
|
0xffffffff7c6a1b78,
|
|
0xffffffff3d208031,
|
|
0xffffffff806b0018,
|
|
0xffffffff61290002, // ori
|
|
0xffffffff2f830000,
|
|
0xffff0000409e0018, // bne
|
|
0xffffffffe8010090,
|
|
0xffffffff7d2307b4,
|
|
0xffffffff38210080,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff4e800020
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerStart,
|
|
0xfffffffff821ff71,
|
|
0xffffffff7c0802a6,
|
|
0xfffffffffbc10080,
|
|
0xf000000083c20000, // lwz
|
|
0xfffffffff80100a0,
|
|
0xfffffffffba10078,
|
|
0xfffffffffbe10088,
|
|
0xffffffff801e0018,
|
|
0xffffffff2f800000,
|
|
0xf0000000409e002c, // bne
|
|
0xffffffff3fe08031,
|
|
0xffffffff63ff0002,
|
|
0xffffffffe80100a0,
|
|
0xffffffff7fe307b4,
|
|
0xffffffffeba10078,
|
|
0xffffffffebc10080,
|
|
0xffffffff7c0803a6,
|
|
0xffffffffebe10088,
|
|
0xffffffff38210090,
|
|
0xffffffff4e800020
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerSetParameter,
|
|
0xfffffffff821ff81,
|
|
0xffffffff7c0802a6,
|
|
0xfffffffffbc10070,
|
|
0xfffffffffc000890,
|
|
0xf000000083c28250, // lwz
|
|
0xffffffff3d208031,
|
|
0xfffffffff8010090,
|
|
0xfffffffffbe10078,
|
|
0xffffffff61290002,
|
|
0xffffffff7c7f1b78,
|
|
0xffffffff801e0018,
|
|
0xffffffff2f800000,
|
|
0xffff0000409e0020, // bne
|
|
0xffffffffe8010090,
|
|
0xffffffff7d2307b4,
|
|
0xffffffffebc10070,
|
|
0xffffffffebe10078,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff38210080,
|
|
0xffffffff4e800020,
|
|
0xffffffff801e001c,
|
|
0xffffffff2b03001f,
|
|
0xffffffff2f800000,
|
|
0xffff0000419cffd8, // blt
|
|
0xffffffff2b83002b,
|
|
0xffff000040990008, // ble
|
|
0xffff0000409d0054 // ble
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerFinalize,
|
|
0xfffffffff821ff91,
|
|
0xffffffff7c0802a6,
|
|
0xfffffffff8010080,
|
|
0xffffff004bfffde1, // bl
|
|
0xffffffffe8010080,
|
|
0xffffffff38600000,
|
|
0xffffffff38210070,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff4e800020,
|
|
0xfffffffff821ff71,
|
|
0xffffffff7c0802a6,
|
|
0xfffffffffba10078,
|
|
0xf000000083a28250, // lwz
|
|
0xfffffffff80100a0,
|
|
0xffffffff817d0018,
|
|
0xffffffff7d635b78,
|
|
0xffffffff812b0000,
|
|
0xffffffff81490000,
|
|
0xffffffff800a0000,
|
|
0xfffffffff8410028,
|
|
0xffffffff7c0903a6,
|
|
0xffffffff804a0004,
|
|
0xffffffff4e800421
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerSurBusAddData,
|
|
0xff00000081428250, // lwz
|
|
0xffffffff7c0802a6,
|
|
0xfffffffff821ff91,
|
|
0xfffffffff8010080,
|
|
0xffffffff7c601b78,
|
|
0xffffffff3d208031,
|
|
0xffffffff806a0018,
|
|
0xffffffff7c8b2378,
|
|
0xffffffff7cc73378,
|
|
0xffffffff2f830000,
|
|
0xffffffff61290002,
|
|
0xffff0000409e0018, // bne
|
|
0xffffffffe8010080,
|
|
0xffffffff7d2307b4,
|
|
0xffffffff38210070,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff4e800020,
|
|
0xffffffff78a40020,
|
|
0xffffffff78050020,
|
|
0xffffffff800a001c,
|
|
0xffffffff78680020,
|
|
0xffffffff2f800000,
|
|
0xffffffff7d034378,
|
|
0xffffffff79660020,
|
|
0xffffffff78e70020,
|
|
0xffff0000419cffcc // blt
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerChStripSetParameter,
|
|
0xff00000081028250, // lwz
|
|
0xffffffff7c6b1b78,
|
|
0xffffffff3c608031,
|
|
0xffffffff7c8a2378,
|
|
0xffffffff7ca62b78,
|
|
0xffffffff60630002,
|
|
0xffffffff81280018,
|
|
0xffffffff2f890000,
|
|
0xffff00004d9e0020, // beqlr
|
|
0xffffffff8008001c,
|
|
0xffffffff79640020,
|
|
0xffffffff79450020,
|
|
0xffffffff2f800000,
|
|
0xffffffff78c60020,
|
|
0xffffffff4d9c0020,
|
|
0xffffffff79230020,
|
|
0xf000000048000000 // b
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerPause,
|
|
0xff00000081428250, // lwz
|
|
0xffffffff7c0802a6,
|
|
0xfffffffff821ff81,
|
|
0xfffffffff8010090,
|
|
0xffffffff3d208031,
|
|
0xfffffffffbe10078,
|
|
0xffffffff800a0018,
|
|
0xffffffff7c7f1b78,
|
|
0xfffffffffbc10070,
|
|
0xffffffff2f800000,
|
|
0xffffffff61290002,
|
|
0xffff0000409e0020, // bne
|
|
0xffffffffe8010090,
|
|
0xffffffff7d2307b4,
|
|
0xffffffffebc10070,
|
|
0xffffffffebe10078,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff38210080,
|
|
0xffffffff4e800020,
|
|
0xffffffff800a001c,
|
|
0xffffffff2b030002,
|
|
0xffffffff2f800000
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerGetCurrentBlockTag,
|
|
0xff00000081628250, // lwz
|
|
0xffffffff3d208031,
|
|
0xffffffff61290002,
|
|
0xffffffff880b0020,
|
|
0xffffffff2f800000,
|
|
0xffff0000419e0010, // beq
|
|
0xffffffffe80b0028,
|
|
0xffffffff39200000,
|
|
0xfffffffff8030000,
|
|
0xffffffff7d2307b4,
|
|
0xffffffff4e800020
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerGetTimestamp,
|
|
0xff00000081628250, // lwz
|
|
0xffffffff7c0802a6,
|
|
0xfffffffff821ff91,
|
|
0xfffffffff8010080,
|
|
0xffffffff7c852378,
|
|
0xffffffff3d208031,
|
|
0xffffffff880b0020,
|
|
0xffffffff7c641b78,
|
|
0xffffffff78a50020,
|
|
0xffffffff2f800000,
|
|
0xffffffff61290002,
|
|
0xffff000040de0018, // bne-
|
|
0xffffffffe8010080,
|
|
0xffffffff7d2307b4,
|
|
0xffffffff38210070,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff4e800020,
|
|
0xffffffff806b04d8,
|
|
0xf000000048000001 // bl
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmixer", cellSurMixerBeep,
|
|
0xff00000081228250, // lwz
|
|
0xffffffff7c641b78,
|
|
0xffffffff80690018,
|
|
0xffffffff2f830000,
|
|
0xffff00004d9e0020, // beqlr
|
|
0xffffffff8009001c,
|
|
0xffffffff78630020,
|
|
0xffffffff78840020,
|
|
0xffffffff2f800000,
|
|
0xffffffff4d9c0020,
|
|
0xf000000048000000 // b
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmxSSP", cellSSPlayerCreate,
|
|
0xfffffffff821ff51,
|
|
0xffffffff7c0802a6,
|
|
0xffffffff2f840000,
|
|
0xfffffffff80100c0,
|
|
0xffffffff3c008031,
|
|
0xfffffffffb210078,
|
|
0xfffffffffb410080,
|
|
0xfffffffffb610088,
|
|
0xfffffffffb810090,
|
|
0xfffffffffba10098,
|
|
0xfffffffffbc100a0,
|
|
0xfffffffffbe100a8,
|
|
0xffffffff7c9a2378,
|
|
0xffffffff7c791b78,
|
|
0xffffffff60000003,
|
|
0xffff0000419e0068, // beq
|
|
0xff00000083620000, // lwz
|
|
0xffffffff3b800000,
|
|
0xffffffff381b0064,
|
|
0xffffffff901b0018,
|
|
0xffffffff5780103a,
|
|
0xffffffff38800010,
|
|
0xffffffff7c0007b4,
|
|
0xffffffff38a01c70,
|
|
0xffffffff7fc0da14,
|
|
0xffffffff38c00000,
|
|
0xffffffff83be0024,
|
|
0xffffffff2f9d0000,
|
|
0xffffffff7ba30020,
|
|
0xffff000041de00c0, // beq-
|
|
0xf000000048000001 // bl
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmxSSP", cellSSPlayerRemove,
|
|
0xffffffff7c641b78,
|
|
0xffffffff7c0802a6,
|
|
0xffffffff3c608031,
|
|
0xffffffff2f840000,
|
|
0xfffffffff821ff51,
|
|
0xfffffffffb010070,
|
|
0xfffffffffb210078,
|
|
0xfffffffffb410080,
|
|
0xfffffffffb610088,
|
|
0xfffffffffb810090,
|
|
0xfffffffffba10098,
|
|
0xfffffffffbc100a0,
|
|
0xfffffffffbe100a8,
|
|
0xfffffffff80100c0,
|
|
0xffffffff60630003,
|
|
0xffff0000419e0074, // beq
|
|
0xffffffff81240000,
|
|
0xffffffff78830020,
|
|
0xffffffff83440004,
|
|
0xffffffff83240008,
|
|
0xffffffff7b5b0020,
|
|
0xffffffff81690000,
|
|
0xffffffff800b0000,
|
|
0xfffffffff8410028,
|
|
0xffffffff7c0903a6,
|
|
0xffffffff804b0004,
|
|
0xffffffff4e800421
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmxSSP", cellSSPlayerSetWave,
|
|
0xffffffff7c601b78,
|
|
0xffffffff78840020,
|
|
0xffffffff2f800000,
|
|
0xffffffff3c608031,
|
|
0xffffffff78a50020,
|
|
0xffff0000419e000c, // beq
|
|
0xffffffff78030020,
|
|
0xf000000048000000, // b
|
|
0xffffffff60630003,
|
|
0xffffffff4e800020
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmxSSP", cellSSPlayerPlay,
|
|
0xffffffff7c601b78,
|
|
0xffffffff3c608031,
|
|
0xffffffff2f800000,
|
|
0xffffffff60630003,
|
|
0xffffffff78840020,
|
|
0xffffffff4d9e0020,
|
|
0xffffffff78030020,
|
|
0xf000000048000000, // b
|
|
0xfffffffff821ff81, // next func
|
|
0xffffffff7c0802a6,
|
|
0xfffffffffbe10078,
|
|
0xffffffff7c7f1b78,
|
|
0xff00000081620028, // lwz
|
|
0xfffffffff8010090,
|
|
0xffffffff39400000,
|
|
0xffffffff38630010
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmxSSP", cellSSPlayerStop,
|
|
0xfffffffff821ff91,
|
|
0xffffffff7c0802a6,
|
|
0xffffffff2f830000,
|
|
0xfffffffff8010080,
|
|
0xffffffff3c008031,
|
|
0xffffffff78630020,
|
|
0xffffffff60000003,
|
|
0xffff0000419e0010, // beq
|
|
0xffffffff78840020,
|
|
0xf000000048000001, // bl
|
|
0xffffffff38000000,
|
|
0xffffffff7c0307b4,
|
|
0xffffffffe8010080,
|
|
0xffffffff38210070,
|
|
0xffffffff7c0803a6,
|
|
0xffffffff4e800020
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmxSSP", cellSSPlayerSetParam,
|
|
0xffffffff7c601b78,
|
|
0xffffffff3c608031,
|
|
0xffffffff2f800000,
|
|
0xffffffff60630003,
|
|
0xffffffff78840020,
|
|
0xffffffff4d9e0020,
|
|
0xffffffff78030020,
|
|
0xf000000048000000, // b
|
|
0xfffffffff821ff71, // next func
|
|
0xffffffff7c0802a6,
|
|
0xffffffff3d608031,
|
|
0xfffffffff80100a0,
|
|
0xffffffff80030068,
|
|
0xffffffff616b0002,
|
|
0xfffffffffbc10080,
|
|
0xffffffff2f800000
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmxSSP", cellSSPlayerGetState,
|
|
0xffffffff7c601b78,
|
|
0xffffffff3c608031,
|
|
0xffffffff2f800000,
|
|
0xffffffff60630003,
|
|
0xffffffff4d9e0020,
|
|
0xffffffff78030020,
|
|
0xf000000048000000 // b
|
|
);
|
|
|
|
REG_SUB(libmixer, "surmxUti", cellSurMixerUtilGetLevelFromDB, 0);
|
|
REG_SUB(libmixer, "surmxUti", cellSurMixerUtilGetLevelFromDBIndex, 0);
|
|
REG_SUB(libmixer, "surmxUti", cellSurMixerUtilNoteToRatio, 0);
|
|
}
|