add some things to maybe help debug sound quality issues (developer option to record user SPU to WAV, define the sample rate 44100 in a single place, printout on audio buffer clear)

This commit is contained in:
nitsuja 2009-11-08 17:04:07 +00:00
parent 1b7d14c178
commit 00b28e5807
10 changed files with 90 additions and 33 deletions

View File

@ -318,7 +318,7 @@ void SPU_struct::ShutUp()
static FORCEINLINE void adjust_channel_timer(channel_struct *chan)
{
chan->sampinc = (((double)ARM7_CLOCK) / (44100 * 2)) / (double)(0x10000 - chan->timer);
chan->sampinc = (((double)ARM7_CLOCK) / (DESMUME_SAMPLE_RATE * 2)) / (double)(0x10000 - chan->timer);
}
void SPU_struct::KeyOn(int channel)
@ -870,7 +870,7 @@ static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
static const int dots_per_clock = 6;
static const int dots_per_hline = 355;
static const double time_per_hline = (double)1.0/((double)ARM7_CLOCK/dots_per_clock/dots_per_hline);
static const double samples_per_hline = time_per_hline * 44100;
static const double samples_per_hline = time_per_hline * DESMUME_SAMPLE_RATE;
int spu_core_samples = 0;
void SPU_Emulate_core()
{
@ -910,6 +910,7 @@ void SPU_Emulate_user(bool mix)
samplesOutput = (SPU_MixAudio(mix,SPU_user,audiosize), audiosize);
SNDCore->UpdateAudio(SPU_user->outbuf, samplesOutput);
WAV_WavSoundUpdate(SPU_user->outbuf, samplesOutput, WAVMODE_USER);
}
}
@ -940,7 +941,7 @@ SoundInterface_struct SNDDummy = {
int SNDDummyInit(int buffersize) { return 0; }
void SNDDummyDeInit() {}
void SNDDummyUpdateAudio(s16 *buffer, u32 num_samples) { }
u32 SNDDummyGetAudioSpace() { return 740; }
u32 SNDDummyGetAudioSpace() { return DESMUME_SAMPLE_RATE/60 + 5; }
void SNDDummyMuteAudio() {}
void SNDDummyUnMuteAudio() {}
void SNDDummySetVolume(int volume) {}
@ -992,7 +993,7 @@ bool WavWriter::open(const std::string & fname)
fmt.chunk.size = 16; // we'll fix this at the end
fmt.compress = 1; // PCM
fmt.numchan = 2; // Stereo
fmt.rate = 44100;
fmt.rate = DESMUME_SAMPLE_RATE;
fmt.bitspersample = 16;
fmt.blockalign = fmt.bitspersample / 8 * fmt.numchan;
fmt.bytespersec = fmt.rate * fmt.blockalign;
@ -1044,26 +1045,33 @@ void WAV_End()
wavWriter.close();
}
bool WAV_Begin(const char* fname)
bool WAV_Begin(const char* fname, WAVMode mode)
{
WAV_End();
if(!wavWriter.open(fname))
return false;
if(mode == WAVMODE_ANY)
mode = WAVMODE_CORE;
wavWriter.mode = mode;
driver->USR_InfoMessage("WAV recording started.");
return true;
}
bool WAV_IsRecording()
bool WAV_IsRecording(WAVMode mode)
{
return wavWriter.isRecording();
if(wavWriter.mode == mode || mode == WAVMODE_ANY)
return wavWriter.isRecording();
return false;
}
void WAV_WavSoundUpdate(void* soundData, int numSamples)
void WAV_WavSoundUpdate(void* soundData, int numSamples, WAVMode mode)
{
wavWriter.update(soundData, numSamples);
if(wavWriter.mode == mode || mode == WAVMODE_ANY)
wavWriter.update(soundData, numSamples);
}

View File

@ -149,6 +149,13 @@ extern int spu_core_samples;
void spu_savestate(EMUFILE* os);
bool spu_loadstate(EMUFILE* is, int size);
enum WAVMode
{
WAVMODE_ANY = -1,
WAVMODE_CORE = 0,
WAVMODE_USER = 1
};
class WavWriter
{
public:
@ -157,14 +164,19 @@ public:
void close();
void update(void* soundData, int numSamples);
bool isRecording() const;
WAVMode mode;
private:
FILE *spufp;
};
void WAV_End();
bool WAV_Begin(const char* fname);
bool WAV_IsRecording();
void WAV_WavSoundUpdate(void* soundData, int numSamples);
bool WAV_Begin(const char* fname, WAVMode mode=WAVMODE_CORE);
bool WAV_IsRecording(WAVMode mode=WAVMODE_ANY);
void WAV_WavSoundUpdate(void* soundData, int numSamples, WAVMode mode=WAVMODE_CORE);
// we should make this configurable eventually
// but at least defining it somewhere is probably a step in the right direction
#define DESMUME_SAMPLE_RATE 44100
//#define DESMUME_SAMPLE_RATE 48000
#endif

View File

