SPU (v0.9.8):
- Backport changes from r4306 to 0.9.8 branch.
This commit is contained in:
parent
19ab1256fa
commit
479a288bc4
|
@ -40,7 +40,6 @@
|
|||
#include "NDSSystem.h"
|
||||
#include "matrix.h"
|
||||
|
||||
#include "metaspu/metaspu.h"
|
||||
|
||||
#define K_ADPCM_LOOPING_RECOVERY_INDEX 99999
|
||||
#define COSINE_INTERPOLATION_RESOLUTION 8192
|
||||
|
@ -1389,52 +1388,117 @@ static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
|
|||
int spu_core_samples = 0;
|
||||
void SPU_Emulate_core()
|
||||
{
|
||||
bool needToMix = true;
|
||||
SoundInterface_struct *soundProcessor = SPU_SoundCore();
|
||||
|
||||
samples += samples_per_hline;
|
||||
spu_core_samples = (int)(samples);
|
||||
samples -= spu_core_samples;
|
||||
|
||||
bool synchronize = (synchmode == ESynchMode_Synchronous);
|
||||
bool mix = driver->AVI_IsRecording() || driver->WAV_IsRecording() || synchronize;
|
||||
|
||||
SPU_MixAudio(mix,SPU_core,spu_core_samples);
|
||||
if(synchronize && SPU_currentCoreNum != SNDCORE_DUMMY)
|
||||
synchronizer->enqueue_samples(SPU_core->outbuf, spu_core_samples);
|
||||
|
||||
// We don't need to mix audio for Dual Synch/Asynch mode since we do this
|
||||
// later in SPU_Emulate_user(). Disable mixing here to speed up processing.
|
||||
if (synchmode == ESynchMode_DualSynchAsynch)
|
||||
{
|
||||
needToMix = false;
|
||||
}
|
||||
|
||||
SPU_MixAudio(needToMix, SPU_core, spu_core_samples);
|
||||
|
||||
if (soundProcessor == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (soundProcessor->FetchSamples != NULL)
|
||||
{
|
||||
soundProcessor->FetchSamples(SPU_core->outbuf, spu_core_samples, synchmode, synchronizer);
|
||||
}
|
||||
else
|
||||
{
|
||||
SPU_DefaultFetchSamples(SPU_core->outbuf, spu_core_samples, synchmode, synchronizer);
|
||||
}
|
||||
}
|
||||
|
||||
void SPU_Emulate_user(bool mix)
|
||||
{
|
||||
u32 audiosize;
|
||||
|
||||
// Check to see how much free space there is
|
||||
// If there is some, fill up the buffer
|
||||
if(!SNDCore) return;
|
||||
audiosize = SNDCore->GetAudioSpace();
|
||||
|
||||
if (audiosize > 0)
|
||||
static s16 *postProcessBuffer = NULL;
|
||||
static size_t postProcessBufferSize = 0;
|
||||
size_t freeSampleCount = 0;
|
||||
size_t processedSampleCount = 0;
|
||||
SoundInterface_struct *soundProcessor = SPU_SoundCore();
|
||||
|
||||
if (soundProcessor == NULL)
|
||||
{
|
||||
//printf("mix %i samples\n", audiosize);
|
||||
if (audiosize > buffersize)
|
||||
audiosize = buffersize;
|
||||
|
||||
s16* outbuf;
|
||||
int samplesOutput;
|
||||
if(synchmode == ESynchMode_Synchronous)
|
||||
{
|
||||
static std::vector<s16> tempbuf;
|
||||
if(tempbuf.size() < audiosize*2) tempbuf.resize(audiosize*2);
|
||||
outbuf = &tempbuf[0];
|
||||
samplesOutput = synchronizer->output_samples(outbuf, audiosize);
|
||||
}
|
||||
else if(SPU_user != NULL)
|
||||
{
|
||||
outbuf = SPU_user->outbuf;
|
||||
samplesOutput = (SPU_MixAudio(mix,SPU_user,audiosize), audiosize);
|
||||
}
|
||||
else return;
|
||||
|
||||
SNDCore->UpdateAudio(outbuf, samplesOutput);
|
||||
WAV_WavSoundUpdate(outbuf, samplesOutput, WAVMODE_USER);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check to see how many free samples are available.
|
||||
// If there are some, fill up the output buffer.
|
||||
freeSampleCount = soundProcessor->GetAudioSpace();
|
||||
if (freeSampleCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//printf("mix %i samples\n", audiosize);
|
||||
if (freeSampleCount > buffersize)
|
||||
{
|
||||
freeSampleCount = buffersize;
|
||||
}
|
||||
|
||||
// If needed, resize the post-process buffer to guarantee that
|
||||
// we can store all the sound data.
|
||||
if (postProcessBufferSize < freeSampleCount * 2 * sizeof(s16))
|
||||
{
|
||||
postProcessBufferSize = freeSampleCount * 2 * sizeof(s16);
|
||||
postProcessBuffer = (s16 *)realloc(postProcessBuffer, postProcessBufferSize);
|
||||
}
|
||||
|
||||
if (soundProcessor->PostProcessSamples != NULL)
|
||||
{
|
||||
processedSampleCount = soundProcessor->PostProcessSamples(postProcessBuffer, freeSampleCount, synchmode, synchronizer);
|
||||
}
|
||||
else
|
||||
{
|
||||
processedSampleCount = SPU_DefaultPostProcessSamples(postProcessBuffer, freeSampleCount, synchmode, synchronizer);
|
||||
}
|
||||
|
||||
soundProcessor->UpdateAudio(postProcessBuffer, processedSampleCount);
|
||||
WAV_WavSoundUpdate(postProcessBuffer, processedSampleCount, WAVMODE_USER);
|
||||
}
|
||||
|
||||
void SPU_DefaultFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)
|
||||
{
|
||||
if (synchMode == ESynchMode_Synchronous)
|
||||
{
|
||||
theSynchronizer->enqueue_samples(sampleBuffer, sampleCount);
|
||||
}
|
||||
}
|
||||
|
||||
size_t SPU_DefaultPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)
|
||||
{
|
||||
size_t processedSampleCount = 0;
|
||||
|
||||
switch (synchMode)
|
||||
{
|
||||
case ESynchMode_DualSynchAsynch:
|
||||
if(SPU_user != NULL)
|
||||
{
|
||||
SPU_MixAudio(true, SPU_user, requestedSampleCount);
|
||||
memcpy(postProcessBuffer, SPU_user->outbuf, requestedSampleCount * 2 * sizeof(s16));
|
||||
processedSampleCount = requestedSampleCount;
|
||||
}
|
||||
break;
|
||||
|
||||
case ESynchMode_Synchronous:
|
||||
processedSampleCount = theSynchronizer->output_samples(postProcessBuffer, requestedSampleCount);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return processedSampleCount;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1448,6 +1512,9 @@ u32 SNDDummyGetAudioSpace();
|
|||
void SNDDummyMuteAudio();
|
||||
void SNDDummyUnMuteAudio();
|
||||
void SNDDummySetVolume(int volume);
|
||||
void SNDDummyClearBuffer();
|
||||
void SNDDummyFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
size_t SNDDummyPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
|
||||
SoundInterface_struct SNDDummy = {
|
||||
SNDCORE_DUMMY,
|
||||
|
@ -1458,7 +1525,10 @@ SoundInterface_struct SNDDummy = {
|
|||
SNDDummyGetAudioSpace,
|
||||
SNDDummyMuteAudio,
|
||||
SNDDummyUnMuteAudio,
|
||||
SNDDummySetVolume
|
||||
SNDDummySetVolume,
|
||||
SNDDummyClearBuffer,
|
||||
SNDDummyFetchSamples,
|
||||
SNDDummyPostProcessSamples
|
||||
};
|
||||
|
||||
int SNDDummyInit(int buffersize) { return 0; }
|
||||
|
@ -1468,6 +1538,9 @@ u32 SNDDummyGetAudioSpace() { return DESMUME_SAMPLE_RATE/60 + 5; }
|
|||
void SNDDummyMuteAudio() {}
|
||||
void SNDDummyUnMuteAudio() {}
|
||||
void SNDDummySetVolume(int volume) {}
|
||||
void SNDDummyClearBuffer() {}
|
||||
void SNDDummyFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) {}
|
||||
size_t SNDDummyPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) { return 0; }
|
||||
|
||||
//---------wav writer------------
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "types.h"
|
||||
#include "matrix.h"
|
||||
#include "emufile.h"
|
||||
#include "metaspu/metaspu.h"
|
||||
|
||||
|
||||
#define SNDCORE_DEFAULT -1
|
||||
|
@ -60,6 +61,8 @@ struct SoundInterface_struct
|
|||
void (*UnMuteAudio)();
|
||||
void (*SetVolume)(int volume);
|
||||
void (*ClearBuffer)();
|
||||
void (*FetchSamples)(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
size_t (*PostProcessSamples)(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
};
|
||||
|
||||
extern SoundInterface_struct SNDDummy;
|
||||
|
@ -212,6 +215,8 @@ u16 SPU_ReadWord(u32 addr);
|
|||
u32 SPU_ReadLong(u32 addr);
|
||||
void SPU_Emulate_core(void);
|
||||
void SPU_Emulate_user(bool mix = true);
|
||||
void SPU_DefaultFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
size_t SPU_DefaultPostProcessSamples(s16 *postProcessBuffer, size_t requestedSampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer);
|
||||
|
||||
extern SPU_struct *SPU_core, *SPU_user;
|
||||
extern int spu_core_samples;
|
||||
|
|
Loading…
Reference in New Issue