⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soundux.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. * * (c) Copyright 1996 - 2001 Gary Henderson (gary@daniver.demon.co.uk) and *                           Jerremy Koot (jkoot@snes9x.com) * * Super FX C emulator code  * (c) Copyright 1997 - 1999 Ivar (Ivar@snes9x.com) and *                           Gary Henderson. * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. * * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. * C4 C code (c) Copyright 2001 Gary Henderson (gary@daniver.demon.co.uk). * * DOS port code contains the works of other authors. See headers in * individual files. * * Snes9x homepage: www.snes9x.com * * Permission to use, copy, modify and distribute Snes9x in both binary and * source form, for non-commercial purposes, is hereby granted without fee, * providing that this license information and copyright notice appear with * all copies and any derived work. * * This software is provided 'as-is', without any express or implied * warranty. In no event shall the authors be held liable for any damages * arising from the use of this software. * * Snes9x is freeware for PERSONAL USE only. Commercial users should * seek permission of the copyright holders first. Commercial use includes * charging money for Snes9x or software derived from Snes9x. * * The copyright holders request that bug fixes and improvements to the code * should be forwarded to them so everyone can benefit from the modifications * in future versions. * * Super NES and Super Nintendo Entertainment System are trademarks of * Nintendo Co., Limited and its subsidiary companies. */#ifdef __DJGPP__#include <allegro.h>#undef TRUE#endif#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <fcntl.h>#define CLIP16(v) \if ((v) < -32768) \    (v) = -32768; \else \if ((v) > 32767) \    (v) = 32767#define CLIP16_latch(v,l) \if ((v) < -32768) \{ (v) = -32768; (l)++; }\else \if ((v) > 32767) \{ (v) = 32767; (l)++; }#define CLIP24(v) \if ((v) < -8388608) \    (v) = -8388608; \else \if ((v) > 8388607) \    (v) = 8388607#define CLIP8(v) \if ((v) < -128) \    (v) = -128; \else \if ((v) > 127) \    (v) = 127#include "snes9x.h"#include "soundux.h"#include "apu.h"#include "memmap.h"#include "cpuexec.h"extern int Echo [24000];extern int DummyEchoBuffer [SOUND_BUFFER_SIZE];extern int MixBuffer [SOUND_BUFFER_SIZE];extern int EchoBuffer [SOUND_BUFFER_SIZE];extern int FilterTaps [8];extern unsigned long Z;extern int Loop [16];extern long FilterValues[4][2];extern int NoiseFreq [32];#undef ABS#define ABS(a) ((a) < 0 ? -(a) : (a))#define FIXED_POINT 0x10000UL#define FIXED_POINT_REMAINDER 0xffffUL#define FIXED_POINT_SHIFT 16#define VOL_DIV8  0x8000#define VOL_DIV16 0x0080#define ENVX_SHIFT 24extern "C" void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *);// F is channel's current frequency and M is the 16-bit modulation waveform// from the previous channel multiplied by the current envelope volume level.#define PITCH_MOD(F,M) ((F) * ((((unsigned long) (M)) + 0x800000) >> 16) >> 7)//#define PITCH_MOD(F,M) ((F) * ((((M) & 0x7fffff) >> 14) + 1) >> 8)#define LAST_SAMPLE 0xffffff#define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE)STATIC inline uint8 *S9xGetSampleAddress (int sample_number){    uint32 addr = (((APU.DSP[APU_DIR] << 8) + (sample_number << 2)) & 0xffff);    return (IAPU.RAM + addr);}void S9xAPUSetEndOfSample (int i, Channel *ch){    ch->state = SOUND_SILENT;    ch->mode = MODE_NONE;    APU.DSP [APU_ENDX] |= 1 << i;    APU.DSP [APU_KON] &= ~(1 << i);    APU.DSP [APU_KOFF] &= ~(1 << i);    APU.KeyedChannels &= ~(1 << i);}#ifdef __DJGPPEND_OF_FUNCTION (S9xAPUSetEndOfSample)#endifvoid S9xAPUSetEndX (int ch){    APU.DSP [APU_ENDX] |= 1 << ch;}#ifdef __DJGPPEND_OF_FUNCTION (S9xAPUSetEndX)#endifvoid S9xSetEnvRate (Channel *ch, unsigned long rate, int direction, int target){    ch->envx_target = target;    if (rate == ~0UL)    {	ch->direction = 0;	rate = 0;    }    else	ch->direction = direction;    static int steps [] =    {//	0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238	0, 64, 619, 619, 128, 1, 64, 55, 64, 619    };    if (rate == 0 || so.playback_rate == 0)	ch->erate = 0;    else    {	ch->erate = (unsigned long)		    (((int64) FIXED_POINT * 1000 * steps [ch->state]) /		      (rate * so.playback_rate));    }}#ifdef __DJGPPEND_OF_FUNCTION(S9xSetEnvRate);#endifvoid S9xSetEnvelopeRate (int channel, unsigned long rate, int direction,			 int target){    S9xSetEnvRate (&SoundData.channels [channel], rate, direction, target);}#ifdef __DJGPPEND_OF_FUNCTION(S9xSetEnvelopeRate);#endifvoid S9xSetSoundVolume (int channel, short volume_left, short volume_right){    Channel *ch = &SoundData.channels[channel];    if (!so.stereo)	volume_left = (ABS(volume_right) + ABS(volume_left)) / 2;    ch->volume_left = volume_left;    ch->volume_right = volume_right;    ch-> left_vol_level = (ch->envx * volume_left) / 128;    ch->right_vol_level = (ch->envx * volume_right) / 128;}void S9xSetMasterVolume (short volume_left, short volume_right){    if (Settings.DisableMasterVolume)    {	SoundData.master_volume_left = 127;	SoundData.master_volume_right = 127;	SoundData.master_volume [0] = SoundData.master_volume [1] = 127;    }    else    {	if (!so.stereo)	    volume_left = (ABS (volume_right) + ABS (volume_left)) / 2;	SoundData.master_volume_left = volume_left;	SoundData.master_volume_right = volume_right;	SoundData.master_volume [Settings.ReverseStereo] = volume_left;	SoundData.master_volume [1 ^ Settings.ReverseStereo] = volume_right;    }}void S9xSetEchoVolume (short volume_left, short volume_right){    if (!so.stereo)	volume_left = (ABS (volume_right) + ABS (volume_left)) / 2;    SoundData.echo_volume_left = volume_left;    SoundData.echo_volume_right = volume_right;    SoundData.echo_volume [Settings.ReverseStereo] = volume_left;    SoundData.echo_volume [1 ^ Settings.ReverseStereo] = volume_right;}void S9xSetEchoEnable (uint8 byte){    SoundData.echo_channel_enable = byte;    if (!SoundData.echo_write_enabled || Settings.DisableSoundEcho)	byte = 0;    if (byte && !SoundData.echo_enable)    {	memset (Echo, 0, sizeof (Echo));	memset (Loop, 0, sizeof (Loop));    }    SoundData.echo_enable = byte;    for (int i = 0; i < 8; i++)    {	if (byte & (1 << i))	    SoundData.channels [i].echo_buf_ptr = EchoBuffer;	else	    SoundData.channels [i].echo_buf_ptr = DummyEchoBuffer;    }}void S9xSetEchoFeedback (int feedback){    CLIP8(feedback);    SoundData.echo_feedback = feedback;}void S9xSetEchoDelay (int delay){    SoundData.echo_buffer_size = (512 * delay * so.playback_rate) / 32000;    if (so.stereo)	SoundData.echo_buffer_size <<= 1;    if (SoundData.echo_buffer_size)	SoundData.echo_ptr %= SoundData.echo_buffer_size;    else	SoundData.echo_ptr = 0;    S9xSetEchoEnable (APU.DSP [APU_EON]);}void S9xSetEchoWriteEnable (uint8 byte){    SoundData.echo_write_enabled = byte;    S9xSetEchoDelay (APU.DSP [APU_EDL] & 15);}void S9xSetFrequencyModulationEnable (uint8 byte){    SoundData.pitch_mod = byte & ~1;}void S9xSetSoundKeyOff (int channel){    Channel *ch = &SoundData.channels[channel];    if (ch->state != SOUND_SILENT)    {	ch->state = SOUND_RELEASE;	ch->mode = MODE_RELEASE;	S9xSetEnvRate (ch, 8, -1, 0);    }}void S9xFixSoundAfterSnapshotLoad (){    SoundData.echo_write_enabled = !(APU.DSP [APU_FLG] & 0x20);    SoundData.echo_channel_enable = APU.DSP [APU_EON];    S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf);    S9xSetEchoFeedback ((signed char) APU.DSP [APU_EFB]);    S9xSetFilterCoefficient (0, (signed char) APU.DSP [APU_C0]);    S9xSetFilterCoefficient (1, (signed char) APU.DSP [APU_C1]);    S9xSetFilterCoefficient (2, (signed char) APU.DSP [APU_C2]);    S9xSetFilterCoefficient (3, (signed char) APU.DSP [APU_C3]);    S9xSetFilterCoefficient (4, (signed char) APU.DSP [APU_C4]);    S9xSetFilterCoefficient (5, (signed char) APU.DSP [APU_C5]);    S9xSetFilterCoefficient (6, (signed char) APU.DSP [APU_C6]);    S9xSetFilterCoefficient (7, (signed char) APU.DSP [APU_C7]);    for (int i = 0; i < 8; i++)    {	SoundData.channels[i].needs_decode = TRUE;	S9xSetSoundFrequency (i, SoundData.channels[i].hertz);	SoundData.channels [i].envxx = SoundData.channels [i].envx << ENVX_SHIFT;	SoundData.channels [i].next_sample = 0;	SoundData.channels [i].interpolate = 0;	SoundData.channels [i].previous [0] = (int32) SoundData.channels [i].previous16 [0];	SoundData.channels [i].previous [1] = (int32) SoundData.channels [i].previous16 [1];    }    SoundData.master_volume [Settings.ReverseStereo] = SoundData.master_volume_left;    SoundData.master_volume [1 ^ Settings.ReverseStereo] = SoundData.master_volume_right;    SoundData.echo_volume [Settings.ReverseStereo] = SoundData.echo_volume_left;    SoundData.echo_volume [1 ^ Settings.ReverseStereo] = SoundData.echo_volume_right;    IAPU.Scanline = 0;}void S9xSetFilterCoefficient (int tap, int value){    FilterTaps [tap & 7] = value;    SoundData.no_filter = (FilterTaps [0] == 127 || FilterTaps [0] == 0) && 			   FilterTaps [1] == 0   &&			   FilterTaps [2] == 0   &&			   FilterTaps [3] == 0   &&			   FilterTaps [4] == 0   &&			   FilterTaps [5] == 0   &&			   FilterTaps [6] == 0   &&			   FilterTaps [7] == 0;}void S9xSetSoundADSR (int channel, int attack_rate, int decay_rate,		      int sustain_rate, int sustain_level, int release_rate){    SoundData.channels[channel].attack_rate = attack_rate;    SoundData.channels[channel].decay_rate = decay_rate;    SoundData.channels[channel].sustain_rate = sustain_rate;    SoundData.channels[channel].release_rate = release_rate;    SoundData.channels[channel].sustain_level = sustain_level + 1;    switch (SoundData.channels[channel].state)    {    case SOUND_ATTACK:	S9xSetEnvelopeRate (channel, attack_rate, 1, 127);	break;    case SOUND_DECAY:	S9xSetEnvelopeRate (channel, decay_rate, -1,			    (MAX_ENVELOPE_HEIGHT * (sustain_level + 1)) >> 3);	break;    case SOUND_SUSTAIN:	S9xSetEnvelopeRate (channel, sustain_rate, -1, 0);	break;    }}void S9xSetEnvelopeHeight (int channel, int level){    Channel *ch = &SoundData.channels[channel];    ch->envx = level;    ch->envxx = level << ENVX_SHIFT;    ch->left_vol_level = (level * ch->volume_left) / 128;    ch->right_vol_level = (level * ch->volume_right) / 128;    if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN)    {	S9xAPUSetEndOfSample (channel, ch);    }}int S9xGetEnvelopeHeight (int channel){    if (Settings.SoundEnvelopeHeightReading &&	SoundData.channels[channel].state != SOUND_SILENT &&	SoundData.channels[channel].state != SOUND_GAIN)    {	return (SoundData.channels[channel].envx);    }    return (0);}#if 1void S9xSetSoundSample (int, uint16) {}#elsevoid S9xSetSoundSample (int channel, uint16 sample_number){    register Channel *ch = &SoundData.channels[channel];    if (ch->state != SOUND_SILENT && 	sample_number != ch->sample_number)    {	int keep = ch->state;	ch->state = SOUND_SILENT;	ch->sample_number = sample_number;	ch->loop = FALSE;	ch->needs_decode = TRUE;	ch->last_block = FALSE;	ch->previous [0] = ch->previous[1] = 0;	uint8 *dir = S9xGetSampleAddress (sample_number);	ch->block_pointer = READ_WORD (dir);	ch->sample_pointer = 0;	ch->state = keep;    }}#endifvoid S9xSetSoundFrequency (int channel, int hertz){    if (so.playback_rate)    {	if (SoundData.channels[channel].type == SOUND_NOISE)	    hertz = NoiseFreq [APU.DSP [APU_FLG] & 0x1f];	SoundData.channels[channel].frequency = (int)	    (((int64) hertz * FIXED_POINT) / so.playback_rate);    }}void S9xSetSoundHertz (int channel, int hertz){    SoundData.channels[channel].hertz = hertz;    S9xSetSoundFrequency (channel, hertz);}void S9xSetSoundType (int channel, int type_of_sound){    SoundData.channels[channel].type = type_of_sound;}bool8 S9xSetSoundMute (bool8 mute){    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;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -