int device_start_sn764xx(UINT8 ChipID, int clock, int shiftregwidth, int noisetaps, int negate, int stereo, int clockdivider, int freq0) { sn764xx_state *info; int rate; if (ChipID >= MAX_CHIPS) return 0; info = &SN764xxData[ChipID]; /* emulator create */ switch(EMU_CORE) { case EC_MAME: rate = sn76496_start(&info->chip, clock, shiftregwidth, noisetaps, negate, stereo, clockdivider, freq0); sn76496_freq_limiter(clock & 0x3FFFFFFF, clockdivider, SampleRate); break; #ifdef ENABLE_ALL_CORES case EC_MAXIM: rate = SampleRate; info->chip = SN76489_Init(clock, rate); if (info->chip == NULL) return 0; SN76489_Config((SN76489_Context*)info->chip, noisetaps, shiftregwidth, 0); break; #endif } return rate; }
int device_start_sn764xx(void **_info, int EMU_CORE, int clock, int SampleRate, int shiftregwidth, int noisetaps, int negate, int stereo, int clockdivider, int freq0) { sn764xx_state *info; int rate; #ifdef ENABLE_ALL_CORES if (EMU_CORE >= 0x02) EMU_CORE = EC_MAME; #else EMU_CORE = EC_MAME; #endif info = (sn764xx_state*) calloc(1, sizeof(sn764xx_state)); *_info = (void *) info; /* emulator create */ info->EMU_CORE = EMU_CORE; switch(EMU_CORE) { case EC_MAME: rate = sn76496_start(&info->chip, clock, shiftregwidth, noisetaps, negate, stereo, clockdivider, freq0); sn76496_freq_limiter(clock & 0x3FFFFFFF, clockdivider, SampleRate); break; #ifdef ENABLE_ALL_CORES case EC_MAXIM: rate = SampleRate; info->chip = SN76489_Init(clock, rate); if (info->chip == NULL) return 0; SN76489_Config((SN76489_Context*)info->chip, noisetaps, shiftregwidth, 0); break; #endif } return rate; }
/* Initialize sound chips emulation */ void sound_init(void) { /* Number of M-cycles executed per second. */ /* */ /* All emulated chips are kept in sync by using a common oscillator (MCLOCK) */ /* */ /* The original console would run exactly 53693175 M-cycles (53203424 for PAL), with */ /* 3420 M-cycles per line and 262 (313 for PAL) lines per frame, which gives an exact */ /* framerate of 59.92 (49.70 for PAL) fps. */ /* */ /* Since audio samples are generated at the end of the frame, to prevent audio skipping */ /* or lag between emulated frames, number of samples rendered per frame must be set to */ /* output samplerate (number of samples played per second) divided by output framerate */ /* (number of frames emulated per seconds). */ /* */ /* On some systems, we may want to achieve 100% smooth video rendering by synchronizing */ /* frame emulation with VSYNC, which frequency is generally not exactly those values. */ /* In that case, number of frames emulated per seconds is the same as the number of */ /* frames rendered per seconds by the host system video hardware. */ /* */ /* When no framerate is specified, base clock is original master clock value. */ /* Otherwise, it is based on the output framerate. */ /* */ double mclk = snd.frame_rate ? (MCYCLES_PER_LINE * lines_per_frame * snd.frame_rate) : system_clock; /* For maximal accuracy, sound chips run in synchronization with 68k and Z80 cpus */ /* These values give the exact number of M-cycles executed per internal sample clock: */ /* . PSG chip runs at original rate and audio is resampled internally after each update */ /* . FM chips run by default (if HQ mode disabled) at the output rate directly */ /* We use 21.11 fixed point precision (max. mcycle value is 3420*313 i.e 21 bits max) */ psg_cycles_ratio = 16 * 15 * (1 << 11); fm_cycles_ratio = (unsigned int)(mclk / (double) snd.sample_rate * 2048.0); psg_cycles_count = 0; fm_cycles_count = 0; /* Initialize PSG core (input clock should be based on emulated system clock) */ SN76489_Init(mclk/15.0,snd.sample_rate); /* Initialize FM cores (input clock and samplerate are only used when HQ mode is disabled) */ if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { /* YM2612 */ YM2612Init(mclk/7.0,snd.sample_rate); YM_Reset = YM2612ResetChip; YM_Update = YM2612Update; YM_Write = YM2612Write; /* In HQ mode, YM2612 is running at original rate (one sample each 144*7 M-cycles) */ /* Audio is resampled externally at the end of a frame. */ if (config.hq_fm) { fm_cycles_ratio = 144 * 7 * (1 << 11); Fir_Resampler_time_ratio(mclk / (double)snd.sample_rate / (144.0 * 7.0), config.rolloff); } } else { /* YM2413 */ YM2413Init(mclk/15.0,snd.sample_rate); YM_Reset = YM2413ResetChip; YM_Update = YM2413Update; YM_Write = YM2413Write; /* In HQ mode, YM2413 is running at original rate (one sample each 72*15 M-cycles) */ /* Audio is resampled externally at the end of a frame. */ if (config.hq_fm) { fm_cycles_ratio = 72 * 15 * (1 << 11); Fir_Resampler_time_ratio(mclk / (double)snd.sample_rate / (72.0 * 15.0), config.rolloff); } } #ifdef LOGSOUND error("%f mcycles per second\n", mclk); error("%d mcycles per PSG sample\n", psg_cycles_ratio); error("%d mcycles per FM sample\n", fm_cycles_ratio); #endif }
int sound_init(void) { uint8 *buf = NULL; int restore_fm = 0; int i; /* Save register settings */ if(snd.enabled && sms.use_fm) { restore_fm = 1; buf = malloc(FM_GetContextSize()); FM_GetContext(buf); } /* If we are reinitializing, shut down sound emulation */ if(snd.enabled) { sound_shutdown(); } /* Disable sound until initialization is complete */ snd.enabled = 0; /* Check if sample rate is invalid */ if(snd.sample_rate < 8000 || snd.sample_rate > 48000) return 0; /* Assign stream mixing callback if none provided */ if(!snd.mixer_callback) snd.mixer_callback = sound_mixer_callback; /* Calculate number of samples generated per frame */ #ifdef PSP /* PSP version requires a sample count divisible by 64 */ snd.sample_count = ((snd.sample_rate / snd.fps) + 63) & ~63; #else snd.sample_count = (snd.sample_rate / snd.fps); #endif /* Calculate size of sample buffer */ snd.buffer_size = snd.sample_count * 2; /* Free sample buffer position table if previously allocated */ if(smptab) { free(smptab); smptab = NULL; } /* Prepare incremental info */ snd.done_so_far = 0; smptab_len = (sms.display == DISPLAY_NTSC) ? 262 : 313; smptab = malloc(smptab_len * sizeof(int)); if(!smptab) return 0; for (i = 0; i < smptab_len; i++) { double calc = (snd.sample_count * i); calc = calc / (double)smptab_len; smptab[i] = (int)calc; } /* Allocate emulated sound streams */ for(i = 0; i < STREAM_MAX; i++) { snd.stream[i] = malloc(snd.buffer_size); if(!snd.stream[i]) return 0; memset(snd.stream[i], 0, snd.buffer_size); } /* Allocate sound output streams */ snd.output[0] = calloc(snd.sample_count, sizeof(int16)); snd.output[1] = calloc(snd.sample_count, sizeof(int16)); if(!snd.output[0] || !snd.output[1]) return 0; /* Set up buffer pointers */ fm_buffer = (int16 **)&snd.stream[STREAM_FM_MO]; psg_buffer = (int16 **)&snd.stream[STREAM_PSG_L]; /* Set up SN76489 emulation */ SN76489_Init(0, snd.psg_clock, snd.sample_rate); /* Set up YM2413 emulation */ FM_Init(); /* Inform other functions that we can use sound */ snd.enabled = 1; /* Restore YM2413 register settings */ if(restore_fm) { FM_SetContext(buf); } return 1; }
int audio_init(int samplerate, double framerate) { /* Number of M-cycles executed per second. */ /* All emulated chips are kept in sync by using a common oscillator (MCLOCK) */ /* */ /* The original console would run exactly 53693175 M-cycles per sec (53203424 for PAL), */ /* 3420 M-cycles per line and 262 (313 for PAL) lines per frame, which gives an exact */ /* framerate of 59.92 (49.70 for PAL) frames per second. */ /* */ /* Since audio samples are generated at the end of the frame, to prevent audio skipping */ /* or lag between emulated frames, number of samples rendered per frame must be set to */ /* output samplerate (number of samples played per second) divided by input framerate */ /* (number of frames emulated per seconds). */ /* */ /* On some systems, we may want to achieve 100% smooth video rendering by synchronizing */ /* frame emulation with VSYNC, which frequency is generally not exactly those values. */ /* In that case, input framerate (number of frames emulated per seconds) is the same as */ /* output framerate (number of frames rendered per seconds) by the host video hardware. */ /* */ /* When no framerate is specified, base clock is set to original master clock value. */ /* Otherwise, it is set to number of M-cycles emulated per line (fixed) multiplied by */ /* number of lines per frame (VDP mode specific) multiplied by input framerate. */ /* */ double mclk = framerate ? (MCYCLES_PER_LINE * (vdp_pal ? 313 : 262) * framerate) : system_clock; /* Shutdown first */ audio_shutdown(); /* Clear the sound data context */ memset(&snd, 0, sizeof (snd)); /* Initialize audio rates */ snd.sample_rate = samplerate; snd.frame_rate = framerate; /* Initialize Blip Buffers */ snd.blips[0][0] = blip_new(samplerate / 10); snd.blips[0][1] = blip_new(samplerate / 10); if (!snd.blips[0][0] || !snd.blips[0][1]) { audio_shutdown(); return -1; } /* For maximal accuracy, sound chips are running at their original rate using common */ /* master clock timebase so they remain perfectly synchronized together, while still */ /* being synchronized with 68K and Z80 CPUs as well. Mixed sound chip output is then */ /* resampled to desired rate at the end of each frame, using Blip Buffer. */ blip_set_rates(snd.blips[0][0], mclk, samplerate); blip_set_rates(snd.blips[0][1], mclk, samplerate); /* Initialize PSG core */ SN76489_Init(snd.blips[0][0], snd.blips[0][1], (system_hw < SYSTEM_MARKIII) ? SN_DISCRETE : SN_INTEGRATED); /* Mega CD sound hardware */ if (system_hw == SYSTEM_MCD) { /* allocate blip buffers */ snd.blips[1][0] = blip_new(samplerate / 10); snd.blips[1][1] = blip_new(samplerate / 10); snd.blips[2][0] = blip_new(samplerate / 10); snd.blips[2][1] = blip_new(samplerate / 10); if (!snd.blips[1][0] || !snd.blips[1][1] || !snd.blips[2][0] || !snd.blips[2][1]) { audio_shutdown(); return -1; } /* Initialize PCM core */ pcm_init(snd.blips[1][0], snd.blips[1][1]); /* Initialize CDD core */ cdd_init(snd.blips[2][0], snd.blips[2][1]); } /* Set audio enable flag */ snd.enabled = 1; /* Reset audio */ audio_reset(); return (0); }