📄 soundux.cpp
字号:
{ bool8 old = so.mute_sound; so.mute_sound = mute; return (old);}void AltDecodeBlock (Channel *ch){ if (ch->block_pointer >= 0x10000 - 9) { ch->last_block = TRUE; ch->loop = FALSE; ch->block = ch->decoded; memset ((void *) ch->decoded, 0, sizeof (int16) * 16); return; } signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; unsigned char filter = *compressed; if ((ch->last_block = filter & 1)) ch->loop = (filter & 2) != 0; #if (defined (USE_X86_ASM) && (defined (__i386__) || defined (__i486__) ||\ defined (__i586__) || defined (__WIN32__) || defined (__DJGPP))) int16 *raw = ch->block = ch->decoded; if (Settings.AltSampleDecode == 1) DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]); else DecodeBlockAsm2 (compressed, raw, &ch->previous [0], &ch->previous [1]);#else int32 out; unsigned char shift; signed char sample1, sample2; unsigned int i; compressed++; signed short *raw = ch->block = ch->decoded; int32 prev0 = ch->previous [0]; int32 prev1 = ch->previous [1]; shift = filter >> 4; switch ((filter >> 2) & 3) { case 0: for (i = 8; i != 0; i--) { sample1 = *compressed++; sample2 = sample1 << 4; sample2 >>= 4; sample1 >>= 4; *raw++ = ((int32) sample1 << shift); *raw++ = ((int32) sample2 << shift); } prev1 = *(raw - 2); prev0 = *(raw - 1); break; case 1: for (i = 8; i != 0; i--) { sample1 = *compressed++; sample2 = sample1 << 4; sample2 >>= 4; sample1 >>= 4; prev0 = (int16) prev0; *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4); prev1 = (int16) prev1; *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4); } break; case 2: for (i = 8; i != 0; i--) { sample1 = *compressed++; sample2 = sample1 << 4; sample2 >>= 4; sample1 >>= 4; out = (sample1 << shift) - prev1 + (prev1 >> 4); prev1 = (int16) prev0; prev0 &= ~3; *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - (prev0 >> 4); out = (sample2 << shift) - prev1 + (prev1 >> 4); prev1 = (int16) prev0; prev0 &= ~3; *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - (prev0 >> 4); } break; case 3: for (i = 8; i != 0; i--) { sample1 = *compressed++; sample2 = sample1 << 4; sample2 >>= 4; sample1 >>= 4; out = (sample1 << shift); out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); prev1 = (int16) prev0; prev0 &= ~3; *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - (prev0 >> 4) - (prev1 >> 6); out = (sample2 << shift); out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); prev1 = (int16) prev0; prev0 &= ~3; *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - (prev0 >> 4) - (prev1 >> 6); } break; } ch->previous [0] = prev0; ch->previous [1] = prev1;#endif ch->block_pointer += 9;}void AltDecodeBlock2 (Channel *ch){ int32 out; unsigned char filter; unsigned char shift; signed char sample1, sample2; unsigned char i; if (ch->block_pointer > 0x10000 - 9) { ch->last_block = TRUE; ch->loop = FALSE; ch->block = ch->decoded; memset ((void *) ch->decoded, 0, sizeof (int16) * 16); return; } signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; filter = *compressed; if ((ch->last_block = filter & 1)) ch->loop = (filter & 2) != 0; compressed++; signed short *raw = ch->block = ch->decoded; shift = filter >> 4; int32 prev0 = ch->previous [0]; int32 prev1 = ch->previous [1]; if(shift > 12) shift -= 4; switch ((filter >> 2) & 3) { case 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; out = (int32)(sample1 << shift); prev1 = prev0; prev0 = out; CLIP16(out); *raw++ = (int16)out; out = (int32)(sample2 << shift); prev1 = prev0; prev0 = out; CLIP16(out); *raw++ = (int16)out; } break; case 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; out = (int32)(sample1 << shift); out += (int32)((double)prev0 * 15/16); prev1 = prev0; prev0 = out; CLIP16(out); *raw++ = (int16)out; out = (int32)(sample2 << shift); out += (int32)((double)prev0 * 15/16); prev1 = prev0; prev0 = out; CLIP16(out); *raw++ = (int16)out; } break; case 2: 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; out = ((sample1 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8; prev1 = prev0; prev0 = (int16)out; *raw++ = (int16)out; out = ((sample2 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8; prev1 = prev0; prev0 = (int16)out; *raw++ = (int16)out; } break; case 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; out = (int32)(sample1 << shift); out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16); prev1 = prev0; prev0 = out; CLIP16(out); *raw++ = (int16)out; out = (int32)(sample2 << shift); out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16); prev1 = prev0; prev0 = out; CLIP16(out); *raw++ = (int16)out; } break; } ch->previous [0] = prev0; ch->previous [1] = prev1; ch->block_pointer += 9;}void DecodeBlock (Channel *ch){ int32 out; unsigned char filter; unsigned char shift; signed char sample1, sample2; unsigned char i; bool invalid_header; if (Settings.AltSampleDecode) { if (Settings.AltSampleDecode < 3) AltDecodeBlock (ch); else AltDecodeBlock2 (ch); return; } if (ch->block_pointer > 0x10000 - 9) { ch->last_block = TRUE; ch->loop = FALSE; ch->block = ch->decoded; return; } signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; 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;}void MixStereo (int sample_count){ static int wave[SOUND_BUFFER_SIZE]; int pitch_mod = SoundData.pitch_mod & ~APU.DSP[APU_NON]; for (uint32 J = 0; J < NUM_CHANNELS; J++) { int32 VL, VR; Channel *ch = &SoundData.channels[J]; unsigned long freq0 = ch->frequency; if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J))) continue; freq0 = (unsigned long) ((double) freq0 * 0.985);//uncommented by jonathan gevaryahu, as it is necessary for most cards in linux bool8 mod = pitch_mod & (1 << J); if (ch->needs_decode) { DecodeBlock(ch); ch->needs_decode = FALSE; ch->sample = ch->block[0]; ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT; if (ch->sample_pointer == 0) ch->sample_pointer = 1; if (ch->sample_pointer > SOUND_DECODE_LENGTH) ch->sample_pointer = SOUND_DECODE_LENGTH - 1; ch->next_sample=ch->block[ch->sample_pointer]; ch->interpolate = 0; if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod) ch->interpolate = ((ch->next_sample - ch->sample) * (long) freq0) / (long) FIXED_POINT; } VL = (ch->sample * ch-> left_vol_level) / 128; VR = (ch->sample * ch->right_vol_level) / 128; for (uint32 I = 0; I < (uint32) sample_count; I += 2) { unsigned long freq = freq0; if (mod) freq = PITCH_MOD(freq, wave [I / 2]); ch->env_error += ch->erate; if (ch->env_error >= FIXED_POINT) { uint32 step = ch->env_error >> FIXED_POINT_SHIFT; switch (ch->state) { case SOUND_ATTACK: ch->env_error &= FIXED_POINT_REMAINDER; ch->envx += step << 1; ch->envxx = ch->envx << ENVX_SHIFT; if (ch->envx >= 126) { ch->envx = 127; ch->envxx = 127 << ENVX_SHIFT; ch->state = SOUND_DECAY; if (ch->sustain_level != 8) { S9xSetEnvRate (ch, ch->decay_rate, -1, (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3); break; } ch->state = SOUND_SUSTAIN; S9xSetEnvRate (ch, ch->sustain_rate, -1, 0); } break; case SOUND_DECAY: while (ch->env_error >= FIXED_POINT) { ch->envxx = (ch->envxx >> 8) * 255; ch->env_error -= FIXED_POINT; } ch->envx = ch->envxx >> ENVX_SHIFT; if (ch->envx <= ch->envx_target) { if (ch->envx <= 0) { S9xAPUSetEndOfSample (J, ch); goto stereo_exit; } ch->state = SOUND_SUSTAIN; S9xSetEnvRate (ch, ch->sustain_rate, -1, 0); } break; case SOUND_SUSTAIN: while (ch->env_error >= FIXED_POINT) { ch->envxx = (ch->envxx >> 8) * 255; ch->env_error -= FIXED_POINT; } ch->envx = ch->envxx >> ENVX_SHIFT; if (ch->envx <= 0) { S9xAPUSetEndOfSample (J, ch); goto stereo_exit; } break; case SOUND_RELEASE: while (ch->env_error >= FIXED_POINT) { ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; ch->env_error -= FIXED_POINT; } ch->envx = ch->envxx >> ENVX_SHIFT; if (ch->envx <= 0) { S9xAPUSetEndOfSample (J, ch); goto stereo_exit; } break; case SOUND_INCREASE_LINEAR: ch->env_error &= FIXED_POINT_REMAINDER; ch->envx += step << 1; ch->envxx = ch->envx << ENVX_SHIFT; if (ch->envx >= 126) { ch->envx = 127; ch->envxx = 127 << ENVX_SHIFT; ch->state = SOUND_GAIN; ch->mode = MODE_GAIN; S9xSetEnvRate (ch, 0, -1, 0); } break; case SOUND_INCREASE_BENT_LINE: if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4) { while (ch->env_error >= FIXED_POINT) { ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; ch->env_error -= FIXED_POINT; } ch->envx = ch->envxx >> ENVX_SHIFT; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -