mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 11:13:19 +01:00
SSPlayer funcs in libmixer
This commit is contained in:
parent
d16953d392
commit
60f3ed3543
@ -21,8 +21,13 @@ std::mutex mixer_mutex;
|
|||||||
float mixdata[8*256];
|
float mixdata[8*256];
|
||||||
u64 mixcount = 0;
|
u64 mixcount = 0;
|
||||||
|
|
||||||
|
std::vector<SSPlayer> ssp;
|
||||||
|
|
||||||
int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 samples)
|
int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 samples)
|
||||||
{
|
{
|
||||||
|
libmixer->Log("cellAANAddData(handle=%d, port=%d, offset=0x%x, addr=0x%x, samples=%d)",
|
||||||
|
aan_handle, aan_port, offset, addr, samples);
|
||||||
|
|
||||||
u32 type = aan_port >> 16;
|
u32 type = aan_port >> 16;
|
||||||
u32 port = aan_port & 0xffff;
|
u32 port = aan_port & 0xffff;
|
||||||
|
|
||||||
@ -40,17 +45,11 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl
|
|||||||
type = 0; break;
|
type = 0; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aan_handle == 0x11111111 && samples == 256 && type && offset == 0)
|
if (aan_handle != 0x11111111 || samples != 256 || !type || offset != 0)
|
||||||
{
|
{
|
||||||
libmixer->Log("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)",
|
libmixer->Error("cellAANAddData(handle=%d, port=%d, offset=0x%x, addr=0x%x, samples=%d): invalid parameters",
|
||||||
aan_handle, aan_port, offset, addr, samples);
|
aan_handle, aan_port, offset, addr, samples);
|
||||||
}
|
return CELL_LIBMIXER_ERROR_INVALID_PARAMATER;
|
||||||
else
|
|
||||||
{
|
|
||||||
libmixer->Error("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)",
|
|
||||||
aan_handle, aan_port, offset, addr, samples);
|
|
||||||
Emu.Pause();
|
|
||||||
return CELL_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(mixer_mutex);
|
std::lock_guard<std::mutex> lock(mixer_mutex);
|
||||||
@ -109,74 +108,386 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl
|
|||||||
|
|
||||||
int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo)
|
int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo)
|
||||||
{
|
{
|
||||||
libmixer->Error("cellAANConnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)",
|
libmixer->Warning("cellAANConnect(receive=%d, receivePortNo=%d, source=%d, sourcePortNo=%d)",
|
||||||
receive, receivePortNo, source, sourcePortNo);
|
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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo)
|
int cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo)
|
||||||
{
|
{
|
||||||
libmixer->Error("cellAANDisconnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)",
|
libmixer->Warning("cellAANDisconnect(receive=%d, receivePortNo=%d, source=%d, sourcePortNo=%d)",
|
||||||
receive, receivePortNo, source, sourcePortNo);
|
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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSSPlayerCreate(mem32_t handle, mem_ptr_t<CellSSPlayerConfig> config)
|
int cellSSPlayerCreate(mem32_t handle, mem_ptr_t<CellSSPlayerConfig> config)
|
||||||
{
|
{
|
||||||
libmixer->Error("cellSSPlayerCreate(handle_addr=0x%x, config_addr=0x%x)",
|
libmixer->Warning("cellSSPlayerCreate(handle_addr=0x%x, config_addr=0x%x)",
|
||||||
handle.GetAddr(), config.GetAddr());
|
handle.GetAddr(), config.GetAddr());
|
||||||
|
|
||||||
|
if (!config.IsGood())
|
||||||
|
{
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = ssp.size() - 1;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSSPlayerRemove(u32 handle)
|
int cellSSPlayerRemove(u32 handle)
|
||||||
{
|
{
|
||||||
libmixer->Error("cellSSPlayerRemove(handle=%d)", 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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSSPlayerSetWave(u32 handle, mem_ptr_t<CellSSPlayerWaveParam> waveInfo, mem_ptr_t<CellSSPlayerCommonParam> commonInfo)
|
int cellSSPlayerSetWave(u32 handle, mem_ptr_t<CellSSPlayerWaveParam> waveInfo, mem_ptr_t<CellSSPlayerCommonParam> commonInfo)
|
||||||
{
|
{
|
||||||
libmixer->Error("cellSSPlayerSetWave(handle=%d, waveInfo_addr=0x%x, commonInfo_addr=0x%x)",
|
libmixer->Warning("cellSSPlayerSetWave(handle=%d, waveInfo_addr=0x%x, commonInfo_addr=0x%x)",
|
||||||
handle, waveInfo.GetAddr(), commonInfo.GetAddr());
|
handle, waveInfo.GetAddr(), commonInfo.GetAddr());
|
||||||
|
|
||||||
|
if (!waveInfo.IsGood() || (commonInfo.GetAddr() && !commonInfo.IsGood()))
|
||||||
|
{
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.GetAddr() ? commonInfo->loopMode : CELL_SSPLAYER_ONESHOT;
|
||||||
|
ssp[handle].m_position = waveInfo->startOffset - 1;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSSPlayerPlay(u32 handle, mem_ptr_t<CellSSPlayerRuntimeInfo> info)
|
int cellSSPlayerPlay(u32 handle, mem_ptr_t<CellSSPlayerRuntimeInfo> info)
|
||||||
{
|
{
|
||||||
libmixer->Error("cellSSPlayerPlay(handle=%d, info_addr=0x%x)", handle, info.GetAddr());
|
libmixer->Warning("cellSSPlayerPlay(handle=%d, info_addr=0x%x)", handle, info.GetAddr());
|
||||||
|
|
||||||
|
if (!info.IsGood())
|
||||||
|
{
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSSPlayerStop(u32 handle, u32 mode)
|
int cellSSPlayerStop(u32 handle, u32 mode)
|
||||||
{
|
{
|
||||||
libmixer->Error("cellSSPlayerStop(handle=%d, mode=0x%x)", handle, 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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSSPlayerSetParam(u32 handle, mem_ptr_t<CellSSPlayerRuntimeInfo> info)
|
int cellSSPlayerSetParam(u32 handle, mem_ptr_t<CellSSPlayerRuntimeInfo> info)
|
||||||
{
|
{
|
||||||
libmixer->Error("cellSSPlayerSetParam(handle=%d, info_addr=0x%x)", handle, info.GetAddr());
|
libmixer->Warning("cellSSPlayerSetParam(handle=%d, info_addr=0x%x)", handle, info.GetAddr());
|
||||||
|
|
||||||
|
if (!info.IsGood())
|
||||||
|
{
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cellSSPlayerGetState(u32 handle)
|
int cellSSPlayerGetState(u32 handle)
|
||||||
{
|
{
|
||||||
libmixer->Error("cellSSPlayerGetState(handle=%d) -> OFF", 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;
|
return CELL_SSPLAYER_STATE_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSurMixerCreate(const mem_ptr_t<CellSurMixerConfig> config)
|
int cellSurMixerCreate(const mem_ptr_t<CellSurMixerConfig> config)
|
||||||
{
|
{
|
||||||
libmixer->Warning("cellSurMixerCreate(config_addr=0x%x)", config.GetAddr());
|
libmixer->Warning("cellSurMixerCreate(config_addr=0x%x)", config.GetAddr());
|
||||||
|
|
||||||
surMixer = *config;
|
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)",
|
libmixer->Warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)",
|
||||||
(u32)surMixer.chStrips1, (u32)surMixer.chStrips2, (u32)surMixer.chStrips6, (u32)surMixer.chStrips8);
|
(u32)surMixer.chStrips1, (u32)surMixer.chStrips2, (u32)surMixer.chStrips6, (u32)surMixer.chStrips8);
|
||||||
|
|
||||||
|
thread t("Surmixer Thread", []()
|
||||||
|
{
|
||||||
|
AudioPortConfig& port = m_config.m_ports[SUR_PORT];
|
||||||
|
|
||||||
|
CPUThread* mixerCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||||
|
|
||||||
|
mixerCb->SetName("Surmixer Callback");
|
||||||
|
|
||||||
|
mixcount = 0;
|
||||||
|
|
||||||
|
while (port.m_is_audio_port_opened)
|
||||||
|
{
|
||||||
|
if (Emu.IsStopped())
|
||||||
|
{
|
||||||
|
LOG_WARNING(HLE, "Surmixer aborted");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mixcount > (port.tag + 15)) // preemptive buffer filling (probably hack)
|
||||||
|
{
|
||||||
|
Sleep(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port.m_is_audio_port_started)
|
||||||
|
{
|
||||||
|
u64 stamp0 = get_system_time();
|
||||||
|
|
||||||
|
memset(mixdata, 0, sizeof(mixdata));
|
||||||
|
if (surMixerCb) mixerCb->ExecAsCallback(surMixerCb, true, 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)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
mem16_t v(p.m_addr + pos * sizeof(u16));
|
||||||
|
left = right = (float)(s16)re16(v.GetValue()) / 0x8000 * p.m_level;
|
||||||
|
}
|
||||||
|
else if (p.m_channels == 2) // get stereo data
|
||||||
|
{
|
||||||
|
mem16_t v1(p.m_addr + (pos * 2 + 0) * sizeof(u16));
|
||||||
|
mem16_t v2(p.m_addr + (pos * 2 + 1) * sizeof(u16));
|
||||||
|
left = (float)(s16)re16(v1.GetValue()) / 0x8000 * p.m_level;
|
||||||
|
right = (float)(s16)re16(v2.GetValue()) / 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 = (be_t<float>*)&Memory[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(mixerCb->GetId());
|
||||||
|
});
|
||||||
|
t.detach();
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSurMixerGetAANHandle(mem32_t handle)
|
int cellSurMixerGetAANHandle(mem32_t handle)
|
||||||
{
|
{
|
||||||
libmixer->Warning("cellSurMixerGetAANHandle(handle_addr=0x%x) -> 0x11111111", handle.GetAddr());
|
libmixer->Warning("cellSurMixerGetAANHandle(handle_addr=0x%x) -> %d", handle.GetAddr(), 0x11111111);
|
||||||
handle = 0x11111111;
|
handle = 0x11111111;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -212,72 +523,9 @@ int cellSurMixerStart()
|
|||||||
|
|
||||||
if (port.m_is_audio_port_opened)
|
if (port.m_is_audio_port_opened)
|
||||||
{
|
{
|
||||||
return CELL_LIBMIXER_ERROR_FULL;
|
port.m_is_audio_port_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
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++;
|
|
||||||
port.m_is_audio_port_started = true;
|
|
||||||
|
|
||||||
thread t("Surmixer Thread", []()
|
|
||||||
{
|
|
||||||
AudioPortConfig& port = m_config.m_ports[SUR_PORT];
|
|
||||||
|
|
||||||
CPUThread* mixerCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
|
||||||
|
|
||||||
mixerCb->SetName("Surmixer Callback");
|
|
||||||
|
|
||||||
mixcount = 0;
|
|
||||||
|
|
||||||
while (port.m_is_audio_port_started)
|
|
||||||
{
|
|
||||||
if (Emu.IsStopped())
|
|
||||||
{
|
|
||||||
LOG_WARNING(HLE, "Surmixer aborted");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mixcount > (port.tag + 15)) // preemptive buffer filling (probably hack)
|
|
||||||
{
|
|
||||||
Sleep(1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 stamp0 = get_system_time();
|
|
||||||
|
|
||||||
memset(mixdata, 0, sizeof(mixdata));
|
|
||||||
mixerCb->ExecAsCallback(surMixerCb, true, surMixerCbArg, mixcount, 256);
|
|
||||||
|
|
||||||
u64 stamp1 = get_system_time();
|
|
||||||
|
|
||||||
auto buf = (be_t<float>*)&Memory[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 stamp2 = get_system_time();
|
|
||||||
|
|
||||||
//ConLog.Write("Libmixer perf: start=%d (cb=%d, finalize=%d)",
|
|
||||||
//stamp0 - m_config.start_time, stamp1-stamp0, stamp2-stamp1);
|
|
||||||
|
|
||||||
mixcount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Emu.GetCPU().RemoveThread(mixerCb->GetId());
|
|
||||||
});
|
|
||||||
t.detach();
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +584,15 @@ int cellSurMixerChStripSetParameter(u32 type, u32 index, mem_ptr_t<CellSurMixerC
|
|||||||
|
|
||||||
int cellSurMixerPause(u32 type)
|
int cellSurMixerPause(u32 type)
|
||||||
{
|
{
|
||||||
libmixer->Error("cellSurMixerPause(type=%d)", 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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ struct CellSSPlayerConfig
|
|||||||
|
|
||||||
struct CellSSPlayerWaveParam
|
struct CellSSPlayerWaveParam
|
||||||
{
|
{
|
||||||
void *addr;
|
be_t<u32> addr;
|
||||||
be_t<s32> format;
|
be_t<s32> format;
|
||||||
be_t<u32> samples;
|
be_t<u32> samples;
|
||||||
be_t<u32> loopStartOffset;
|
be_t<u32> loopStartOffset;
|
||||||
@ -158,10 +158,26 @@ struct CellSurMixerConfig
|
|||||||
struct CellSurMixerChStripParam
|
struct CellSurMixerChStripParam
|
||||||
{
|
{
|
||||||
be_t<u32> param;
|
be_t<u32> param;
|
||||||
void *attribute;
|
be_t<u32> attribute_addr;
|
||||||
be_t<s32> dBSwitch;
|
be_t<s32> dBSwitch;
|
||||||
be_t<float> floatVal;
|
be_t<float> floatVal;
|
||||||
be_t<s32> intVal;
|
be_t<s32> intVal;
|
||||||
};
|
};
|
||||||
|
|
||||||
CellSSPlayerWaveParam current_SSPlayerWaveParam;
|
struct SSPlayer
|
||||||
|
{
|
||||||
|
bool m_created; // SSPlayerCreate/Remove
|
||||||
|
bool m_connected; // AANConnect/Disconnect
|
||||||
|
bool m_active; // SSPlayerPlay/Stop
|
||||||
|
u32 m_channels; // 1 or 2
|
||||||
|
u32 m_addr;
|
||||||
|
u32 m_samples;
|
||||||
|
u32 m_loop_start;
|
||||||
|
u32 m_loop_mode;
|
||||||
|
u32 m_position;
|
||||||
|
float m_level;
|
||||||
|
float m_speed;
|
||||||
|
float m_x;
|
||||||
|
float m_y;
|
||||||
|
float m_z;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user