mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-29 18:32:47 +00:00
Audio mixing fixed
Libmixer reseen Some bugs fixed
This commit is contained in:
parent
72bb0c842f
commit
fce074d812
1
.gitignore
vendored
1
.gitignore
vendored
@ -57,5 +57,4 @@ rpcs3/git-version.h
|
||||
!/bin/dev_hdd0/game/TEST12345/
|
||||
|
||||
# Ignore other system generated files
|
||||
bin/dev_hdd0/home/00000001/trophy
|
||||
bin/dev_hdd0/log.txt
|
||||
|
@ -170,7 +170,8 @@ public:
|
||||
}
|
||||
break;
|
||||
|
||||
default: ConLog.Error("Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, is_swizzled ? "swizzled" : "linear", tex.GetFormat() & 0x40); break;
|
||||
default: ConLog.Error("Init tex error: Bad tex format (0x%x | %s | 0x%x)", format,
|
||||
wxString(is_swizzled ? "swizzled" : "linear").wx_str(), tex.GetFormat() & 0x40); break;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.GetMipmap() - 1);
|
||||
|
@ -949,7 +949,17 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
||||
|
||||
case NV4097_SET_VIEWPORT_OFFSET:
|
||||
{
|
||||
/*const u32 offset0 = ARGS(0);
|
||||
const u32 offset1 = ARGS(1);
|
||||
const u32 offset2 = ARGS(2);
|
||||
const u32 offset3 = ARGS(3);
|
||||
const u32 scale0 = ARGS(4);
|
||||
const u32 scale1 = ARGS(5);
|
||||
const u32 scale2 = ARGS(6);
|
||||
const u32 scale3 = ARGS(7);*/
|
||||
//TODO
|
||||
//ConLog.Warning("NV4097_SET_VIEWPORT_OFFSET: offset (%d, %d, %d, %d), scale (%d, %d, %d, %d)",
|
||||
//offset0, offset1, offset2, offset3, scale0, scale1, scale2, scale3);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -38,8 +38,10 @@ int cellAudioInit()
|
||||
thread t("Audio Thread", []()
|
||||
{
|
||||
AudioDumper m_dump(2); // WAV file header (stereo)
|
||||
|
||||
bool do_dump = Ini.AudioDumpToFile.GetValue();
|
||||
|
||||
if (Ini.AudioDumpToFile.GetValue() && !m_dump.Init())
|
||||
if (do_dump && !m_dump.Init())
|
||||
{
|
||||
ConLog.Error("Audio aborted: cannot create file!");
|
||||
return;
|
||||
@ -50,7 +52,7 @@ int cellAudioInit()
|
||||
if (Ini.AudioDumpToFile.GetValue())
|
||||
m_dump.WriteHeader();
|
||||
|
||||
float buffer[2*256]; // buffer for 2 channels
|
||||
float buffer[2*256]; // intermediate buffer for 2 channels
|
||||
be_t<float> buffer2[8*256]; // buffer for 8 channels (max count)
|
||||
//u16 oal_buffer[2*256]; // buffer for OpenAL
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
@ -79,7 +81,9 @@ int cellAudioInit()
|
||||
|
||||
m_config.start_time = get_system_time();
|
||||
|
||||
thread iat("Internal Audio Thread", [oal_buffer_size, &queue]()
|
||||
volatile bool internal_finished = false;
|
||||
|
||||
thread iat("Internal Audio Thread", [oal_buffer_size, &queue, &internal_finished]()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
@ -92,7 +96,8 @@ int cellAudioInit()
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
internal_finished = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -128,13 +133,12 @@ int cellAudioInit()
|
||||
|
||||
bool first_mix = true;
|
||||
|
||||
// MIX:
|
||||
// mixing:
|
||||
for (u32 i = 0; i < m_config.AUDIO_PORT_COUNT; i++)
|
||||
{
|
||||
if (!m_config.m_ports[i].m_is_audio_port_started) continue;
|
||||
|
||||
AudioPortConfig& port = m_config.m_ports[i];
|
||||
mem64_t index(m_config.m_indexes + i * sizeof(u64));
|
||||
|
||||
const u32 block_size = port.channel * 256;
|
||||
|
||||
@ -145,28 +149,17 @@ int cellAudioInit()
|
||||
memcpy(buffer2, Memory + buf_addr, block_size * sizeof(float));
|
||||
memset(Memory + buf_addr, 0, block_size * sizeof(float));
|
||||
|
||||
{
|
||||
SMutexGeneralLocker lock(audioMutex);
|
||||
port.counter = m_config.counter;
|
||||
port.tag++; // absolute index of block that will be read
|
||||
index = (position + 1) % port.block; // write new value
|
||||
}
|
||||
|
||||
const u32 k = port.channel / 2;
|
||||
|
||||
if (first_mix)
|
||||
{
|
||||
for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2)
|
||||
{
|
||||
// reverse byte order (TODO: use port.m_param.level)
|
||||
// reverse byte order
|
||||
buffer[i] = buffer2[i*k];
|
||||
buffer[i+1] = buffer2[i*k+1];
|
||||
|
||||
// convert the data from float to u16
|
||||
//assert(buffer[i] >= -1.0f && buffer[i] <= 1.0f);
|
||||
//assert(buffer[i+1] >= -1.0f && buffer[i+1] <= 1.0f);
|
||||
oal_buffer[oal_pos][oal_buffer_offset + i] = (u16)(buffer[i] * ((1 << 14) - 1));
|
||||
oal_buffer[oal_pos][oal_buffer_offset + i + 1] = (u16)(buffer[i+1] * ((1 << 14) - 1));
|
||||
// TODO: use port.m_param.level
|
||||
// TODO: downmix channels that are ignored (?) or implement surround sound
|
||||
}
|
||||
|
||||
first_mix = false;
|
||||
@ -175,34 +168,20 @@ int cellAudioInit()
|
||||
{
|
||||
for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2)
|
||||
{
|
||||
buffer[i] = (buffer[i] + buffer2[i*k]) * 0.5; // TODO: valid mixing
|
||||
buffer[i+1] = (buffer[i+1] + buffer2[i*k+1]) * 0.5;
|
||||
|
||||
// convert the data from float to u16
|
||||
//assert(buffer[i] >= -1.0f && buffer[i] <= 1.0f);
|
||||
//assert(buffer[i+1] >= -1.0f && buffer[i+1] <= 1.0f);
|
||||
oal_buffer[oal_pos][oal_buffer_offset + i] = (u16)(buffer[i] * ((1 << 14) - 1));
|
||||
oal_buffer[oal_pos][oal_buffer_offset + i + 1] = (u16)(buffer[i+1] * ((1 << 14) - 1));
|
||||
buffer[i] += buffer2[i*k];
|
||||
buffer[i+1] += buffer2[i*k+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert the data from float to u16 and clip:
|
||||
for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++)
|
||||
{
|
||||
oal_buffer[oal_pos][oal_buffer_offset + i] = (s16)(min<float>(max<float>(buffer[i] * 0x8000, -0x8000), 0x7fff));
|
||||
}
|
||||
|
||||
const u64 stamp1 = get_system_time();
|
||||
|
||||
// send aftermix event (normal audio event)
|
||||
{
|
||||
SMutexGeneralLocker lock(audioMutex);
|
||||
keys.SetCount(m_config.m_keys.GetCount());
|
||||
memcpy(keys.GetPtr(), m_config.m_keys.GetPtr(), sizeof(u64) * keys.GetCount());
|
||||
}
|
||||
for (u32 i = 0; i < keys.GetCount(); i++)
|
||||
{
|
||||
// TODO: check event source
|
||||
Emu.GetEventManager().SendEvent(keys[i], 0x10103000e010e07, 0, 0, 0);
|
||||
}
|
||||
|
||||
const u64 stamp2 = get_system_time();
|
||||
|
||||
oal_buffer_offset += sizeof(buffer) / sizeof(float);
|
||||
|
||||
if(oal_buffer_offset >= oal_buffer_size)
|
||||
@ -215,9 +194,37 @@ int cellAudioInit()
|
||||
oal_buffer_offset = 0;
|
||||
}
|
||||
|
||||
const u64 stamp2 = get_system_time();
|
||||
|
||||
// send aftermix event (normal audio event)
|
||||
{
|
||||
SMutexGeneralLocker lock(audioMutex);
|
||||
// update indexes:
|
||||
for (u32 i = 0; i < m_config.AUDIO_PORT_COUNT; i++)
|
||||
{
|
||||
if (!m_config.m_ports[i].m_is_audio_port_started) continue;
|
||||
|
||||
AudioPortConfig& port = m_config.m_ports[i];
|
||||
mem64_t index(m_config.m_indexes + i * sizeof(u64));
|
||||
|
||||
u32 position = port.tag % port.block; // old value
|
||||
port.counter = m_config.counter;
|
||||
port.tag++; // absolute index of block that will be read
|
||||
index = (position + 1) % port.block; // write new value
|
||||
}
|
||||
// load keys:
|
||||
keys.SetCount(m_config.m_keys.GetCount());
|
||||
memcpy(keys.GetPtr(), m_config.m_keys.GetPtr(), sizeof(u64) * keys.GetCount());
|
||||
}
|
||||
for (u32 i = 0; i < keys.GetCount(); i++)
|
||||
{
|
||||
// TODO: check event source
|
||||
Emu.GetEventManager().SendEvent(keys[i], 0x10103000e010e07, 0, 0, 0);
|
||||
}
|
||||
|
||||
const u64 stamp3 = get_system_time();
|
||||
|
||||
if(Ini.AudioDumpToFile.GetValue())
|
||||
if(do_dump)
|
||||
{
|
||||
if (m_dump.WriteData(&buffer, sizeof(buffer)) != sizeof(buffer)) // write file data
|
||||
{
|
||||
@ -228,21 +235,24 @@ int cellAudioInit()
|
||||
|
||||
const u64 stamp4 = get_system_time();
|
||||
|
||||
//ConLog.Write("Audio perf: start=%d (access=%d, event=%d, AddData=%d, dump=%d)",
|
||||
//ConLog.Write("Audio perf: start=%d (access=%d, AddData=%d, events=%d, dump=%d)",
|
||||
//stamp0 - m_config.start_time, stamp1-stamp0, stamp2-stamp1, stamp3-stamp2, stamp4-stamp3);
|
||||
}
|
||||
ConLog.Write("Audio finished");
|
||||
abort:
|
||||
queue.Push(nullptr);
|
||||
while (queue.GetCount())
|
||||
|
||||
if(do_dump)
|
||||
m_dump.Finalize();
|
||||
|
||||
m_config.m_is_audio_initialized = false;
|
||||
|
||||
while (!internal_finished)
|
||||
{
|
||||
Sleep(1);
|
||||
}
|
||||
if(Ini.AudioDumpToFile.GetValue())
|
||||
m_dump.Finalize();
|
||||
|
||||
m_config.m_is_audio_finalized = true;
|
||||
m_config.m_is_audio_initialized = false;
|
||||
});
|
||||
t.detach();
|
||||
|
||||
|
@ -12,13 +12,30 @@ CellSurMixerConfig surMixer;
|
||||
#define SUR_PORT (7)
|
||||
u32 surMixerCb = 0;
|
||||
u32 surMixerCbArg = 0;
|
||||
u64 mixcount = 0, stamp1 = 0, stamp2 = 0;
|
||||
SMutex mixer_mutex;
|
||||
bool mixfirst;
|
||||
float mixdata[2*256];
|
||||
u64 mixcount = 0;
|
||||
|
||||
int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 samples)
|
||||
{
|
||||
stamp1 = get_system_time();
|
||||
u32 ch = aan_port >> 16;
|
||||
u32 port = aan_port & 0xffff;
|
||||
switch (ch)
|
||||
{
|
||||
case 1:
|
||||
if (port >= surMixer.chStrips1) ch = 0; break;
|
||||
case 2:
|
||||
if (port >= surMixer.chStrips2) ch = 0; break;
|
||||
case 6:
|
||||
if (port >= surMixer.chStrips6) ch = 0; break;
|
||||
case 8:
|
||||
if (port >= surMixer.chStrips8) ch = 0; break;
|
||||
default:
|
||||
ch = 0;
|
||||
}
|
||||
|
||||
if (aan_handle == 0x11111111 && aan_port == (2 << 16))
|
||||
if (aan_handle == 0x11111111 && samples == 256 && ch && offset == 0)
|
||||
{
|
||||
libmixer.Log("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)",
|
||||
aan_handle, aan_port, offset, addr, samples);
|
||||
@ -31,16 +48,28 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
AudioPortConfig& port = m_config.m_ports[SUR_PORT];
|
||||
SMutexLocker lock(mixer_mutex);
|
||||
|
||||
u32 to = m_config.m_buffer + (128 * 1024 * SUR_PORT) + ((mixcount + 12) % 16) * 2 * 256 * sizeof(float) + offset;
|
||||
const u32 k = ch / 2;
|
||||
|
||||
if (!Memory.Copy(to, addr, 2 * samples * sizeof(float)))
|
||||
if (mixfirst)
|
||||
{
|
||||
return CELL_LIBMIXER_ERROR_NO_MEMORY;
|
||||
for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i += 2)
|
||||
{
|
||||
// reverse byte order and mix
|
||||
mixdata[i] = *(be_t<float>*)&Memory[addr + i * k * sizeof(float)];
|
||||
mixdata[i + 1] = *(be_t<float>*)&Memory[addr + (i * k + 1) * sizeof(float)];
|
||||
}
|
||||
mixfirst = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i += 2)
|
||||
{
|
||||
mixdata[i] += *(be_t<float>*)&Memory[addr + i * k * sizeof(float)];
|
||||
mixdata[i + 1] += *(be_t<float>*)&Memory[addr + (i * k + 1) * sizeof(float)];
|
||||
}
|
||||
}
|
||||
|
||||
stamp2 = get_system_time();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -119,14 +148,14 @@ int cellSurMixerGetAANHandle(mem32_t handle)
|
||||
|
||||
int cellSurMixerChStripGetAANPortNo(mem32_t port, u32 type, u32 index)
|
||||
{
|
||||
libmixer.Warning("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x) -> 0", port.GetAddr(), type, index);
|
||||
libmixer.Warning("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x) -> 0x%x", port.GetAddr(), type, index, (type << 16) | index);
|
||||
port = (type << 16) | index;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSurMixerSetNotifyCallback(u32 func, u32 arg)
|
||||
{
|
||||
libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func, arg);
|
||||
libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x) (surMixerCb=0x%x)", func, arg, surMixerCb);
|
||||
surMixerCb = func;
|
||||
surMixerCbArg = arg;
|
||||
return CELL_OK;
|
||||
@ -134,7 +163,7 @@ int cellSurMixerSetNotifyCallback(u32 func, u32 arg)
|
||||
|
||||
int cellSurMixerRemoveNotifyCallback(u32 func)
|
||||
{
|
||||
libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x)", func);
|
||||
libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x) (surMixerCb=0x%x)", func, surMixerCb);
|
||||
surMixerCb = 0;
|
||||
surMixerCbArg = 0;
|
||||
return CELL_OK;
|
||||
@ -181,22 +210,38 @@ int cellSurMixerStart()
|
||||
return;
|
||||
}
|
||||
|
||||
if (mixcount > port.tag)
|
||||
if (mixcount > (port.tag + 15)) // preemptive buffer filling (probably hack)
|
||||
{
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
u64 stamp0 = get_system_time();
|
||||
stamp1 = 0;
|
||||
stamp2 = 0;
|
||||
|
||||
mixfirst = true;
|
||||
mixerCb->ExecAsCallback(surMixerCb, true, surMixerCbArg, mixcount, 256);
|
||||
|
||||
u64 stamp3 = get_system_time();
|
||||
u64 stamp1 = get_system_time();
|
||||
|
||||
//ConLog.Write("Libmixer perf: start=%d (cb_before=%d, cb=%d, cb_after=%d)",
|
||||
//stamp0 - m_config.start_time, stamp1-stamp0, stamp2-stamp1, stamp3-stamp2);
|
||||
auto buf = (be_t<float>*)&Memory[m_config.m_buffer + (128 * 1024 * SUR_PORT) + (mixcount % 16) * 2 * 256 * sizeof(float)];
|
||||
|
||||
if (!mixfirst)
|
||||
{
|
||||
for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i++)
|
||||
{
|
||||
// reverse byte order
|
||||
buf[i] = mixdata[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no data?
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
@ -229,7 +274,41 @@ int cellSurMixerFinalize()
|
||||
|
||||
int cellSurMixerSurBusAddData(u32 busNo, u32 offset, u32 addr, u32 samples)
|
||||
{
|
||||
libmixer.Error("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, 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.Error("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples);
|
||||
Emu.Pause();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (busNo > 1) // channels from 3 to 8 ignored (TODO)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
SMutexLocker lock(mixer_mutex);
|
||||
|
||||
if (mixfirst)
|
||||
{
|
||||
for (u32 i = 0; i < samples; i++)
|
||||
{
|
||||
// reverse byte order and mix
|
||||
mixdata[i * 2 + busNo] = *(be_t<float>*)&Memory[addr + i * sizeof(float)];
|
||||
}
|
||||
mixfirst = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 0; i < samples; i++)
|
||||
{
|
||||
mixdata[i * 2 + busNo] += *(be_t<float>*)&Memory[addr + i * sizeof(float)];
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,7 @@ enum
|
||||
CELL_LIBMIXER_ERROR_NOT_FOUND = 0x8031000a,
|
||||
};
|
||||
|
||||
//Callback Functions
|
||||
typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); //Currently unused.
|
||||
|
||||
//libmixer datatypes
|
||||
typedef void * CellAANHandle;
|
||||
typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples);
|
||||
|
||||
struct CellSSPlayerConfig
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ int sys_lwmutex_create(mem_ptr_t<sys_lwmutex_t> lwmutex, mem_ptr_t<sys_lwmutex_a
|
||||
}
|
||||
|
||||
lwmutex->attribute = attr->attr_protocol | attr->attr_recursive;
|
||||
lwmutex->all_info() = ~0;
|
||||
lwmutex->waiter = 0;
|
||||
lwmutex->mutex.initialize();
|
||||
//lwmutex->waiter = lwmutex->owner.GetOwner();
|
||||
lwmutex->pad = 0;
|
||||
|
@ -175,15 +175,16 @@ bool ELF32Loader::LoadShdrInfo()
|
||||
for(u32 i=0; i<shdr_arr.GetCount(); ++i)
|
||||
{
|
||||
elf32_f.Seek(shdr_arr[ehdr.e_shstrndx].sh_offset + shdr_arr[i].sh_name);
|
||||
wxString name = wxEmptyString;
|
||||
Array<char> name;
|
||||
while(!elf32_f.Eof())
|
||||
{
|
||||
char c;
|
||||
elf32_f.Read(&c, 1);
|
||||
if(c == 0) break;
|
||||
name += c;
|
||||
name.AddCpy(c);
|
||||
}
|
||||
shdr_name_arr.Add(name);
|
||||
name.AddCpy('\0');
|
||||
shdr_name_arr.Add(wxString(name.GetPtr(), wxConvUTF8));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -176,16 +176,16 @@ bool ELF64Loader::LoadShdrInfo(s64 offset)
|
||||
for(u32 i=0; i<shdr_arr.GetCount(); ++i)
|
||||
{
|
||||
elf64_f.Seek((offset < 0 ? shdr_arr[ehdr.e_shstrndx].sh_offset : shdr_arr[ehdr.e_shstrndx].sh_offset - ehdr.e_shoff + offset) + shdr_arr[i].sh_name);
|
||||
wxString name = wxEmptyString;
|
||||
Array<char> name;
|
||||
while(!elf64_f.Eof())
|
||||
{
|
||||
char c;
|
||||
elf64_f.Read(&c, 1);
|
||||
if(c == 0) break;
|
||||
name += c;
|
||||
name.AddCpy(c);
|
||||
}
|
||||
|
||||
shdr_name_arr.Add(name);
|
||||
name.AddCpy('\0');
|
||||
shdr_name_arr.Add(wxString(name.GetPtr(), wxConvUTF8));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user