Added AI FIFO wave logging to HLE plugin. Same for LLE plugin is coming soon. Plus some extra critical section locks in LLE plugin.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@797 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
8dc32f5dee
commit
49534ca586
|
@ -0,0 +1,121 @@
|
|||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "Common.h"
|
||||
#include "WaveFile.h"
|
||||
|
||||
enum {BUF_SIZE = 32*1024};
|
||||
|
||||
WaveFileWriter::WaveFileWriter()
|
||||
{
|
||||
conv_buffer = 0;
|
||||
skip_silence = false;
|
||||
}
|
||||
|
||||
WaveFileWriter::~WaveFileWriter()
|
||||
{
|
||||
delete [] conv_buffer;
|
||||
Stop();
|
||||
}
|
||||
|
||||
bool WaveFileWriter::Start(const char *filename)
|
||||
{
|
||||
if (!conv_buffer)
|
||||
conv_buffer = new short[BUF_SIZE];
|
||||
|
||||
if (file)
|
||||
return false;
|
||||
file = fopen(filename, "wb");
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
Write4("RIFF");
|
||||
Write(100 * 1000 * 1000); // write big value in case the file gets truncated
|
||||
Write4("WAVE");
|
||||
Write4("fmt ");
|
||||
Write(16); // size of fmt block
|
||||
Write(0x00020001); //two channels, uncompressed
|
||||
const u32 sample_rate = 32000;
|
||||
Write(sample_rate);
|
||||
Write(sample_rate * 2 * 2); //two channels, 16bit
|
||||
Write(0x00100004);
|
||||
Write4("data");
|
||||
Write(100 * 1000 * 1000 - 32);
|
||||
// We are now at offset 44
|
||||
if (ftell(file) != 44)
|
||||
PanicAlert("wrong offset: %i", ftell(file));
|
||||
}
|
||||
|
||||
void WaveFileWriter::Stop()
|
||||
{
|
||||
if (!file)
|
||||
return;
|
||||
u32 file_size = (u32)ftell(file);
|
||||
fseek(file, 4, SEEK_SET);
|
||||
Write(audio_size + 36);
|
||||
fseek(file, 40, SEEK_SET);
|
||||
Write(audio_size);
|
||||
fclose(file);
|
||||
file = 0;
|
||||
}
|
||||
|
||||
void WaveFileWriter::Write(u32 value)
|
||||
{
|
||||
fwrite(&value, 4, 1, file);
|
||||
}
|
||||
|
||||
void WaveFileWriter::Write4(const char *ptr)
|
||||
{
|
||||
fwrite(ptr, 4, 1, file);
|
||||
}
|
||||
|
||||
void WaveFileWriter::AddStereoSamples(const short *sample_data, int count)
|
||||
{
|
||||
if (!file)
|
||||
PanicAlert("WaveFileWriter - file not open.");
|
||||
if (skip_silence) {
|
||||
bool all_zero = true;
|
||||
for (int i = 0; i < count * 2; i++)
|
||||
if (sample_data[i])
|
||||
all_zero = false;
|
||||
if (all_zero)
|
||||
return;
|
||||
}
|
||||
fwrite(sample_data, count * 4, 1, file);
|
||||
audio_size += count * 4;
|
||||
}
|
||||
|
||||
void WaveFileWriter::AddStereoSamplesBE(const short *sample_data, int count)
|
||||
{
|
||||
if (!file)
|
||||
PanicAlert("WaveFileWriter - file not open.");
|
||||
if (count > BUF_SIZE * 2)
|
||||
PanicAlert("WaveFileWriter - buffer too small (count = %i).", count);
|
||||
if (skip_silence) {
|
||||
bool all_zero = true;
|
||||
for (int i = 0; i < count * 2; i++)
|
||||
if (sample_data[i])
|
||||
all_zero = false;
|
||||
if (all_zero)
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < count * 2; i++) {
|
||||
conv_buffer[i] = Common::swap16((u16)sample_data[i]);
|
||||
}
|
||||
fwrite(conv_buffer, count * 4, 1, file);
|
||||
audio_size += count * 4;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
// WaveFileWriter
|
||||
|
||||
// Simple utility class to make it easy to write long 16-bit stereo
|
||||
// audio streams to disk.
|
||||
// Use Start() to start recording to a file, and AddStereoSamples to add wave data.
|
||||
// The float variant will convert from -1.0-1.0 range and clamp.
|
||||
// Alternatively, AddSamplesBE for big endian wave data.
|
||||
// If Stop is not called when it destructs, the destructor will call Stop().
|
||||
|
||||
#ifndef _WAVEFILE_H
|
||||
#define _WAVEFILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
class WaveFileWriter
|
||||
{
|
||||
FILE *file;
|
||||
bool skip_silence;
|
||||
u32 audio_size;
|
||||
short *conv_buffer;
|
||||
void Write(u32 value);
|
||||
void Write4(const char *ptr);
|
||||
|
||||
public:
|
||||
WaveFileWriter();
|
||||
~WaveFileWriter();
|
||||
|
||||
bool Start(const char *filename);
|
||||
void Stop();
|
||||
|
||||
void SetSkipSilence(bool skip) { skip_silence = skip; }
|
||||
|
||||
void AddStereoSamples(const short *sample_data, int count);
|
||||
void AddStereoSamplesBE(const short *sample_data, int count); // big endian
|
||||
};
|
||||
|
||||
#endif // _WAVEFILE_H
|
|
@ -163,7 +163,7 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
|
|||
|
||||
for (int i = 0; i < numberOfPBs; i++)
|
||||
{
|
||||
vector1.at(i).at(vectorLength-1) = PBs[i].running;
|
||||
vector1.at(i).at(vectorLength-1) = PBs[i].running ? true : false;
|
||||
}
|
||||
// ==============
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
|
||||
#include "Debugger/Debugger.h" // for the CDebugger class
|
||||
#include "ChunkFile.h"
|
||||
#include "WaveFile.h"
|
||||
#include "resource.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -34,15 +34,14 @@
|
|||
#include "Config.h"
|
||||
|
||||
#include "Logging/Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
|
||||
// ===================
|
||||
|
||||
|
||||
// =======================================================================================
|
||||
// DSP struct
|
||||
// -------------------
|
||||
DSPInitialize g_dspInitialize;
|
||||
u8* g_pMemory;
|
||||
|
||||
// Set this if you want to log audio. search for log_ai in this file to see the filename.
|
||||
static bool log_ai = false;
|
||||
static WaveFileWriter g_wave_writer;
|
||||
|
||||
struct DSPState
|
||||
{
|
||||
u32 CPUMailbox;
|
||||
|
@ -211,10 +210,16 @@ void DSP_Initialize(DSPInitialize _dspInitialize)
|
|||
#else
|
||||
AOSound::AOSound_StartSound(48000, Mixer);
|
||||
#endif
|
||||
if (log_ai) {
|
||||
g_wave_writer.Start("D:\\ai_log.wav");
|
||||
g_wave_writer.SetSkipSilence(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DSP_Shutdown()
|
||||
{
|
||||
if (log_ai)
|
||||
g_wave_writer.Stop();
|
||||
// delete the UCodes
|
||||
#ifdef _WIN32
|
||||
DSound::DSound_StopSound();
|
||||
|
@ -315,6 +320,8 @@ void DSP_SendAIBuffer(unsigned int address, int sample_rate)
|
|||
for (int i = 0; i < 16; i++) {
|
||||
samples[i] = Memory_Read_U16(address + i * 2);
|
||||
}
|
||||
if (log_ai)
|
||||
g_wave_writer.AddStereoSamples(samples, 8);
|
||||
}
|
||||
Mixer_PushSamples(samples, 32 / 4, sample_rate);
|
||||
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "Globals.h"
|
||||
#include "gdsp_interface.h"
|
||||
|
||||
extern uint16 dsp_swap16(uint16 x);
|
||||
|
||||
|
||||
// the hardware adpcm decoder :)
|
||||
// The hardware adpcm decoder :)
|
||||
sint16 ADPCM_Step(uint32& _rSamplePos, uint32 _BaseAddress)
|
||||
{
|
||||
sint16* pCoefTable = (sint16*)&gdsp_ifx_regs[DSP_COEF_A1_0];
|
||||
|
@ -42,30 +42,25 @@ sint16 ADPCM_Step(uint32& _rSamplePos, uint32 _BaseAddress)
|
|||
(g_dspInitialize.pARAM_Read_U8(_rSamplePos >> 1) >> 4);
|
||||
|
||||
if (temp >= 8)
|
||||
{
|
||||
temp -= 16; //temp += 0xFFFFFFF0;
|
||||
}
|
||||
temp -= 16;
|
||||
|
||||
// 0x400 = 0.5 in 11-bit fixed point
|
||||
int val = (scale * temp) + ((0x400 + coef1 * (sint16)gdsp_ifx_regs[DSP_YN1] + coef2 * (sint16)gdsp_ifx_regs[DSP_YN2]) >> 11);
|
||||
|
||||
// Clamp values.
|
||||
if (val > 0x7FFF)
|
||||
{
|
||||
val = 0x7FFF;
|
||||
}
|
||||
else if (val < -0x7FFF)
|
||||
{
|
||||
val = -0x7FFF;
|
||||
}
|
||||
|
||||
gdsp_ifx_regs[DSP_YN2] = gdsp_ifx_regs[DSP_YN1];
|
||||
gdsp_ifx_regs[DSP_YN1] = val;
|
||||
|
||||
_rSamplePos++;
|
||||
|
||||
return(val);
|
||||
|
||||
// I think the interpolation (linear, polyphase,...) is done by the UCode
|
||||
// The advanced interpolation (linear, polyphase,...) is done by the UCode, so we don't
|
||||
// need to bother with it here.
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,6 +101,10 @@ uint16 dsp_read_aram()
|
|||
Address = (gdsp_ifx_regs[DSP_ACSAH] << 16) | gdsp_ifx_regs[DSP_ACSAL];
|
||||
// ErrorLog("Should we generate a lvl5 exception !??!");
|
||||
// gdsp_exception(5);
|
||||
|
||||
// Somehow, YN1 and YN2 must be initialized with their "loop" values, so yeah,
|
||||
// it seems likely that we should raise an exception to let the DSP program do that,
|
||||
// at least if DSP_FORMAT == 0x0A.
|
||||
}
|
||||
|
||||
gdsp_ifx_regs[DSP_ACCAH] = Address >> 16;
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
#pragma once
|
||||
|
||||
#ifndef _GDSP_ARAM_H
|
||||
#define _GDSP_ARAM_H
|
||||
|
||||
uint16 dsp_read_aram();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include "Globals.h"
|
||||
#include "Thread.h"
|
||||
|
||||
#include "gdsp_aram.h"
|
||||
#include "gdsp_interpreter.h"
|
||||
|
@ -66,9 +67,8 @@ const char* reg_names[] =
|
|||
|
||||
void gdsp_dma();
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
extern CRITICAL_SECTION g_CriticalSection;
|
||||
#ifdef WITH_DSP_ON_THREAD
|
||||
Common::CriticalSection g_CriticalSection;
|
||||
#endif
|
||||
|
||||
static volatile uint16 gdsp_mbox[2][2];
|
||||
|
@ -93,20 +93,27 @@ void gdsp_ifx_init()
|
|||
|
||||
uint32 gdsp_mbox_peek(uint8 mbx)
|
||||
{
|
||||
return((gdsp_mbox[mbx][0] << 16) | gdsp_mbox[mbx][1]);
|
||||
#if WITH_DSP_ON_THREAD
|
||||
g_CriticalSection.Enter();
|
||||
#endif
|
||||
uint32 value = ((gdsp_mbox[mbx][0] << 16) | gdsp_mbox[mbx][1]);
|
||||
#if WITH_DSP_ON_THREAD
|
||||
g_CriticalSection.Leave();
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void gdsp_mbox_write_h(uint8 mbx, uint16 val)
|
||||
{
|
||||
#if WITH_DSP_ON_THREAD
|
||||
EnterCriticalSection(&g_CriticalSection);
|
||||
g_CriticalSection.Enter();
|
||||
#endif
|
||||
|
||||
gdsp_mbox[mbx][0] = val & 0x7fff;
|
||||
|
||||
#if WITH_DSP_ON_THREAD
|
||||
LeaveCriticalSection(&g_CriticalSection);
|
||||
g_CriticalSection.Leave();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -114,14 +121,14 @@ void gdsp_mbox_write_h(uint8 mbx, uint16 val)
|
|||
void gdsp_mbox_write_l(uint8 mbx, uint16 val)
|
||||
{
|
||||
#if WITH_DSP_ON_THREAD
|
||||
EnterCriticalSection(&g_CriticalSection);
|
||||
g_CriticalSection.Enter();
|
||||
#endif
|
||||
|
||||
gdsp_mbox[mbx][1] = val;
|
||||
gdsp_mbox[mbx][0] |= 0x8000;
|
||||
|
||||
#if WITH_DSP_ON_THREAD
|
||||
LeaveCriticalSection(&g_CriticalSection);
|
||||
g_CriticalSection.Leave();
|
||||
#endif
|
||||
|
||||
if (mbx == GDSP_MBOX_DSP)
|
||||
|
@ -141,14 +148,14 @@ uint16 gdsp_mbox_read_l(uint8 mbx)
|
|||
{
|
||||
uint16 val;
|
||||
#if WITH_DSP_ON_THREAD
|
||||
EnterCriticalSection(&g_CriticalSection);
|
||||
g_CriticalSection.Enter();
|
||||
#endif
|
||||
|
||||
val = gdsp_mbox[mbx][1];
|
||||
gdsp_mbox[mbx][0] &= ~0x8000;
|
||||
|
||||
#if WITH_DSP_ON_THREAD
|
||||
LeaveCriticalSection(&g_CriticalSection);
|
||||
g_CriticalSection.Leave();
|
||||
#endif
|
||||
return(val);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue