MSU1 fixes backported

The following fixes are backported from the Snes9x master branch:
- Release msu data and audio streams on exit, use unzClose when closing
- Fix MSU-1 channel swap on loop
- Ensure all MSU-1 reads are stereo channel aligned
- Clean up S9xMSU1Generate code
- Fix MSU1 swapping.
- Fix casting on MSU1 volume
- Get rid of "Unable to find msu file" console spam
This commit is contained in:
bladeoner 2018-07-29 19:33:25 +02:00 committed by GitHub
parent 8ea78dde4a
commit 74f3ee4caf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 62 deletions

View File

@ -510,7 +510,7 @@ bool8 S9xInitSound (int buffer_ms, int lag_ms)
return (FALSE);
if (msu::landing_buffer)
delete[] msu::landing_buffer;
msu::landing_buffer = new uint8[msu::buffer_size * 2];
msu::landing_buffer = (uint8*) new uint32[msu::buffer_size / 2]; // Ensure 4-byte alignment
if (!msu::landing_buffer)
return (FALSE);
@ -635,6 +635,8 @@ void S9xDeinitAPU (void)
delete[] msu::resample_buffer;
msu::resample_buffer = NULL;
}
S9xMSU1DeInit();
}
static inline int S9xAPUGetClock (int32 cpucycles)

View File

@ -17,7 +17,7 @@ class Resampler : public ring_buffer
{
}
~Resampler ()
virtual ~Resampler ()
{
}

View File

@ -4082,7 +4082,10 @@ static bool8 ReadBPSPatch (Reader *r, long, int32 &rom_size)
switch((int)mode) {
case SourceRead:
while(length--) patched_rom[outputOffset++] = Memory.ROM[outputOffset];
while(length--) {
patched_rom[outputOffset] = Memory.ROM[outputOffset];
outputOffset++;
}
break;
case TargetRead:
while(length--) patched_rom[outputOffset++] = data[addr++];
@ -4337,7 +4340,7 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
}
}
// Mercurial Magic (MSU-1 distribution pack)
// Mercurial Magic (MSU-1 distribution pack)
if (strcasecmp(ext, "msu1") && strcasecmp(ext, ".msu1"))
{
_makepath(fname, drive, dir, name, "msu1");
@ -4350,8 +4353,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{
printf(" in %s", fname);
ret = ReadBPSPatch(new unzReader(file), offset, rom_size);
unzCloseCurrentFile(file);
Stream *s = new unzStream(msu1file);
ret = ReadBPSPatch(s, offset, rom_size);
s->closeStream();
if (ret)
printf("!\n");

View File

@ -200,7 +200,7 @@
STREAM dataStream = NULL;
STREAM audioStream = NULL;
uint32 audioLoopPos;
size_t partial_samples;
size_t partial_frames;
// Sample buffer
int16 *bufPos, *bufBegin, *bufEnd;
@ -239,17 +239,22 @@ static int unzFindExtension(unzFile &file, const char *ext, bool restart = TRUE,
}
#endif
STREAM S9xMSU1OpenFile(char *msu_ext)
STREAM S9xMSU1OpenFile(const char *msu_ext, bool skip_unpacked)
{
char filename[MAXPATHLEN];
sprintf(filename, "%s%s%s", Memory.ROMFilePath, Memory.ROMFilename, msu_ext);
STREAM file = OPEN_STREAM(filename, "rb");
if (file)
printf("Using msu file %s.\n", filename);
STREAM file = 0;
if (!skip_unpacked)
{
file = OPEN_STREAM(filename, "rb");
if (file)
printf("Using msu file %s.\n", filename);
}
#ifdef UNZIP_SUPPORT
// look for msu file in .msu1 (Mercurial Magic pack) if not found in rom dir
// look for msu1 pack file in the rom or patch dir if msu data file not found in rom dir
if (!file)
{
char zip_filename[MAXPATHLEN];
@ -265,26 +270,28 @@ STREAM S9xMSU1OpenFile(char *msu_ext)
file = new unzStream(unzFile);
}
else
unzCloseCurrentFile(unzFile);
unzClose(unzFile);
}
}
#endif
if(!file)
printf("Unable to find msu file %s.\n", filename);
return file;
}
bool AudioOpen()
static void AudioClose()
{
if (audioStream)
{
CLOSE_STREAM(audioStream);
audioStream = NULL;
}
}
static bool AudioOpen()
{
MSU1.MSU1_STATUS |= AudioError;
if (audioStream)
{
CLOSE_STREAM(audioStream);
audioStream = NULL;
}
AudioClose();
char ext[_MAX_EXT];
snprintf(ext, _MAX_EXT, "-%d.pcm", MSU1.MSU1_CURRENT_TRACK);
@ -305,6 +312,8 @@ bool AudioOpen()
audioLoopPos = GET_LE32(&audioLoopPos);
audioLoopPos <<= 2;
audioLoopPos += 8;
MSU1.MSU1_AUDIO_POS = 8;
MSU1.MSU1_STATUS &= ~AudioError;
return true;
@ -313,13 +322,18 @@ bool AudioOpen()
return false;
}
bool DataOpen()
static void DataClose()
{
if (dataStream)
{
CLOSE_STREAM(dataStream);
dataStream = NULL;
}
if (dataStream)
{
CLOSE_STREAM(dataStream);
dataStream = NULL;
}
}
static bool DataOpen()
{
DataClose();
dataStream = S9xMSU1OpenFile(".msu");
@ -347,19 +361,11 @@ void S9xResetMSU(void)
bufBegin = 0;
bufEnd = 0;
partial_samples = 0;
partial_frames = 0;
if (dataStream)
{
CLOSE_STREAM(dataStream);
dataStream = NULL;
}
DataClose();
if (audioStream)
{
CLOSE_STREAM(audioStream);
audioStream = NULL;
}
AudioClose();
Settings.MSU1 = S9xMSU1ROMExists();
}
@ -369,6 +375,13 @@ void S9xMSU1Init(void)
DataOpen();
}
void S9xMSU1DeInit(void)
{
DataClose();
AudioClose();
}
bool S9xMSU1ROMExists(void)
{
STREAM s = S9xMSU1OpenFile(".msu");
@ -384,7 +397,7 @@ bool S9xMSU1ROMExists(void)
if (unzFile)
{
unzCloseCurrentFile(unzFile);
unzClose(unzFile);
return true;
}
#endif
@ -393,31 +406,30 @@ bool S9xMSU1ROMExists(void)
void S9xMSU1Generate(size_t sample_count)
{
partial_samples += 4410 * sample_count;
partial_frames += 4410 * (sample_count / 2);
while (((uintptr_t)bufPos < (uintptr_t)bufEnd) && partial_samples > 3204)
while ((bufPos < (bufEnd - 2)) && partial_frames >= 3204)
{
if (MSU1.MSU1_STATUS & AudioPlaying && audioStream)
{
int16 sample;
int bytes_read = READ_STREAM((char *)&sample, 2, audioStream);
if (bytes_read == 2)
{
sample = (int16)((double)(int16)GET_LE16(&sample) * (double)MSU1.MSU1_VOLUME / 255.0);
int32 sample;
int16* left = (int16*)&sample;
int16* right = left + 1;
*(bufPos++) = sample;
MSU1.MSU1_AUDIO_POS += 2;
partial_samples -= 3204;
int bytes_read = READ_STREAM((char *)&sample, 4, audioStream);
if (bytes_read == 4)
{
*left = ((int32)(int16)GET_LE16(left) * MSU1.MSU1_VOLUME / 255);
*right = ((int32)(int16)GET_LE16(right) * MSU1.MSU1_VOLUME / 255);
*(bufPos++) = *left;
*(bufPos++) = *right;
MSU1.MSU1_AUDIO_POS += 4;
partial_frames -= 3204;
}
else
if (bytes_read >= 0)
{
sample = (int16)((double)(int16)GET_LE16(&sample) * (double)MSU1.MSU1_VOLUME / 255.0);
*(bufPos++) = sample;
MSU1.MSU1_AUDIO_POS += 2;
partial_samples -= 3204;
if (MSU1.MSU1_STATUS & AudioRepeating)
{
MSU1.MSU1_AUDIO_POS = audioLoopPos;
@ -437,7 +449,8 @@ void S9xMSU1Generate(size_t sample_count)
else
{
MSU1.MSU1_STATUS &= ~(AudioPlaying | AudioRepeating);
partial_samples -= 3204;
partial_frames -= 3204;
*(bufPos++) = 0;
*(bufPos++) = 0;
}
}
@ -449,7 +462,7 @@ uint8 S9xMSU1ReadPort(uint8 port)
switch (port)
{
case 0:
return MSU1.MSU1_STATUS;
return MSU1.MSU1_STATUS | MSU1_REVISION;
case 1:
{
if (MSU1.MSU1_STATUS & DataBusy)
@ -594,5 +607,5 @@ void S9xMSU1PostLoadState(void)
bufBegin = 0;
bufEnd = 0;
partial_samples = 0;
partial_frames = 0;
}

View File

@ -196,6 +196,8 @@
#include <stdint.h>
#include <sys\stat.h>
#define MSU1_REVISION 0x02
struct SMSU1
{
uint8 MSU1_STATUS;
@ -211,8 +213,7 @@ struct SMSU1
};
enum SMSU1_FLAG {
Revision = 0x02, //max: 0x07
AudioResume = 0x04,
Revision = 0x07, // bitmask, not the actual version number
AudioError = 0x08,
AudioPlaying = 0x10,
AudioRepeating = 0x20,
@ -230,8 +231,9 @@ extern struct SMSU1 MSU1;
void S9xResetMSU(void);
void S9xMSU1Init(void);
void S9xMSU1DeInit(void);
bool S9xMSU1ROMExists(void);
STREAM S9xMSU1OpenFile(char *msu_ext);
STREAM S9xMSU1OpenFile(const char *msu_ext, bool skip_unpacked = FALSE);
void S9xMSU1Init(void);
void S9xMSU1Generate(size_t sample_count);
uint8 S9xMSU1ReadPort(uint8 port);