int BurnYM2612Init(int num, int nClockFrequency, FM_IRQHANDLER IRQCallback, int (*StreamCallback)(int), double (*GetTimeCallback)(), int bAddSignal) { if (num > MAX_YM2612) num = MAX_YM2612; BurnTimerInit(&YM2612TimerOver, GetTimeCallback); if (nBurnSoundRate <= 0) { BurnYM2612StreamCallback = YM2612StreamCallbackDummy; BurnYM2612Update = YM2612UpdateDummy; YM2612Init(num, nClockFrequency, 11025, &BurnOPNTimerCallback, IRQCallback); return 0; } BurnYM2612StreamCallback = StreamCallback; nBurnYM2612SoundRate = nBurnSoundRate; BurnYM2612Update = YM2612UpdateNormal; YM2612Init(num, nClockFrequency, nBurnYM2612SoundRate, &BurnOPNTimerCallback, IRQCallback); pBuffer = (short*)malloc(4096 * 2 * num * sizeof(short)); memset(pBuffer, 0, 4096 * 2 * num * sizeof(short)); nYM2612Position = 0; nFractionalPosition = 0; nNumChips = num; bYM2612AddSignal = bAddSignal; return 0; }
void sound_init( void ) { /* Initialize FM chip */ if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { /* YM2612 */ YM2612Init(); YM2612Config(config.dac_bits); YM_Reset = YM2612ResetChip; YM_Update = YM2612Update; YM_Write = YM2612Write; /* chip is running a VCLK / 144 = MCLK / 7 / 144 */ fm_cycles_ratio = 144 * 7; } else { /* YM2413 */ YM2413Init(); YM_Reset = YM2413ResetChip; YM_Update = YM2413Update; YM_Write = YM2413Write; /* chip is running a ZCLK / 72 = MCLK / 15 / 72 */ fm_cycles_ratio = 72 * 15; } /* Initialize PSG chip */ SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff); }
int YM2612_sh_start(const struct MachineSound *msound) { int i,j; int rate = Machine->sample_rate; char buf[YM2612_NUMBUF][40]; const char *name[YM2612_NUMBUF]; intf = msound->sound_interface; if( intf->num > MAX_2612 ) return 1; /* FM init */ /* Timer Handler set */ FMTimerInit(); /* stream system initialize */ for (i = 0;i < intf->num;i++) { int vol[YM2612_NUMBUF]; /* stream setup */ for (j = 0 ; j < YM2612_NUMBUF ; j++) { vol[j] = intf->mixing_level[i]; name[j] = buf[j]; sprintf(buf[j],"YM2612(%s) #%d",j < 2 ? "FM" : "ADPCM",i); } stream[i] = stream_init_multi(YM2612_NUMBUF, name,vol,rate,FM_OUTPUT_BIT, i,YM2612UpdateOne); } /**** initialize YM2612 ****/ if (YM2612Init(intf->num,intf->baseclock,rate,TimerHandler,IRQHandler) == 0) return 0; /* error */ return 1; }
static void *ym2612_start(int sndindex, int clock, const void *config) { static const struct YM2612interface dummy = { 0 }; int rate = Machine->sample_rate; struct ym2612_info *info; info = auto_malloc(sizeof(*info)); memset(info, 0, sizeof(*info)); info->intf = config ? config : &dummy; /* FM init */ /* Timer Handler set */ info->timer[0] =timer_alloc_ptr(timer_callback_2612_0, info); info->timer[1] =timer_alloc_ptr(timer_callback_2612_1, info); /* stream system initialize */ info->stream = stream_create(0,2,rate,info,ym2612_stream_update); /**** initialize YM2612 ****/ info->chip = YM2612Init(info,sndindex,clock,rate,TimerHandler,IRQHandler); state_save_register_func_postload_ptr(ym2612_postload, info); if (info->chip) return info; /* error */ return NULL; }
/* 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 }