openMSX
|
#include <YM2413Okazaki.hh>
Public Member Functions | |
YM2413 () | |
void | reset () override |
Reset this YM2413 core. | |
void | writePort (bool port, uint8_t value, int offset) override |
Write to the YM2413 register/data port. | |
void | pokeReg (uint8_t reg, uint8_t data) override |
Write to a YM2413 register (for debug). | |
uint8_t | peekReg (uint8_t reg) const override |
Read from a YM2413 register (for debug). | |
void | generateChannels (std::span< float *, 9+5 > bufs, unsigned num) override |
Generate the sound output. | |
float | getAmplificationFactor () const override |
Returns normalization factor. | |
Patch & | getPatch (unsigned instrument, bool carrier) |
template<typename Archive > | |
void | serialize (Archive &ar, unsigned version) |
template<unsigned FLAGS> | |
ALWAYS_INLINE void | calcChannel (Channel &ch, std::span< float > buf) |
Public Member Functions inherited from openmsx::YM2413Core | |
virtual | ~YM2413Core ()=default |
virtual void | setSpeed (double) |
Sets real-time speed factor (aka the openMSX 'speed' setting). | |
Additional Inherited Members | |
Static Public Attributes inherited from openmsx::YM2413Core | |
static constexpr int | CLOCK_FREQ = 3579545 |
Input clock frequency. | |
Protected Member Functions inherited from openmsx::YM2413Core | |
YM2413Core ()=default | |
Definition at line 141 of file YM2413Okazaki.hh.
openmsx::YM2413Okazaki::YM2413::YM2413 | ( | ) |
Definition at line 659 of file YM2413Okazaki.cc.
References ranges::fill(), reset(), and xrange().
ALWAYS_INLINE void openmsx::YM2413Okazaki::YM2413::calcChannel | ( | Channel & | ch, |
std::span< float > | buf | ||
) |
Definition at line 1071 of file YM2413Okazaki.cc.
References openmsx::YM2413Okazaki::Patch::AMPM, openmsx::YM2413Okazaki::Slot::calc_fixed_env(), openmsx::YM2413Okazaki::Slot::calc_slot_car(), openmsx::YM2413Okazaki::Slot::calc_slot_mod(), openmsx::YM2413Okazaki::Channel::car, openmsx::YM2413Okazaki::Channel::mod, and openmsx::YM2413Okazaki::Slot::patch.
|
overridevirtual |
Generate the sound output.
bufs | Pointers to output buffers. |
num | The number of required output samples. |
The requested number of samples must be strictly bigger than zero.
The output of the different channels is put in separate output buffers. This makes it possible to e.g. record individual channels or to pan, mute or adjust volume per channel. The YM2413 can operate in two modes: 9 channels or 6 channels + 5 drum channels. The latter mode requires a total of 11 output buffers. In the first mode, the last two output buffers are filled with silence (this is very efficient, see below). Each output buffer should be big enough to hold at least 'num' number of ints.
The output is not simply stored in the buffer, but added to the existing data in the buffer. So you'll have to zero the content of the buffer before passing it to this function. OTOH if you want to combine (some of) the channels, you can pass the same buffer for all those channels. This approach may have a little overhead when you're interested in all channels, but it is very efficient if you're only interested in the combined channels (the most common case). You can even directly combine this output with other chips with the same native frequency (like Y8950 or YMF262).
When the core detects that some channel is silent, it will assign nullptr to the buffer pointer (so the content of the buffer is left unchanged, but the pointer to that buffer is set to zero). When all the channels you're interested in are silent you can even skip all subsequent audio processing for this channel (e.g. skip resampling to 44kHz). It is very common that some or even all of the channels are silent, so it's definitely worth it to implement this optimization. Also the cores internally try to detect silent channels very early, so an idle YM2413 core generally requires very little emulation time.
Implements openmsx::YM2413Core.
Definition at line 1123 of file YM2413Okazaki.cc.
References openmsx::YM2413Okazaki::Patch::AMPM, openmsx::YM2413Okazaki::Slot::calc_phase(), openmsx::YM2413Okazaki::Slot::calc_slot_car(), openmsx::YM2413Okazaki::Slot::calc_slot_cym(), openmsx::YM2413Okazaki::Slot::calc_slot_hat(), openmsx::YM2413Okazaki::Slot::calc_slot_mod(), openmsx::YM2413Okazaki::Slot::calc_slot_snare(), openmsx::YM2413Okazaki::Slot::calc_slot_tom(), openmsx::YM2413Okazaki::Channel::car, openmsx::YM2413Okazaki::Slot::cPhase, openmsx::YM2413Okazaki::Patch::FB, openmsx::YM2413Okazaki::Slot::isActive(), openmsx::YM2413Okazaki::Channel::mod, openmsx::YM2413Okazaki::Slot::patch, openmsx::YM2413Okazaki::Slot::state, UNREACHABLE, and xrange().
|
overridevirtual |
Returns normalization factor.
The output of the generateChannels() method should still be amplified (=multiplied) with this factor to get a consistent volume level across the different implementations of the YM2413 core. This allows to internally calculate with native volume levels, and possibly results in slightly simpler and/or faster code. It's very likely that subsequent audio processing steps (like resampler, filters or volume adjustments) must anyway still multiply the output sample values, so this factor can be folded-in for free.
Implements openmsx::YM2413Core.
Definition at line 1048 of file YM2413Okazaki.cc.
Patch & openmsx::YM2413Okazaki::YM2413::getPatch | ( | unsigned | instrument, |
bool | carrier | ||
) |
Definition at line 1065 of file YM2413Okazaki.cc.
Referenced by openmsx::YM2413Okazaki::Channel::setPatch().
|
overridevirtual |
Read from a YM2413 register (for debug).
Note that the real YM2413 chip doesn't allow to read the registers. This returns the last written value or the default value if this register hasn't been written to since the last reset() call. Reading registers has no influence on the generated sound.
Implements openmsx::YM2413Core.
Definition at line 1585 of file YM2413Okazaki.cc.
|
overridevirtual |
Write to a YM2413 register (for debug).
Because of the timing constraint on writing registers via writePort(), writing registers via that way is not very suited for use in a debugger. Use this method as an alternative.
Implements openmsx::YM2413Core.
Definition at line 1374 of file YM2413Okazaki.cc.
|
overridevirtual |
Reset this YM2413 core.
Implements openmsx::YM2413Core.
Definition at line 704 of file YM2413Okazaki.cc.
References xrange().
Referenced by YM2413().
void openmsx::YM2413Okazaki::YM2413::serialize | ( | Archive & | ar, |
unsigned | version | ||
) |
Definition at line 1643 of file YM2413Okazaki.cc.
References enumerate().
|
overridevirtual |
Write to the YM2413 register/data port.
Writing to a register is a 2-step process: First write the register number to the register port (0), then write the value for that register to the data port (1). There are various timing constraints that must be taken into account (not described here).
We emulate the YM2413 as-if it generates a stream at 49.7kHz and at each step it produces one sample for each of the 9+5 sound channels. Though in reality the YM2413 spreads out the generation of the channels over time. So it's like a stream at 18 x 49.7kHz where the 9+5 channels have a fixed position in the 18 possible slots (so not all 18 slots produce a (non-zero) output).
In other words: we emulate the YM2413 18 steps at a time. Though for accurate emulation we still need to take the exact timing of register writes into account. That's what the 'offset' parameter is for. It must have a value [0..17] and indicates the sub-sample timing of the port-write.
Implements openmsx::YM2413Core.
Definition at line 1365 of file YM2413Okazaki.cc.