@ -80,8 +80,11 @@ static const int SndOutVolumeShift = 0;
// is too problematic. :)
//this is hardcoded differently for metaspu
//edit - zeromus 23-oct-2009
//static const int SampleRate = 48000;
static const int SampleRate = 44100;
////static const int SampleRate = 48000;
//static const int SampleRate = 44100;
//edit - nitsuja: make it use the global sample rate define
#include "..\SPU.h"
static const int SampleRate = DESMUME_SAMPLE_RATE;
extern int FindOutputModuleById( const wchar_t* omodid );

View File

@ -26,6 +26,7 @@
#include "gfx3d.h"
#include "aviout.h"
#include "../GPU_osd.h"
#include "../SPU.h"
#include <assert.h>
#include <vfw.h>
@ -80,7 +81,7 @@ static struct AVIFile
long tBytes, ByteBuffer;
u8 audio_buffer[44100*2*2]; // 1 second buffer
u8 audio_buffer[DESMUME_SAMPLE_RATE*2*2]; // 1 second buffer
int audio_buffer_pos;
} *avi_file = NULL;
@ -365,10 +366,10 @@ bool DRV_AviBegin(const char* fname)
WAVEFORMATEX wf;
wf.cbSize = sizeof(WAVEFORMATEX);
wf.nAvgBytesPerSec = 44100 * 4;
wf.nAvgBytesPerSec = DESMUME_SAMPLE_RATE * 4;
wf.nBlockAlign = 4;
wf.nChannels = 2;
wf.nSamplesPerSec = 44100;
wf.nSamplesPerSec = DESMUME_SAMPLE_RATE;
wf.wBitsPerSample = 16;
wf.wFormatTag = WAVE_FORMAT_PCM;

View File

@ -238,7 +238,7 @@ void HK_DecreaseVolume(int, bool justPressed)
void HK_Reset(int, bool justPressed) {ResetGame();}
void HK_RecordAVI(int, bool justPressed) { if (AVI_IsRecording()) AviEnd(); else AviRecordTo(); }
void HK_RecordWAV(int, bool justPressed) { if (WAV_IsRecording()) WavEnd(); else WavRecordTo(); }
void HK_RecordWAV(int, bool justPressed) { if (WAV_IsRecording()) WavEnd(); else WavRecordTo(WAVMODE_CORE); }
void HK_ToggleFrame(int, bool justPressed) {CommonSettings.hud.FrameCounterDisplay ^= true;}
void HK_ToggleFPS(int, bool justPressed) {CommonSettings.hud.FpsDisplay ^= true;}

View File

@ -140,6 +140,10 @@ void wxTest() {
#endif
#ifndef PUBLIC_RELEASE
#define DEVELOPER_MENU_ITEMS
#endif
const int kGapNone = 0;
const int kGapBorder = 5;
const int kGapNDS = 64; // extremely tilted (but some games seem to use this value)
@ -269,7 +273,7 @@ extern bool userTouchesScreen;
/*__declspec(thread)*/ bool inFrameBoundary = false;
static int sndcoretype=SNDCORE_DIRECTX;
static int sndbuffersize=735*8;
static int sndbuffersize=DESMUME_SAMPLE_RATE*8/60;
static int snd_synchmode=0;
static int snd_synchmethod=0;
int sndvolume=100;
@ -1481,7 +1485,7 @@ static void StepRunLoop_Core()
Lock lock;
NDS_exec<false>();
//SPU_Emulate_user();
win_sound_samplecounter = 735;
win_sound_samplecounter = DESMUME_SAMPLE_RATE/60;
}
inFrameBoundary = true;
DRV_AviVideoUpdate((u16*)GPU_screen);
@ -1844,6 +1848,12 @@ int MenuInit()
ResetSaveStateTimes();
#ifndef DEVELOPER_MENU_ITEMS
// menu items that are only useful for desmume developers (maybe)
HMENU fileMenu = GetSubMenu(mainMenu, 0);
DeleteMenu(fileMenu, IDM_FILE_RECORDUSERSPUWAV, MF_BYCOMMAND);
#endif
return 1;
}
@ -2450,7 +2460,7 @@ int _main()
#endif
LOG("Init sound core\n");
sndcoretype = GetPrivateProfileInt("Sound","SoundCore2", SNDCORE_DIRECTX, IniName);
sndbuffersize = GetPrivateProfileInt("Sound","SoundBufferSize2", 735*8, IniName);
sndbuffersize = GetPrivateProfileInt("Sound","SoundBufferSize2", DESMUME_SAMPLE_RATE*8/60, IniName);
CommonSettings.spuInterpolationMode = (SPUInterpolationMode)GetPrivateProfileInt("Sound","SPUInterpolation", 1, IniName);
EnterCriticalSection(&win_execute_sync);
@ -3019,7 +3029,7 @@ void WavEnd()
}
//Shows an Open File menu and starts recording an WAV
void WavRecordTo()
void WavRecordTo(int wavmode)
{
NDS_Pause();
@ -3061,7 +3071,7 @@ void WavRecordTo()
if(GetSaveFileName(&ofn))
{
WAV_Begin(szChoice);
WAV_Begin(szChoice, (WAVMode)wavmode);
}
NDS_UnPause();
@ -3462,6 +3472,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
DesEnableMenuItem(mainMenu, IDM_CHEATS_LIST, romloaded);
DesEnableMenuItem(mainMenu, IDM_CHEATS_SEARCH, romloaded);
//DesEnableMenuItem(mainMenu, IDM_WIFISETTINGS, romloaded);
#ifdef DEVELOPER_MENU_ITEMS
DesEnableMenuItem(mainMenu, IDM_FILE_RECORDUSERSPUWAV, romloaded && !WAV_IsRecording());
#endif
DesEnableMenuItem(mainMenu, IDM_RECORD_MOVIE, (romloaded /*&& movieMode == MOVIEMODE_INACTIVE*/));
DesEnableMenuItem(mainMenu, IDM_PLAY_MOVIE, (romloaded /*&& movieMode == MOVIEMODE_INACTIVE*/));
@ -4098,8 +4111,16 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
if (WAV_IsRecording())
WAV_End();
else
WavRecordTo();
WavRecordTo(WAVMODE_CORE);
break;
#ifdef DEVELOPER_MENU_ITEMS
case IDM_FILE_RECORDUSERSPUWAV:
if (WAV_IsRecording())
WAV_End();
else
WavRecordTo(WAVMODE_USER);
break;
#endif
case IDC_STATEREWINDING:
if(staterewindingenabled) staterewindingenabled = false;
else staterewindingenabled = true;

View File

@ -16,7 +16,7 @@ void FrameAdvance(bool state);
void ResetGame(); //Resets game (for the menu item & hotkey
void AviRecordTo();
void AviEnd();
void WavRecordTo();
void WavRecordTo(int wavmode);
void WavEnd();
extern bool frameCounterDisplay;

View File

@ -694,6 +694,7 @@
#define IDM_SCREENSEP_COLORWHITE 40023
#define IDM_SCREENSEP_COLORGRAY 40024
#define IDM_SCREENSEP_COLORBLACK 40025
#define IDM_FILE_RECORDUSERSPUWAV 40026
#define ID_FILE_RECENTROM 40034
#define IDC_SAVETYPE7 40037
#define IDM_DEFSIZE 40038

Binary file not shown.

View File

@ -132,7 +132,7 @@ int SNDDXInit(int buffersize)
memset(&wfx, 0, sizeof(wfx));
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = 44100;
wfx.nSamplesPerSec = DESMUME_SAMPLE_RATE;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = (wfx.wBitsPerSample / 8) * wfx.nChannels;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
@ -248,12 +248,12 @@ void SNDDXUpdateAudio(s16 *buffer, u32 num_samples)
}
else
{
samplecounter = win_sound_samplecounter -= 245;
samplecounter_fakecontribution += 245;
samplecounter = win_sound_samplecounter -= DESMUME_SAMPLE_RATE/180;
samplecounter_fakecontribution += DESMUME_SAMPLE_RATE/180;
}
}
bool silence = (samplecounter<-44100*15/60); //behind by more than a quarter second -> silence
bool silence = (samplecounter<-DESMUME_SAMPLE_RATE*15/60); //behind by more than a quarter second -> silence
if(insilence)
{
@ -266,6 +266,12 @@ void SNDDXUpdateAudio(s16 *buffer, u32 num_samples)
{
if(silence)
{
#ifndef PUBLIC_RELEASE
extern volatile bool execute;
if(execute)
printf("snddx: emergency cleared sound buffer. (%d, %d, %d)\n", win_sound_samplecounter, num_samples, samplecounter_fakecontribution);
#endif
samplecounter_fakecontribution = 0;
insilence = true;
SNDDXClearAudioBuffer();
return;
@ -299,13 +305,18 @@ void SNDDXUpdateAudio(s16 *buffer, u32 num_samples)
void SNDDXClearAudioBuffer()
{
// we shouldn't need to provide 2 buffers since it's 1 contiguous range
// but maybe newer directsound implementations have issues
LPVOID buffer1;
DWORD buffer1_size;
HRESULT hr = lpDSB2->Lock(0, 0, &buffer1, &buffer1_size, NULL, NULL, DSBLOCK_ENTIREBUFFER);
LPVOID buffer2;
DWORD buffer1_size, buffer2_size;
HRESULT hr = lpDSB2->Lock(0, 0, &buffer1, &buffer1_size, &buffer2, &buffer2_size, DSBLOCK_ENTIREBUFFER);
if(FAILED(hr))
return;
memset(buffer1, 0, buffer1_size);
lpDSB2->Unlock(buffer1, buffer1_size, NULL, 0);
if(buffer2)
memset(buffer2, 0, buffer2_size);
lpDSB2->Unlock(buffer1, buffer1_size, buffer2, buffer2_size);
}