AudioDumper: 8ch output

This commit is contained in:
Nekotekina 2014-04-04 00:46:40 +04:00
parent fb9dbfab3a
commit 24eb97f287
6 changed files with 169 additions and 59 deletions

View File

@ -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;

View File

@ -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; }
};

View File

@ -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<u16[]> oal_buffer[32];
SQueue<u16*, 31> queue;
for (u32 i = 0; i < sizeof(oal_buffer) / sizeof(oal_buffer[0]); i++)
@ -139,25 +140,45 @@ int cellAudioInit()
auto buf = (be_t<float>*)&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;
}
}

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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<float>*)&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<float>*)&Memory[addr + i * 2 * sizeof(float)];
const float right = *(be_t<float>*)&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<float>*)&Memory[addr + (i * 6 + 3) * sizeof(float)];
const float rear_left = *(be_t<float>*)&Memory[addr + (i * 6 + 4) * sizeof(float)];
const float rear_right = *(be_t<float>*)&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)