#ifndef __Y8950_HH__ #define __Y8950_HH__ #include "blargg_common.h" #include "emuadpcm.h" #define AUDIO_MONO_BUFFER_SIZE 1024 // Dynamic range of envelope static const double EG_STEP = 0.1875; #define EG_BITS 9 #define EG_MUTE (1< int *plfo_pm; int *plfo_am; }; void slotReset(struct Slot* slot); struct OPLChannel { bool alg; struct Slot mod, car; }; void channelReset(struct OPLChannel* ch); struct Y8950 { int adr; int output[2]; // Register byte reg[0x100]; bool rythm_mode; // Pitch Modulator int pm_mode; unsigned int pm_phase; // Amp Modulator int am_mode; unsigned int am_phase; // Noise Generator int noise_seed; int whitenoise; int noiseA; int noiseB; unsigned int noiseA_phase; unsigned int noiseB_phase; unsigned int noiseA_dphase; unsigned int noiseB_dphase; // Channel & Slot struct OPLChannel ch[9]; struct Slot *slot[18]; unsigned int pm_dphase; int lfo_pm; unsigned int am_dphase; int lfo_am; int maxVolume; bool internalMuted; int clockRate; /** STATUS Register. */ byte status; /** bit=0 -> masked. */ byte statusMask; /* MsxAudioIRQHelper irq; */ // ADPCM struct Y8950Adpcm adpcm; /** 13-bit (exponential) DAC. */ /* DACSound16S dac13; */ // DAC stuff int dacSampleVolume; int dacOldSampleVolume; int dacSampleVolumeSum; int dacCtrlVolume; int dacDaVolume; int dacEnabled; // Internal buffer int buffer[AUDIO_MONO_BUFFER_SIZE]; }; void OPL_init(struct Y8950* this_, byte* ramBank, int sampleRam); void OPL_reset(struct Y8950* this_); void OPL_writeReg(struct Y8950* this_, byte reg, byte data); byte OPL_readReg(struct Y8950* this_, byte reg); byte OPL_readStatus(struct Y8950* this_); static inline void OPL_setInternalMute(struct Y8950* this_, bool muted) { this_->internalMuted = muted; } static inline bool OPL_isInternalMuted(struct Y8950* this_) { return this_->internalMuted; } void OPL_setSampleRate(struct Y8950* this_, int sampleRate, int clockRate); int* OPL_updateBuffer(struct Y8950* this_, int length); // SoundDevice void OPL_setInternalVolume(struct Y8950* this_, short maxVolume); void OPL_setStatus(struct Y8950* this_, byte flags); void OPL_resetStatus(struct Y8950* this_, byte flags); void OPL_changeStatusMask(struct Y8950* this_, byte newMask); // Adjust envelope speed which depends on sampling rate static inline unsigned int rate_adjust(double x, int rate, int clk) { double tmp = x * clk / 72 / rate + 0.5; // +0.5 to round // assert (tmp <= 4294967295U); return (unsigned int)tmp; } #endif