Fix looping and (partly) resume.

This commit is contained in:
qwertymodo 2016-11-03 19:14:45 -07:00
parent 80d9ee7a97
commit 07ce784c1b
2 changed files with 49 additions and 15 deletions

View File

@ -386,7 +386,13 @@ void S9xFinalizeSamples (void)
if (Settings.MSU1) if (Settings.MSU1)
{ {
S9xMSU1Generate(SNES::dsp.spc_dsp.sample_count()); S9xMSU1Generate(SNES::dsp.spc_dsp.sample_count());
msu::resampler->push((short *)msu::landing_buffer, S9xMSU1Samples()); if (!msu::resampler->push((short *)msu::landing_buffer, S9xMSU1Samples()))
{
//spc::sound_in_sync = FALSE;
//if (Settings.SoundSync && !Settings.TurboMode)
//return;
}
} }
if (!spc::resampler->push((short *)spc::landing_buffer, SNES::dsp.spc_dsp.sample_count())) if (!spc::resampler->push((short *)spc::landing_buffer, SNES::dsp.spc_dsp.sample_count()))
@ -482,7 +488,7 @@ bool8 S9xInitSound (int buffer_ms, int lag_ms)
spc::buffer_size <<= 1; spc::buffer_size <<= 1;
if (Settings.SixteenBitSound) if (Settings.SixteenBitSound)
spc::buffer_size <<= 1; spc::buffer_size <<= 1;
msu::buffer_size = (buffer_ms * 44100 / 1000) << 2; // Always 16-bit, Stereo msu::buffer_size = ((buffer_ms * 44100 / 1000) * 441000 / 320405) << 2; // Always 16-bit, Stereo
printf("Sound buffer size: %d (%d samples)\n", spc::buffer_size, sample_count); printf("Sound buffer size: %d (%d samples)\n", spc::buffer_size, sample_count);

View File

