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:
parent
1b7d14c178
commit
00b28e5807
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue