mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
ymfm: Sync with upstream
* Fix LFO disable on YM2151 * Fix swapped lower nibbles for 12-bit PCM on OPL4
This commit is contained in:
parent
6b4f53d5e0
commit
f996103315
37
3rdparty/ymfm/README.md
vendored
37
3rdparty/ymfm/README.md
vendored
@ -11,39 +11,42 @@ It has been tested on gcc, clang, and Microsoft Visual C++ 2019.
|
||||
|
||||
Currently, support is present for the following chips (organized by header file):
|
||||
|
||||
* ymfm_misc.h:
|
||||
* YM2149 (SSG) [1983: MSX; Atari ST]
|
||||
* ymfm_opm.h:
|
||||
* YM2151 (OPM)
|
||||
* YM2164 (OPP)
|
||||
* YM2151 (OPM) [1983: Sharp X1, X68000; MSX; synths: DX21, DX27, DX100]
|
||||
* YM2164 (OPP) [1985: FB-01 MIDI Expander; IBM Music Feature Card; MSX; synths: Korg DS-8, 707]
|
||||
* ymfm_opn.h:
|
||||
* YM2149 (SSG)
|
||||
* YM2203 (OPN)
|
||||
* YM2608 (OPNA)
|
||||
* YM2610 (OPNB)
|
||||
* YM2203 (OPN) [1984: NEC PC-88, PC-98, NEC PC-6001mkII SR, PC-6601 SR]
|
||||
* YM2608 (OPNA) [1985: NEC PC-88, PC-98]
|
||||
* YM2610 (OPNB) [1987: Neo Geo]
|
||||
* YM2610B (OPNB2)
|
||||
* YM2612 (OPN2)
|
||||
* YM2612 (OPN2) [1988: Sega Mega Drive/Genesis; FM Towns]
|
||||
* YM3438 (OPN2C)
|
||||
* YMF276 (OPN2L)
|
||||
* YMF288 (OPN3L)
|
||||
* YMF288 (OPN3L) [1995: NEC PC-98]
|
||||
* ymfm_opl.h:
|
||||
* YM3526 (OPL)
|
||||
* Y8950 (MSX-Audio)
|
||||
* YM3812 (OPL2)
|
||||
* YMF262 (OPL3)
|
||||
* YM3526 (OPL) [1984: C64 SFX Sound Expander]
|
||||
* Y8950 (MSX-Audio) [1984: MSX]
|
||||
* YM3812 (OPL2) [1985: AdLib, Sound Blaster; synths: some Portasound keyboards]
|
||||
* YMF262 (OPL3) [1988: Sound Blaster Pro 2.0, SB16]
|
||||
* YMF289B (OPL3L)
|
||||
* YMF278B (OPL4)
|
||||
* YM2413 (OPLL)
|
||||
* YMF278B (OPL4) [1993: MSX Moonsound cartridge]
|
||||
* YM2413 (OPLL) [1986: Sega Master System, Mark III; MSX; synths: Portasound PSS-140, PSS-170, PSS-270]
|
||||
* YM2423 (OPLL-X)
|
||||
* YMF281 (OPLLP)
|
||||
* DS1001 (Konami 053982)
|
||||
* DS1001 (Konami 053982/VRC7) [1991: Famicom cartridge Lagrange Point]
|
||||
* ymfm_opq.h:
|
||||
* YM3806 (OPQ) -- preliminary
|
||||
* YM3806 (OPQ) [synths: PSR-60/70]
|
||||
* ymfm_opz.h:
|
||||
* YM2414 (OPZ) -- preliminary
|
||||
* YM2414 (OPZ) [1987: synths: TX81Z, DX11, YS200; Korg Z3 guitar synth]
|
||||
|
||||
There are some obviously-related chips that also are on my horizon but have no implementation as yet:
|
||||
|
||||
* YMW-258-F 'GEW8' (aka Sega 315-5560 aka Sega Multi-PCM)
|
||||
* YMF271 (OPX)
|
||||
* YM21280 (OPS) / YM21290 (EGS) [synths: DX7, DX1, DX5, DX9, TX7, TX216, TX416, TX816]
|
||||
* OPK?
|
||||
|
||||
## History
|
||||
|
||||
|
14
3rdparty/ymfm/examples/vgmrender/vgmrender.cpp
vendored
14
3rdparty/ymfm/examples/vgmrender/vgmrender.cpp
vendored
@ -329,7 +329,7 @@ void add_chips(uint32_t clock, chip_type type, char const *chipname)
|
||||
{
|
||||
char name[100];
|
||||
sprintf(name, "%s #%d", chipname, index);
|
||||
active_chips.push_back(new vgm_chip<ChipType>(clockval, type, chipname));
|
||||
active_chips.push_back(new vgm_chip<ChipType>(clockval, type, (numchips == 2) ? name : chipname));
|
||||
}
|
||||
|
||||
if (type == CHIP_YM2608)
|
||||
@ -910,7 +910,6 @@ void generate_all(std::vector<uint8_t> &buffer, uint32_t data_start, uint32_t ou
|
||||
break;
|
||||
uint8_t type = buffer[offset++];
|
||||
uint32_t size = parse_uint32(buffer, offset);
|
||||
uint32_t start, length;
|
||||
uint32_t localoffset = offset;
|
||||
|
||||
switch (type)
|
||||
@ -1114,15 +1113,22 @@ int write_wav(char const *filename, uint32_t output_rate, std::vector<int32_t> &
|
||||
{
|
||||
// determine normalization parameters
|
||||
int32_t max_scale = 0;
|
||||
for (int index = 0; index < wav_buffer_src.size(); index++)
|
||||
for (size_t index = 0; index < wav_buffer_src.size(); index++)
|
||||
{
|
||||
int32_t absval = std::abs(wav_buffer_src[index]);
|
||||
max_scale = std::max(max_scale, absval);
|
||||
}
|
||||
|
||||
// warn if only silence was detected (and also avoid divide by zero)
|
||||
if (max_scale == 0)
|
||||
{
|
||||
fprintf(stderr, "The WAV file data will only contain silence.\n");
|
||||
max_scale = 1;
|
||||
}
|
||||
|
||||
// now convert
|
||||
std::vector<int16_t> wav_buffer(wav_buffer_src.size());
|
||||
for (int index = 0; index < wav_buffer_src.size(); index++)
|
||||
for (size_t index = 0; index < wav_buffer_src.size(); index++)
|
||||
wav_buffer[index] = wav_buffer_src[index] * 26000 / max_scale;
|
||||
|
||||
// write the WAV file
|
||||
|
10
3rdparty/ymfm/src/ymfm.h
vendored
10
3rdparty/ymfm/src/ymfm.h
vendored
@ -33,6 +33,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
@ -136,7 +140,7 @@ inline uint8_t count_leading_zeros(uint32_t value)
|
||||
inline uint8_t count_leading_zeros(uint32_t value)
|
||||
{
|
||||
unsigned long index;
|
||||
return _BitScanReverse(&index, value) ? (31U - index) : 32U;
|
||||
return _BitScanReverse(&index, value) ? uint8_t(31U - index) : 32U;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -355,8 +359,8 @@ public:
|
||||
void save(bool &data) { write(data ? 1 : 0); }
|
||||
void save(int8_t &data) { write(data); }
|
||||
void save(uint8_t &data) { write(data); }
|
||||
void save(int16_t &data) { write(data).write(data >> 8); }
|
||||
void save(uint16_t &data) { write(data).write(data >> 8); }
|
||||
void save(int16_t &data) { write(uint8_t(data)).write(data >> 8); }
|
||||
void save(uint16_t &data) { write(uint8_t(data)).write(data >> 8); }
|
||||
void save(int32_t &data) { write(data).write(data >> 8).write(data >> 16).write(data >> 24); }
|
||||
void save(uint32_t &data) { write(data).write(data >> 8).write(data >> 16).write(data >> 24); }
|
||||
void save(envelope_state &data) { write(uint8_t(data)); }
|
||||
|
6
3rdparty/ymfm/src/ymfm_fm.ipp
vendored
6
3rdparty/ymfm/src/ymfm_fm.ipp
vendored
@ -91,7 +91,7 @@ inline uint32_t attenuation_to_volume(uint32_t input)
|
||||
// as a nod to performance, the implicit 0x400 bit is pre-incorporated, and
|
||||
// the values are left-shifted by 2 so that a simple right shift is all that
|
||||
// is needed; also the order is reversed to save a NOT on the input
|
||||
#define X(a) ((a | 0x400) << 2)
|
||||
#define X(a) (((a) | 0x400) << 2)
|
||||
static uint16_t const s_power_table[256] =
|
||||
{
|
||||
X(0x3fa),X(0x3f5),X(0x3ef),X(0x3ea),X(0x3e4),X(0x3df),X(0x3da),X(0x3d4),
|
||||
@ -500,7 +500,7 @@ int32_t fm_operator<RegisterType>::compute_noise_volume(uint32_t am_offset) cons
|
||||
// application manual says the logarithmic transform is not applied here, so we
|
||||
// just use the raw envelope attenuation, inverted (since 0 attenuation should be
|
||||
// maximum), and shift it up from a 10-bit value to an 11-bit value
|
||||
uint32_t result = (envelope_attenuation(am_offset) ^ 0x3ff) << 1;
|
||||
int32_t result = (envelope_attenuation(am_offset) ^ 0x3ff) << 1;
|
||||
|
||||
// QUESTION: is AM applied still?
|
||||
|
||||
@ -995,7 +995,7 @@ void fm_channel<RegisterType>::output_4op(output_data &output, uint32_t rshift,
|
||||
// -x-------- include opout[2] in final sum
|
||||
// x--------- include opout[3] in final sum
|
||||
#define ALGORITHM(op2in, op3in, op4in, op1out, op2out, op3out) \
|
||||
(op2in | (op3in << 1) | (op4in << 4) | (op1out << 7) | (op2out << 8) | (op3out << 9))
|
||||
((op2in) | ((op3in) << 1) | ((op4in) << 4) | ((op1out) << 7) | ((op2out) << 8) | ((op3out) << 9))
|
||||
static uint16_t const s_algorithm_ops[8+4] =
|
||||
{
|
||||
ALGORITHM(1,2,3, 0,0,0), // 0: O1 -> O2 -> O3 -> O4 -> out (O4)
|
||||
|
12
3rdparty/ymfm/src/ymfm_opl.cpp
vendored
12
3rdparty/ymfm/src/ymfm_opl.cpp
vendored
@ -383,7 +383,7 @@ std::string opl_registers_base<Revision>::log_keyon(uint32_t choffs, uint32_t op
|
||||
char buffer[256];
|
||||
char *end = &buffer[0];
|
||||
|
||||
end += sprintf(end, "%2d.%02d freq=%04X fb=%d alg=%X mul=%X tl=%02X ksr=%d ns=%d ksl=%d adr=%X/%X/%X sl=%X sus=%d",
|
||||
end += sprintf(end, "%2u.%02u freq=%04X fb=%u alg=%X mul=%X tl=%02X ksr=%u ns=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u",
|
||||
chnum, opnum,
|
||||
ch_block_freq(choffs),
|
||||
ch_feedback(choffs),
|
||||
@ -406,11 +406,11 @@ std::string opl_registers_base<Revision>::log_keyon(uint32_t choffs, uint32_t op
|
||||
ch_output_2(choffs) ? '0' : '-',
|
||||
ch_output_3(choffs) ? '1' : '-');
|
||||
if (op_lfo_am_enable(opoffs) != 0)
|
||||
end += sprintf(end, " am=%d", lfo_am_depth());
|
||||
end += sprintf(end, " am=%u", lfo_am_depth());
|
||||
if (op_lfo_pm_enable(opoffs) != 0)
|
||||
end += sprintf(end, " pm=%d", lfo_pm_depth());
|
||||
end += sprintf(end, " pm=%u", lfo_pm_depth());
|
||||
if (waveform_enable() && op_waveform(opoffs) != 0)
|
||||
end += sprintf(end, " wf=%d", op_waveform(opoffs));
|
||||
end += sprintf(end, " wf=%u", op_waveform(opoffs));
|
||||
if (is_rhythm(choffs))
|
||||
end += sprintf(end, " rhy=1");
|
||||
if (DYNAMIC_OPS)
|
||||
@ -682,7 +682,7 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
|
||||
char buffer[256];
|
||||
char *end = &buffer[0];
|
||||
|
||||
end += sprintf(end, "%d.%02d freq=%04X inst=%X fb=%d mul=%X",
|
||||
end += sprintf(end, "%u.%02u freq=%04X inst=%X fb=%u mul=%X",
|
||||
chnum, opnum,
|
||||
ch_block_freq(choffs),
|
||||
ch_instrument(choffs),
|
||||
@ -694,7 +694,7 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
|
||||
else
|
||||
end += sprintf(end, " tl=%02X", ch_total_level(choffs));
|
||||
|
||||
end += sprintf(end, " ksr=%d ksl=%d adr=%X/%X/%X sl=%X sus=%d/%d",
|
||||
end += sprintf(end, " ksr=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u/%u",
|
||||
op_ksr(opoffs),
|
||||
op_ksl(opoffs),
|
||||
op_attack_rate(opoffs),
|
||||
|
17
3rdparty/ymfm/src/ymfm_opm.cpp
vendored
17
3rdparty/ymfm/src/ymfm_opm.cpp
vendored
@ -152,10 +152,6 @@ bool opm_registers::write(uint16_t index, uint8_t data, uint32_t &channel, uint3
|
||||
else if (index != 0x1a)
|
||||
m_regdata[index] = data;
|
||||
|
||||
// check test register writes for the LFO reset bit
|
||||
if (index == 0x01 && bitfield(data, 1))
|
||||
m_lfo_counter = 0;
|
||||
|
||||
// handle writes to the key on index
|
||||
if (index == 0x08)
|
||||
{
|
||||
@ -200,6 +196,13 @@ int32_t opm_registers::clock_noise_and_lfo()
|
||||
// manual, though it might not be implemented exactly this way on chip
|
||||
uint32_t rate = lfo_rate();
|
||||
m_lfo_counter += (0x10 | bitfield(rate, 0, 4)) << bitfield(rate, 4, 4);
|
||||
|
||||
// bit 1 of the test register is officially undocumented but has been
|
||||
// discovered to hold the LFO in reset while active
|
||||
if (lfo_reset())
|
||||
m_lfo_counter = 0;
|
||||
|
||||
// now pull out the non-fractional LFO value
|
||||
uint32_t lfo = bitfield(m_lfo_counter, 22, 8);
|
||||
|
||||
// fill in the noise entry 1 ahead of our current position; this
|
||||
@ -352,7 +355,7 @@ std::string opm_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
|
||||
char buffer[256];
|
||||
char *end = &buffer[0];
|
||||
|
||||
end += sprintf(end, "%d.%02d freq=%04X dt2=%d dt=%d fb=%d alg=%X mul=%X tl=%02X ksr=%d adsr=%02X/%02X/%02X/%X sl=%X out=%c%c",
|
||||
end += sprintf(end, "%u.%02u freq=%04X dt2=%u dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c",
|
||||
chnum, opnum,
|
||||
ch_block_freq(choffs),
|
||||
op_detune2(opoffs),
|
||||
@ -372,10 +375,10 @@ std::string opm_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
|
||||
|
||||
bool am = (lfo_am_depth() != 0 && ch_lfo_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0);
|
||||
if (am)
|
||||
end += sprintf(end, " am=%d/%02X", ch_lfo_am_sens(choffs), lfo_am_depth());
|
||||
end += sprintf(end, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth());
|
||||
bool pm = (lfo_pm_depth() != 0 && ch_lfo_pm_sens(choffs) != 0);
|
||||
if (pm)
|
||||
end += sprintf(end, " pm=%d/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth());
|
||||
end += sprintf(end, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth());
|
||||
if (am || pm)
|
||||
end += sprintf(end, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]);
|
||||
if (noise_enable() && opoffs == 31)
|
||||
|
4
3rdparty/ymfm/src/ymfm_opm.h
vendored
4
3rdparty/ymfm/src/ymfm_opm.h
vendored
@ -49,7 +49,8 @@ namespace ymfm
|
||||
// OPM register map:
|
||||
//
|
||||
// System-wide registers:
|
||||
// 01 xxxxxxxx Test register
|
||||
// 01 xxxxxx-x Test register
|
||||
// ------x- LFO reset
|
||||
// 08 -x------ Key on/off operator 4
|
||||
// --x----- Key on/off operator 3
|
||||
// ---x---- Key on/off operator 2
|
||||
@ -172,6 +173,7 @@ public:
|
||||
|
||||
// system-wide registers
|
||||
uint32_t test() const { return byte(0x01, 0, 8); }
|
||||
uint32_t lfo_reset() const { return byte(0x01, 1, 1); }
|
||||
uint32_t noise_frequency() const { return byte(0x0f, 0, 5); }
|
||||
uint32_t noise_enable() const { return byte(0x0f, 7, 1); }
|
||||
uint32_t timer_a_value() const { return word(0x10, 0, 8, 0x11, 0, 2); }
|
||||
|
6
3rdparty/ymfm/src/ymfm_opn.cpp
vendored
6
3rdparty/ymfm/src/ymfm_opn.cpp
vendored
@ -396,7 +396,7 @@ std::string opn_registers_base<IsOpnA>::log_keyon(uint32_t choffs, uint32_t opof
|
||||
char buffer[256];
|
||||
char *end = &buffer[0];
|
||||
|
||||
end += sprintf(end, "%d.%02d freq=%04X dt=%d fb=%d alg=%X mul=%X tl=%02X ksr=%d adsr=%02X/%02X/%02X/%X sl=%X",
|
||||
end += sprintf(end, "%u.%02u freq=%04X dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X",
|
||||
chnum, opnum,
|
||||
block_freq,
|
||||
op_detune(opoffs),
|
||||
@ -419,10 +419,10 @@ std::string opn_registers_base<IsOpnA>::log_keyon(uint32_t choffs, uint32_t opof
|
||||
end += sprintf(end, " ssg=%X", op_ssg_eg_mode(opoffs));
|
||||
bool am = (lfo_enable() && op_lfo_am_enable(opoffs) && ch_lfo_am_sens(choffs) != 0);
|
||||
if (am)
|
||||
end += sprintf(end, " am=%d", ch_lfo_am_sens(choffs));
|
||||
end += sprintf(end, " am=%u", ch_lfo_am_sens(choffs));
|
||||
bool pm = (lfo_enable() && ch_lfo_pm_sens(choffs) != 0);
|
||||
if (pm)
|
||||
end += sprintf(end, " pm=%d", ch_lfo_pm_sens(choffs));
|
||||
end += sprintf(end, " pm=%u", ch_lfo_pm_sens(choffs));
|
||||
if (am || pm)
|
||||
end += sprintf(end, " lfo=%02X", lfo_rate());
|
||||
if (multi_freq() && choffs == 2)
|
||||
|
6
3rdparty/ymfm/src/ymfm_opq.cpp
vendored
6
3rdparty/ymfm/src/ymfm_opq.cpp
vendored
@ -341,7 +341,7 @@ std::string opq_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
|
||||
char buffer[256];
|
||||
char *end = &buffer[0];
|
||||
|
||||
end += sprintf(end, "%d.%02d freq=%04X dt=%+2d fb=%d alg=%X mul=%X tl=%02X ksr=%d adsr=%02X/%02X/%02X/%X sl=%X out=%c%c",
|
||||
end += sprintf(end, "%u.%02u freq=%04X dt=%+2d fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c",
|
||||
chnum, opnum,
|
||||
(opoffs & 1) ? ch_block_freq_24(choffs) : ch_block_freq_13(choffs),
|
||||
int32_t(op_detune(opoffs)) - 0x20,
|
||||
@ -360,10 +360,10 @@ std::string opq_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
|
||||
|
||||
bool am = (lfo_enable() && op_lfo_am_enable(opoffs) && ch_lfo_am_sens(choffs) != 0);
|
||||
if (am)
|
||||
end += sprintf(end, " am=%d", ch_lfo_am_sens(choffs));
|
||||
end += sprintf(end, " am=%u", ch_lfo_am_sens(choffs));
|
||||
bool pm = (lfo_enable() && ch_lfo_pm_sens(choffs) != 0);
|
||||
if (pm)
|
||||
end += sprintf(end, " pm=%d", ch_lfo_pm_sens(choffs));
|
||||
end += sprintf(end, " pm=%u", ch_lfo_pm_sens(choffs));
|
||||
if (am || pm)
|
||||
end += sprintf(end, " lfo=%02X", lfo_rate());
|
||||
if (ch_reverb(choffs))
|
||||
|
20
3rdparty/ymfm/src/ymfm_opz.cpp
vendored
20
3rdparty/ymfm/src/ymfm_opz.cpp
vendored
@ -557,14 +557,14 @@ std::string opz_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
|
||||
char buffer[256];
|
||||
char *end = &buffer[0];
|
||||
|
||||
end += sprintf(end, "%d.%02d", chnum, opnum);
|
||||
end += sprintf(end, "%u.%02u", chnum, opnum);
|
||||
|
||||
if (op_fix_mode(opoffs))
|
||||
end += sprintf(end, " fixfreq=%X fine=%X shift=%X", op_fix_frequency(opoffs), op_fine(opoffs), op_fix_range(opoffs));
|
||||
else
|
||||
end += sprintf(end, " freq=%04X dt2=%d fine=%X", ch_block_freq(choffs), op_detune2(opoffs), op_fine(opoffs));
|
||||
end += sprintf(end, " freq=%04X dt2=%u fine=%X", ch_block_freq(choffs), op_detune2(opoffs), op_fine(opoffs));
|
||||
|
||||
end += sprintf(end, " dt=%d fb=%d alg=%X mul=%X tl=%02X ksr=%d adsr=%02X/%02X/%02X/%X sl=%X out=%c%c",
|
||||
end += sprintf(end, " dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c",
|
||||
op_detune(opoffs),
|
||||
ch_feedback(choffs),
|
||||
ch_algorithm(choffs),
|
||||
@ -580,30 +580,30 @@ std::string opz_registers::log_keyon(uint32_t choffs, uint32_t opoffs)
|
||||
ch_output_1(choffs) ? 'R' : '-');
|
||||
|
||||
if (op_eg_shift(opoffs) != 0)
|
||||
end += sprintf(end, " egshift=%d", op_eg_shift(opoffs));
|
||||
end += sprintf(end, " egshift=%u", op_eg_shift(opoffs));
|
||||
|
||||
bool am = (lfo_am_depth() != 0 && ch_lfo_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0);
|
||||
if (am)
|
||||
end += sprintf(end, " am=%d/%02X", ch_lfo_am_sens(choffs), lfo_am_depth());
|
||||
end += sprintf(end, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth());
|
||||
bool pm = (lfo_pm_depth() != 0 && ch_lfo_pm_sens(choffs) != 0);
|
||||
if (pm)
|
||||
end += sprintf(end, " pm=%d/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth());
|
||||
end += sprintf(end, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth());
|
||||
if (am || pm)
|
||||
end += sprintf(end, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]);
|
||||
|
||||
bool am2 = (lfo2_am_depth() != 0 && ch_lfo2_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0);
|
||||
if (am2)
|
||||
end += sprintf(end, " am2=%d/%02X", ch_lfo2_am_sens(choffs), lfo2_am_depth());
|
||||
end += sprintf(end, " am2=%u/%02X", ch_lfo2_am_sens(choffs), lfo2_am_depth());
|
||||
bool pm2 = (lfo2_pm_depth() != 0 && ch_lfo2_pm_sens(choffs) != 0);
|
||||
if (pm2)
|
||||
end += sprintf(end, " pm2=%d/%02X", ch_lfo2_pm_sens(choffs), lfo2_pm_depth());
|
||||
end += sprintf(end, " pm2=%u/%02X", ch_lfo2_pm_sens(choffs), lfo2_pm_depth());
|
||||
if (am2 || pm2)
|
||||
end += sprintf(end, " lfo2=%02X/%c", lfo2_rate(), "WQTN"[lfo2_waveform()]);
|
||||
|
||||
if (op_reverb_rate(opoffs) != 0)
|
||||
end += sprintf(end, " rev=%d", op_reverb_rate(opoffs));
|
||||
end += sprintf(end, " rev=%u", op_reverb_rate(opoffs));
|
||||
if (op_waveform(opoffs) != 0)
|
||||
end += sprintf(end, " wf=%d", op_waveform(opoffs));
|
||||
end += sprintf(end, " wf=%u", op_waveform(opoffs));
|
||||
if (noise_enable() && opoffs == 31)
|
||||
end += sprintf(end, " noise=1");
|
||||
|
||||
|
6
3rdparty/ymfm/src/ymfm_pcm.cpp
vendored
6
3rdparty/ymfm/src/ymfm_pcm.cpp
vendored
@ -425,7 +425,7 @@ void pcm_channel::load_wavetable()
|
||||
// for some reason that is unclear
|
||||
m_endpos = read_pcm(wavheader + 5) << 8;
|
||||
m_endpos |= read_pcm(wavheader + 6);
|
||||
m_endpos = -m_endpos << 16;
|
||||
m_endpos = -int32_t(m_endpos) << 16;
|
||||
|
||||
// remaining data values set registers
|
||||
m_owner.write(0x80 + m_choffs, read_pcm(wavheader + 7));
|
||||
@ -560,9 +560,9 @@ int16_t pcm_channel::fetch_sample() const
|
||||
// 12-bit PCM: assemble out of half of 3 bytes
|
||||
addr += (pos / 2) * 3;
|
||||
if ((pos & 1) == 0)
|
||||
return (read_pcm(addr + 0) << 8) | ((read_pcm(addr + 1) << 0) & 0xf0);
|
||||
return (read_pcm(addr + 0) << 8) | ((read_pcm(addr + 1) << 4) & 0xf0);
|
||||
else
|
||||
return (read_pcm(addr + 2) << 8) | ((read_pcm(addr + 1) << 4) & 0xf0);
|
||||
return (read_pcm(addr + 2) << 8) | ((read_pcm(addr + 1) << 0) & 0xf0);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user