@ -194,12 +194,16 @@
#include "display.h" #include "display.h"
#include "msu1.h" #include "msu1.h"
#include <fstream> #include <fstream>
#include <cerrno>
#define APU_DEFAULT_INPUT_RATE 32000
std::ifstream dataFile, audioFile; std::ifstream dataFile, audioFile;
uint32 dataPos, audioPos, audioResumePos, audioLoopPos; uint32 dataPos, audioPos, audioResumePos, audioLoopPos;
uint16 audioTrack, audioResumeTrack; uint16 audioTrack, audioResumeTrack;
char fName[64]; char fName[64];
uint32 partial_samples; uint32 partial_samples;
bool audioResume;
// Sample buffer // Sample buffer
int16 *bufPos, *bufBegin, *bufEnd; int16 *bufPos, *bufBegin, *bufEnd;
@ -236,7 +240,6 @@ void S9xMSU1Init(void)
void S9xMSU1Generate(int sample_count) void S9xMSU1Generate(int sample_count)
{ {
static uint32 hitcount = 0;
partial_samples += 441000 * sample_count; partial_samples += 441000 * sample_count;
while (((uintptr_t)bufPos < (uintptr_t)bufEnd) && (MSU1.MSU1_STATUS & AudioPlaying) && partial_samples > 320405) while (((uintptr_t)bufPos < (uintptr_t)bufEnd) && (MSU1.MSU1_STATUS & AudioPlaying) && partial_samples > 320405)
@ -246,7 +249,6 @@ void S9xMSU1Generate(int sample_count)
int16 sample; int16 sample;
if (audioFile.read((char *)&sample, 2).good()) if (audioFile.read((char *)&sample, 2).good())
{ {
hitcount++;
sample = (double)sample * (double)MSU1.MSU1_VOLUME / 255.0; sample = (double)sample * (double)MSU1.MSU1_VOLUME / 255.0;
*(bufPos++) = sample; *(bufPos++) = sample;
@ -256,14 +258,22 @@ void S9xMSU1Generate(int sample_count)
else else
if (audioFile.eof()) if (audioFile.eof())
{ {
sample = (double)sample * (double)MSU1.MSU1_VOLUME / 255.0;
*(bufPos++) = sample;
audioPos += 2;
partial_samples -= 320405;
if (MSU1.MSU1_STATUS & AudioRepeating) if (MSU1.MSU1_STATUS & AudioRepeating)
{ {
audioFile.clear();
audioPos = audioLoopPos; audioPos = audioLoopPos;
audioFile.seekg(audioPos); audioFile.seekg(audioPos);
} }
else else
{ {
MSU1.MSU1_STATUS &= ~(AudioPlaying | AudioRepeating); MSU1.MSU1_STATUS &= ~(AudioPlaying | AudioRepeating);
audioFile.clear();
audioFile.seekg(8); audioFile.seekg(8);
return; return;
} }
@ -338,13 +348,15 @@ void S9xMSU1WritePort(int port, uint8 byte)
audioTrack = MSU1.MSU1_TRACK; audioTrack = MSU1.MSU1_TRACK;
if (audioFile.is_open()) if (audioFile.is_open())
audioFile.close(); audioFile.close();
// This is an ugly hack... need to see if there's a better way to get the base name without extension // This is an ugly hack... need to see if there's a better way to get the base name without extension
sprintf(fName, "%s", S9xGetFilename(".msu", ROMFILENAME_DIR)); sprintf(fName, "%s", S9xGetFilename(".msu", ROMFILENAME_DIR));
fName[strlen(fName) - 4] = '\0'; fName[strlen(fName) - 4] = '\0';
sprintf(fName, "%s-%d.pcm", fName, audioTrack); sprintf(fName, "%s-%d.pcm", fName, audioTrack);
audioFile.clear();
audioFile.open(fName, std::ios::in | std::ios::binary); audioFile.open(fName, std::ios::in | std::ios::binary);
if (audioFile.is_open() && audioFile.good()) if (audioFile.is_open())
{ {
MSU1.MSU1_STATUS |= AudioError; MSU1.MSU1_STATUS |= AudioError;
@ -357,29 +369,40 @@ void S9xMSU1WritePort(int port, uint8 byte)
if (audioFile.get() != '1') if (audioFile.get() != '1')
break; break;
((uint8 *)(&audioLoopPos))[0] = audioFile.get(); audioFile.read((char *)&audioLoopPos, 4);
((uint8 *)(&audioLoopPos))[1] = audioFile.get(); audioLoopPos <<= 2;
((uint8 *)(&audioLoopPos))[2] = audioFile.get();
((uint8 *)(&audioLoopPos))[3] = audioFile.get();
audioLoopPos += 8; audioLoopPos += 8;
MSU1.MSU1_STATUS &= ~AudioPlaying; MSU1.MSU1_STATUS &= ~AudioPlaying;
MSU1.MSU1_STATUS &= ~AudioRepeating; MSU1.MSU1_STATUS &= ~AudioRepeating;
if (audioTrack == audioResumeTrack)
if (audioResume)
{ {
audioPos = audioResumePos; audioResumeTrack = audioTrack;
audioResumeTrack = 0xFFFF; audioResumePos = audioPos;
audioResumePos = 0; audioResume = FALSE;
} }
else else
audioPos = 8; {
if (audioTrack == audioResumeTrack)
{
audioPos = audioResumePos;
audioResumeTrack = 0xFFFF;
audioResumePos = 0;
}
else
audioPos = 8;
}
audioFile.seekg(audioPos); audioFile.seekg(audioPos);
MSU1.MSU1_STATUS &= ~AudioError; MSU1.MSU1_STATUS &= ~AudioError;
} }
else else
{
char *e = strerror(errno);
MSU1.MSU1_STATUS |= AudioError; MSU1.MSU1_STATUS |= AudioError;
}
break; break;
case 6: case 6:
MSU1.MSU1_VOLUME = byte; MSU1.MSU1_VOLUME = byte;
@ -389,8 +412,13 @@ void S9xMSU1WritePort(int port, uint8 byte)
break; break;
MSU1.MSU1_STATUS = (MSU1.MSU1_STATUS & ~0x30) | ((byte & 0x03) << 4); MSU1.MSU1_STATUS = (MSU1.MSU1_STATUS & ~0x30) | ((byte & 0x03) << 4);
if ((byte & 0x05) == 0x05)
audioResume = ((byte & 0x05) == 0x05);
if (byte & 0x04)
{
audioResumeTrack = audioTrack; audioResumeTrack = audioTrack;
audioResumePos = audioPos;
}
break; break;
} }
} }