// license:GPL-2.0+ // copyright-holders:Jarek Burczynski,Ernesto Corvi #ifndef MAME_SOUND_YM2413_H #define MAME_SOUND_YM2413_H #pragma once class ym2413_device : public device_t, public device_sound_interface { public: ym2413_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); void write(offs_t offset, u8 data); void register_port_w(u8 data); void data_port_w(u8 data); protected: ym2413_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_start() override; virtual void device_clock_changed() override; virtual void device_reset() override; // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; uint8_t m_inst_table[19][8]; private: struct OPLL_SLOT { uint32_t ar = 0; /* attack rate: AR<<2 */ uint32_t dr = 0; /* decay rate: DR<<2 */ uint32_t rr = 0; /* release rate:RR<<2 */ uint8_t KSR = 0; /* key scale rate */ uint8_t ksl = 0; /* keyscale level */ uint8_t ksr = 0; /* key scale rate: kcode>>KSR */ uint8_t mul = 0; /* multiple: mul_tab[ML] */ /* Phase Generator */ uint32_t phase = 0; /* frequency counter */ uint32_t freq = 0; /* frequency counter step */ uint8_t fb_shift = 0; /* feedback shift value */ int32_t op1_out[2] = { 0, 0 }; /* slot1 output for feedback */ /* Envelope Generator */ uint8_t eg_type = 0; /* percussive/nonpercussive mode*/ uint8_t state = 0; /* phase type */ uint32_t TL = 0; /* total level: TL << 2 */ int32_t TLL = 0; /* adjusted now TL */ int32_t volume = 0; /* envelope counter */ uint32_t sl = 0; /* sustain level: sl_tab[SL] */ uint8_t eg_sh_dp = 0; /* (dump state) */ uint8_t eg_sel_dp = 0; /* (dump state) */ uint8_t eg_sh_ar = 0; /* (attack state) */ uint8_t eg_sel_ar = 0; /* (attack state) */ uint8_t eg_sh_dr = 0; /* (decay state) */ uint8_t eg_sel_dr = 0; /* (decay state) */ uint8_t eg_sh_rr = 0; /* (release state for non-perc.)*/ uint8_t eg_sel_rr = 0; /* (release state for non-perc.)*/ uint8_t eg_sh_rs = 0; /* (release state for perc.mode)*/ uint8_t eg_sel_rs = 0; /* (release state for perc.mode)*/ uint32_t key = 0; /* 0 = KEY OFF, >0 = KEY ON */ /* LFO */ uint32_t AMmask = 0; /* LFO Amplitude Modulation enable mask */ uint8_t vib = 0; /* LFO Phase Modulation enable flag (active high)*/ /* waveform select */ unsigned int wavetable = 0; }; struct OPLL_CH { OPLL_SLOT SLOT[2]; /* phase generator state */ uint32_t block_fnum = 0; /* block+fnum */ uint32_t fc = 0; /* Freq. freqement base */ uint32_t ksl_base = 0; /* KeyScaleLevel Base step */ uint8_t kcode = 0; /* key code (for key scaling) */ uint8_t sus = 0; /* sus on/off (release speed in percussive mode)*/ }; enum { RATE_STEPS = (8), /* sinwave entries */ SIN_BITS = 10, SIN_LEN = (1<increment counter */ uint8_t address; /* address register */ signed int output[2]; // internal state sound_stream * m_stream; int limit( int val, int max, int min ); void advance_lfo(); void advance(); int op_calc(uint32_t phase, unsigned int env, signed int pm, unsigned int wave_tab); int op_calc1(uint32_t phase, unsigned int env, signed int pm, unsigned int wave_tab); void chan_calc( OPLL_CH *CH ); void rhythm_calc( OPLL_CH *CH, unsigned int noise ); void key_on(OPLL_SLOT *SLOT, uint32_t key_set); void key_off(OPLL_SLOT *SLOT, uint32_t key_clr); void calc_fcslot(OPLL_CH *CH, OPLL_SLOT *SLOT); void set_mul(int slot,int v); void set_ksl_tl(int chan,int v); void set_ksl_wave_fb(int chan,int v); void set_ar_dr(int slot,int v); void set_sl_rr(int slot,int v); void load_instrument(uint32_t chan, uint32_t slot, uint8_t* inst ); void update_instrument_zero( uint8_t r ); void write_reg(int r, int v); }; DECLARE_DEVICE_TYPE(YM2413, ym2413_device) class vrc7snd_device : public ym2413_device { public: vrc7snd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); private: static const uint8_t vrc7_table[19][8]; }; DECLARE_DEVICE_TYPE(VRC7, vrc7snd_device) #endif // MAME_SOUND_YM2413_H