diff options
-rw-r--r-- | source/nds/entry.cpp | 4 | ||||
-rw-r--r-- | source/snes9x.h | 1 | ||||
-rw-r--r-- | source/soundux.cpp | 208 | ||||
-rw-r--r-- | source/soundux.h | 2 |
4 files changed, 163 insertions, 52 deletions
diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp index 77620bf..c4cc389 100644 --- a/source/nds/entry.cpp +++ b/source/nds/entry.cpp @@ -425,7 +425,9 @@ void init_sfc_setting(void) //sound settings Settings.APUEnabled = Settings.NextAPUEnabled = TRUE; Settings.FixFrequency = 1; - Settings.InterpolatedSound = TRUE; + + S9xSetEightBitConsoleSound (TRUE); + Settings.H_Max = SNES_CYCLES_PER_SCANLINE; Settings.SkipFrames = AUTO_FRAMERATE; diff --git a/source/snes9x.h b/source/snes9x.h index 2661923..ab70efa 100644 --- a/source/snes9x.h +++ b/source/snes9x.h @@ -337,6 +337,7 @@ struct SSettings{ #ifndef FOREVER_16_BIT_SOUND bool8 SixteenBitSound; #endif + bool8 EightBitConsoleSound; // due to caching, this needs S9xSetEightBitConsoleSound() int SoundBufferSize; int SoundMixInterval; bool8 SoundEnvelopeHeightReading; diff --git a/source/soundux.cpp b/source/soundux.cpp index c20f366..d8ce223 100644 --- a/source/soundux.cpp +++ b/source/soundux.cpp @@ -168,6 +168,19 @@ extern "C" void DecodeBlockAsm2 (int8 *, int16 *, int32 *, int32 *); #define LAST_SAMPLE 0xffffff #define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE) +void S9xSetEightBitConsoleSound (bool8 Enabled) +{ + if (Settings.EightBitConsoleSound != Enabled) + { + Settings.EightBitConsoleSound = Enabled; + int i; + for (i = 0; i < 8; i++) + { + SoundData.channels[i].needs_decode = TRUE; + } + } +} + STATIC inline uint8 *S9xGetSampleAddress (int sample_number) { uint32 addr = (((APU.DSP[APU_DIR] << 8) + (sample_number << 2)) & 0xffff); @@ -803,7 +816,7 @@ void DecodeBlock (Channel *ch) signed char sample1, sample2; unsigned char i; bool invalid_header; - + if (Settings.AltSampleDecode) { if (Settings.AltSampleDecode < 3) @@ -819,74 +832,167 @@ void DecodeBlock (Channel *ch) ch->block = ch->decoded; return; } - signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; + + if (Settings.EightBitConsoleSound) + { + signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; - filter = *compressed; - if ((ch->last_block = filter & 1)) - ch->loop = (filter & 2) != 0; + filter = *compressed; + if ((ch->last_block = filter & 1)) + ch->loop = (filter & 2) != 0; - compressed++; - signed short *raw = ch->block = ch->decoded; + compressed++; + signed short *raw = ch->block = ch->decoded; - // Seperate out the header parts used for decoding + // Seperate out the header parts used for decoding - shift = filter >> 4; + shift = filter >> 4; - // Header validity check: if range(shift) is over 12, ignore - // all bits of the data for that block except for the sign bit of each - invalid_header = (shift >= 0xD); + // Header validity check: if range(shift) is over 12, ignore + // all bits of the data for that block except for the sign bit of each + invalid_header = (shift >= 0xD); + + filter = filter&0x0c; - filter = filter&0x0c; + int32 prev0 = ch->previous [0]; + int32 prev1 = ch->previous [1]; - int32 prev0 = ch->previous [0]; - int32 prev1 = ch->previous [1]; + int16 amplitude = 0; - for (i = 8; i != 0; i--) - { - sample1 = *compressed++; - sample2 = sample1 << 4; - //Sample 2 = Bottom Nibble, Sign Extended. - sample2 >>= 4; - //Sample 1 = Top Nibble, shifted down and Sign Extended. - sample1 >>= 4; - if (invalid_header) { sample1>>=3; sample2>>=3; } + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + if (invalid_header) { sample1>>=3; sample2>>=3; } - for (int nybblesmp = 0; nybblesmp<2; nybblesmp++){ - out=(((nybblesmp) ? sample2 : sample1) << shift); - out >>= 1; + for (int nybblesmp = 0; nybblesmp<2; nybblesmp++){ + out=(((nybblesmp) ? sample2 : sample1) << shift); + out >>= 1; - switch(filter) - { - case 0x00: - // Method0 - [Smp] - break; + switch(filter) + { + case 0x00: + // Method0 - [Smp] + break; - case 0x04: - // Method1 - [Delta]+[Smp-1](15/16) - out+=(prev0>>1)+((-prev0)>>5); - break; + case 0x04: + // Method1 - [Delta]+[Smp-1](15/16) + out+=(prev0>>1)+((-prev0)>>5); + break; - case 0x08: - // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16) - out+=(prev0)+((-(prev0 +(prev0>>1)))>>5)-(prev1>>1)+(prev1>>5); - break; + case 0x08: + // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16) + out+=(prev0)+((-(prev0 +(prev0>>1)))>>5)-(prev1>>1)+(prev1>>5); + break; - default: - // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16) - out+=(prev0)+((-(prev0 + (prev0<<2) + (prev0<<3)))>>7)-(prev1>>1)+((prev1+(prev1>>1))>>4); - break; + default: + // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16) + out+=(prev0)+((-(prev0 + (prev0<<2) + (prev0<<3)))>>7)-(prev1>>1)+((prev1+(prev1>>1))>>4); + break; + } + CLIP16(out); + int16 result = (signed short)(out<<1); + if (abs(result) > amplitude) + amplitude = abs(result); + prev1=(signed short)prev0; + prev0=(signed short)(out<<1); } - CLIP16(out); - *raw++ = (signed short)(out<<1); - prev1=(signed short)prev0; - prev0=(signed short)(out<<1); } + ch->previous [0] = prev0; + ch->previous [1] = prev1; + // Make it a square wave with an amplitude equivalent to that + // of the highest amplitude sample of the block. + /* for (i = 0; i < 8; i++) + ch->decoded[i] = amplitude; + for (i = 8; i < 16; i++) + ch->decoded[i] = -amplitude; */ + // Make it a triangle wave with an amplitude equivalent to that + // of the highest amplitude sample of the block. + ch->decoded[0] = ch->decoded[8] = 0; + ch->decoded[1] = ch->decoded[7] = amplitude / 4; + ch->decoded[2] = ch->decoded[6] = amplitude / 2; + ch->decoded[3] = ch->decoded[5] = amplitude * 3 / 4; + ch->decoded[4] = amplitude; + ch->decoded[9] = ch->decoded[15] = -(amplitude / 4); + ch->decoded[10] = ch->decoded[14] = -(amplitude / 2); + ch->decoded[11] = ch->decoded[13] = -(amplitude * 3 / 4); + ch->decoded[12] = -amplitude; } - ch->previous [0] = prev0; - ch->previous [1] = prev1; + else + { + signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; - ch->block_pointer += 9; + filter = *compressed; + if ((ch->last_block = filter & 1)) + ch->loop = (filter & 2) != 0; + + compressed++; + signed short *raw = ch->block = ch->decoded; + + // Seperate out the header parts used for decoding + + shift = filter >> 4; + + // Header validity check: if range(shift) is over 12, ignore + // all bits of the data for that block except for the sign bit of each + invalid_header = (shift >= 0xD); + + filter = filter&0x0c; + + int32 prev0 = ch->previous [0]; + int32 prev1 = ch->previous [1]; + + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + if (invalid_header) { sample1>>=3; sample2>>=3; } + + for (int nybblesmp = 0; nybblesmp<2; nybblesmp++){ + out=(((nybblesmp) ? sample2 : sample1) << shift); + out >>= 1; + + switch(filter) + { + case 0x00: + // Method0 - [Smp] + break; + + case 0x04: + // Method1 - [Delta]+[Smp-1](15/16) + out+=(prev0>>1)+((-prev0)>>5); + break; + + case 0x08: + // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16) + out+=(prev0)+((-(prev0 +(prev0>>1)))>>5)-(prev1>>1)+(prev1>>5); + break; + + default: + // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16) + out+=(prev0)+((-(prev0 + (prev0<<2) + (prev0<<3)))>>7)-(prev1>>1)+((prev1+(prev1>>1))>>4); + break; + + } + CLIP16(out); + *raw++ = (signed short)(out<<1); + prev1=(signed short)prev0; + prev0=(signed short)(out<<1); + } + } + ch->previous [0] = prev0; + ch->previous [1] = prev1; + } + ch->block_pointer += 9; } static inline void MixStereo (int sample_count) diff --git a/source/soundux.h b/source/soundux.h index b603df8..b57e945 100644 --- a/source/soundux.h +++ b/source/soundux.h @@ -220,6 +220,8 @@ typedef struct EXTERN_C SSoundData SoundData; +void S9xSetEightBitConsoleSound (bool8 Enabled); + void S9xSetSoundVolume (int channel, short volume_left, short volume_right); void S9xSetSoundFrequency (int channel, int hertz); void S9xSetSoundHertz (int channel, int hertz); |