From 24eb97f28712b9bed50f5227e6f1a78f1856cd35 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 4 Apr 2014 00:46:40 +0400 Subject: [PATCH] AudioDumper: 8ch output --- rpcs3/Emu/Audio/AudioDumper.cpp | 16 +- rpcs3/Emu/Audio/AudioDumper.h | 1 + rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 165 +++++++++++++++++---- rpcs3/Emu/SysCalls/Modules/cellDmux.cpp | 22 ++- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 4 +- rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 20 +-- 6 files changed, 169 insertions(+), 59 deletions(-) diff --git a/rpcs3/Emu/Audio/AudioDumper.cpp b/rpcs3/Emu/Audio/AudioDumper.cpp index 118ffd6623..1a2e61fea2 100644 --- a/rpcs3/Emu/Audio/AudioDumper.cpp +++ b/rpcs3/Emu/Audio/AudioDumper.cpp @@ -11,9 +11,7 @@ AudioDumper::~AudioDumper() bool AudioDumper::Init() { - if(m_output.Open("audio.wav", wxFile::write)) - return true; - return false; + return m_output.Open("audio.wav", wxFile::write); } void AudioDumper::WriteHeader() @@ -23,16 +21,18 @@ void AudioDumper::WriteHeader() size_t AudioDumper::WriteData(const void* buffer, size_t size) { - /*for (u32 i = 0; i < size / 8; i++) +#ifdef SKIP_EMPTY_AUDIO + bool do_save = false; + for (u32 i = 0; i < size / 8; i++) { - if (((u64*)buffer)[i]) goto process; + if (((u64*)buffer)[i]) do_save = true; } for (u32 i = 0; i < size % 8; i++) { - if (((u8*)buffer)[i + (size & ~7)]) goto process; + if (((u8*)buffer)[i + (size & ~7)]) do_save = true; } - return size; // ignore empty data -process:*/ + if (!do_save) return size; // ignore empty data +#endif size_t ret = m_output.Write(buffer, size); m_header.Size += ret; m_header.RIFF.Size += ret; diff --git a/rpcs3/Emu/Audio/AudioDumper.h b/rpcs3/Emu/Audio/AudioDumper.h index f9ac030476..11a2f6e7e9 100644 --- a/rpcs3/Emu/Audio/AudioDumper.h +++ b/rpcs3/Emu/Audio/AudioDumper.h @@ -65,4 +65,5 @@ public: void WriteHeader(); size_t WriteData(const void* buffer, size_t size); void Finalize(); + const u8 GetCh() const { return m_header.FMT.NumChannels; } }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index aacc9ea3ff..310cd9ec9d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -36,13 +36,13 @@ int cellAudioInit() thread t("Audio Thread", []() { - AudioDumper m_dump(2); // WAV file header (stereo) + AudioDumper m_dump(8); // WAV file header (8 ch) bool do_dump = Ini.AudioDumpToFile.GetValue(); if (do_dump && !m_dump.Init()) { - ConLog.Error("Audio aborted: cannot create file!"); + ConLog.Error("Audio aborted: AudioDumper::Init() failed"); return; } @@ -51,10 +51,11 @@ int cellAudioInit() if (Ini.AudioDumpToFile.GetValue()) m_dump.WriteHeader(); - float buffer[2*256]; // intermediate buffer for 2 channels + float buf2ch[2 * 256]; // intermediate buffer for 2 channels + float buf8ch[8 * 256]; // intermediate buffer for 8 channels uint oal_buffer_offset = 0; - uint oal_buffer_size = sizeof(buffer) / sizeof(float); + uint oal_buffer_size = sizeof(buf2ch) / sizeof(float); std::unique_ptr oal_buffer[32]; SQueue queue; for (u32 i = 0; i < sizeof(oal_buffer) / sizeof(oal_buffer[0]); i++) @@ -139,25 +140,45 @@ int cellAudioInit() auto buf = (be_t*)&Memory[buf_addr]; - static const float k = 1.0f; + static const float k = 1.0f; // may be 0.5f const float m = port.level; if (port.channel == 2) { if (first_mix) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { // reverse byte order - buffer[i] = buf[i] * m; + const float left = buf[i + 0] * m; + const float right = buf[i + 1] * m; + + buf2ch[i + 0] = left; + buf2ch[i + 1] = right; + + buf8ch[i * 4 + 0] = left; + buf8ch[i * 4 + 1] = right; + buf8ch[i * 4 + 2] = 0.0f; + buf8ch[i * 4 + 3] = 0.0f; + buf8ch[i * 4 + 4] = 0.0f; + buf8ch[i * 4 + 5] = 0.0f; + buf8ch[i * 4 + 6] = 0.0f; + buf8ch[i * 4 + 7] = 0.0f; } first_mix = false; } else { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - buffer[i] += buf[i] * m; + const float left = buf[i + 0] * m; + const float right = buf[i + 1] * m; + + buf2ch[i + 0] += left; + buf2ch[i + 1] += right; + + buf8ch[i * 4 + 0] += left; + buf8ch[i * 4 + 1] += right; } } } @@ -165,21 +186,51 @@ int cellAudioInit() { if (first_mix) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*3+2] + buf[i*3+3]) * 0.708f; - buffer[i] = (buf[i*3] + buf[i*3+4] + center) * k * m; - buffer[i+1] = (buf[i*3+1] + buf[i*3+5] + center) * k * m; + const float left = buf[i * 3 + 0] * m; + const float right = buf[i * 3 + 1] * m; + const float center = buf[i * 3 + 2] * m; + const float low_freq = buf[i * 3 + 3] * m; + const float rear_left = buf[i * 3 + 4] * m; + const float rear_right = buf[i * 3 + 5] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] = (left + rear_left + mid) * k; + buf2ch[i + 1] = (right + rear_right + mid) * k; + + buf8ch[i * 4 + 0] = left; + buf8ch[i * 4 + 1] = right; + buf8ch[i * 4 + 2] = center; + buf8ch[i * 4 + 3] = low_freq; + buf8ch[i * 4 + 4] = rear_left; + buf8ch[i * 4 + 5] = rear_right; + buf8ch[i * 4 + 6] = 0.0f; + buf8ch[i * 4 + 7] = 0.0f; } first_mix = false; } else { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*3+2] + buf[i*3+3]) * 0.708f; - buffer[i] += (buf[i*3] + buf[i*3+4] + center) * k * m; - buffer[i+1] += (buf[i*3+1] + buf[i*3+5] + center) * k * m; + const float left = buf[i * 3 + 0] * m; + const float right = buf[i * 3 + 1] * m; + const float center = buf[i * 3 + 2] * m; + const float low_freq = buf[i * 3 + 3] * m; + const float rear_left = buf[i * 3 + 4] * m; + const float rear_right = buf[i * 3 + 5] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] += (left + rear_left + mid) * k; + buf2ch[i + 1] += (right + rear_right + mid) * k; + + buf8ch[i * 4 + 0] += left; + buf8ch[i * 4 + 1] += right; + buf8ch[i * 4 + 2] += center; + buf8ch[i * 4 + 3] += low_freq; + buf8ch[i * 4 + 4] += rear_left; + buf8ch[i * 4 + 5] += rear_right; } } } @@ -187,21 +238,57 @@ int cellAudioInit() { if (first_mix) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*4+2] + buf[i*4+3]) * 0.708f; - buffer[i] = (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * k * m; - buffer[i+1] = (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * k * m; + const float left = buf[i * 4 + 0] * m; + const float right = buf[i * 4 + 1] * m; + const float center = buf[i * 4 + 2] * m; + const float low_freq = buf[i * 4 + 3] * m; + const float rear_left = buf[i * 4 + 4] * m; + const float rear_right = buf[i * 4 + 5] * m; + const float side_left = buf[i * 4 + 6] * m; + const float side_right = buf[i * 4 + 7] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] = (left + rear_left + side_left + mid) * k; + buf2ch[i + 1] = (right + rear_right + side_right + mid) * k; + + buf8ch[i * 4 + 0] = left; + buf8ch[i * 4 + 1] = right; + buf8ch[i * 4 + 2] = center; + buf8ch[i * 4 + 3] = low_freq; + buf8ch[i * 4 + 4] = rear_left; + buf8ch[i * 4 + 5] = rear_right; + buf8ch[i * 4 + 6] = side_left; + buf8ch[i * 4 + 7] = side_right; } first_mix = false; } else { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*4+2] + buf[i*4+3]) * 0.708f; - buffer[i] += (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * k * m; - buffer[i+1] += (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * k * m; + const float left = buf[i * 4 + 0] * m; + const float right = buf[i * 4 + 1] * m; + const float center = buf[i * 4 + 2] * m; + const float low_freq = buf[i * 4 + 3] * m; + const float rear_left = buf[i * 4 + 4] * m; + const float rear_right = buf[i * 4 + 5] * m; + const float side_left = buf[i * 4 + 6] * m; + const float side_right = buf[i * 4 + 7] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] += (left + rear_left + side_left + mid) * k; + buf2ch[i + 1] += (right + rear_right + side_right + mid) * k; + + buf8ch[i * 4 + 0] += left; + buf8ch[i * 4 + 1] += right; + buf8ch[i * 4 + 2] += center; + buf8ch[i * 4 + 3] += low_freq; + buf8ch[i * 4 + 4] += rear_left; + buf8ch[i * 4 + 5] += rear_right; + buf8ch[i * 4 + 6] += side_left; + buf8ch[i * 4 + 7] += side_right; } } } @@ -221,12 +308,12 @@ int cellAudioInit() // 2x MINPS (optional) // 2x CVTPS2DQ (converts float to s32) // PACKSSDW (converts s32 to s16 with clipping) - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 8) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 8) { static const __m128 float2u16 = { 0x8000, 0x8000, 0x8000, 0x8000 }; (__m128i&)(oal_buffer[oal_pos][oal_buffer_offset + i]) = _mm_packs_epi32( - _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buffer[i]), float2u16)), - _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buffer[i + 4]), float2u16))); + _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buf2ch[i]), float2u16)), + _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buf2ch[i + 4]), float2u16))); } } @@ -234,7 +321,7 @@ int cellAudioInit() if (!first_mix) { - oal_buffer_offset += sizeof(buffer) / sizeof(float); + oal_buffer_offset += sizeof(buf2ch) / sizeof(float); if(oal_buffer_offset >= oal_buffer_size) { @@ -279,9 +366,25 @@ int cellAudioInit() if (do_dump && !first_mix) { - if (m_dump.WriteData(&buffer, sizeof(buffer)) != sizeof(buffer)) // write file data + if (m_dump.GetCh() == 8) { - ConLog.Error("Port aborted: cannot write file!"); + if (m_dump.WriteData(&buf8ch, sizeof(buf8ch)) != sizeof(buf8ch)) // write file data + { + ConLog.Error("Audio aborted: AudioDumper::WriteData() failed"); + goto abort; + } + } + else if (m_dump.GetCh() == 2) + { + if (m_dump.WriteData(&buf2ch, sizeof(buf2ch)) != sizeof(buf2ch)) // write file data + { + ConLog.Error("Audio aborted: AudioDumper::WriteData() failed"); + goto abort; + } + } + else + { + ConLog.Error("Audio aborted: unknown AudioDumper::GetCh() value (%d)", m_dump.GetCh()); goto abort; } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 2fac7e0bae..4b9aef7444 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -337,8 +337,13 @@ u32 dmuxOpen(Demuxer* data) cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/ dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, task.type == dmuxResetStreamAndWaitDone, dmux.id, dmuxMsg.GetAddr(), dmux.cbArg); + updates_signaled++; dmux.is_running = false; + if (task.type == dmuxResetStreamAndWaitDone) + { + dmux.fbSetStream.Push(0); + } } break; @@ -675,16 +680,17 @@ int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) dmux->job.Push(DemuxerTask(dmuxResetStreamAndWaitDone)); - while (dmux->is_running) + u32 addr; + if (!dmux->fbSetStream.Pop(addr)) { - if (Emu.IsStopped()) - { - ConLog.Warning("cellDmuxResetStreamAndWaitDone(%d) aborted", demuxerHandle); - break; - } - Sleep(1); + ConLog.Warning("cellDmuxResetStreamAndWaitDone(%d) aborted (fbSetStream.Pop())", demuxerHandle); + return CELL_OK; + } + if (addr != 0) + { + ConLog.Error("cellDmuxResetStreamAndWaitDone(%d): wrong stream queued (0x%x)", demuxerHandle, addr); + Emu.Pause(); } - return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index c261d848e9..ec9ac69f31 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -532,7 +532,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) option = 0; - int available = 2; // should be at least 2 + int available = 8; // should be at least 2 switch(fs) { @@ -573,7 +573,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3 option = 0; - int available = 2; // should be at least 2 + int available = 8; // should be at least 2 switch(fs) { diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index f441922fa7..e49ac699b0 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -56,8 +56,8 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl for (u32 i = 0; i < samples; i++) { const float center = *(be_t*)&Memory[addr + i * sizeof(float)]; - mixdata[i*8+0] += center; - mixdata[i*8+1] += center; + mixdata[i * 8 + 0] += center; + mixdata[i * 8 + 1] += center; } } else if (type == CELL_SURMIXER_CHSTRIP_TYPE2A) @@ -67,8 +67,8 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl { const float left = *(be_t*)&Memory[addr + i * 2 * sizeof(float)]; const float right = *(be_t*)&Memory[addr + (i * 2 + 1) * sizeof(float)]; - mixdata[i*8+0] += left; - mixdata[i*8+1] += right; + mixdata[i * 8 + 0] += left; + mixdata[i * 8 + 1] += right; } } else if (type == CELL_SURMIXER_CHSTRIP_TYPE6A) @@ -82,12 +82,12 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl const float low_freq = *(be_t*)&Memory[addr + (i * 6 + 3) * sizeof(float)]; const float rear_left = *(be_t*)&Memory[addr + (i * 6 + 4) * sizeof(float)]; const float rear_right = *(be_t*)&Memory[addr + (i * 6 + 5) * sizeof(float)]; - 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; + 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)