📄 mzpokeysnd.c
字号:
static unsigned char readout1_normal(PokeyState* ps){ if(ps->c1t2) return ps->vol1; else return 0;}/*********************************** READ OUTPUT 2 ************************************/static unsigned char readout2_vo(PokeyState* ps){ return ps->vol2;}static unsigned char readout2_normal(PokeyState* ps){ if(ps->c2t2) return ps->vol2; else return 0;}/*********************************** READ OUTPUT 3 ************************************/static unsigned char readout3_vo(PokeyState* ps){ return ps->vol3;}static unsigned char readout3_normal(PokeyState* ps){ if(ps->c3t2) return ps->vol3; else return 0;}/*********************************** EVENT CHANNEL 0 ************************************/static void event0_pure(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c0t2 = !ps->c0t2; ps->c0t1 = p5v;}static void event0_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c0t1) ps->c0t2 = !ps->c0t2; ps->c0t1 = p5v;}static void event0_p4(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c0t2 = p4v; ps->c0t1 = p5v;}static void event0_p917(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c0t2 = p917v; ps->c0t1 = p5v;}static void event0_p4_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c0t1) ps->c0t2 = p4v; ps->c0t1 = p5v;}static void event0_p917_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c0t1) ps->c0t2 = p917v; ps->c0t1 = p5v;}/*********************************** EVENT CHANNEL 1 ************************************/static void event1_pure(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c1t2 = !ps->c1t2; ps->c1t1 = p5v;}static void event1_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c1t1) ps->c1t2 = !ps->c1t2; ps->c1t1 = p5v;}static void event1_p4(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c1t2 = p4v; ps->c1t1 = p5v;}static void event1_p917(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c1t2 = p917v; ps->c1t1 = p5v;}static void event1_p4_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c1t1) ps->c1t2 = p4v; ps->c1t1 = p5v;}static void event1_p917_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c1t1) ps->c1t2 = p917v; ps->c1t1 = p5v;}/*********************************** EVENT CHANNEL 2 ************************************/static void event2_pure(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c2t2 = !ps->c2t2; ps->c2t1 = p5v; /* high-pass clock for channel 0 */ ps->c0t3 = ps->c0t2;}static void event2_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c2t1) ps->c2t2 = !ps->c2t2; ps->c2t1 = p5v; /* high-pass clock for channel 0 */ ps->c0t3 = ps->c0t2;}static void event2_p4(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c2t2 = p4v; ps->c2t1 = p5v; /* high-pass clock for channel 0 */ ps->c0t3 = ps->c0t2;}static void event2_p917(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c2t2 = p917v; ps->c2t1 = p5v; /* high-pass clock for channel 0 */ ps->c0t3 = ps->c0t2;}static void event2_p4_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c2t1) ps->c2t2 = p4v; ps->c2t1 = p5v; /* high-pass clock for channel 0 */ ps->c0t3 = ps->c0t2;}static void event2_p917_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c2t1) ps->c2t2 = p917v; ps->c2t1 = p5v; /* high-pass clock for channel 0 */ ps->c0t3 = ps->c0t2;}/*********************************** EVENT CHANNEL 3 ************************************/static void event3_pure(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c3t2 = !ps->c3t2; ps->c3t1 = p5v; /* high-pass closk for channel 1 */ ps->c1t3 = ps->c1t2;}static void event3_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c3t1) ps->c3t2 = !ps->c3t2; ps->c3t1 = p5v; /* high-pass closk for channel 1 */ ps->c1t3 = ps->c1t2;}static void event3_p4(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c3t2 = p4v; ps->c3t1 = p5v; /* high-pass closk for channel 1 */ ps->c1t3 = ps->c1t2;}static void event3_p917(PokeyState* ps, char p5v, char p4v, char p917v){ ps->c3t2 = p917v; ps->c3t1 = p5v; /* high-pass closk for channel 1 */ ps->c1t3 = ps->c1t2;}static void event3_p4_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c3t1) ps->c3t2 = p4v; ps->c3t1 = p5v; /* high-pass closk for channel 1 */ ps->c1t3 = ps->c1t2;}static void event3_p917_p5(PokeyState* ps, char p5v, char p4v, char p917v){ if(ps->c3t1) ps->c3t2 = p917v; ps->c3t1 = p5v; /* high-pass closk for channel 1 */ ps->c1t3 = ps->c1t2;}static void advance_ticks(PokeyState* ps, unsigned long ticks){ unsigned long ta,tbe, tbe0, tbe1, tbe2, tbe3; char p5v,p4v,p917v; unsigned char outvol_new; unsigned char need0=0; unsigned char need1=0; unsigned char need2=0; unsigned char need3=0; unsigned char need=0; if(ps->forcero) { ps->forcero = 0; outvol_new = ps->outvol_0 + ps->outvol_1 + ps->outvol_2 + ps->outvol_3; if(outvol_new != ps->outvol_all) { ps->outvol_all = outvol_new; add_change(ps, outvol_new); } } while(ticks>0) { tbe0 = ps->c0divpos; tbe1 = ps->c1divpos; tbe2 = ps->c2divpos; tbe3 = ps->c3divpos; tbe = ticks+1; if(!ps->c0stop && tbe0 < tbe) tbe = tbe0; if(!ps->c1stop && tbe1 < tbe) tbe = tbe1; if(!ps->c2stop && tbe2 < tbe) tbe = tbe2; if(!ps->c3stop && tbe3 < tbe) tbe = tbe3; if(tbe>ticks) ta = ticks; else { ta = tbe; need = 1; } ticks -= ta; if(!ps->c0stop) ps->c0divpos -= ta; if(!ps->c1stop) ps->c1divpos -= ta; if(!ps->c2stop) ps->c2divpos -= ta; if(!ps->c3stop) ps->c3divpos -= ta; advance_polies(ps,ta); bump_qe_subticks(ps,ta); if(need) { p5v = poly5tbl[ps->poly5pos] & 1; p4v = poly4tbl[ps->poly4pos] & 1; if(ps->selpoly9) p917v = poly9tbl[ps->poly9pos] & 1; else p917v = poly17tbl[ps->poly17pos] & 1; if(!ps->c0stop && ta == tbe0) { ps->event_0(ps,p5v,p4v,p917v); ps->c0divpos = ps->c0divstart; need0 = 1; } if(!ps->c1stop && ta == tbe1) { ps->event_1(ps,p5v,p4v,p917v); ps->c1divpos = ps->c1divstart; if(ps->c1_f0) ps->c0divpos = ps->c0divstart_p; need1 = 1; } if(!ps->c2stop && ta == tbe2) { ps->event_2(ps,p5v,p4v,p917v); ps->c2divpos = ps->c2divstart; need2 = 1; if(ps->c0sw4) need0 = 1; } if(!ps->c3stop && ta == tbe3) { ps->event_3(ps,p5v,p4v,p917v); ps->c3divpos = ps->c3divstart; if(ps->c3_f2) ps->c2divpos = ps->c2divstart_p; need3 = 1; if(ps->c1sw4) need1 = 1; } if(need0) { ps->outvol_0 = 2*ps->readout_0(ps); } if(need1) { ps->outvol_1 = 2*ps->readout_1(ps); } if(need2) { ps->outvol_2 = 2*ps->readout_2(ps); } if(need3) { ps->outvol_3 = 2*ps->readout_3(ps); } outvol_new = ps->outvol_0 + ps->outvol_1 + ps->outvol_2 + ps->outvol_3; if(outvol_new != ps->outvol_all) { ps->outvol_all = outvol_new; add_change(ps, outvol_new); } } }}static double generate_sample(PokeyState* ps){ /*unsigned long ta = (subticks+pokey_frq)/sample_rate; subticks = (subticks+pokey_frq)%sample_rate;*/ advance_ticks(ps, pokey_frq/sample_rate); return read_resam_all(ps);}/****************************************** filter table generator by Krzysztof Nikiel ******************************************/
#if 0static int remez_filter_table(double resamp_rate, /* output_rate/input_rate */ double *cutoff, int quality){ int i; static const int orders[] = {600, 800, 1000, 1200}; static const struct { int stop; /* stopband ripple */ double weight; /* stopband weight */ double twidth[sizeof(orders)/sizeof(orders[0])]; } paramtab[] = { {70, 90, {4.9e-3, 3.45e-3, 2.65e-3, 2.2e-3}}, {55, 25, {3.4e-3, 2.7e-3, 2.05e-3, 1.7e-3}}, {40, 6.0, {2.6e-3, 1.8e-3, 1.5e-3, 1.2e-3}}, {-1, 0, {0, 0, 0, 0}} }; static const double passtab[] = {0.5, 0.6, 0.7}; int ripple = 0, order = 0; int size; double weights[2], desired[2], bands[4]; static const int interlevel = 5; double step = 1.0 / interlevel; *cutoff = 0.95 * 0.5 * resamp_rate; if (quality >= (int) (sizeof(passtab) / sizeof(passtab[0]))) quality = (int) (sizeof(passtab) / sizeof(passtab[0])) - 1; for (ripple = 0; paramtab[ripple].stop > 0; ripple++) { for (order = 0; order < (int) (sizeof(orders)/sizeof(orders[0])); order++) { if ((*cutoff - paramtab[ripple].twidth[order]) > passtab[quality] * 0.5 * resamp_rate) /* transition width OK */ goto found; } } /* not found -- use shortest trasition */ ripple--; order--;found:#if 0 printf("order: %d, cutoff: %g\tstopband:%d\ttranswidth:%f\n", orders[order], 1789790 * *cutoff, paramtab[ripple].stop, 1789790 * paramtab[ripple].twidth[order]); exit(1);#endif size = orders[order] + 1; if (size > SND_FILTER_SIZE) /* static table too short */ return 0; desired[0] = 1; desired[1] = 0; weights[0] = 1; weights[1] = paramtab[ripple].weight; bands[0] = 0; bands[2] = *cutoff; bands[1] = bands[2] - paramtab[ripple].twidth[order]; bands[3] = 0.5; bands[1] *= (double)interlevel; bands[2] *= (double)interlevel; remez(filter_data, (size / interlevel) + 1, 2, bands, desired, weights, BANDPASS); for (i = size - interlevel; i >= 0; i -= interlevel) { int s; double h1 = filter_data[i/interlevel]; double h2 = filter_data[i/interlevel+1]; for (s = 0; s < interlevel; s++) { double d = (double)s * step; filter_data[i+s] = (h1*(1.0 - d) + h2 * d) * step; } } /* compute reversed cumulative sum table */ for (i = size - 2; i >= 0; i--) filter_data[i] += filter_data[i + 1];#if 0 for (i = 0; i < size; i++) printf("%.15f,\n", filter_data[i]); fflush(stdout); exit(1);#endif return size;}#endif/*****************************************************************************//* Module: Pokey_sound_init() *//* Purpose: to handle the power-up initialization functions *//* these functions should only be executed on a cold-restart *//* *//* Authors: Michael Borisov, Krzystof Nikiel *//* *//* Inputs: freq17 - the value for the '1.79MHz' Pokey audio clock *//* playback_freq - the playback frequency in samples per second *//* num_pokeys - specifies the number of pokey chips to be emulated *//* *//* Outputs: Adjusts local globals - no return value *//* *//*****************************************************************************/static void Pokey_process_8(void* sndbuffer, unsigned sndn);static void Pokey_process_16(void* sndbuffer, unsigned sndn);static void Update_pokey_sound_mz(uint16 addr, uint8 val, uint8 chip, uint8 gain);#ifdef SERIO_SOUNDstatic void Update_serio_sound_mz(int out, UBYTE data);#endif#ifdef CONSOLE_SOUNDstatic void Update_consol_sound_mz( int set );#endif#ifdef VOL_ONLY_SOUNDstatic void Update_vol_only_sound_mz( void );#endifint Pokey_sound_init_mz(uint32 freq17, uint16 playback_freq, uint8 num_pokeys, int flags, int quality#ifdef __PLUS , int clear_regs#endif ){ double cutoff; sample_rate = playback_freq; snd_flags = flags; snd_quality = quality; Update_pokey_sound = Update_pokey_sound_mz;#ifdef SERIO_SOUND Update_serio_sound = Update_serio_sound_mz;#endif#ifdef CONSOLE_SOUND Update_consol_sound = Update_consol_sound_mz;#endif#ifdef VOL_ONLY_SOUND Update_vol_only_sound = Update_vol_only_sound_mz;#endif#ifdef VOL_ONLY_SOUND samp_freq=playback_freq;#endif /* VOL_ONLY_SOUND */ Pokey_process_ptr = (flags & SND_BIT16) ? Pokey_process_16 : Pokey_process_8; switch(playback_freq) {#if 0 case 44100: if(flags & SND_BIT16) { filter_data = filter_44; filter_size = filter_size_44; } else { filter_data = filter_44_8; filter_size = filter_size_44_8; } pokey_frq = 1808100; /* 1.02% off ideal */ audible_frq = 20000; /* ultrasound */ break; case 22050:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -