From 4cefc6908e2c3d9c51c7bc7a7a36d996b2228b09 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Nov 2022 16:11:46 +0600 Subject: [PATCH 1/8] Add OPL4-ML daughterboard emulation --- src/include/86box/midi.h | 1 + src/include/86box/opl4_defines.h | 101 +++ src/include/86box/snd_opl.h | 1 + src/sound/CMakeLists.txt | 2 +- src/sound/midi.c | 1 + src/sound/midi_opl4.c | 703 ++++++++++++++++++++ src/sound/midi_opl4_yrw801.c | 1042 ++++++++++++++++++++++++++++++ src/sound/snd_opl_nuked.c | 1 + src/sound/snd_opl_ymfm.cpp | 8 + src/sound/yrw801.h | 45 ++ 10 files changed, 1904 insertions(+), 1 deletion(-) create mode 100644 src/include/86box/opl4_defines.h create mode 100644 src/sound/midi_opl4.c create mode 100644 src/sound/midi_opl4_yrw801.c create mode 100644 src/sound/yrw801.h diff --git a/src/include/86box/midi.h b/src/include/86box/midi.h index e2b8c2626..9f3a81581 100644 --- a/src/include/86box/midi.h +++ b/src/include/86box/midi.h @@ -92,6 +92,7 @@ extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #ifdef EMU_DEVICE_H extern const device_t rtmidi_output_device; extern const device_t rtmidi_input_device; +extern const device_t opl4_midi_device; # ifdef USE_FLUIDSYNTH extern const device_t fluidsynth_device; # endif diff --git a/src/include/86box/opl4_defines.h b/src/include/86box/opl4_defines.h new file mode 100644 index 000000000..248b1f729 --- /dev/null +++ b/src/include/86box/opl4_defines.h @@ -0,0 +1,101 @@ +/* + * RoboPlay for MSX + * Copyright (C) 2020 by RoboSoft Inc. + * + * opl4_defines.h + * + */ + +#ifndef __OPL4_DEFINES_H +#define __OPL4_DEFINES_H + +/* + * Register numbers + */ + +#define OPL4_REG_TEST0 0x00 +#define OPL4_REG_TEST1 0x01 + +#define OPL4_REG_MEMORY_CONFIGURATION 0x02 +#define OPL4_MODE_BIT 0x01 +#define OPL4_MTYPE_BIT 0x02 +#define OPL4_TONE_HEADER_MASK 0x1C +#define OPL4_DEVICE_ID_MASK 0xE0 + +#define OPL4_REG_MEMORY_ADDRESS_HIGH 0x03 +#define OPL4_REG_MEMORY_ADDRESS_MID 0x04 +#define OPL4_REG_MEMORY_ADDRESS_LOW 0x05 +#define OPL4_REG_MEMORY_DATA 0x06 + +/* + * Offsets to the register banks for voices. To get the + * register number just add the voice number to the bank offset. + * + * Wave Table Number low bits (0x08 to 0x1F) + */ +#define OPL4_REG_TONE_NUMBER 0x08 + +/* Wave Table Number high bit, F-Number low bits (0x20 to 0x37) */ +#define OPL4_REG_F_NUMBER 0x20 +#define OPL4_TONE_NUMBER_BIT8 0x01 +#define OPL4_F_NUMBER_LOW_MASK 0xFE + +/* F-Number high bits, Octave, Pseudo-Reverb (0x38 to 0x4F) */ +#define OPL4_REG_OCTAVE 0x38 +#define OPL4_F_NUMBER_HIGH_MASK 0x07 +#define OPL4_BLOCK_MASK 0xF0 +#define OPL4_PSEUDO_REVERB_BIT 0x08 + +/* Total Level, Level Direct (0x50 to 0x67) */ +#define OPL4_REG_LEVEL 0x50 +#define OPL4_TOTAL_LEVEL_MASK 0xFE +#define OPL4_LEVEL_DIRECT_BIT 0x01 + +/* Key On, Damp, LFO RST, CH, Panpot (0x68 to 0x7F) */ +#define OPL4_REG_MISC 0x68 +#define OPL4_KEY_ON_BIT 0x80 +#define OPL4_DAMP_BIT 0x40 +#define OPL4_LFO_RESET_BIT 0x20 +#define OPL4_OUTPUT_CHANNEL_BIT 0x10 +#define OPL4_PAN_POT_MASK 0x0F + +/* LFO, VIB (0x80 to 0x97) */ +#define OPL4_REG_LFO_VIBRATO 0x80 +#define OPL4_LFO_FREQUENCY_MASK 0x38 +#define OPL4_VIBRATO_DEPTH_MASK 0x07 +#define OPL4_CHORUS_SEND_MASK 0xC0 + +/* Attack / Decay 1 rate (0x98 to 0xAF) */ +#define OPL4_REG_ATTACK_DECAY1 0x98 +#define OPL4_ATTACK_RATE_MASK 0xF0 +#define OPL4_DECAY1_RATE_MASK 0x0F + +/* Decay level / 2 rate (0xB0 to 0xC7) */ +#define OPL4_REG_LEVEL_DECAY2 0xB0 +#define OPL4_DECAY_LEVEL_MASK 0xF0 +#define OPL4_DECAY2_RATE_MASK 0x0F + +/* Release rate / Rate correction (0xC8 to 0xDF) */ +#define OPL4_REG_RELEASE_CORRECTION 0xC8 +#define OPL4_RELEASE_RATE_MASK 0x0F +#define OPL4_RATE_INTERPOLATION_MASK 0xF0 + +/* AM (0xE0 to 0xF7) */ +#define OPL4_REG_TREMOLO 0xE0 +#define OPL4_TREMOLO_DEPTH_MASK 0x07 +#define OPL4_REVERB_SEND_MASK 0xE0 + +/* Mixer */ +#define OPL4_REG_MIX_CONTROL_FM 0xF8 +#define OPL4_REG_MIX_CONTROL_PCM 0xF9 +#define OPL4_MIX_LEFT_MASK 0x07 +#define OPL4_MIX_RIGHT_MASK 0x38 + +#define OPL4_REG_ATC 0xFA +#define OPL4_ATC_BIT 0x01 + +/* Bits in the OPL4 Status register */ +#define OPL4_STATUS_BUSY 0x01 +#define OPL4_STATUS_LOAD 0x02 + +#endif /* __OPL4_DEFINES_H */ diff --git a/src/include/86box/snd_opl.h b/src/include/86box/snd_opl.h index 5caccf8fc..3b84a837b 100644 --- a/src/include/86box/snd_opl.h +++ b/src/include/86box/snd_opl.h @@ -38,6 +38,7 @@ typedef struct { void (*reset_buffer)(void *priv); void (*set_do_cycles)(void *priv, int8_t do_cycles); void *priv; + void (*generate)(void *priv, int32_t *data, uint32_t num_samples); /* daughterboard only. */ } fm_drv_t; extern uint8_t fm_driver_get(int chip_id, fm_drv_t *drv); diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 66672d547..7024bc5fc 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c) + snd_optimc.c midi_opl4.c midi_opl4_yrw801.c) if(OPENAL) if(VCPKG_TOOLCHAIN) diff --git a/src/sound/midi.c b/src/sound/midi.c index 93fa62891..c58342648 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -100,6 +100,7 @@ static const MIDI_OUT_DEVICE devices[] = { #ifdef USE_RTMIDI { &rtmidi_output_device }, #endif + { &opl4_midi_device }, { NULL } // clang-format on }; diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c new file mode 100644 index 000000000..f816cff49 --- /dev/null +++ b/src/sound/midi_opl4.c @@ -0,0 +1,703 @@ +// Based off ROBOPLAY's OPL4 MID player code, with some fixes and modifications to make it work well. + +#include +#include +#include +#include +#include +#include +#include + +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/midi.h> +#include <86box/plat.h> +#include <86box/thread.h> +#include <86box/rom.h> +#include <86box/sound.h> +#include <86box/ui.h> +#include <86box/snd_opl.h> +#include <86box/opl4_defines.h> + +#include "yrw801.h" + +#define NR_OF_MIDI_CHANNELS 16 +#define NR_OF_WAVE_CHANNELS 24 + +#define DRUM_CHANNEL 9 + +typedef struct +{ + uint8_t instrument; + uint8_t panpot; + uint8_t vibrato; + bool drum_channel; +} MIDI_CHANNEL_DATA; + +typedef struct +{ + bool is_active; + uint64_t activated; + + uint8_t number; + MIDI_CHANNEL_DATA *midi_channel; + uint8_t note; + uint8_t velocity; + const YRW801_WAVE_DATA *wave_data; + uint8_t level_direct; + uint8_t reg_f_number; + uint8_t reg_misc; + uint8_t reg_lfo_vibrato; +} VOICE_DATA; + +static const int16_t g_wave_pitch_map[0x600] = { + 0x000, 0x000, 0x001, 0x001, 0x002, 0x002, 0x003, 0x003, + 0x004, 0x004, 0x005, 0x005, 0x006, 0x006, 0x006, 0x007, + 0x007, 0x008, 0x008, 0x009, 0x009, 0x00a, 0x00a, 0x00b, + 0x00b, 0x00c, 0x00c, 0x00d, 0x00d, 0x00d, 0x00e, 0x00e, + 0x00f, 0x00f, 0x010, 0x010, 0x011, 0x011, 0x012, 0x012, + 0x013, 0x013, 0x014, 0x014, 0x015, 0x015, 0x015, 0x016, + 0x016, 0x017, 0x017, 0x018, 0x018, 0x019, 0x019, 0x01a, + 0x01a, 0x01b, 0x01b, 0x01c, 0x01c, 0x01d, 0x01d, 0x01e, + 0x01e, 0x01e, 0x01f, 0x01f, 0x020, 0x020, 0x021, 0x021, + 0x022, 0x022, 0x023, 0x023, 0x024, 0x024, 0x025, 0x025, + 0x026, 0x026, 0x027, 0x027, 0x028, 0x028, 0x029, 0x029, + 0x029, 0x02a, 0x02a, 0x02b, 0x02b, 0x02c, 0x02c, 0x02d, + 0x02d, 0x02e, 0x02e, 0x02f, 0x02f, 0x030, 0x030, 0x031, + 0x031, 0x032, 0x032, 0x033, 0x033, 0x034, 0x034, 0x035, + 0x035, 0x036, 0x036, 0x037, 0x037, 0x038, 0x038, 0x038, + 0x039, 0x039, 0x03a, 0x03a, 0x03b, 0x03b, 0x03c, 0x03c, + 0x03d, 0x03d, 0x03e, 0x03e, 0x03f, 0x03f, 0x040, 0x040, + 0x041, 0x041, 0x042, 0x042, 0x043, 0x043, 0x044, 0x044, + 0x045, 0x045, 0x046, 0x046, 0x047, 0x047, 0x048, 0x048, + 0x049, 0x049, 0x04a, 0x04a, 0x04b, 0x04b, 0x04c, 0x04c, + 0x04d, 0x04d, 0x04e, 0x04e, 0x04f, 0x04f, 0x050, 0x050, + 0x051, 0x051, 0x052, 0x052, 0x053, 0x053, 0x054, 0x054, + 0x055, 0x055, 0x056, 0x056, 0x057, 0x057, 0x058, 0x058, + 0x059, 0x059, 0x05a, 0x05a, 0x05b, 0x05b, 0x05c, 0x05c, + 0x05d, 0x05d, 0x05e, 0x05e, 0x05f, 0x05f, 0x060, 0x060, + 0x061, 0x061, 0x062, 0x062, 0x063, 0x063, 0x064, 0x064, + 0x065, 0x065, 0x066, 0x066, 0x067, 0x067, 0x068, 0x068, + 0x069, 0x069, 0x06a, 0x06a, 0x06b, 0x06b, 0x06c, 0x06c, + 0x06d, 0x06d, 0x06e, 0x06e, 0x06f, 0x06f, 0x070, 0x071, + 0x071, 0x072, 0x072, 0x073, 0x073, 0x074, 0x074, 0x075, + 0x075, 0x076, 0x076, 0x077, 0x077, 0x078, 0x078, 0x079, + 0x079, 0x07a, 0x07a, 0x07b, 0x07b, 0x07c, 0x07c, 0x07d, + 0x07d, 0x07e, 0x07e, 0x07f, 0x07f, 0x080, 0x081, 0x081, + 0x082, 0x082, 0x083, 0x083, 0x084, 0x084, 0x085, 0x085, + 0x086, 0x086, 0x087, 0x087, 0x088, 0x088, 0x089, 0x089, + 0x08a, 0x08a, 0x08b, 0x08b, 0x08c, 0x08d, 0x08d, 0x08e, + 0x08e, 0x08f, 0x08f, 0x090, 0x090, 0x091, 0x091, 0x092, + 0x092, 0x093, 0x093, 0x094, 0x094, 0x095, 0x096, 0x096, + 0x097, 0x097, 0x098, 0x098, 0x099, 0x099, 0x09a, 0x09a, + 0x09b, 0x09b, 0x09c, 0x09c, 0x09d, 0x09d, 0x09e, 0x09f, + 0x09f, 0x0a0, 0x0a0, 0x0a1, 0x0a1, 0x0a2, 0x0a2, 0x0a3, + 0x0a3, 0x0a4, 0x0a4, 0x0a5, 0x0a6, 0x0a6, 0x0a7, 0x0a7, + 0x0a8, 0x0a8, 0x0a9, 0x0a9, 0x0aa, 0x0aa, 0x0ab, 0x0ab, + 0x0ac, 0x0ad, 0x0ad, 0x0ae, 0x0ae, 0x0af, 0x0af, 0x0b0, + 0x0b0, 0x0b1, 0x0b1, 0x0b2, 0x0b2, 0x0b3, 0x0b4, 0x0b4, + 0x0b5, 0x0b5, 0x0b6, 0x0b6, 0x0b7, 0x0b7, 0x0b8, 0x0b8, + 0x0b9, 0x0ba, 0x0ba, 0x0bb, 0x0bb, 0x0bc, 0x0bc, 0x0bd, + 0x0bd, 0x0be, 0x0be, 0x0bf, 0x0c0, 0x0c0, 0x0c1, 0x0c1, + 0x0c2, 0x0c2, 0x0c3, 0x0c3, 0x0c4, 0x0c4, 0x0c5, 0x0c6, + 0x0c6, 0x0c7, 0x0c7, 0x0c8, 0x0c8, 0x0c9, 0x0c9, 0x0ca, + 0x0cb, 0x0cb, 0x0cc, 0x0cc, 0x0cd, 0x0cd, 0x0ce, 0x0ce, + 0x0cf, 0x0d0, 0x0d0, 0x0d1, 0x0d1, 0x0d2, 0x0d2, 0x0d3, + 0x0d3, 0x0d4, 0x0d5, 0x0d5, 0x0d6, 0x0d6, 0x0d7, 0x0d7, + 0x0d8, 0x0d8, 0x0d9, 0x0da, 0x0da, 0x0db, 0x0db, 0x0dc, + 0x0dc, 0x0dd, 0x0de, 0x0de, 0x0df, 0x0df, 0x0e0, 0x0e0, + 0x0e1, 0x0e1, 0x0e2, 0x0e3, 0x0e3, 0x0e4, 0x0e4, 0x0e5, + 0x0e5, 0x0e6, 0x0e7, 0x0e7, 0x0e8, 0x0e8, 0x0e9, 0x0e9, + 0x0ea, 0x0eb, 0x0eb, 0x0ec, 0x0ec, 0x0ed, 0x0ed, 0x0ee, + 0x0ef, 0x0ef, 0x0f0, 0x0f0, 0x0f1, 0x0f1, 0x0f2, 0x0f3, + 0x0f3, 0x0f4, 0x0f4, 0x0f5, 0x0f5, 0x0f6, 0x0f7, 0x0f7, + 0x0f8, 0x0f8, 0x0f9, 0x0f9, 0x0fa, 0x0fb, 0x0fb, 0x0fc, + 0x0fc, 0x0fd, 0x0fd, 0x0fe, 0x0ff, 0x0ff, 0x100, 0x100, + 0x101, 0x101, 0x102, 0x103, 0x103, 0x104, 0x104, 0x105, + 0x106, 0x106, 0x107, 0x107, 0x108, 0x108, 0x109, 0x10a, + 0x10a, 0x10b, 0x10b, 0x10c, 0x10c, 0x10d, 0x10e, 0x10e, + 0x10f, 0x10f, 0x110, 0x111, 0x111, 0x112, 0x112, 0x113, + 0x114, 0x114, 0x115, 0x115, 0x116, 0x116, 0x117, 0x118, + 0x118, 0x119, 0x119, 0x11a, 0x11b, 0x11b, 0x11c, 0x11c, + 0x11d, 0x11e, 0x11e, 0x11f, 0x11f, 0x120, 0x120, 0x121, + 0x122, 0x122, 0x123, 0x123, 0x124, 0x125, 0x125, 0x126, + 0x126, 0x127, 0x128, 0x128, 0x129, 0x129, 0x12a, 0x12b, + 0x12b, 0x12c, 0x12c, 0x12d, 0x12e, 0x12e, 0x12f, 0x12f, + 0x130, 0x131, 0x131, 0x132, 0x132, 0x133, 0x134, 0x134, + 0x135, 0x135, 0x136, 0x137, 0x137, 0x138, 0x138, 0x139, + 0x13a, 0x13a, 0x13b, 0x13b, 0x13c, 0x13d, 0x13d, 0x13e, + 0x13e, 0x13f, 0x140, 0x140, 0x141, 0x141, 0x142, 0x143, + 0x143, 0x144, 0x144, 0x145, 0x146, 0x146, 0x147, 0x148, + 0x148, 0x149, 0x149, 0x14a, 0x14b, 0x14b, 0x14c, 0x14c, + 0x14d, 0x14e, 0x14e, 0x14f, 0x14f, 0x150, 0x151, 0x151, + 0x152, 0x153, 0x153, 0x154, 0x154, 0x155, 0x156, 0x156, + 0x157, 0x157, 0x158, 0x159, 0x159, 0x15a, 0x15b, 0x15b, + 0x15c, 0x15c, 0x15d, 0x15e, 0x15e, 0x15f, 0x160, 0x160, + 0x161, 0x161, 0x162, 0x163, 0x163, 0x164, 0x165, 0x165, + 0x166, 0x166, 0x167, 0x168, 0x168, 0x169, 0x16a, 0x16a, + 0x16b, 0x16b, 0x16c, 0x16d, 0x16d, 0x16e, 0x16f, 0x16f, + 0x170, 0x170, 0x171, 0x172, 0x172, 0x173, 0x174, 0x174, + 0x175, 0x175, 0x176, 0x177, 0x177, 0x178, 0x179, 0x179, + 0x17a, 0x17a, 0x17b, 0x17c, 0x17c, 0x17d, 0x17e, 0x17e, + 0x17f, 0x180, 0x180, 0x181, 0x181, 0x182, 0x183, 0x183, + 0x184, 0x185, 0x185, 0x186, 0x187, 0x187, 0x188, 0x188, + 0x189, 0x18a, 0x18a, 0x18b, 0x18c, 0x18c, 0x18d, 0x18e, + 0x18e, 0x18f, 0x190, 0x190, 0x191, 0x191, 0x192, 0x193, + 0x193, 0x194, 0x195, 0x195, 0x196, 0x197, 0x197, 0x198, + 0x199, 0x199, 0x19a, 0x19a, 0x19b, 0x19c, 0x19c, 0x19d, + 0x19e, 0x19e, 0x19f, 0x1a0, 0x1a0, 0x1a1, 0x1a2, 0x1a2, + 0x1a3, 0x1a4, 0x1a4, 0x1a5, 0x1a6, 0x1a6, 0x1a7, 0x1a8, + 0x1a8, 0x1a9, 0x1a9, 0x1aa, 0x1ab, 0x1ab, 0x1ac, 0x1ad, + 0x1ad, 0x1ae, 0x1af, 0x1af, 0x1b0, 0x1b1, 0x1b1, 0x1b2, + 0x1b3, 0x1b3, 0x1b4, 0x1b5, 0x1b5, 0x1b6, 0x1b7, 0x1b7, + 0x1b8, 0x1b9, 0x1b9, 0x1ba, 0x1bb, 0x1bb, 0x1bc, 0x1bd, + 0x1bd, 0x1be, 0x1bf, 0x1bf, 0x1c0, 0x1c1, 0x1c1, 0x1c2, + 0x1c3, 0x1c3, 0x1c4, 0x1c5, 0x1c5, 0x1c6, 0x1c7, 0x1c7, + 0x1c8, 0x1c9, 0x1c9, 0x1ca, 0x1cb, 0x1cb, 0x1cc, 0x1cd, + 0x1cd, 0x1ce, 0x1cf, 0x1cf, 0x1d0, 0x1d1, 0x1d1, 0x1d2, + 0x1d3, 0x1d3, 0x1d4, 0x1d5, 0x1d5, 0x1d6, 0x1d7, 0x1d7, + 0x1d8, 0x1d9, 0x1d9, 0x1da, 0x1db, 0x1db, 0x1dc, 0x1dd, + 0x1dd, 0x1de, 0x1df, 0x1df, 0x1e0, 0x1e1, 0x1e1, 0x1e2, + 0x1e3, 0x1e4, 0x1e4, 0x1e5, 0x1e6, 0x1e6, 0x1e7, 0x1e8, + 0x1e8, 0x1e9, 0x1ea, 0x1ea, 0x1eb, 0x1ec, 0x1ec, 0x1ed, + 0x1ee, 0x1ee, 0x1ef, 0x1f0, 0x1f0, 0x1f1, 0x1f2, 0x1f3, + 0x1f3, 0x1f4, 0x1f5, 0x1f5, 0x1f6, 0x1f7, 0x1f7, 0x1f8, + 0x1f9, 0x1f9, 0x1fa, 0x1fb, 0x1fb, 0x1fc, 0x1fd, 0x1fe, + 0x1fe, 0x1ff, 0x200, 0x200, 0x201, 0x202, 0x202, 0x203, + 0x204, 0x205, 0x205, 0x206, 0x207, 0x207, 0x208, 0x209, + 0x209, 0x20a, 0x20b, 0x20b, 0x20c, 0x20d, 0x20e, 0x20e, + 0x20f, 0x210, 0x210, 0x211, 0x212, 0x212, 0x213, 0x214, + 0x215, 0x215, 0x216, 0x217, 0x217, 0x218, 0x219, 0x21a, + 0x21a, 0x21b, 0x21c, 0x21c, 0x21d, 0x21e, 0x21e, 0x21f, + 0x220, 0x221, 0x221, 0x222, 0x223, 0x223, 0x224, 0x225, + 0x226, 0x226, 0x227, 0x228, 0x228, 0x229, 0x22a, 0x22b, + 0x22b, 0x22c, 0x22d, 0x22d, 0x22e, 0x22f, 0x230, 0x230, + 0x231, 0x232, 0x232, 0x233, 0x234, 0x235, 0x235, 0x236, + 0x237, 0x237, 0x238, 0x239, 0x23a, 0x23a, 0x23b, 0x23c, + 0x23c, 0x23d, 0x23e, 0x23f, 0x23f, 0x240, 0x241, 0x241, + 0x242, 0x243, 0x244, 0x244, 0x245, 0x246, 0x247, 0x247, + 0x248, 0x249, 0x249, 0x24a, 0x24b, 0x24c, 0x24c, 0x24d, + 0x24e, 0x24f, 0x24f, 0x250, 0x251, 0x251, 0x252, 0x253, + 0x254, 0x254, 0x255, 0x256, 0x257, 0x257, 0x258, 0x259, + 0x259, 0x25a, 0x25b, 0x25c, 0x25c, 0x25d, 0x25e, 0x25f, + 0x25f, 0x260, 0x261, 0x262, 0x262, 0x263, 0x264, 0x265, + 0x265, 0x266, 0x267, 0x267, 0x268, 0x269, 0x26a, 0x26a, + 0x26b, 0x26c, 0x26d, 0x26d, 0x26e, 0x26f, 0x270, 0x270, + 0x271, 0x272, 0x273, 0x273, 0x274, 0x275, 0x276, 0x276, + 0x277, 0x278, 0x279, 0x279, 0x27a, 0x27b, 0x27c, 0x27c, + 0x27d, 0x27e, 0x27f, 0x27f, 0x280, 0x281, 0x282, 0x282, + 0x283, 0x284, 0x285, 0x285, 0x286, 0x287, 0x288, 0x288, + 0x289, 0x28a, 0x28b, 0x28b, 0x28c, 0x28d, 0x28e, 0x28e, + 0x28f, 0x290, 0x291, 0x291, 0x292, 0x293, 0x294, 0x294, + 0x295, 0x296, 0x297, 0x298, 0x298, 0x299, 0x29a, 0x29b, + 0x29b, 0x29c, 0x29d, 0x29e, 0x29e, 0x29f, 0x2a0, 0x2a1, + 0x2a1, 0x2a2, 0x2a3, 0x2a4, 0x2a5, 0x2a5, 0x2a6, 0x2a7, + 0x2a8, 0x2a8, 0x2a9, 0x2aa, 0x2ab, 0x2ab, 0x2ac, 0x2ad, + 0x2ae, 0x2af, 0x2af, 0x2b0, 0x2b1, 0x2b2, 0x2b2, 0x2b3, + 0x2b4, 0x2b5, 0x2b5, 0x2b6, 0x2b7, 0x2b8, 0x2b9, 0x2b9, + 0x2ba, 0x2bb, 0x2bc, 0x2bc, 0x2bd, 0x2be, 0x2bf, 0x2c0, + 0x2c0, 0x2c1, 0x2c2, 0x2c3, 0x2c4, 0x2c4, 0x2c5, 0x2c6, + 0x2c7, 0x2c7, 0x2c8, 0x2c9, 0x2ca, 0x2cb, 0x2cb, 0x2cc, + 0x2cd, 0x2ce, 0x2ce, 0x2cf, 0x2d0, 0x2d1, 0x2d2, 0x2d2, + 0x2d3, 0x2d4, 0x2d5, 0x2d6, 0x2d6, 0x2d7, 0x2d8, 0x2d9, + 0x2da, 0x2da, 0x2db, 0x2dc, 0x2dd, 0x2dd, 0x2de, 0x2df, + 0x2e0, 0x2e1, 0x2e1, 0x2e2, 0x2e3, 0x2e4, 0x2e5, 0x2e5, + 0x2e6, 0x2e7, 0x2e8, 0x2e9, 0x2e9, 0x2ea, 0x2eb, 0x2ec, + 0x2ed, 0x2ed, 0x2ee, 0x2ef, 0x2f0, 0x2f1, 0x2f1, 0x2f2, + 0x2f3, 0x2f4, 0x2f5, 0x2f5, 0x2f6, 0x2f7, 0x2f8, 0x2f9, + 0x2f9, 0x2fa, 0x2fb, 0x2fc, 0x2fd, 0x2fd, 0x2fe, 0x2ff, + 0x300, 0x301, 0x302, 0x302, 0x303, 0x304, 0x305, 0x306, + 0x306, 0x307, 0x308, 0x309, 0x30a, 0x30a, 0x30b, 0x30c, + 0x30d, 0x30e, 0x30f, 0x30f, 0x310, 0x311, 0x312, 0x313, + 0x313, 0x314, 0x315, 0x316, 0x317, 0x318, 0x318, 0x319, + 0x31a, 0x31b, 0x31c, 0x31c, 0x31d, 0x31e, 0x31f, 0x320, + 0x321, 0x321, 0x322, 0x323, 0x324, 0x325, 0x326, 0x326, + 0x327, 0x328, 0x329, 0x32a, 0x32a, 0x32b, 0x32c, 0x32d, + 0x32e, 0x32f, 0x32f, 0x330, 0x331, 0x332, 0x333, 0x334, + 0x334, 0x335, 0x336, 0x337, 0x338, 0x339, 0x339, 0x33a, + 0x33b, 0x33c, 0x33d, 0x33e, 0x33e, 0x33f, 0x340, 0x341, + 0x342, 0x343, 0x343, 0x344, 0x345, 0x346, 0x347, 0x348, + 0x349, 0x349, 0x34a, 0x34b, 0x34c, 0x34d, 0x34e, 0x34e, + 0x34f, 0x350, 0x351, 0x352, 0x353, 0x353, 0x354, 0x355, + 0x356, 0x357, 0x358, 0x359, 0x359, 0x35a, 0x35b, 0x35c, + 0x35d, 0x35e, 0x35f, 0x35f, 0x360, 0x361, 0x362, 0x363, + 0x364, 0x364, 0x365, 0x366, 0x367, 0x368, 0x369, 0x36a, + 0x36a, 0x36b, 0x36c, 0x36d, 0x36e, 0x36f, 0x370, 0x370, + 0x371, 0x372, 0x373, 0x374, 0x375, 0x376, 0x377, 0x377, + 0x378, 0x379, 0x37a, 0x37b, 0x37c, 0x37d, 0x37d, 0x37e, + 0x37f, 0x380, 0x381, 0x382, 0x383, 0x383, 0x384, 0x385, + 0x386, 0x387, 0x388, 0x389, 0x38a, 0x38a, 0x38b, 0x38c, + 0x38d, 0x38e, 0x38f, 0x390, 0x391, 0x391, 0x392, 0x393, + 0x394, 0x395, 0x396, 0x397, 0x398, 0x398, 0x399, 0x39a, + 0x39b, 0x39c, 0x39d, 0x39e, 0x39f, 0x39f, 0x3a0, 0x3a1, + 0x3a2, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7, 0x3a7, 0x3a8, + 0x3a9, 0x3aa, 0x3ab, 0x3ac, 0x3ad, 0x3ae, 0x3ae, 0x3af, + 0x3b0, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b6, + 0x3b7, 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd, 0x3be, + 0x3bf, 0x3bf, 0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4, 0x3c5, + 0x3c6, 0x3c7, 0x3c7, 0x3c8, 0x3c9, 0x3ca, 0x3cb, 0x3cc, + 0x3cd, 0x3ce, 0x3cf, 0x3d0, 0x3d1, 0x3d1, 0x3d2, 0x3d3, + 0x3d4, 0x3d5, 0x3d6, 0x3d7, 0x3d8, 0x3d9, 0x3da, 0x3da, + 0x3db, 0x3dc, 0x3dd, 0x3de, 0x3df, 0x3e0, 0x3e1, 0x3e2, + 0x3e3, 0x3e4, 0x3e4, 0x3e5, 0x3e6, 0x3e7, 0x3e8, 0x3e9, + 0x3ea, 0x3eb, 0x3ec, 0x3ed, 0x3ee, 0x3ef, 0x3ef, 0x3f0, + 0x3f1, 0x3f2, 0x3f3, 0x3f4, 0x3f5, 0x3f6, 0x3f7, 0x3f8, + 0x3f9, 0x3fa, 0x3fa, 0x3fb, 0x3fc, 0x3fd, 0x3fe, 0x3ff +}; + +/* + * Attenuation according to GM recommendations, in -0.375 dB units. + * table[v] = 40 * log(v / 127) / -0.375 + */ +static const uint8_t g_volume_table[128] = { + 255, 224, 192, 173, 160, 150, 141, 134, + 128, 122, 117, 113, 109, 105, 102, 99, + 96, 93, 90, 88, 85, 83, 81, 79, + 77, 75, 73, 71, 70, 68, 67, 65, + 64, 62, 61, 59, 58, 57, 56, 54, + 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 40, 39, 39, + 38, 37, 36, 35, 34, 34, 33, 32, + 31, 31, 30, 29, 29, 28, 27, 27, + 26, 25, 25, 24, 24, 23, 22, 22, + 21, 21, 20, 19, 19, 18, 18, 17, + 17, 16, 16, 15, 15, 14, 14, 13, + 13, 12, 12, 11, 11, 10, 10, 9, + 9, 9, 8, 8, 7, 7, 6, 6, + 6, 5, 5, 4, 4, 4, 3, 3, + 2, 2, 2, 1, 1, 0, 0, 0 +}; + +typedef struct opl4_midi { + fm_drv_t opl4; + MIDI_CHANNEL_DATA midi_channel_data[16]; + VOICE_DATA voice_data[24]; + int16_t buffer[SOUNDBUFLEN * 2]; + float buffer_float[SOUNDBUFLEN * 2]; + uint32_t midi_pos; + bool on; + atomic_bool gen_in_progress; + thread_t *thread; + event_t *wait_event; +} opl4_midi_t; + +static opl4_midi_t *opl4_midi_cur; + +static void +opl4_write_wave_register(const uint8_t reg, const uint8_t value, opl4_midi_t *opl4_midi) +{ + opl4_midi->opl4.write(0x380, reg, opl4_midi->opl4.priv); + opl4_midi->opl4.write(0x381, value, opl4_midi->opl4.priv); +} + +VOICE_DATA * +get_voice(const YRW801_WAVE_DATA *wave_data, opl4_midi_t *opl4_midi) +{ + VOICE_DATA *free_voice = &opl4_midi->voice_data[0]; + VOICE_DATA *oldest_voice = &opl4_midi->voice_data[0]; + for (uint8_t voice = 0; voice < 24; voice++) { + if (opl4_midi_cur->voice_data[voice].is_active) { + if (opl4_midi_cur->voice_data[voice].activated < oldest_voice->activated) + oldest_voice = &opl4_midi_cur->voice_data[voice]; + } else { + if (opl4_midi_cur->voice_data[voice].wave_data == wave_data) { + free_voice = &opl4_midi_cur->voice_data[voice]; + break; + } + + if (opl4_midi_cur->voice_data[voice].activated < free_voice->activated) + free_voice = &opl4_midi_cur->voice_data[voice]; + } + } + + /* If no free voice found, deactivate the 'oldest' */ + if (free_voice->is_active) { + free_voice = oldest_voice; + free_voice->is_active = 0; + free_voice->activated = 0; + + free_voice->reg_misc &= ~OPL4_KEY_ON_BIT; + opl4_write_wave_register(OPL4_REG_MISC + free_voice->number, free_voice->reg_misc, opl4_midi); + } + + return free_voice; +} + +static void +update_pan(VOICE_DATA *voice, opl4_midi_t *opl4_midi) +{ + int8_t pan = voice->wave_data->panpot; + + if (!voice->midi_channel->drum_channel) + pan += voice->midi_channel->panpot; + if (pan < -7) + pan = -7; + else if (pan > 7) + pan = 7; + + voice->reg_misc = (voice->reg_misc & ~OPL4_PAN_POT_MASK) | (pan & OPL4_PAN_POT_MASK); + opl4_write_wave_register(OPL4_REG_MISC + voice->number, voice->reg_misc, opl4_midi); +} + +void +update_pitch(VOICE_DATA *voice, uint16_t pitch_bend, opl4_midi_t *opl4_midi) +{ + int32_t pitch = voice->midi_channel->drum_channel ? 0 : (voice->note - 60) * 128; + pitch = pitch * (int) voice->wave_data->key_scaling / 100; + pitch = pitch + 7680; + pitch += voice->wave_data->pitch_offset; + pitch += pitch_bend * 256 / 0x2000; + if (pitch < 0) + pitch = 0; + else if (pitch > 0x5FFF) + pitch = 0x5FFF; + + int8_t octave = pitch / 0x600 - 8; + uint16_t fnumber = g_wave_pitch_map[pitch % 0x600]; + + opl4_write_wave_register(OPL4_REG_OCTAVE + voice->number, (octave << 4) | ((fnumber >> 7) & 0x07), opl4_midi); + voice->reg_f_number = (voice->reg_f_number & OPL4_TONE_NUMBER_BIT8) | ((fnumber << 1) & OPL4_F_NUMBER_LOW_MASK); + opl4_write_wave_register(OPL4_REG_F_NUMBER + voice->number, voice->reg_f_number, opl4_midi); +} + +void +update_volume(VOICE_DATA *voice, opl4_midi_t *opl4_midi) +{ + int16_t att = voice->wave_data->tone_attenuate; + + att += g_volume_table[voice->velocity]; + att = 0x7F - (0x7F - att) * (voice->wave_data->volume_factor) / 0xFE; + att -= 16; + if (att < 0) + att = 0; + else if (att > 0x7E) + att = 0x7E; + + opl4_write_wave_register(OPL4_REG_LEVEL + voice->number, (att << 1) | voice->level_direct, opl4_midi); + voice->level_direct = 0; +} + +void +note_off(uint8_t note, uint8_t velocity, MIDI_CHANNEL_DATA *midi_channel, opl4_midi_t *opl4_midi) +{ + /* Velocity not used */ + (void) velocity; + + while (opl4_midi->gen_in_progress) { } + for (uint8_t i = 0; i < 24; i++) { + VOICE_DATA *voice = &opl4_midi->voice_data[i]; + if (voice->is_active && voice->midi_channel == midi_channel && voice->note == note) { + voice->is_active = false; + voice->activated = 0; + + voice->reg_misc &= ~OPL4_KEY_ON_BIT; + opl4_write_wave_register(OPL4_REG_MISC + voice->number, voice->reg_misc, opl4_midi); + } + } +} + +void +update_vibrato_depth(VOICE_DATA *voice, opl4_midi_t *opl4_midi) +{ + uint16_t depth; + + depth = (7 - voice->wave_data->vibrato) * (voice->midi_channel->vibrato & 0x7F); + depth = (depth >> 7) + voice->wave_data->vibrato; + voice->reg_lfo_vibrato &= ~OPL4_VIBRATO_DEPTH_MASK; + voice->reg_lfo_vibrato |= depth & OPL4_VIBRATO_DEPTH_MASK; + opl4_write_wave_register(OPL4_REG_LFO_VIBRATO + voice->number, voice->reg_lfo_vibrato, opl4_midi); +} + +void +note_on(uint8_t note, uint8_t velocity, MIDI_CHANNEL_DATA *midi_channel, opl4_midi_t *opl4_midi) +{ + const YRW801_REGION_DATA_PTR *region_ptr = &snd_yrw801_regions[0]; + const YRW801_WAVE_DATA *wave_data[2]; + VOICE_DATA *voice[2]; + uint8_t i = 0, voices = 0; + uint32_t j = 0; + static uint64_t activation_num = 0; + + while (opl4_midi->gen_in_progress) { } + + if (midi_channel->drum_channel) + wave_data[voices++] = ®ion_ptr[0x80].regions[note - 0x1A].wave_data; + else { + /* Determine the number of voices and voice parameters */ + const YRW801_REGION_DATA *region = region_ptr[midi_channel->instrument & 0x7F].regions; + + while (i < region_ptr[midi_channel->instrument & 0x7F].count) { + if (note >= region[i].key_min && note <= region[i].key_max) { + wave_data[voices] = ®ion[i].wave_data; + if (++voices >= 2) + break; + } + i++; + } + } + + /* Allocate and initialize needed voices */ + for (i = 0; i < voices; i++) { + voice[i] = get_voice(wave_data[i], opl4_midi); + voice[i]->is_active = true; + voice[i]->activated = activation_num++; + + voice[i]->midi_channel = midi_channel; + voice[i]->note = note; + voice[i]->velocity = velocity & 0x7F; + } + + for (i = 0; i < voices; i++) { + voice[i]->reg_f_number = (wave_data[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8; + opl4_write_wave_register(OPL4_REG_F_NUMBER + voice[i]->number, voice[i]->reg_f_number, opl4_midi); + + bool new_wave = (voice[i]->wave_data != wave_data[i]); + /* Set tone number (triggers header loading) */ + if (new_wave) { + opl4_write_wave_register(OPL4_REG_TONE_NUMBER + voice[i]->number, wave_data[i]->tone & 0xFF, opl4_midi); + voice[i]->wave_data = wave_data[i]; + } + + voice[i]->reg_misc = OPL4_LFO_RESET_BIT; + update_pan(voice[i], opl4_midi); + update_pitch(voice[i], 0, opl4_midi); + voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT; + update_volume(voice[i], opl4_midi); + if (new_wave) { + /* Set remaining parameters */ + opl4_write_wave_register(OPL4_REG_ATTACK_DECAY1 + voice[i]->number, voice[i]->wave_data->reg_attack_decay1, opl4_midi); + opl4_write_wave_register(OPL4_REG_LEVEL_DECAY2 + voice[i]->number, voice[i]->wave_data->reg_level_decay2, opl4_midi); + opl4_write_wave_register(OPL4_REG_RELEASE_CORRECTION + voice[i]->number, voice[i]->wave_data->reg_release_correction, opl4_midi); + opl4_write_wave_register(OPL4_REG_TREMOLO + voice[i]->number, voice[i]->wave_data->reg_tremolo, opl4_midi); + + voice[i]->reg_lfo_vibrato = voice[i]->wave_data->reg_lfo_vibrato; + + if (!midi_channel->drum_channel) + update_vibrato_depth(voice[i], opl4_midi); + } + } + + /* Finally, switch on all voices */ + for (i = 0; i < voices; i++) { + voice[i]->reg_misc = (voice[i]->reg_misc & 0x1F) | OPL4_KEY_ON_BIT; + opl4_write_wave_register(OPL4_REG_MISC + voice[i]->number, voice[i]->reg_misc, opl4_midi); + } +} + +void +control_change(uint8_t midi_channel, uint8_t id, uint8_t value, opl4_midi_t *opl4_midi) +{ + int i = 0; + switch (id) { + case 10: + /* Change stereo panning */ + if (midi_channel != DRUM_CHANNEL) { + opl4_midi->midi_channel_data[midi_channel].panpot = (value - 0x40) >> 3; + for (i = 0; i < NR_OF_WAVE_CHANNELS; i++) { + if (opl4_midi->voice_data[i].is_active && opl4_midi->voice_data[i].midi_channel == &opl4_midi->midi_channel_data[midi_channel]) { + update_pan(&opl4_midi->voice_data[i], opl4_midi); + } + } + } + break; + } +} + +void +pitch_wheel(uint8_t midi_channel, uint16_t value, opl4_midi_t *opl4_midi) +{ + int i = 0; + + for (i = 0; i < 24; i++) { + if (opl4_midi->voice_data[i].is_active && opl4_midi->voice_data[i].midi_channel == &opl4_midi->midi_channel_data[midi_channel]) { + update_pitch(&opl4_midi->voice_data[i], value, opl4_midi); + } + } +} + +void +channel_pressure(uint8_t midi_channel, uint8_t pressure) +{ + (void) midi_channel; + (void) pressure; +} + +void +key_pressure(uint8_t midi_channel, uint8_t note, uint8_t pressure) +{ + (void) midi_channel; + (void) note; + (void) pressure; +} + +void +program_change(uint8_t midi_channel, uint8_t program, opl4_midi_t *opl4_midi) +{ + opl4_midi->midi_channel_data[midi_channel].instrument = program; +} + +#define RENDER_RATE (48000 / 100) +static void +opl4_midi_thread(void *arg) +{ + opl4_midi_t *opl4_midi = opl4_midi_cur; + uint32_t i = 0; + uint32_t buf_size = RENDER_RATE * 2; + + int32_t buffer[RENDER_RATE * 2]; + + extern void givealbuffer_midi(void *buf, uint32_t size); + while (opl4_midi->on) { + thread_wait_event(opl4_midi->wait_event, -1); + thread_reset_event(opl4_midi->wait_event); + if (!opl4_midi->on) + break; + atomic_store(&opl4_midi->gen_in_progress, true); + opl4_midi->opl4.generate(opl4_midi->opl4.priv, buffer, RENDER_RATE); + atomic_store(&opl4_midi->gen_in_progress, false); + if (sound_is_float) { + for (i = 0; i < (buf_size / 2); i++) { + opl4_midi->buffer_float[i * 2] = buffer[i * 2] / 32768.0; + opl4_midi->buffer_float[(i * 2) + 1] = buffer[(i * 2) + 1] / 32768.0; + } + givealbuffer_midi(opl4_midi->buffer_float, buf_size); + } else { + for (i = 0; i < (buf_size / 2); i++) { + opl4_midi->buffer[i * 2] = buffer[i * 2] & 0xFFFF; /* Outputs are clamped beforehand. */ + opl4_midi->buffer[(i * 2) + 1] = buffer[(i * 2) + 1] & 0xFFFF; /* Outputs are clamped beforehand. */ + } + givealbuffer_midi(opl4_midi->buffer, buf_size); + } + } +} + +static void +opl4_midi_poll(void) +{ + opl4_midi_t *opl4_midi = opl4_midi_cur; + opl4_midi->midi_pos++; + if (opl4_midi->midi_pos == RENDER_RATE) { + opl4_midi->midi_pos = 0; + thread_set_event(opl4_midi->wait_event); + } +} + +void +opl4_midi_msg(uint8_t *val) +{ + opl4_midi_t *opl4_midi = opl4_midi_cur; + + uint32_t msg = *(uint32_t *) (val); + uint8_t data_byte_1 = msg & 0xFF; + uint8_t data_byte_2 = (msg >> 8) & 0xFF; + uint8_t data_byte_3 = (msg >> 16) & 0xFF; + + uint8_t midi_channel = data_byte_1 & 0x0F; + uint8_t midi_command = data_byte_1 >> 4; + + switch (midi_command) { + case 0x8: // Note OFF + note_off(data_byte_2 & 0x7F, data_byte_3, &opl4_midi->midi_channel_data[midi_channel], opl4_midi); + break; + case 0x9: // Note ON + note_on(data_byte_2 & 0x7F, data_byte_3, &opl4_midi->midi_channel_data[midi_channel], opl4_midi); + break; + case 0xA: // Key after-touch + break; + case 0xB: // Control change + control_change(midi_channel, data_byte_2, data_byte_3, opl4_midi); + break; + case 0xC: // Program change + program_change(midi_channel, data_byte_2 & 0x7F, opl4_midi); + break; + case 0xD: // Channel after-touch + break; + case 0xE: // Pitch wheel + pitch_wheel(midi_channel, ((data_byte_3 <<= 7) | data_byte_2), opl4_midi); + break; + } +} + +void +opl4_midi_sysex(uint8_t *data, unsigned int len) +{ +} + +void * +opl4_init(const device_t *info) +{ + midi_device_t *dev; + extern void al_set_midi(int freq, int buf_size); + + dev = malloc(sizeof(midi_device_t)); + memset(dev, 0, sizeof(midi_device_t)); + + dev->play_msg = opl4_midi_msg; + dev->play_sysex = opl4_midi_sysex; + dev->poll = opl4_midi_poll; + + al_set_midi(48000, 4800); + + opl4_midi_cur = calloc(1, sizeof(opl4_midi_t)); + + fm_driver_get(FM_YMF278B, &opl4_midi_cur->opl4); + + opl4_midi_cur->opl4.write(0x38A, 0x05, opl4_midi_cur->opl4.priv); + opl4_midi_cur->opl4.write(0x389, 0x3, opl4_midi_cur->opl4.priv); + midi_out_init(dev); + + opl4_midi_cur->on = true; + opl4_midi_cur->midi_channel_data[9].drum_channel = true; + atomic_init(&opl4_midi_cur->gen_in_progress, 0); + + for (uint8_t voice = 0; voice < NR_OF_WAVE_CHANNELS; voice++) { + opl4_midi_cur->voice_data[voice].number = voice; + opl4_midi_cur->voice_data[voice].is_active = false; + opl4_midi_cur->voice_data[voice].activated = 0; + opl4_midi_cur->voice_data[voice].midi_channel = NULL; + opl4_midi_cur->voice_data[voice].note = 0; + opl4_midi_cur->voice_data[voice].velocity = 0; + opl4_midi_cur->voice_data[voice].wave_data = NULL; + opl4_midi_cur->voice_data[voice].level_direct = 0; + opl4_midi_cur->voice_data[voice].reg_f_number = 0; + opl4_midi_cur->voice_data[voice].reg_misc = 0; + opl4_midi_cur->voice_data[voice].reg_lfo_vibrato = 0; + } + opl4_midi_cur->wait_event = thread_create_event(); + opl4_midi_cur->thread = thread_create(opl4_midi_thread, NULL); + return dev; +} + +void +opl4_close(void *p) +{ + if (!p) + return; + + opl4_midi_cur->on = false; + thread_set_event(opl4_midi_cur->wait_event); + thread_wait(opl4_midi_cur->thread); + free(opl4_midi_cur); + opl4_midi_cur = NULL; +} + +static int +opl4_midi_available(void) +{ + return rom_present("roms/sound/yamaha/yrw801.rom"); +} + +const device_t opl4_midi_device = { + .name = "OPL4-ML Daughterboard", + .internal_name = "opl4-ml", + .flags = 0, + .local = 0, + .init = opl4_init, + .close = opl4_close, + .reset = NULL, + { .available = opl4_midi_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sound/midi_opl4_yrw801.c b/src/sound/midi_opl4_yrw801.c new file mode 100644 index 000000000..96822b9af --- /dev/null +++ b/src/sound/midi_opl4_yrw801.c @@ -0,0 +1,1042 @@ +/* Table taken from linux/sound/drivers/opl4/yrw801.c */ +/* Macros from Linux source code as well */ + +#include "yrw801.h" + +static const YRW801_REGION_DATA regions_00[] = { + /* Acoustic Grand Piano */ + { 0x14, 0x27, { 0x12c, 7474, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6816, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5899, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5290, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4260, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3625, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3116, 100, 0, 0, 0x04, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2081, 100, 0, 0, 0x03, 0xc8, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1444, 100, 0, 0, 0x07, 0xc8, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1915, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_01[] = { + /* Bright Acoustic Piano */ + { 0x14, 0x2d, { 0x12c, 7474, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12d, 6816, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12e, 5899, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x12f, 5290, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x130, 4260, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x131, 3625, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x132, 3116, 100, 0, 0, 0x04, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x53, 0x58, { 0x133, 2081, 100, 0, 0, 0x07, 0xc8, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x59, 0x5e, { 0x134, 1444, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x5f, 0x6d, { 0x135, 1915, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_02[] = { + /* Electric Grand Piano */ + { 0x14, 0x2d, { 0x12c, 7476, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x13, 0x07, 0x0 } }, + { 0x2e, 0x33, { 0x12d, 6818, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x34, 0x39, { 0x12e, 5901, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x3a, 0x3f, { 0x12f, 5292, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x40, 0x45, { 0x130, 4262, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x46, 0x4b, { 0x131, 3627, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x4c, 0x52, { 0x132, 3118, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x53, 0x58, { 0x133, 2083, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x17, 0x0 } }, + { 0x59, 0x5e, { 0x134, 1446, 100, 1, 0, 0x00, 0xae, 0x20, 0xf3, 0x14, 0x17, 0x0 } }, + { 0x5f, 0x6d, { 0x135, 1917, 100, 1, 0, 0x00, 0xae, 0x20, 0xf4, 0x15, 0x07, 0x0 } }, + { 0x00, 0x7f, { 0x06c, 6375, 100, -1, 0, 0x00, 0xc2, 0x28, 0xf4, 0x23, 0x18, 0x0 }} +}; +static const YRW801_REGION_DATA regions_03[] = { + /* Honky-Tonk Piano */ + { 0x14, 0x27, { 0x12c, 7474, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6816, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5899, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5290, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4260, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3625, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3116, 100, 0, 0, 0x04, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2081, 100, 0, 0, 0x03, 0xb4, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1444, 100, 0, 0, 0x07, 0xb4, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1915, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf4, 0x15, 0x08, 0x0 }}, + { 0x14, 0x27, { 0x12c, 7486, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6803, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5912, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5275, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4274, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3611, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3129, 100, 0, 0, 0x04, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2074, 100, 0, 0, 0x07, 0xb4, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1457, 100, 0, 0, 0x01, 0xb4, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1903, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_04[] = { + /* Electric Piano 1 */ + { 0x15, 0x6c, { 0x00b, 6570, 100, 0, 0, 0x00, 0x28, 0x38, 0xf0, 0x00, 0x0c, 0x0 }}, + { 0x00, 0x7f, { 0x06c, 6375, 100, 0, 2, 0x00, 0xb0, 0x22, 0xf4, 0x23, 0x19, 0x0 }} +}; +static const YRW801_REGION_DATA regions_05[] = { + /* Electric Piano 2 */ + { 0x14, 0x27, { 0x12c, 7476, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6818, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5901, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5292, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4262, 100, 0, 3, 0x0a, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3627, 100, 0, 3, 0x0a, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3118, 100, 0, 3, 0x04, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2083, 100, 0, 3, 0x03, 0xa2, 0x1b, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1446, 100, 0, 3, 0x07, 0xa2, 0x1b, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1917, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf4, 0x15, 0x08, 0x0 }}, + { 0x14, 0x2d, { 0x12c, 7472, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12d, 6814, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12e, 5897, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x12f, 5288, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x130, 4258, 100, 0, 0, 0x0a, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x131, 3623, 100, 0, 0, 0x0a, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x132, 3114, 100, 0, 0, 0x04, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x53, 0x58, { 0x133, 2079, 100, 0, 0, 0x07, 0xa2, 0x18, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x59, 0x5e, { 0x134, 1442, 100, 0, 0, 0x0a, 0xa2, 0x18, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x5f, 0x6d, { 0x135, 1913, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_06[] = { + /* Harpsichord */ + { 0x15, 0x39, { 0x080, 5158, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x24, 0x19, 0x0 }}, + { 0x3a, 0x3f, { 0x081, 4408, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x09, 0x0 }}, + { 0x40, 0x45, { 0x082, 3622, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x09, 0x0 }}, + { 0x46, 0x4d, { 0x083, 2843, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x19, 0x0 }}, + { 0x4e, 0x6c, { 0x084, 1307, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x29, 0x0 }} +}; +static const YRW801_REGION_DATA regions_07[] = { + /* Clavinet */ + { 0x15, 0x51, { 0x027, 5009, 100, 0, 0, 0x00, 0xd2, 0x28, 0xf5, 0x13, 0x2b, 0x0 }}, + { 0x52, 0x6c, { 0x028, 3495, 100, 0, 0, 0x00, 0xd2, 0x28, 0xf5, 0x13, 0x3b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_08[] = { + /* Celesta */ + { 0x15, 0x6c, { 0x02b, 3267, 100, 0, 0, 0x00, 0xdc, 0x20, 0xf4, 0x15, 0x07, 0x3 }} +}; +static const YRW801_REGION_DATA regions_09[] = { + /* Glockenspiel */ + { 0x15, 0x78, { 0x0f3, 285, 100, 0, 0, 0x00, 0xc2, 0x28, 0xf6, 0x25, 0x25, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0a[] = { + /* Music Box */ + { 0x15, 0x6c, { 0x0f3, 3362, 100, 0, 0, 0x00, 0xb6, 0x20, 0xa6, 0x25, 0x25, 0x0 }}, + { 0x15, 0x6c, { 0x101, 4773, 100, 0, 0, 0x00, 0xaa, 0x20, 0xd4, 0x14, 0x16, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0b[] = { + /* Vibraphone */ + { 0x15, 0x6c, { 0x101, 4778, 100, 0, 0, 0x00, 0xc0, 0x28, 0xf4, 0x14, 0x16, 0x4 }} +}; +static const YRW801_REGION_DATA regions_0c[] = { + /* Marimba */ + { 0x15, 0x3f, { 0x0f4, 4778, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x47, 0x08, 0x0 }}, + { 0x40, 0x4c, { 0x0f5, 3217, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x47, 0x08, 0x0 }}, + { 0x4d, 0x5a, { 0x0f5, 3217, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x48, 0x08, 0x0 }}, + { 0x5b, 0x7f, { 0x0f5, 3218, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x48, 0x18, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0d[] = { + /* Xylophone */ + { 0x00, 0x7f, { 0x136, 1729, 100, 0, 0, 0x00, 0xd2, 0x38, 0xf0, 0x06, 0x36, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0e[] = { + /* Tubular Bell */ + { 0x01, 0x7f, { 0x0ff, 3999, 100, 0, 1, 0x00, 0x90, 0x21, 0xf4, 0xa3, 0x25, 0x1 }} +}; +static const YRW801_REGION_DATA regions_0f[] = { + /* Dulcimer */ + { 0x00, 0x7f, { 0x03f, 4236, 100, 0, 1, 0x00, 0xbc, 0x29, 0xf5, 0x16, 0x07, 0x0 }}, + { 0x00, 0x7f, { 0x040, 4236, 100, 0, 2, 0x0e, 0x94, 0x2a, 0xf5, 0x16, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_10[] = { + /* Drawbar Organ */ + { 0x01, 0x7f, { 0x08e, 4394, 100, 0, 2, 0x14, 0xc2, 0x3a, 0xf0, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_11[] = { + /* Percussive Organ */ + { 0x15, 0x3b, { 0x08c, 6062, 100, 0, 3, 0x00, 0xbe, 0x3b, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3c, 0x6c, { 0x08d, 2984, 100, 0, 3, 0x00, 0xbe, 0x3b, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_12[] = { + /* Rock Organ */ + { 0x15, 0x30, { 0x128, 6574, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x31, 0x3c, { 0x129, 5040, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x3d, 0x48, { 0x12a, 3498, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x49, 0x54, { 0x12b, 1957, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x55, 0x6c, { 0x127, 423, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 } } +}; +static const YRW801_REGION_DATA regions_13[] = { + /* Church Organ */ + { 0x15, 0x29, { 0x087, 7466, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x2a, 0x30, { 0x088, 6456, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x31, 0x38, { 0x089, 5428, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x39, 0x41, { 0x08a, 4408, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x42, 0x6c, { 0x08b, 3406, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_14[] = { + /* Reed Organ */ + { 0x00, 0x53, { 0x0ac, 5570, 100, 0, 0, 0x06, 0xc0, 0x38, 0xf0, 0x00, 0x09, 0x1 }}, + { 0x54, 0x7f, { 0x0ad, 2497, 100, 0, 0, 0x00, 0xc0, 0x38, 0xf0, 0x00, 0x09, 0x1 }} +}; +static const YRW801_REGION_DATA regions_15[] = { + /* Accordion */ + { 0x15, 0x4c, { 0x006, 4261, 100, 0, 2, 0x00, 0xa4, 0x22, 0x90, 0x00, 0x09, 0x0 }}, + { 0x4d, 0x6c, { 0x007, 1530, 100, 0, 2, 0x00, 0xa4, 0x22, 0x90, 0x00, 0x09, 0x0 }}, + { 0x15, 0x6c, { 0x070, 4391, 100, 0, 3, 0x00, 0x8a, 0x23, 0xa0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_16[] = { + /* Harmonica */ + { 0x15, 0x6c, { 0x070, 4408, 100, 0, 0, 0x00, 0xae, 0x30, 0xa0, 0x00, 0x09, 0x2 }} +}; +static const YRW801_REGION_DATA regions_17[] = { + /* Tango Accordion */ + { 0x00, 0x53, { 0x0ac, 5573, 100, 0, 0, 0x00, 0xae, 0x38, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x54, 0x7f, { 0x0ad, 2500, 100, 0, 0, 0x00, 0xae, 0x38, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x15, 0x6c, { 0x041, 8479, 100, 0, 2, 0x00, 0x6a, 0x3a, 0x75, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_18[] = { + /* Nylon Guitar */ + { 0x15, 0x2f, { 0x0b3, 6964, 100, 0, 0, 0x05, 0xca, 0x28, 0xf5, 0x34, 0x09, 0x0 }}, + { 0x30, 0x36, { 0x0b7, 5567, 100, 0, 0, 0x0c, 0xca, 0x28, 0xf5, 0x34, 0x09, 0x0 }}, + { 0x37, 0x3c, { 0x0b5, 4653, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }}, + { 0x3d, 0x43, { 0x0b4, 3892, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x35, 0x09, 0x0 }}, + { 0x44, 0x60, { 0x0b6, 2723, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x35, 0x19, 0x0 }} +}; +static const YRW801_REGION_DATA regions_19[] = { + /* Steel Guitar */ + { 0x15, 0x31, { 0x00c, 6937, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x04, 0x19, 0x0 }}, + { 0x32, 0x38, { 0x00d, 5410, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x05, 0x09, 0x0 }}, + { 0x39, 0x47, { 0x00e, 4379, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf5, 0x94, 0x09, 0x0 }}, + { 0x48, 0x6c, { 0x00f, 2843, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf6, 0x95, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1a[] = { + /* Jazz Guitar */ + { 0x15, 0x31, { 0x05a, 6832, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }}, + { 0x32, 0x3f, { 0x05b, 4897, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }}, + { 0x40, 0x6c, { 0x05c, 3218, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1b[] = { + /* Clean Guitar */ + { 0x15, 0x2c, { 0x061, 7053, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x54, 0x0a, 0x0 }}, + { 0x2d, 0x31, { 0x060, 6434, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x54, 0x0a, 0x0 }}, + { 0x32, 0x38, { 0x063, 5764, 100, 0, 1, 0x00, 0xbe, 0x29, 0xf5, 0x55, 0x0a, 0x0 }}, + { 0x39, 0x3f, { 0x062, 4627, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x0a, 0x0 }}, + { 0x40, 0x44, { 0x065, 3963, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x1a, 0x0 }}, + { 0x45, 0x4b, { 0x064, 3313, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x1a, 0x0 }}, + { 0x4c, 0x54, { 0x066, 2462, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x2a, 0x0 }}, + { 0x55, 0x6c, { 0x067, 1307, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf6, 0x56, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1c[] = { + /* Muted Guitar */ + { 0x01, 0x7f, { 0x068, 4408, 100, 0, 0, 0x00, 0xcc, 0x28, 0xf6, 0x15, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1d[] = { + /* Overdriven Guitar */ + { 0x00, 0x40, { 0x0a5, 6589, 100, 0, 1, 0x00, 0xc0, 0x29, 0xf2, 0x11, 0x09, 0x0 }}, + { 0x41, 0x7f, { 0x0a6, 5428, 100, 0, 1, 0x00, 0xc0, 0x29, 0xf2, 0x11, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1e[] = { + /* Distortion Guitar */ + { 0x15, 0x2a, { 0x051, 6928, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x2b, 0x2e, { 0x052, 6433, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x2f, 0x32, { 0x053, 5944, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x33, 0x36, { 0x054, 5391, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x37, 0x3a, { 0x055, 4897, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x3b, 0x3e, { 0x056, 4408, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x3f, 0x42, { 0x057, 3892, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x43, 0x46, { 0x058, 3361, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x47, 0x6c, { 0x059, 2784, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1f[] = { + /* Guitar Harmonics */ + { 0x15, 0x44, { 0x05e, 5499, 100, 0, 0, 0x00, 0xce, 0x28, 0xf4, 0x24, 0x09, 0x0 }}, + { 0x45, 0x49, { 0x05d, 4850, 100, 0, 0, 0x00, 0xe2, 0x28, 0xf4, 0x24, 0x09, 0x0 }}, + { 0x4a, 0x6c, { 0x05f, 4259, 100, 0, 0, 0x00, 0xce, 0x28, 0xf4, 0x24, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_20[] = { + /* Acoustic Bass */ + { 0x15, 0x30, { 0x004, 8053, 100, 0, 0, 0x00, 0xe2, 0x18, 0xf5, 0x15, 0x09, 0x0 }}, + { 0x31, 0x6c, { 0x005, 4754, 100, 0, 0, 0x00, 0xe2, 0x18, 0xf5, 0x15, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_21[] = { + /* Fingered Bass */ + { 0x01, 0x20, { 0x04a, 8762, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }}, + { 0x21, 0x25, { 0x04b, 8114, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }}, + { 0x26, 0x2a, { 0x04c, 7475, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }}, + { 0x2b, 0x7f, { 0x04d, 6841, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_22[] = { + /* Picked Bass */ + { 0x15, 0x23, { 0x04f, 7954, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf3, 0x90, 0x0a, 0x0 }}, + { 0x24, 0x2a, { 0x050, 7318, 100, 0, 0, 0x05, 0xcc, 0x18, 0xf3, 0x90, 0x1a, 0x0 }}, + { 0x2b, 0x2f, { 0x06b, 6654, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf3, 0x90, 0x2a, 0x0 }}, + { 0x30, 0x47, { 0x069, 6031, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf5, 0xb0, 0x0a, 0x0 }}, + { 0x48, 0x6c, { 0x06a, 5393, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf5, 0xb0, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_23[] = { + /* Fretless Bass */ + { 0x01, 0x7f, { 0x04e, 5297, 100, 0, 0, 0x00, 0xd2, 0x10, 0xf3, 0x63, 0x19, 0x0 }} +}; +static const YRW801_REGION_DATA regions_24[] = { + /* Slap Bass 1 */ + { 0x15, 0x6c, { 0x0a3, 7606, 100, 0, 1, 0x00, 0xde, 0x19, 0xf5, 0x32, 0x1a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_25[] = { + /* Slap Bass 2 */ + { 0x01, 0x7f, { 0x0a2, 6694, 100, 0, 0, 0x00, 0xda, 0x20, 0xb0, 0x02, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_26[] = { + /* Synth Bass 1 */ + { 0x15, 0x6c, { 0x0be, 7466, 100, 0, 1, 0x00, 0xb8, 0x39, 0xf4, 0x14, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_27[] = { + /* Synth Bass 2 */ + { 0x00, 0x7f, { 0x117, 8103, 100, 0, 1, 0x00, 0xca, 0x39, 0xf3, 0x50, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_28[] = { + /* Violin */ + { 0x15, 0x3a, { 0x105, 5158, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x3b, 0x3f, { 0x102, 4754, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x40, 0x41, { 0x106, 4132, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x42, 0x44, { 0x107, 4033, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x45, 0x47, { 0x108, 3580, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x48, 0x4a, { 0x10a, 2957, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4b, 0x4c, { 0x10b, 2724, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4d, 0x4e, { 0x10c, 2530, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4f, 0x51, { 0x10d, 2166, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x52, 0x6c, { 0x109, 1825, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_29[] = { + /* Viola */ + { 0x15, 0x32, { 0x103, 5780, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x33, 0x35, { 0x104, 5534, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x36, 0x38, { 0x105, 5158, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x39, 0x3d, { 0x102, 4754, 100, 0, 3, 0x00, 0xca, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x3e, 0x3f, { 0x106, 4132, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x40, 0x42, { 0x107, 4033, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x43, 0x45, { 0x108, 3580, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x46, 0x48, { 0x10a, 2957, 100, 0, 3, 0x00, 0xca, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x49, 0x4a, { 0x10b, 2724, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x4b, 0x4c, { 0x10c, 2530, 100, 0, 3, 0x00, 0xca, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x4d, 0x4f, { 0x10d, 2166, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x50, 0x6c, { 0x109, 1825, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2a[] = { + /* Cello */ + { 0x15, 0x2d, { 0x112, 6545, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x08, 0x0 }}, + { 0x2e, 0x37, { 0x113, 5764, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x08, 0x0 }}, + { 0x38, 0x3e, { 0x115, 4378, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x18, 0x0 }}, + { 0x3f, 0x44, { 0x116, 3998, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x18, 0x0 }}, + { 0x45, 0x6c, { 0x114, 3218, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x18, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2b[] = { + /* Contrabass */ + { 0x15, 0x29, { 0x110, 7713, 100, 0, 1, 0x00, 0xc2, 0x19, 0x90, 0x00, 0x09, 0x0 }}, + { 0x2a, 0x6c, { 0x111, 6162, 100, 0, 1, 0x00, 0xc2, 0x19, 0x90, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2c[] = { + /* Tremolo Strings */ + { 0x15, 0x3b, { 0x0b0, 4810, 100, 0, 0, 0x0a, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x3c, 0x41, { 0x035, 4035, 100, 0, 0, 0x05, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x42, 0x47, { 0x033, 3129, 100, 0, 0, 0x05, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x48, 0x52, { 0x034, 2625, 100, 0, 0, 0x05, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x53, 0x6c, { 0x0af, 936, 100, 0, 0, 0x00, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 } } +}; +static const YRW801_REGION_DATA regions_2d[] = { + /* Pizzicato Strings */ + { 0x15, 0x32, { 0x0b8, 6186, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x33, 0x3b, { 0x0b9, 5031, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x3c, 0x42, { 0x0bb, 4146, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x43, 0x48, { 0x0ba, 3245, 100, 0, 0, 0x00, 0xc2, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x49, 0x6c, { 0x0bc, 2352, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2e[] = { + /* Harp */ + { 0x15, 0x46, { 0x07e, 3740, 100, 0, 1, 0x00, 0xd2, 0x29, 0xf5, 0x25, 0x07, 0x0 }}, + { 0x47, 0x6c, { 0x07f, 2319, 100, 0, 1, 0x00, 0xd2, 0x29, 0xf5, 0x25, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2f[] = { + /* Timpani */ + { 0x15, 0x6c, { 0x100, 6570, 100, 0, 0, 0x00, 0xf8, 0x28, 0xf0, 0x05, 0x16, 0x0 }} +}; +static const YRW801_REGION_DATA regions_30[] = { + /* Strings */ + { 0x15, 0x3b, { 0x13c, 4806, 100, 0, 0, 0x00, 0xc8, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x3c, 0x41, { 0x13e, 4035, 100, 0, 0, 0x00, 0xc8, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x42, 0x47, { 0x13d, 3122, 100, 0, 0, 0x00, 0xc8, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x48, 0x52, { 0x13f, 2629, 100, 0, 0, 0x00, 0xbe, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x53, 0x6c, { 0x140, 950, 100, 0, 0, 0x00, 0xbe, 0x20, 0x80, 0x00, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_31[] = { + /* Slow Strings */ + { 0x15, 0x3b, { 0x0b0, 4810, 100, 0, 1, 0x0a, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x3c, 0x41, { 0x035, 4035, 100, 0, 1, 0x05, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x42, 0x47, { 0x033, 3129, 100, 0, 1, 0x05, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x48, 0x52, { 0x034, 2625, 100, 0, 1, 0x05, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x53, 0x6c, { 0x0af, 936, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_32[] = { + /* Synth Strings 1 */ + { 0x05, 0x71, { 0x002, 6045, 100, -2, 0, 0x00, 0xa6, 0x20, 0x93, 0x22, 0x06, 0x0 }}, + { 0x15, 0x6c, { 0x0ae, 3261, 100, 2, 0, 0x00, 0xc6, 0x20, 0x70, 0x01, 0x06, 0x0 } } +}; +static const YRW801_REGION_DATA regions_33[] = { + /* Synth Strings 2 */ + { 0x15, 0x6c, { 0x002, 4513, 100, 5, 1, 0x00, 0xb4, 0x19, 0x70, 0x00, 0x06, 0x0 } }, + { 0x15, 0x6c, { 0x002, 4501, 100, -5, 1, 0x00, 0xb4, 0x19, 0x70, 0x00, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_34[] = { + /* Choir Aahs */ + { 0x15, 0x3a, { 0x018, 5010, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }}, + { 0x3b, 0x40, { 0x019, 4370, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }}, + { 0x41, 0x47, { 0x01a, 3478, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }}, + { 0x48, 0x6c, { 0x01b, 2197, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_35[] = { + /* Voice Oohs */ + { 0x15, 0x6c, { 0x029, 3596, 100, 0, 0, 0x00, 0xe6, 0x20, 0xf7, 0x20, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_36[] = { + /* Synth Voice */ + { 0x15, 0x6c, { 0x02a, 3482, 100, 0, 1, 0x00, 0xc2, 0x19, 0x85, 0x21, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_37[] = { + /* Orchestra Hit */ + { 0x15, 0x6c, { 0x049, 4394, 100, 0, 0, 0x00, 0xfe, 0x30, 0x80, 0x05, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_38[] = { + /* Trumpet */ + { 0x15, 0x3c, { 0x0f6, 4706, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x3d, 0x43, { 0x0f8, 3894, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x44, 0x48, { 0x0f7, 3118, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x49, 0x4e, { 0x0fa, 2322, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x4f, 0x55, { 0x0f9, 1634, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x56, 0x6c, { 0x0fb, 786, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 } } +}; +static const YRW801_REGION_DATA regions_39[] = { + /* Trombone */ + { 0x15, 0x3a, { 0x0f0, 5053, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3b, 0x3f, { 0x0f1, 4290, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x40, 0x6c, { 0x0f2, 3580, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3a[] = { + /* Tuba */ + { 0x15, 0x2d, { 0x085, 7096, 100, 0, 1, 0x00, 0xde, 0x21, 0xf5, 0x10, 0x09, 0x0 }}, + { 0x2e, 0x6c, { 0x086, 6014, 100, 0, 1, 0x00, 0xde, 0x21, 0xf5, 0x10, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3b[] = { + /* Muted Trumpet */ + { 0x15, 0x45, { 0x0b1, 4135, 100, 0, 0, 0x00, 0xcc, 0x28, 0xf3, 0x10, 0x0a, 0x1 }}, + { 0x46, 0x6c, { 0x0b2, 2599, 100, 0, 0, 0x00, 0xcc, 0x28, 0x83, 0x10, 0x0a, 0x1 }} +}; +static const YRW801_REGION_DATA regions_3c[] = { + /* French Horns */ + { 0x15, 0x49, { 0x07c, 3624, 100, 0, 2, 0x00, 0xd0, 0x1a, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x4a, 0x6c, { 0x07d, 2664, 100, 0, 2, 0x00, 0xd0, 0x1a, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3d[] = { + /* Brass Section */ + { 0x15, 0x42, { 0x0fc, 4375, 100, 0, 0, 0x00, 0xd6, 0x28, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x43, 0x6c, { 0x0fd, 2854, 100, 0, 0, 0x00, 0xd6, 0x28, 0xf0, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3e[] = { + /* Synth Brass 1 */ + { 0x01, 0x27, { 0x0d3, 9094, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x0da, 8335, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x0d4, 7558, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x0db, 6785, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x0d5, 6042, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x0dc, 5257, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x0d6, 4493, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x4c, 0x51, { 0x0dd, 3741, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x52, 0x57, { 0x0d7, 3012, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x58, 0x5d, { 0x0de, 2167, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x5e, 0x63, { 0x0d8, 1421, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x64, 0x7f, { 0x0d9, -115, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x01, 0x27, { 0x118, 9103, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x28, 0x2d, { 0x119, 8340, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x2e, 0x33, { 0x11a, 7565, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x34, 0x39, { 0x11b, 6804, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x3a, 0x3f, { 0x11c, 6042, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x40, 0x45, { 0x11d, 5277, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x46, 0x4b, { 0x11e, 4520, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x4c, 0x51, { 0x11f, 3741, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x52, 0x57, { 0x120, 3012, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x58, 0x5d, { 0x121, 2166, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x5e, 0x64, { 0x122, 1421, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x65, 0x7f, { 0x123, -115, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } } +}; +static const YRW801_REGION_DATA regions_3f[] = { + /* Synth Brass 2 */ + { 0x01, 0x27, { 0x118, 9113, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x28, 0x2d, { 0x119, 8350, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x2e, 0x33, { 0x11a, 7575, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x34, 0x39, { 0x11b, 6814, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x3a, 0x3f, { 0x11c, 6052, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x40, 0x45, { 0x11d, 5287, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x46, 0x4b, { 0x11e, 4530, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x4c, 0x51, { 0x11f, 3751, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x52, 0x57, { 0x120, 3022, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x58, 0x5d, { 0x121, 2176, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x5e, 0x64, { 0x122, 1431, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x65, 0x7f, { 0x123, -105, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x00, 0x7f, { 0x124, 4034, 100, -3, 2, 0x00, 0xea, 0x22, 0x85, 0x23, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_40[] = { + /* Soprano Sax */ + { 0x15, 0x3f, { 0x0e3, 4228, 100, 0, 1, 0x00, 0xc8, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x0e4, 3495, 100, 0, 1, 0x00, 0xc8, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x0e5, 2660, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x0e6, 2002, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x52, 0x59, { 0x0e7, 1186, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x59, 0x6c, { 0x0e8, 1730, 100, 0, 1, 0x00, 0xc8, 0x21, 0xf5, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_41[] = { + /* Alto Sax */ + { 0x15, 0x32, { 0x092, 6204, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x33, 0x35, { 0x096, 5812, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x36, 0x3a, { 0x099, 5318, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x3b, 0x3b, { 0x08f, 5076, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x3c, 0x3e, { 0x093, 4706, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x3f, 0x41, { 0x097, 4321, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x42, 0x44, { 0x09a, 3893, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x45, 0x47, { 0x090, 3497, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x48, 0x4a, { 0x094, 3119, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x4b, 0x4d, { 0x098, 2726, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x4e, 0x50, { 0x09b, 2393, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x51, 0x53, { 0x091, 2088, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x54, 0x6c, { 0x095, 1732, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_42[] = { + /* Tenor Sax */ + { 0x24, 0x30, { 0x0e9, 6301, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x31, 0x34, { 0x0ea, 5781, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x35, 0x3a, { 0x0eb, 5053, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x3b, 0x41, { 0x0ed, 4165, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x42, 0x47, { 0x0ec, 3218, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x48, 0x51, { 0x0ee, 2462, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x52, 0x6c, { 0x0ef, 1421, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_43[] = { + /* Baritone Sax */ + { 0x15, 0x2d, { 0x0df, 6714, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x2e, 0x34, { 0x0e1, 5552, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x35, 0x39, { 0x0e2, 5178, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x3a, 0x6c, { 0x0e0, 4437, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_44[] = { + /* Oboe */ + { 0x15, 0x3c, { 0x042, 4493, 100, 0, 1, 0x00, 0xe6, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x3d, 0x43, { 0x044, 3702, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x44, 0x49, { 0x043, 2956, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x4a, 0x4f, { 0x046, 2166, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x50, 0x55, { 0x045, 1420, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x56, 0x6c, { 0x047, 630, 100, 0, 1, 0x00, 0xe6, 0x39, 0xf4, 0x10, 0x0a, 0x0 } } +}; +static const YRW801_REGION_DATA regions_45[] = { + /* English Horn */ + { 0x15, 0x38, { 0x03c, 5098, 100, 0, 1, 0x00, 0xc4, 0x31, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x39, 0x3e, { 0x03b, 4291, 100, 0, 1, 0x00, 0xc4, 0x31, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3f, 0x6c, { 0x03d, 3540, 100, 0, 1, 0x00, 0xc4, 0x31, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_46[] = { + /* Bassoon */ + { 0x15, 0x22, { 0x038, 7833, 100, 0, 1, 0x00, 0xc6, 0x31, 0xf0, 0x00, 0x0b, 0x0 }}, + { 0x23, 0x2e, { 0x03a, 7070, 100, 0, 1, 0x00, 0xc6, 0x31, 0xf0, 0x00, 0x0b, 0x0 }}, + { 0x2f, 0x6c, { 0x039, 6302, 100, 0, 1, 0x00, 0xc6, 0x31, 0xf0, 0x00, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_47[] = { + /* Clarinet */ + { 0x15, 0x3b, { 0x09e, 5900, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x3c, 0x41, { 0x0a0, 5158, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x42, 0x4a, { 0x09f, 4260, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x4b, 0x6c, { 0x0a1, 2957, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_48[] = { + /* Piccolo */ + { 0x15, 0x40, { 0x071, 4803, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x41, 0x4d, { 0x072, 3314, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x4e, 0x53, { 0x073, 1731, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x54, 0x5f, { 0x074, 2085, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x60, 0x6c, { 0x075, 1421, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }} +}; +static const YRW801_REGION_DATA regions_49[] = { + /* Flute */ + { 0x15, 0x40, { 0x071, 4803, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x41, 0x4d, { 0x072, 3314, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x4e, 0x6c, { 0x073, 1731, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }} +}; +static const YRW801_REGION_DATA regions_4a[] = { + /* Recorder */ + { 0x15, 0x6f, { 0x0bd, 4897, 100, 0, 0, 0x00, 0xec, 0x30, 0x70, 0x00, 0x09, 0x1 }} +}; +static const YRW801_REGION_DATA regions_4b[] = { + /* Pan Flute */ + { 0x15, 0x6c, { 0x077, 2359, 100, 0, 0, 0x00, 0xde, 0x38, 0xf0, 0x00, 0x09, 0x3 }} +}; +static const YRW801_REGION_DATA regions_4c[] = { + /* Bottle Blow */ + { 0x15, 0x6c, { 0x077, 2359, 100, 0, 0, 0x00, 0xc8, 0x38, 0xf0, 0x00, 0x09, 0x1 }}, + { 0x01, 0x7f, { 0x125, 7372, 100, 0, 0, 0x1e, 0x80, 0x00, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_4d[] = { + /* Shakuhachi */ + { 0x00, 0x7f, { 0x0ab, 4548, 100, 0, 0, 0x00, 0xd6, 0x30, 0xf0, 0x00, 0x0a, 0x3 }}, + { 0x15, 0x6c, { 0x076, 3716, 100, 0, 0, 0x00, 0xa2, 0x28, 0x70, 0x00, 0x09, 0x2 }} +}; +static const YRW801_REGION_DATA regions_4e[] = { + /* Whistle */ + { 0x00, 0x7f, { 0x0aa, 1731, 100, 0, 4, 0x00, 0xd2, 0x2c, 0x70, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_4f[] = { + /* Ocarina */ + { 0x00, 0x7f, { 0x0aa, 1731, 100, 0, 1, 0x00, 0xce, 0x29, 0x90, 0x00, 0x0a, 0x1 }} +}; +static const YRW801_REGION_DATA regions_50[] = { + /* Square Lead */ + { 0x01, 0x2a, { 0x0cc, 9853, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x2b, 0x36, { 0x0cd, 6785, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x37, 0x42, { 0x0ca, 5248, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x43, 0x4e, { 0x0cf, 3713, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x4f, 0x5a, { 0x0ce, 2176, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x5b, 0x7f, { 0x0cb, 640, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x01, 0x2a, { 0x0cc, 9844, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x2b, 0x36, { 0x0cd, 6776, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x37, 0x42, { 0x0ca, 5239, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x43, 0x4e, { 0x0cf, 3704, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x4f, 0x5a, { 0x0ce, 2167, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x5b, 0x7f, { 0x0cb, 631, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 } } +}; +static const YRW801_REGION_DATA regions_51[] = { + /* Sawtooth Lead */ + { 0x01, 0x27, { 0x118, 9108, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8345, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7570, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6809, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6047, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5282, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4525, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3746, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x52, 0x57, { 0x120, 3017, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2171, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1426, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x67, 0x7f, { 0x123, -110, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x01, 0x27, { 0x118, 9098, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8335, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7560, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6799, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6037, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5272, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4515, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3736, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x52, 0x57, { 0x120, 3007, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2161, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1416, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x67, 0x7f, { 0x123, -120, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_52[] = { + /* Calliope Lead */ + { 0x00, 0x7f, { 0x0aa, 1731, 100, 0, 0, 0x00, 0xc2, 0x28, 0x90, 0x00, 0x0a, 0x2 }}, + { 0x15, 0x6c, { 0x076, 3716, 100, 0, 0, 0x00, 0xb6, 0x28, 0xb0, 0x00, 0x09, 0x2 }} +}; +static const YRW801_REGION_DATA regions_53[] = { + /* Chiffer Lead */ + { 0x00, 0x7f, { 0x13a, 3665, 100, 0, 2, 0x00, 0xcc, 0x2a, 0xf0, 0x10, 0x09, 0x1 }}, + { 0x01, 0x7f, { 0x0fe, 3660, 100, 0, 0, 0x00, 0xbe, 0x28, 0xf3, 0x10, 0x17, 0x0 }} +}; +static const YRW801_REGION_DATA regions_54[] = { + /* Charang Lead */ + { 0x00, 0x40, { 0x0a5, 6594, 100, 0, 3, 0x00, 0xba, 0x33, 0xf2, 0x11, 0x09, 0x0 }}, + { 0x41, 0x7f, { 0x0a6, 5433, 100, 0, 3, 0x00, 0xba, 0x33, 0xf2, 0x11, 0x09, 0x0 }}, + { 0x01, 0x27, { 0x118, 9098, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8335, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7560, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6799, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6037, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5272, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4515, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3736, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x52, 0x57, { 0x120, 3007, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2161, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1416, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x67, 0x7f, { 0x123, -120, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }} +}; +static const YRW801_REGION_DATA regions_55[] = { + /* Voice Lead */ + { 0x00, 0x7f, { 0x0aa, 1739, 100, 0, 6, 0x00, 0x8c, 0x2e, 0x90, 0x00, 0x0a, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3474, 100, 0, 1, 0x00, 0xd8, 0x29, 0xf0, 0x05, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_56[] = { + /* 5ths Lead */ + { 0x01, 0x27, { 0x118, 8468, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x119, 7705, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 6930, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6169, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 5407, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x11d, 4642, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 3885, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3106, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x52, 0x57, { 0x120, 2377, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x58, 0x5d, { 0x121, 1531, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x5e, 0x64, { 0x122, 786, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 } }, + { 0x65, 0x7f, { 0x123, -750, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x05, 0x71, { 0x002, 4503, 100, 0, 1, 0x00, 0xb8, 0x31, 0xb3, 0x20, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_57[] = { + /* Bass & Lead */ + { 0x00, 0x7f, { 0x117, 8109, 100, 0, 1, 0x00, 0xbc, 0x29, 0xf3, 0x50, 0x08, 0x0 }}, + { 0x01, 0x27, { 0x118, 9097, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8334, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7559, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6798, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6036, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5271, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4514, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3735, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x52, 0x57, { 0x120, 3006, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2160, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1415, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x67, 0x7f, { 0x123, -121, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_58[] = { + /* New Age Pad */ + { 0x15, 0x6c, { 0x002, 4501, 100, 0, 4, 0x00, 0xa4, 0x24, 0x80, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x0f3, 4253, 100, 0, 3, 0x00, 0x8c, 0x23, 0xa2, 0x14, 0x06, 0x1 }} +}; +static const YRW801_REGION_DATA regions_59[] = { + /* Warm Pad */ + { 0x15, 0x6c, { 0x04e, 5306, 100, 2, 2, 0x00, 0x92, 0x2a, 0x34, 0x23, 0x05, 0x2 } }, + { 0x15, 0x6c, { 0x029, 3575, 100, -2, 2, 0x00, 0xbe, 0x22, 0x31, 0x23, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5a[] = { + /* Polysynth Pad */ + { 0x01, 0x27, { 0x118, 9111, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x28, 0x2d, { 0x119, 8348, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x2e, 0x33, { 0x11a, 7573, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x34, 0x39, { 0x11b, 6812, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x3a, 0x3f, { 0x11c, 6050, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x40, 0x45, { 0x11d, 5285, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x46, 0x4b, { 0x11e, 4528, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x4c, 0x51, { 0x11f, 3749, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x52, 0x57, { 0x120, 3020, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x58, 0x5d, { 0x121, 2174, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x5e, 0x66, { 0x122, 1429, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x67, 0x7f, { 0x123, -107, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x00, 0x7f, { 0x124, 4024, 100, 0, 2, 0x00, 0xae, 0x22, 0xe5, 0x20, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5b[] = { + /* Choir Pad */ + { 0x15, 0x3a, { 0x018, 5010, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x3b, 0x40, { 0x019, 4370, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x41, 0x47, { 0x01a, 3478, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x48, 0x6c, { 0x01b, 2197, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3482, 100, 0, 4, 0x00, 0x98, 0x24, 0x65, 0x21, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5c[] = { + /* Bowed Pad */ + { 0x15, 0x6c, { 0x101, 4790, 100, -1, 1, 0x00, 0xbe, 0x19, 0x44, 0x14, 0x16, 0x0 }}, + { 0x00, 0x7f, { 0x0aa, 1720, 100, 1, 1, 0x00, 0x94, 0x19, 0x40, 0x00, 0x06, 0x0 } } +}; +static const YRW801_REGION_DATA regions_5d[] = { + /* Metallic Pad */ + { 0x15, 0x31, { 0x00c, 6943, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x32, 0x38, { 0x00d, 5416, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x39, 0x47, { 0x00e, 4385, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x48, 0x6c, { 0x00f, 2849, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x00, 0x7f, { 0x03f, 4224, 100, 0, 1, 0x00, 0x9c, 0x31, 0x65, 0x16, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5e[] = { + /* Halo Pad */ + { 0x00, 0x7f, { 0x124, 4038, 100, 0, 2, 0x00, 0xa6, 0x1a, 0x85, 0x23, 0x08, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3471, 100, 0, 3, 0x00, 0xc0, 0x1b, 0xc0, 0x05, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5f[] = { + /* Sweep Pad */ + { 0x01, 0x27, { 0x0d3, 9100, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x28, 0x2d, { 0x0da, 8341, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x2e, 0x33, { 0x0d4, 7564, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x34, 0x39, { 0x0db, 6791, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x3a, 0x3f, { 0x0d5, 6048, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x40, 0x45, { 0x0dc, 5263, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x46, 0x4b, { 0x0d6, 4499, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x4c, 0x51, { 0x0dd, 3747, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x52, 0x57, { 0x0d7, 3018, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x58, 0x5d, { 0x0de, 2173, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x5e, 0x63, { 0x0d8, 1427, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x64, 0x7f, { 0x0d9, -109, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x01, 0x27, { 0x0d3, 9088, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x28, 0x2d, { 0x0da, 8329, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x2e, 0x33, { 0x0d4, 7552, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x34, 0x39, { 0x0db, 6779, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x3a, 0x3f, { 0x0d5, 6036, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x40, 0x45, { 0x0dc, 5251, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x46, 0x4b, { 0x0d6, 4487, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x4c, 0x51, { 0x0dd, 3735, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x52, 0x57, { 0x0d7, 3006, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x58, 0x5d, { 0x0de, 2161, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x5e, 0x63, { 0x0d8, 1415, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x64, 0x7f, { 0x0d9, -121, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_60[] = { + /* Ice Rain */ + { 0x01, 0x7f, { 0x04e, 9345, 100, 0, 2, 0x00, 0xcc, 0x22, 0xa3, 0x63, 0x17, 0x0 }}, + { 0x00, 0x7f, { 0x143, 5586, 20, 0, 2, 0x00, 0x6e, 0x2a, 0xf0, 0x05, 0x05, 0x0 } } +}; +static const YRW801_REGION_DATA regions_61[] = { + /* Soundtrack */ + { 0x15, 0x6c, { 0x002, 4501, 100, 0, 2, 0x00, 0xb6, 0x2a, 0x60, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x0f3, 1160, 100, 0, 5, 0x00, 0xa8, 0x2d, 0x52, 0x14, 0x06, 0x2 }} +}; +static const YRW801_REGION_DATA regions_62[] = { + /* Crystal */ + { 0x15, 0x6c, { 0x0f3, 1826, 100, 0, 3, 0x00, 0xb8, 0x33, 0xf6, 0x25, 0x25, 0x0 }}, + { 0x15, 0x2c, { 0x06d, 7454, 100, 0, 3, 0x00, 0xac, 0x3b, 0x85, 0x24, 0x06, 0x0 }}, + { 0x2d, 0x36, { 0x06e, 5925, 100, 0, 3, 0x00, 0xac, 0x3b, 0x85, 0x24, 0x06, 0x0 }}, + { 0x37, 0x6c, { 0x06f, 4403, 100, 0, 3, 0x09, 0xac, 0x3b, 0x85, 0x24, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_63[] = { + /* Atmosphere */ + { 0x05, 0x71, { 0x002, 4509, 100, 0, 2, 0x00, 0xc8, 0x32, 0x73, 0x22, 0x06, 0x1 }}, + { 0x15, 0x2f, { 0x0b3, 6964, 100, 0, 2, 0x05, 0xc2, 0x32, 0xf5, 0x34, 0x07, 0x2 }}, + { 0x30, 0x36, { 0x0b7, 5567, 100, 0, 2, 0x0c, 0xc2, 0x32, 0xf5, 0x34, 0x07, 0x2 }}, + { 0x37, 0x3c, { 0x0b5, 4653, 100, 0, 2, 0x00, 0xc2, 0x32, 0xf6, 0x34, 0x07, 0x2 }}, + { 0x3d, 0x43, { 0x0b4, 3892, 100, 0, 2, 0x00, 0xc2, 0x32, 0xf6, 0x35, 0x07, 0x2 }}, + { 0x44, 0x60, { 0x0b6, 2723, 100, 0, 2, 0x00, 0xc2, 0x32, 0xf6, 0x35, 0x17, 0x2 }} +}; +static const YRW801_REGION_DATA regions_64[] = { + /* Brightness */ + { 0x00, 0x7f, { 0x137, 5285, 100, 0, 2, 0x00, 0xbe, 0x2a, 0xa5, 0x18, 0x08, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3481, 100, 0, 1, 0x00, 0xc8, 0x29, 0x80, 0x05, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_65[] = { + /* Goblins */ + { 0x15, 0x6c, { 0x002, 4501, 100, -1, 2, 0x00, 0xca, 0x2a, 0x40, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x009, 9679, 20, 1, 4, 0x00, 0x3c, 0x0c, 0x22, 0x11, 0x06, 0x0 } } +}; +static const YRW801_REGION_DATA regions_66[] = { + /* Echoes */ + { 0x15, 0x6c, { 0x02a, 3487, 100, 0, 3, 0x00, 0xae, 0x2b, 0xf5, 0x21, 0x06, 0x0 }}, + { 0x00, 0x7f, { 0x124, 4027, 100, 0, 3, 0x00, 0xae, 0x2b, 0x85, 0x23, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_67[] = { + /* Sci-Fi */ + { 0x15, 0x31, { 0x00c, 6940, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x32, 0x38, { 0x00d, 5413, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x39, 0x47, { 0x00e, 4382, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x48, 0x6c, { 0x00f, 2846, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x15, 0x6c, { 0x002, 4498, 100, 0, 2, 0x00, 0xd4, 0x22, 0x80, 0x01, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_68[] = { + /* Sitar */ + { 0x00, 0x7f, { 0x10f, 4408, 100, 0, 2, 0x00, 0xc4, 0x32, 0xf4, 0x15, 0x16, 0x1 }} +}; +static const YRW801_REGION_DATA regions_69[] = { + /* Banjo */ + { 0x15, 0x34, { 0x013, 5685, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x35, 0x38, { 0x014, 5009, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x39, 0x3c, { 0x012, 4520, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x3d, 0x44, { 0x015, 3622, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x45, 0x4c, { 0x017, 2661, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x4d, 0x6d, { 0x016, 1632, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6a[] = { + /* Shamisen */ + { 0x15, 0x6c, { 0x10e, 3273, 100, 0, 0, 0x00, 0xc0, 0x28, 0xf7, 0x76, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6b[] = { + /* Koto */ + { 0x00, 0x7f, { 0x0a9, 4033, 100, 0, 0, 0x00, 0xc6, 0x20, 0xf0, 0x06, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6c[] = { + /* Kalimba */ + { 0x00, 0x7f, { 0x137, 3749, 100, 0, 0, 0x00, 0xce, 0x38, 0xf5, 0x18, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6d[] = { + /* Bagpipe */ + { 0x15, 0x39, { 0x0a4, 7683, 100, 0, 4, 0x00, 0xc0, 0x1c, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x15, 0x39, { 0x0a7, 7680, 100, 0, 1, 0x00, 0xaa, 0x19, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3a, 0x6c, { 0x0a8, 3697, 100, 0, 1, 0x00, 0xaa, 0x19, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6e[] = { + /* Fiddle */ + { 0x15, 0x3a, { 0x105, 5158, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x3b, 0x3f, { 0x102, 4754, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x40, 0x41, { 0x106, 4132, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x42, 0x44, { 0x107, 4033, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x45, 0x47, { 0x108, 3580, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x48, 0x4a, { 0x10a, 2957, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4b, 0x4c, { 0x10b, 2724, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4d, 0x4e, { 0x10c, 2530, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4f, 0x51, { 0x10d, 2166, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x52, 0x6c, { 0x109, 1825, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6f[] = { + /* Shanai */ + { 0x15, 0x6c, { 0x041, 6946, 100, 0, 1, 0x00, 0xc4, 0x31, 0x95, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_70[] = { + /* Tinkle Bell */ + { 0x15, 0x73, { 0x0f3, 1821, 100, 0, 3, 0x00, 0xc8, 0x3b, 0xd6, 0x25, 0x25, 0x0 }}, + { 0x00, 0x7f, { 0x137, 5669, 100, 0, 3, 0x00, 0x66, 0x3b, 0xf5, 0x18, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_71[] = { + /* Agogo */ + { 0x15, 0x74, { 0x00b, 2474, 100, 0, 0, 0x00, 0xd2, 0x38, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_72[] = { + /* Steel Drums */ + { 0x01, 0x7f, { 0x0fe, 3670, 100, 0, 0, 0x00, 0xca, 0x38, 0xf3, 0x06, 0x17, 0x1 }}, + { 0x15, 0x6c, { 0x100, 9602, 100, 0, 0, 0x00, 0x54, 0x38, 0xb0, 0x05, 0x16, 0x1 }} +}; +static const YRW801_REGION_DATA regions_73[] = { + /* Woodblock */ + { 0x15, 0x6c, { 0x02c, 2963, 50, 0, 0, 0x07, 0xd4, 0x00, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_74[] = { + /* Taiko Drum */ + { 0x13, 0x6c, { 0x03e, 1194, 50, 0, 0, 0x00, 0xaa, 0x38, 0xf0, 0x04, 0x04, 0x0 }} +}; +static const YRW801_REGION_DATA regions_75[] = { + /* Melodic Tom */ + { 0x15, 0x6c, { 0x0c7, 6418, 50, 0, 0, 0x00, 0xe4, 0x38, 0xf0, 0x05, 0x01, 0x0 }} +}; +static const YRW801_REGION_DATA regions_76[] = { + /* Synth Drum */ + { 0x15, 0x6c, { 0x026, 3898, 50, 0, 0, 0x00, 0xd0, 0x38, 0xf0, 0x04, 0x04, 0x0 }} +}; +static const YRW801_REGION_DATA regions_77[] = { + /* Reverse Cymbal */ + { 0x15, 0x6c, { 0x031, 4138, 50, 0, 0, 0x00, 0xfe, 0x38, 0x3a, 0xf0, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_78[] = { + /* Guitar Fret Noise */ + { 0x15, 0x6c, { 0x138, 5266, 100, 0, 0, 0x00, 0xa0, 0x38, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_79[] = { + /* Breath Noise */ + { 0x01, 0x7f, { 0x125, 4269, 100, 0, 0, 0x1e, 0xd0, 0x38, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_7a[] = { + /* Seashore */ + { 0x15, 0x6c, { 0x008, 2965, 20, -2, 0, 0x00, 0xfe, 0x00, 0x20, 0x03, 0x04, 0x0 }}, + { 0x01, 0x7f, { 0x037, 4394, 20, 2, 0, 0x14, 0xfe, 0x00, 0x20, 0x04, 0x05, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7b[] = { + /* Bird Tweet */ + { 0x15, 0x6c, { 0x009, 8078, 5, -4, 7, 0x00, 0xc2, 0x0f, 0x22, 0x12, 0x07, 0x0 }}, + { 0x15, 0x6c, { 0x009, 3583, 5, 4, 5, 0x00, 0xae, 0x15, 0x72, 0x12, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7c[] = { + /* Telephone Ring */ + { 0x15, 0x6c, { 0x003, 3602, 10, 0, 0, 0x00, 0xce, 0x00, 0xf0, 0x00, 0x0f, 0x0 }} +}; +static const YRW801_REGION_DATA regions_7d[] = { + /* Helicopter */ + { 0x0c, 0x7f, { 0x001, 2965, 10, -2, 0, 0x00, 0xe0, 0x08, 0x30, 0x01, 0x07, 0x0 }}, + { 0x01, 0x7f, { 0x037, 4394, 10, 2, 0, 0x44, 0x76, 0x00, 0x30, 0x01, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7e[] = { + /* Applause */ + { 0x15, 0x6c, { 0x036, 8273, 20, -6, 7, 0x00, 0xc4, 0x0f, 0x70, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x036, 8115, 5, 6, 7, 0x00, 0xc6, 0x07, 0x70, 0x01, 0x05, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7f[] = { + /* Gun Shot */ + { 0x15, 0x6c, { 0x139, 2858, 20, 0, 0, 0x00, 0xbe, 0x38, 0xf0, 0x03, 0x00, 0x0 }} +}; +static const YRW801_REGION_DATA regions_drums[] = { + { 0x18, 0x18, { 0x0cb, 6397, 100, 3, 0, 0x00, 0xf4, 0x38, 0xc9, 0x1c, 0x0c, 0x0 } }, + { 0x19, 0x19, { 0x0c4, 3714, 100, 0, 0, 0x00, 0xe0, 0x00, 0x97, 0x19, 0x09, 0x0 } }, + { 0x1a, 0x1a, { 0x0c4, 3519, 100, 0, 0, 0x00, 0xea, 0x00, 0x61, 0x01, 0x07, 0x0 } }, + { 0x1b, 0x1b, { 0x0c4, 3586, 100, 0, 0, 0x00, 0xea, 0x00, 0xf7, 0x19, 0x09, 0x0 } }, + { 0x1c, 0x1c, { 0x0c4, 3586, 100, 0, 0, 0x00, 0xea, 0x00, 0x81, 0x01, 0x07, 0x0 } }, + { 0x1e, 0x1e, { 0x0c3, 4783, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x1f, 0x1f, { 0x0d1, 4042, 100, 0, 0, 0x00, 0xd6, 0x00, 0xf0, 0x05, 0x05, 0x0 } }, + { 0x20, 0x20, { 0x0d2, 5943, 100, 0, 0, 0x00, 0xcc, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x21, 0x21, { 0x011, 3842, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x16, 0x06, 0x0 } }, + { 0x23, 0x23, { 0x011, 4098, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x16, 0x06, 0x0 } }, + { 0x24, 0x24, { 0x011, 4370, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x06, 0x0 } }, + { 0x25, 0x25, { 0x0d2, 4404, 100, 0, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x06, 0x0 } }, + { 0x26, 0x26, { 0x0d1, 4298, 100, 0, 0, 0x00, 0xd6, 0x00, 0xf0, 0x05, 0x05, 0x0 } }, + { 0x27, 0x27, { 0x00a, 4403, 100, -1, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x28, 0x28, { 0x0d1, 4554, 100, 0, 0, 0x00, 0xdc, 0x00, 0xf0, 0x07, 0x07, 0x0 } }, + { 0x29, 0x29, { 0x0c8, 4242, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf6, 0x16, 0x06, 0x0 }}, + { 0x2a, 0x2a, { 0x079, 6160, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf5, 0x19, 0x09, 0x0 } }, + { 0x2b, 0x2b, { 0x0c8, 4626, 100, -3, 0, 0x00, 0xd6, 0x00, 0xf6, 0x16, 0x06, 0x0 }}, + { 0x2c, 0x2c, { 0x07b, 6039, 100, 2, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x2d, 0x2d, { 0x0c8, 5394, 100, -2, 0, 0x00, 0xd6, 0x00, 0xf6, 0x16, 0x06, 0x0 }}, + { 0x2e, 0x2e, { 0x07a, 5690, 100, 2, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x05, 0x0 } }, + { 0x2f, 0x2f, { 0x0c7, 5185, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf6, 0x17, 0x07, 0x0 } }, + { 0x30, 0x30, { 0x0c7, 5650, 100, 3, 0, 0x00, 0xe0, 0x00, 0xf6, 0x17, 0x07, 0x0 } }, + { 0x31, 0x31, { 0x031, 4395, 100, 2, 0, 0x00, 0xea, 0x00, 0xf0, 0x05, 0x05, 0x0 } }, + { 0x32, 0x32, { 0x0c7, 6162, 100, 4, 0, 0x00, 0xe0, 0x00, 0xf6, 0x17, 0x07, 0x0 } }, + { 0x33, 0x33, { 0x02e, 4391, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x05, 0x05, 0x0 }}, + { 0x34, 0x34, { 0x07a, 3009, 100, -2, 0, 0x00, 0xea, 0x00, 0xf2, 0x15, 0x05, 0x0 }}, + { 0x35, 0x35, { 0x021, 4522, 100, -3, 0, 0x00, 0xd6, 0x00, 0xf0, 0x05, 0x05, 0x0 }}, + { 0x36, 0x36, { 0x025, 5163, 100, 1, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x37, 0x37, { 0x031, 5287, 100, -1, 0, 0x00, 0xea, 0x00, 0xf5, 0x16, 0x06, 0x0 }}, + { 0x38, 0x38, { 0x01d, 4395, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x39, 0x39, { 0x031, 4647, 100, -2, 0, 0x00, 0xea, 0x00, 0xf4, 0x16, 0x06, 0x0 }}, + { 0x3a, 0x3a, { 0x09d, 4426, 100, -4, 0, 0x00, 0xe0, 0x00, 0xf4, 0x17, 0x07, 0x0 }}, + { 0x3b, 0x3b, { 0x02e, 4659, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x06, 0x06, 0x0 }}, + { 0x3c, 0x3c, { 0x01c, 4769, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x3d, 0x3d, { 0x01c, 4611, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x3e, 0x3e, { 0x01e, 4402, 100, -3, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3f, 0x3f, { 0x01f, 4387, 100, -3, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x40, 0x40, { 0x01f, 3983, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x41, 0x41, { 0x09c, 4526, 100, 2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x42, 0x42, { 0x09c, 4016, 100, 2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x43, 0x43, { 0x00b, 4739, 100, -4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x44, 0x44, { 0x00b, 4179, 100, -4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x45, 0x45, { 0x02f, 4787, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x46, 0x46, { 0x030, 4665, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x47, 0x47, { 0x144, 4519, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x0b, 0x0 } }, + { 0x48, 0x48, { 0x144, 4111, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x0b, 0x0 } }, + { 0x49, 0x49, { 0x024, 6408, 100, 3, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4a, 0x4a, { 0x024, 4144, 100, 3, 0, 0x00, 0xcc, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4b, 0x4b, { 0x020, 4001, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4c, 0x4c, { 0x02c, 4402, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4d, 0x4d, { 0x02c, 3612, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4e, 0x4e, { 0x022, 4129, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x4f, 0x4f, { 0x023, 4147, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x50, 0x50, { 0x032, 4412, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x08, 0x09, 0x0 }}, + { 0x51, 0x51, { 0x032, 4385, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x52, 0x52, { 0x02f, 5935, 100, -1, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }} +}; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#define REGION(num) \ + { \ + ARRAY_SIZE(regions##num), regions##num \ + } +const YRW801_REGION_DATA_PTR snd_yrw801_regions[0x81] = { + REGION(_00), REGION(_01), REGION(_02), REGION(_03), + REGION(_04), REGION(_05), REGION(_06), REGION(_07), + REGION(_08), REGION(_09), REGION(_0a), REGION(_0b), + REGION(_0c), REGION(_0d), REGION(_0e), REGION(_0f), + REGION(_10), REGION(_11), REGION(_12), REGION(_13), + REGION(_14), REGION(_15), REGION(_16), REGION(_17), + REGION(_18), REGION(_19), REGION(_1a), REGION(_1b), + REGION(_1c), REGION(_1d), REGION(_1e), REGION(_1f), + REGION(_20), REGION(_21), REGION(_22), REGION(_23), + REGION(_24), REGION(_25), REGION(_26), REGION(_27), + REGION(_28), REGION(_29), REGION(_2a), REGION(_2b), + REGION(_2c), REGION(_2d), REGION(_2e), REGION(_2f), + REGION(_30), REGION(_31), REGION(_32), REGION(_33), + REGION(_34), REGION(_35), REGION(_36), REGION(_37), + REGION(_38), REGION(_39), REGION(_3a), REGION(_3b), + REGION(_3c), REGION(_3d), REGION(_3e), REGION(_3f), + REGION(_40), REGION(_41), REGION(_42), REGION(_43), + REGION(_44), REGION(_45), REGION(_46), REGION(_47), + REGION(_48), REGION(_49), REGION(_4a), REGION(_4b), + REGION(_4c), REGION(_4d), REGION(_4e), REGION(_4f), + REGION(_50), REGION(_51), REGION(_52), REGION(_53), + REGION(_54), REGION(_55), REGION(_56), REGION(_57), + REGION(_58), REGION(_59), REGION(_5a), REGION(_5b), + REGION(_5c), REGION(_5d), REGION(_5e), REGION(_5f), + REGION(_60), REGION(_61), REGION(_62), REGION(_63), + REGION(_64), REGION(_65), REGION(_66), REGION(_67), + REGION(_68), REGION(_69), REGION(_6a), REGION(_6b), + REGION(_6c), REGION(_6d), REGION(_6e), REGION(_6f), + REGION(_70), REGION(_71), REGION(_72), REGION(_73), + REGION(_74), REGION(_75), REGION(_76), REGION(_77), + REGION(_78), REGION(_79), REGION(_7a), REGION(_7b), + REGION(_7c), REGION(_7d), REGION(_7e), REGION(_7f), + REGION(_drums) +}; \ No newline at end of file diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index 3c0d22131..ee761e627 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -1622,4 +1622,5 @@ const fm_drv_t nuked_opl_drv = { &nuked_drv_reset_buffer, &nuked_drv_set_do_cycles, NULL, + NULL, }; \ No newline at end of file diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index bb52f3c55..b2466dcb5 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -368,6 +368,13 @@ ymfm_drv_set_do_cycles(void *priv, int8_t do_cycles) drv->set_do_cycles(do_cycles); } +static void +ymfm_drv_generate(void *priv, int32_t *data, uint32_t num_samples) +{ + YMFMChipBase *drv = (YMFMChipBase *) priv; + drv->generate_resampled(data, num_samples); +} + const device_t ym3812_ymfm_device = { .name = "Yamaha YM3812 OPL2 (YMFM)", .internal_name = "ym3812_ymfm", @@ -431,5 +438,6 @@ const fm_drv_t ymfm_drv { &ymfm_drv_reset_buffer, &ymfm_drv_set_do_cycles, NULL, + ymfm_drv_generate, }; } diff --git a/src/sound/yrw801.h b/src/sound/yrw801.h new file mode 100644 index 000000000..0df3c0343 --- /dev/null +++ b/src/sound/yrw801.h @@ -0,0 +1,45 @@ +/* + * RoboPlay for MSX + * Copyright (C) 2022 by RoboSoft Inc. + * + * yrw801.h + */ + +/* Cacodemon345: Added pointer structs from Linux */ + +#pragma once + +#include + +typedef struct +{ + uint16_t tone; + int16_t pitch_offset; + uint8_t key_scaling; + int8_t panpot; + uint8_t vibrato; + uint8_t tone_attenuate; + uint8_t volume_factor; + uint8_t reg_lfo_vibrato; + uint8_t reg_attack_decay1; + uint8_t reg_level_decay2; + uint8_t reg_release_correction; + uint8_t reg_tremolo; +} YRW801_WAVE_DATA; + +typedef struct +{ + uint8_t key_min; + uint8_t key_max; + + YRW801_WAVE_DATA wave_data; +} YRW801_REGION_DATA; + +typedef struct +{ + int count; + + const YRW801_REGION_DATA* regions; +} YRW801_REGION_DATA_PTR; + +extern const YRW801_REGION_DATA_PTR snd_yrw801_regions[0x81]; \ No newline at end of file From 9df45dba0f8aaef9b3e52148f86bb59ed34ae8b4 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Nov 2022 21:24:17 +0600 Subject: [PATCH 2/8] Fix OPL4 audio crackling --- src/sound/midi_opl4.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c index f816cff49..b75ac23b5 100644 --- a/src/sound/midi_opl4.c +++ b/src/sound/midi_opl4.c @@ -269,12 +269,15 @@ static const uint8_t g_volume_table[128] = { 2, 2, 2, 1, 1, 0, 0, 0 }; +#define BUFFER_SEGMENTS 10 +#define RENDER_RATE (48000 / 100) + typedef struct opl4_midi { fm_drv_t opl4; MIDI_CHANNEL_DATA midi_channel_data[16]; VOICE_DATA voice_data[24]; - int16_t buffer[SOUNDBUFLEN * 2]; - float buffer_float[SOUNDBUFLEN * 2]; + int16_t buffer[(48000 / 100) * 2 * BUFFER_SEGMENTS]; + float buffer_float[(48000 / 100) * 2 * BUFFER_SEGMENTS]; uint32_t midi_pos; bool on; atomic_bool gen_in_progress; @@ -537,13 +540,14 @@ program_change(uint8_t midi_channel, uint8_t program, opl4_midi_t *opl4_midi) opl4_midi->midi_channel_data[midi_channel].instrument = program; } -#define RENDER_RATE (48000 / 100) static void opl4_midi_thread(void *arg) { opl4_midi_t *opl4_midi = opl4_midi_cur; uint32_t i = 0; uint32_t buf_size = RENDER_RATE * 2; + uint32_t buf_size_segments = buf_size * BUFFER_SEGMENTS; + uint32_t buf_pos = 0; int32_t buffer[RENDER_RATE * 2]; @@ -558,16 +562,24 @@ opl4_midi_thread(void *arg) atomic_store(&opl4_midi->gen_in_progress, false); if (sound_is_float) { for (i = 0; i < (buf_size / 2); i++) { - opl4_midi->buffer_float[i * 2] = buffer[i * 2] / 32768.0; - opl4_midi->buffer_float[(i * 2) + 1] = buffer[(i * 2) + 1] / 32768.0; + opl4_midi->buffer_float[(i + buf_pos) * 2] = buffer[i * 2] / 32768.0; + opl4_midi->buffer_float[((i + buf_pos) * 2) + 1] = buffer[(i * 2) + 1] / 32768.0; + } + buf_pos += buf_size / 2; + if (buf_pos >= (buf_size_segments / 2)) { + givealbuffer_midi(opl4_midi->buffer_float, buf_size_segments); + buf_pos = 0; } - givealbuffer_midi(opl4_midi->buffer_float, buf_size); } else { for (i = 0; i < (buf_size / 2); i++) { - opl4_midi->buffer[i * 2] = buffer[i * 2] & 0xFFFF; /* Outputs are clamped beforehand. */ - opl4_midi->buffer[(i * 2) + 1] = buffer[(i * 2) + 1] & 0xFFFF; /* Outputs are clamped beforehand. */ + opl4_midi->buffer[(i + buf_pos) * 2] = buffer[i * 2] & 0xFFFF; /* Outputs are clamped beforehand. */ + opl4_midi->buffer[((i + buf_pos) * 2) + 1] = buffer[(i * 2) + 1] & 0xFFFF; /* Outputs are clamped beforehand. */ + } + buf_pos += buf_size / 2; + if (buf_pos >= (buf_size_segments / 2)) { + givealbuffer_midi(opl4_midi->buffer, buf_size_segments); + buf_pos = 0; } - givealbuffer_midi(opl4_midi->buffer, buf_size); } } } From ca6ebbec72e4790185e34172c9a81f3963a36138 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Nov 2022 21:35:08 +0600 Subject: [PATCH 3/8] OPL4 activation timestamp now comes from platform timestamp --- src/sound/midi_opl4.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c index b75ac23b5..5a4480835 100644 --- a/src/sound/midi_opl4.c +++ b/src/sound/midi_opl4.c @@ -270,7 +270,7 @@ static const uint8_t g_volume_table[128] = { }; #define BUFFER_SEGMENTS 10 -#define RENDER_RATE (48000 / 100) +#define RENDER_RATE (48000 / 100) typedef struct opl4_midi { fm_drv_t opl4; @@ -419,8 +419,7 @@ note_on(uint8_t note, uint8_t velocity, MIDI_CHANNEL_DATA *midi_channel, opl4_mi const YRW801_WAVE_DATA *wave_data[2]; VOICE_DATA *voice[2]; uint8_t i = 0, voices = 0; - uint32_t j = 0; - static uint64_t activation_num = 0; + uint32_t j = 0; while (opl4_midi->gen_in_progress) { } @@ -444,7 +443,7 @@ note_on(uint8_t note, uint8_t velocity, MIDI_CHANNEL_DATA *midi_channel, opl4_mi for (i = 0; i < voices; i++) { voice[i] = get_voice(wave_data[i], opl4_midi); voice[i]->is_active = true; - voice[i]->activated = activation_num++; + voice[i]->activated = plat_get_ticks(); voice[i]->midi_channel = midi_channel; voice[i]->note = note; @@ -543,11 +542,11 @@ program_change(uint8_t midi_channel, uint8_t program, opl4_midi_t *opl4_midi) static void opl4_midi_thread(void *arg) { - opl4_midi_t *opl4_midi = opl4_midi_cur; - uint32_t i = 0; - uint32_t buf_size = RENDER_RATE * 2; + opl4_midi_t *opl4_midi = opl4_midi_cur; + uint32_t i = 0; + uint32_t buf_size = RENDER_RATE * 2; uint32_t buf_size_segments = buf_size * BUFFER_SEGMENTS; - uint32_t buf_pos = 0; + uint32_t buf_pos = 0; int32_t buffer[RENDER_RATE * 2]; From facdbfaef6aabfe0d6bfc154ca3079e351b3df5e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Nov 2022 16:11:46 +0600 Subject: [PATCH 4/8] Add OPL4-ML daughterboard emulation --- src/include/86box/midi.h | 1 + src/include/86box/opl4_defines.h | 101 +++ src/include/86box/snd_opl.h | 1 + src/sound/CMakeLists.txt | 2 +- src/sound/midi.c | 1 + src/sound/midi_opl4.c | 703 ++++++++++++++++++++ src/sound/midi_opl4_yrw801.c | 1042 ++++++++++++++++++++++++++++++ src/sound/snd_opl_nuked.c | 1 + src/sound/snd_opl_ymfm.cpp | 8 + src/sound/yrw801.h | 45 ++ 10 files changed, 1904 insertions(+), 1 deletion(-) create mode 100644 src/include/86box/opl4_defines.h create mode 100644 src/sound/midi_opl4.c create mode 100644 src/sound/midi_opl4_yrw801.c create mode 100644 src/sound/yrw801.h diff --git a/src/include/86box/midi.h b/src/include/86box/midi.h index e2b8c2626..9f3a81581 100644 --- a/src/include/86box/midi.h +++ b/src/include/86box/midi.h @@ -92,6 +92,7 @@ extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #ifdef EMU_DEVICE_H extern const device_t rtmidi_output_device; extern const device_t rtmidi_input_device; +extern const device_t opl4_midi_device; # ifdef USE_FLUIDSYNTH extern const device_t fluidsynth_device; # endif diff --git a/src/include/86box/opl4_defines.h b/src/include/86box/opl4_defines.h new file mode 100644 index 000000000..248b1f729 --- /dev/null +++ b/src/include/86box/opl4_defines.h @@ -0,0 +1,101 @@ +/* + * RoboPlay for MSX + * Copyright (C) 2020 by RoboSoft Inc. + * + * opl4_defines.h + * + */ + +#ifndef __OPL4_DEFINES_H +#define __OPL4_DEFINES_H + +/* + * Register numbers + */ + +#define OPL4_REG_TEST0 0x00 +#define OPL4_REG_TEST1 0x01 + +#define OPL4_REG_MEMORY_CONFIGURATION 0x02 +#define OPL4_MODE_BIT 0x01 +#define OPL4_MTYPE_BIT 0x02 +#define OPL4_TONE_HEADER_MASK 0x1C +#define OPL4_DEVICE_ID_MASK 0xE0 + +#define OPL4_REG_MEMORY_ADDRESS_HIGH 0x03 +#define OPL4_REG_MEMORY_ADDRESS_MID 0x04 +#define OPL4_REG_MEMORY_ADDRESS_LOW 0x05 +#define OPL4_REG_MEMORY_DATA 0x06 + +/* + * Offsets to the register banks for voices. To get the + * register number just add the voice number to the bank offset. + * + * Wave Table Number low bits (0x08 to 0x1F) + */ +#define OPL4_REG_TONE_NUMBER 0x08 + +/* Wave Table Number high bit, F-Number low bits (0x20 to 0x37) */ +#define OPL4_REG_F_NUMBER 0x20 +#define OPL4_TONE_NUMBER_BIT8 0x01 +#define OPL4_F_NUMBER_LOW_MASK 0xFE + +/* F-Number high bits, Octave, Pseudo-Reverb (0x38 to 0x4F) */ +#define OPL4_REG_OCTAVE 0x38 +#define OPL4_F_NUMBER_HIGH_MASK 0x07 +#define OPL4_BLOCK_MASK 0xF0 +#define OPL4_PSEUDO_REVERB_BIT 0x08 + +/* Total Level, Level Direct (0x50 to 0x67) */ +#define OPL4_REG_LEVEL 0x50 +#define OPL4_TOTAL_LEVEL_MASK 0xFE +#define OPL4_LEVEL_DIRECT_BIT 0x01 + +/* Key On, Damp, LFO RST, CH, Panpot (0x68 to 0x7F) */ +#define OPL4_REG_MISC 0x68 +#define OPL4_KEY_ON_BIT 0x80 +#define OPL4_DAMP_BIT 0x40 +#define OPL4_LFO_RESET_BIT 0x20 +#define OPL4_OUTPUT_CHANNEL_BIT 0x10 +#define OPL4_PAN_POT_MASK 0x0F + +/* LFO, VIB (0x80 to 0x97) */ +#define OPL4_REG_LFO_VIBRATO 0x80 +#define OPL4_LFO_FREQUENCY_MASK 0x38 +#define OPL4_VIBRATO_DEPTH_MASK 0x07 +#define OPL4_CHORUS_SEND_MASK 0xC0 + +/* Attack / Decay 1 rate (0x98 to 0xAF) */ +#define OPL4_REG_ATTACK_DECAY1 0x98 +#define OPL4_ATTACK_RATE_MASK 0xF0 +#define OPL4_DECAY1_RATE_MASK 0x0F + +/* Decay level / 2 rate (0xB0 to 0xC7) */ +#define OPL4_REG_LEVEL_DECAY2 0xB0 +#define OPL4_DECAY_LEVEL_MASK 0xF0 +#define OPL4_DECAY2_RATE_MASK 0x0F + +/* Release rate / Rate correction (0xC8 to 0xDF) */ +#define OPL4_REG_RELEASE_CORRECTION 0xC8 +#define OPL4_RELEASE_RATE_MASK 0x0F +#define OPL4_RATE_INTERPOLATION_MASK 0xF0 + +/* AM (0xE0 to 0xF7) */ +#define OPL4_REG_TREMOLO 0xE0 +#define OPL4_TREMOLO_DEPTH_MASK 0x07 +#define OPL4_REVERB_SEND_MASK 0xE0 + +/* Mixer */ +#define OPL4_REG_MIX_CONTROL_FM 0xF8 +#define OPL4_REG_MIX_CONTROL_PCM 0xF9 +#define OPL4_MIX_LEFT_MASK 0x07 +#define OPL4_MIX_RIGHT_MASK 0x38 + +#define OPL4_REG_ATC 0xFA +#define OPL4_ATC_BIT 0x01 + +/* Bits in the OPL4 Status register */ +#define OPL4_STATUS_BUSY 0x01 +#define OPL4_STATUS_LOAD 0x02 + +#endif /* __OPL4_DEFINES_H */ diff --git a/src/include/86box/snd_opl.h b/src/include/86box/snd_opl.h index 5caccf8fc..3b84a837b 100644 --- a/src/include/86box/snd_opl.h +++ b/src/include/86box/snd_opl.h @@ -38,6 +38,7 @@ typedef struct { void (*reset_buffer)(void *priv); void (*set_do_cycles)(void *priv, int8_t do_cycles); void *priv; + void (*generate)(void *priv, int32_t *data, uint32_t num_samples); /* daughterboard only. */ } fm_drv_t; extern uint8_t fm_driver_get(int chip_id, fm_drv_t *drv); diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 66672d547..7024bc5fc 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c) + snd_optimc.c midi_opl4.c midi_opl4_yrw801.c) if(OPENAL) if(VCPKG_TOOLCHAIN) diff --git a/src/sound/midi.c b/src/sound/midi.c index 93fa62891..c58342648 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -100,6 +100,7 @@ static const MIDI_OUT_DEVICE devices[] = { #ifdef USE_RTMIDI { &rtmidi_output_device }, #endif + { &opl4_midi_device }, { NULL } // clang-format on }; diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c new file mode 100644 index 000000000..f816cff49 --- /dev/null +++ b/src/sound/midi_opl4.c @@ -0,0 +1,703 @@ +// Based off ROBOPLAY's OPL4 MID player code, with some fixes and modifications to make it work well. + +#include +#include +#include +#include +#include +#include +#include + +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/midi.h> +#include <86box/plat.h> +#include <86box/thread.h> +#include <86box/rom.h> +#include <86box/sound.h> +#include <86box/ui.h> +#include <86box/snd_opl.h> +#include <86box/opl4_defines.h> + +#include "yrw801.h" + +#define NR_OF_MIDI_CHANNELS 16 +#define NR_OF_WAVE_CHANNELS 24 + +#define DRUM_CHANNEL 9 + +typedef struct +{ + uint8_t instrument; + uint8_t panpot; + uint8_t vibrato; + bool drum_channel; +} MIDI_CHANNEL_DATA; + +typedef struct +{ + bool is_active; + uint64_t activated; + + uint8_t number; + MIDI_CHANNEL_DATA *midi_channel; + uint8_t note; + uint8_t velocity; + const YRW801_WAVE_DATA *wave_data; + uint8_t level_direct; + uint8_t reg_f_number; + uint8_t reg_misc; + uint8_t reg_lfo_vibrato; +} VOICE_DATA; + +static const int16_t g_wave_pitch_map[0x600] = { + 0x000, 0x000, 0x001, 0x001, 0x002, 0x002, 0x003, 0x003, + 0x004, 0x004, 0x005, 0x005, 0x006, 0x006, 0x006, 0x007, + 0x007, 0x008, 0x008, 0x009, 0x009, 0x00a, 0x00a, 0x00b, + 0x00b, 0x00c, 0x00c, 0x00d, 0x00d, 0x00d, 0x00e, 0x00e, + 0x00f, 0x00f, 0x010, 0x010, 0x011, 0x011, 0x012, 0x012, + 0x013, 0x013, 0x014, 0x014, 0x015, 0x015, 0x015, 0x016, + 0x016, 0x017, 0x017, 0x018, 0x018, 0x019, 0x019, 0x01a, + 0x01a, 0x01b, 0x01b, 0x01c, 0x01c, 0x01d, 0x01d, 0x01e, + 0x01e, 0x01e, 0x01f, 0x01f, 0x020, 0x020, 0x021, 0x021, + 0x022, 0x022, 0x023, 0x023, 0x024, 0x024, 0x025, 0x025, + 0x026, 0x026, 0x027, 0x027, 0x028, 0x028, 0x029, 0x029, + 0x029, 0x02a, 0x02a, 0x02b, 0x02b, 0x02c, 0x02c, 0x02d, + 0x02d, 0x02e, 0x02e, 0x02f, 0x02f, 0x030, 0x030, 0x031, + 0x031, 0x032, 0x032, 0x033, 0x033, 0x034, 0x034, 0x035, + 0x035, 0x036, 0x036, 0x037, 0x037, 0x038, 0x038, 0x038, + 0x039, 0x039, 0x03a, 0x03a, 0x03b, 0x03b, 0x03c, 0x03c, + 0x03d, 0x03d, 0x03e, 0x03e, 0x03f, 0x03f, 0x040, 0x040, + 0x041, 0x041, 0x042, 0x042, 0x043, 0x043, 0x044, 0x044, + 0x045, 0x045, 0x046, 0x046, 0x047, 0x047, 0x048, 0x048, + 0x049, 0x049, 0x04a, 0x04a, 0x04b, 0x04b, 0x04c, 0x04c, + 0x04d, 0x04d, 0x04e, 0x04e, 0x04f, 0x04f, 0x050, 0x050, + 0x051, 0x051, 0x052, 0x052, 0x053, 0x053, 0x054, 0x054, + 0x055, 0x055, 0x056, 0x056, 0x057, 0x057, 0x058, 0x058, + 0x059, 0x059, 0x05a, 0x05a, 0x05b, 0x05b, 0x05c, 0x05c, + 0x05d, 0x05d, 0x05e, 0x05e, 0x05f, 0x05f, 0x060, 0x060, + 0x061, 0x061, 0x062, 0x062, 0x063, 0x063, 0x064, 0x064, + 0x065, 0x065, 0x066, 0x066, 0x067, 0x067, 0x068, 0x068, + 0x069, 0x069, 0x06a, 0x06a, 0x06b, 0x06b, 0x06c, 0x06c, + 0x06d, 0x06d, 0x06e, 0x06e, 0x06f, 0x06f, 0x070, 0x071, + 0x071, 0x072, 0x072, 0x073, 0x073, 0x074, 0x074, 0x075, + 0x075, 0x076, 0x076, 0x077, 0x077, 0x078, 0x078, 0x079, + 0x079, 0x07a, 0x07a, 0x07b, 0x07b, 0x07c, 0x07c, 0x07d, + 0x07d, 0x07e, 0x07e, 0x07f, 0x07f, 0x080, 0x081, 0x081, + 0x082, 0x082, 0x083, 0x083, 0x084, 0x084, 0x085, 0x085, + 0x086, 0x086, 0x087, 0x087, 0x088, 0x088, 0x089, 0x089, + 0x08a, 0x08a, 0x08b, 0x08b, 0x08c, 0x08d, 0x08d, 0x08e, + 0x08e, 0x08f, 0x08f, 0x090, 0x090, 0x091, 0x091, 0x092, + 0x092, 0x093, 0x093, 0x094, 0x094, 0x095, 0x096, 0x096, + 0x097, 0x097, 0x098, 0x098, 0x099, 0x099, 0x09a, 0x09a, + 0x09b, 0x09b, 0x09c, 0x09c, 0x09d, 0x09d, 0x09e, 0x09f, + 0x09f, 0x0a0, 0x0a0, 0x0a1, 0x0a1, 0x0a2, 0x0a2, 0x0a3, + 0x0a3, 0x0a4, 0x0a4, 0x0a5, 0x0a6, 0x0a6, 0x0a7, 0x0a7, + 0x0a8, 0x0a8, 0x0a9, 0x0a9, 0x0aa, 0x0aa, 0x0ab, 0x0ab, + 0x0ac, 0x0ad, 0x0ad, 0x0ae, 0x0ae, 0x0af, 0x0af, 0x0b0, + 0x0b0, 0x0b1, 0x0b1, 0x0b2, 0x0b2, 0x0b3, 0x0b4, 0x0b4, + 0x0b5, 0x0b5, 0x0b6, 0x0b6, 0x0b7, 0x0b7, 0x0b8, 0x0b8, + 0x0b9, 0x0ba, 0x0ba, 0x0bb, 0x0bb, 0x0bc, 0x0bc, 0x0bd, + 0x0bd, 0x0be, 0x0be, 0x0bf, 0x0c0, 0x0c0, 0x0c1, 0x0c1, + 0x0c2, 0x0c2, 0x0c3, 0x0c3, 0x0c4, 0x0c4, 0x0c5, 0x0c6, + 0x0c6, 0x0c7, 0x0c7, 0x0c8, 0x0c8, 0x0c9, 0x0c9, 0x0ca, + 0x0cb, 0x0cb, 0x0cc, 0x0cc, 0x0cd, 0x0cd, 0x0ce, 0x0ce, + 0x0cf, 0x0d0, 0x0d0, 0x0d1, 0x0d1, 0x0d2, 0x0d2, 0x0d3, + 0x0d3, 0x0d4, 0x0d5, 0x0d5, 0x0d6, 0x0d6, 0x0d7, 0x0d7, + 0x0d8, 0x0d8, 0x0d9, 0x0da, 0x0da, 0x0db, 0x0db, 0x0dc, + 0x0dc, 0x0dd, 0x0de, 0x0de, 0x0df, 0x0df, 0x0e0, 0x0e0, + 0x0e1, 0x0e1, 0x0e2, 0x0e3, 0x0e3, 0x0e4, 0x0e4, 0x0e5, + 0x0e5, 0x0e6, 0x0e7, 0x0e7, 0x0e8, 0x0e8, 0x0e9, 0x0e9, + 0x0ea, 0x0eb, 0x0eb, 0x0ec, 0x0ec, 0x0ed, 0x0ed, 0x0ee, + 0x0ef, 0x0ef, 0x0f0, 0x0f0, 0x0f1, 0x0f1, 0x0f2, 0x0f3, + 0x0f3, 0x0f4, 0x0f4, 0x0f5, 0x0f5, 0x0f6, 0x0f7, 0x0f7, + 0x0f8, 0x0f8, 0x0f9, 0x0f9, 0x0fa, 0x0fb, 0x0fb, 0x0fc, + 0x0fc, 0x0fd, 0x0fd, 0x0fe, 0x0ff, 0x0ff, 0x100, 0x100, + 0x101, 0x101, 0x102, 0x103, 0x103, 0x104, 0x104, 0x105, + 0x106, 0x106, 0x107, 0x107, 0x108, 0x108, 0x109, 0x10a, + 0x10a, 0x10b, 0x10b, 0x10c, 0x10c, 0x10d, 0x10e, 0x10e, + 0x10f, 0x10f, 0x110, 0x111, 0x111, 0x112, 0x112, 0x113, + 0x114, 0x114, 0x115, 0x115, 0x116, 0x116, 0x117, 0x118, + 0x118, 0x119, 0x119, 0x11a, 0x11b, 0x11b, 0x11c, 0x11c, + 0x11d, 0x11e, 0x11e, 0x11f, 0x11f, 0x120, 0x120, 0x121, + 0x122, 0x122, 0x123, 0x123, 0x124, 0x125, 0x125, 0x126, + 0x126, 0x127, 0x128, 0x128, 0x129, 0x129, 0x12a, 0x12b, + 0x12b, 0x12c, 0x12c, 0x12d, 0x12e, 0x12e, 0x12f, 0x12f, + 0x130, 0x131, 0x131, 0x132, 0x132, 0x133, 0x134, 0x134, + 0x135, 0x135, 0x136, 0x137, 0x137, 0x138, 0x138, 0x139, + 0x13a, 0x13a, 0x13b, 0x13b, 0x13c, 0x13d, 0x13d, 0x13e, + 0x13e, 0x13f, 0x140, 0x140, 0x141, 0x141, 0x142, 0x143, + 0x143, 0x144, 0x144, 0x145, 0x146, 0x146, 0x147, 0x148, + 0x148, 0x149, 0x149, 0x14a, 0x14b, 0x14b, 0x14c, 0x14c, + 0x14d, 0x14e, 0x14e, 0x14f, 0x14f, 0x150, 0x151, 0x151, + 0x152, 0x153, 0x153, 0x154, 0x154, 0x155, 0x156, 0x156, + 0x157, 0x157, 0x158, 0x159, 0x159, 0x15a, 0x15b, 0x15b, + 0x15c, 0x15c, 0x15d, 0x15e, 0x15e, 0x15f, 0x160, 0x160, + 0x161, 0x161, 0x162, 0x163, 0x163, 0x164, 0x165, 0x165, + 0x166, 0x166, 0x167, 0x168, 0x168, 0x169, 0x16a, 0x16a, + 0x16b, 0x16b, 0x16c, 0x16d, 0x16d, 0x16e, 0x16f, 0x16f, + 0x170, 0x170, 0x171, 0x172, 0x172, 0x173, 0x174, 0x174, + 0x175, 0x175, 0x176, 0x177, 0x177, 0x178, 0x179, 0x179, + 0x17a, 0x17a, 0x17b, 0x17c, 0x17c, 0x17d, 0x17e, 0x17e, + 0x17f, 0x180, 0x180, 0x181, 0x181, 0x182, 0x183, 0x183, + 0x184, 0x185, 0x185, 0x186, 0x187, 0x187, 0x188, 0x188, + 0x189, 0x18a, 0x18a, 0x18b, 0x18c, 0x18c, 0x18d, 0x18e, + 0x18e, 0x18f, 0x190, 0x190, 0x191, 0x191, 0x192, 0x193, + 0x193, 0x194, 0x195, 0x195, 0x196, 0x197, 0x197, 0x198, + 0x199, 0x199, 0x19a, 0x19a, 0x19b, 0x19c, 0x19c, 0x19d, + 0x19e, 0x19e, 0x19f, 0x1a0, 0x1a0, 0x1a1, 0x1a2, 0x1a2, + 0x1a3, 0x1a4, 0x1a4, 0x1a5, 0x1a6, 0x1a6, 0x1a7, 0x1a8, + 0x1a8, 0x1a9, 0x1a9, 0x1aa, 0x1ab, 0x1ab, 0x1ac, 0x1ad, + 0x1ad, 0x1ae, 0x1af, 0x1af, 0x1b0, 0x1b1, 0x1b1, 0x1b2, + 0x1b3, 0x1b3, 0x1b4, 0x1b5, 0x1b5, 0x1b6, 0x1b7, 0x1b7, + 0x1b8, 0x1b9, 0x1b9, 0x1ba, 0x1bb, 0x1bb, 0x1bc, 0x1bd, + 0x1bd, 0x1be, 0x1bf, 0x1bf, 0x1c0, 0x1c1, 0x1c1, 0x1c2, + 0x1c3, 0x1c3, 0x1c4, 0x1c5, 0x1c5, 0x1c6, 0x1c7, 0x1c7, + 0x1c8, 0x1c9, 0x1c9, 0x1ca, 0x1cb, 0x1cb, 0x1cc, 0x1cd, + 0x1cd, 0x1ce, 0x1cf, 0x1cf, 0x1d0, 0x1d1, 0x1d1, 0x1d2, + 0x1d3, 0x1d3, 0x1d4, 0x1d5, 0x1d5, 0x1d6, 0x1d7, 0x1d7, + 0x1d8, 0x1d9, 0x1d9, 0x1da, 0x1db, 0x1db, 0x1dc, 0x1dd, + 0x1dd, 0x1de, 0x1df, 0x1df, 0x1e0, 0x1e1, 0x1e1, 0x1e2, + 0x1e3, 0x1e4, 0x1e4, 0x1e5, 0x1e6, 0x1e6, 0x1e7, 0x1e8, + 0x1e8, 0x1e9, 0x1ea, 0x1ea, 0x1eb, 0x1ec, 0x1ec, 0x1ed, + 0x1ee, 0x1ee, 0x1ef, 0x1f0, 0x1f0, 0x1f1, 0x1f2, 0x1f3, + 0x1f3, 0x1f4, 0x1f5, 0x1f5, 0x1f6, 0x1f7, 0x1f7, 0x1f8, + 0x1f9, 0x1f9, 0x1fa, 0x1fb, 0x1fb, 0x1fc, 0x1fd, 0x1fe, + 0x1fe, 0x1ff, 0x200, 0x200, 0x201, 0x202, 0x202, 0x203, + 0x204, 0x205, 0x205, 0x206, 0x207, 0x207, 0x208, 0x209, + 0x209, 0x20a, 0x20b, 0x20b, 0x20c, 0x20d, 0x20e, 0x20e, + 0x20f, 0x210, 0x210, 0x211, 0x212, 0x212, 0x213, 0x214, + 0x215, 0x215, 0x216, 0x217, 0x217, 0x218, 0x219, 0x21a, + 0x21a, 0x21b, 0x21c, 0x21c, 0x21d, 0x21e, 0x21e, 0x21f, + 0x220, 0x221, 0x221, 0x222, 0x223, 0x223, 0x224, 0x225, + 0x226, 0x226, 0x227, 0x228, 0x228, 0x229, 0x22a, 0x22b, + 0x22b, 0x22c, 0x22d, 0x22d, 0x22e, 0x22f, 0x230, 0x230, + 0x231, 0x232, 0x232, 0x233, 0x234, 0x235, 0x235, 0x236, + 0x237, 0x237, 0x238, 0x239, 0x23a, 0x23a, 0x23b, 0x23c, + 0x23c, 0x23d, 0x23e, 0x23f, 0x23f, 0x240, 0x241, 0x241, + 0x242, 0x243, 0x244, 0x244, 0x245, 0x246, 0x247, 0x247, + 0x248, 0x249, 0x249, 0x24a, 0x24b, 0x24c, 0x24c, 0x24d, + 0x24e, 0x24f, 0x24f, 0x250, 0x251, 0x251, 0x252, 0x253, + 0x254, 0x254, 0x255, 0x256, 0x257, 0x257, 0x258, 0x259, + 0x259, 0x25a, 0x25b, 0x25c, 0x25c, 0x25d, 0x25e, 0x25f, + 0x25f, 0x260, 0x261, 0x262, 0x262, 0x263, 0x264, 0x265, + 0x265, 0x266, 0x267, 0x267, 0x268, 0x269, 0x26a, 0x26a, + 0x26b, 0x26c, 0x26d, 0x26d, 0x26e, 0x26f, 0x270, 0x270, + 0x271, 0x272, 0x273, 0x273, 0x274, 0x275, 0x276, 0x276, + 0x277, 0x278, 0x279, 0x279, 0x27a, 0x27b, 0x27c, 0x27c, + 0x27d, 0x27e, 0x27f, 0x27f, 0x280, 0x281, 0x282, 0x282, + 0x283, 0x284, 0x285, 0x285, 0x286, 0x287, 0x288, 0x288, + 0x289, 0x28a, 0x28b, 0x28b, 0x28c, 0x28d, 0x28e, 0x28e, + 0x28f, 0x290, 0x291, 0x291, 0x292, 0x293, 0x294, 0x294, + 0x295, 0x296, 0x297, 0x298, 0x298, 0x299, 0x29a, 0x29b, + 0x29b, 0x29c, 0x29d, 0x29e, 0x29e, 0x29f, 0x2a0, 0x2a1, + 0x2a1, 0x2a2, 0x2a3, 0x2a4, 0x2a5, 0x2a5, 0x2a6, 0x2a7, + 0x2a8, 0x2a8, 0x2a9, 0x2aa, 0x2ab, 0x2ab, 0x2ac, 0x2ad, + 0x2ae, 0x2af, 0x2af, 0x2b0, 0x2b1, 0x2b2, 0x2b2, 0x2b3, + 0x2b4, 0x2b5, 0x2b5, 0x2b6, 0x2b7, 0x2b8, 0x2b9, 0x2b9, + 0x2ba, 0x2bb, 0x2bc, 0x2bc, 0x2bd, 0x2be, 0x2bf, 0x2c0, + 0x2c0, 0x2c1, 0x2c2, 0x2c3, 0x2c4, 0x2c4, 0x2c5, 0x2c6, + 0x2c7, 0x2c7, 0x2c8, 0x2c9, 0x2ca, 0x2cb, 0x2cb, 0x2cc, + 0x2cd, 0x2ce, 0x2ce, 0x2cf, 0x2d0, 0x2d1, 0x2d2, 0x2d2, + 0x2d3, 0x2d4, 0x2d5, 0x2d6, 0x2d6, 0x2d7, 0x2d8, 0x2d9, + 0x2da, 0x2da, 0x2db, 0x2dc, 0x2dd, 0x2dd, 0x2de, 0x2df, + 0x2e0, 0x2e1, 0x2e1, 0x2e2, 0x2e3, 0x2e4, 0x2e5, 0x2e5, + 0x2e6, 0x2e7, 0x2e8, 0x2e9, 0x2e9, 0x2ea, 0x2eb, 0x2ec, + 0x2ed, 0x2ed, 0x2ee, 0x2ef, 0x2f0, 0x2f1, 0x2f1, 0x2f2, + 0x2f3, 0x2f4, 0x2f5, 0x2f5, 0x2f6, 0x2f7, 0x2f8, 0x2f9, + 0x2f9, 0x2fa, 0x2fb, 0x2fc, 0x2fd, 0x2fd, 0x2fe, 0x2ff, + 0x300, 0x301, 0x302, 0x302, 0x303, 0x304, 0x305, 0x306, + 0x306, 0x307, 0x308, 0x309, 0x30a, 0x30a, 0x30b, 0x30c, + 0x30d, 0x30e, 0x30f, 0x30f, 0x310, 0x311, 0x312, 0x313, + 0x313, 0x314, 0x315, 0x316, 0x317, 0x318, 0x318, 0x319, + 0x31a, 0x31b, 0x31c, 0x31c, 0x31d, 0x31e, 0x31f, 0x320, + 0x321, 0x321, 0x322, 0x323, 0x324, 0x325, 0x326, 0x326, + 0x327, 0x328, 0x329, 0x32a, 0x32a, 0x32b, 0x32c, 0x32d, + 0x32e, 0x32f, 0x32f, 0x330, 0x331, 0x332, 0x333, 0x334, + 0x334, 0x335, 0x336, 0x337, 0x338, 0x339, 0x339, 0x33a, + 0x33b, 0x33c, 0x33d, 0x33e, 0x33e, 0x33f, 0x340, 0x341, + 0x342, 0x343, 0x343, 0x344, 0x345, 0x346, 0x347, 0x348, + 0x349, 0x349, 0x34a, 0x34b, 0x34c, 0x34d, 0x34e, 0x34e, + 0x34f, 0x350, 0x351, 0x352, 0x353, 0x353, 0x354, 0x355, + 0x356, 0x357, 0x358, 0x359, 0x359, 0x35a, 0x35b, 0x35c, + 0x35d, 0x35e, 0x35f, 0x35f, 0x360, 0x361, 0x362, 0x363, + 0x364, 0x364, 0x365, 0x366, 0x367, 0x368, 0x369, 0x36a, + 0x36a, 0x36b, 0x36c, 0x36d, 0x36e, 0x36f, 0x370, 0x370, + 0x371, 0x372, 0x373, 0x374, 0x375, 0x376, 0x377, 0x377, + 0x378, 0x379, 0x37a, 0x37b, 0x37c, 0x37d, 0x37d, 0x37e, + 0x37f, 0x380, 0x381, 0x382, 0x383, 0x383, 0x384, 0x385, + 0x386, 0x387, 0x388, 0x389, 0x38a, 0x38a, 0x38b, 0x38c, + 0x38d, 0x38e, 0x38f, 0x390, 0x391, 0x391, 0x392, 0x393, + 0x394, 0x395, 0x396, 0x397, 0x398, 0x398, 0x399, 0x39a, + 0x39b, 0x39c, 0x39d, 0x39e, 0x39f, 0x39f, 0x3a0, 0x3a1, + 0x3a2, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7, 0x3a7, 0x3a8, + 0x3a9, 0x3aa, 0x3ab, 0x3ac, 0x3ad, 0x3ae, 0x3ae, 0x3af, + 0x3b0, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b6, + 0x3b7, 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd, 0x3be, + 0x3bf, 0x3bf, 0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4, 0x3c5, + 0x3c6, 0x3c7, 0x3c7, 0x3c8, 0x3c9, 0x3ca, 0x3cb, 0x3cc, + 0x3cd, 0x3ce, 0x3cf, 0x3d0, 0x3d1, 0x3d1, 0x3d2, 0x3d3, + 0x3d4, 0x3d5, 0x3d6, 0x3d7, 0x3d8, 0x3d9, 0x3da, 0x3da, + 0x3db, 0x3dc, 0x3dd, 0x3de, 0x3df, 0x3e0, 0x3e1, 0x3e2, + 0x3e3, 0x3e4, 0x3e4, 0x3e5, 0x3e6, 0x3e7, 0x3e8, 0x3e9, + 0x3ea, 0x3eb, 0x3ec, 0x3ed, 0x3ee, 0x3ef, 0x3ef, 0x3f0, + 0x3f1, 0x3f2, 0x3f3, 0x3f4, 0x3f5, 0x3f6, 0x3f7, 0x3f8, + 0x3f9, 0x3fa, 0x3fa, 0x3fb, 0x3fc, 0x3fd, 0x3fe, 0x3ff +}; + +/* + * Attenuation according to GM recommendations, in -0.375 dB units. + * table[v] = 40 * log(v / 127) / -0.375 + */ +static const uint8_t g_volume_table[128] = { + 255, 224, 192, 173, 160, 150, 141, 134, + 128, 122, 117, 113, 109, 105, 102, 99, + 96, 93, 90, 88, 85, 83, 81, 79, + 77, 75, 73, 71, 70, 68, 67, 65, + 64, 62, 61, 59, 58, 57, 56, 54, + 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 40, 39, 39, + 38, 37, 36, 35, 34, 34, 33, 32, + 31, 31, 30, 29, 29, 28, 27, 27, + 26, 25, 25, 24, 24, 23, 22, 22, + 21, 21, 20, 19, 19, 18, 18, 17, + 17, 16, 16, 15, 15, 14, 14, 13, + 13, 12, 12, 11, 11, 10, 10, 9, + 9, 9, 8, 8, 7, 7, 6, 6, + 6, 5, 5, 4, 4, 4, 3, 3, + 2, 2, 2, 1, 1, 0, 0, 0 +}; + +typedef struct opl4_midi { + fm_drv_t opl4; + MIDI_CHANNEL_DATA midi_channel_data[16]; + VOICE_DATA voice_data[24]; + int16_t buffer[SOUNDBUFLEN * 2]; + float buffer_float[SOUNDBUFLEN * 2]; + uint32_t midi_pos; + bool on; + atomic_bool gen_in_progress; + thread_t *thread; + event_t *wait_event; +} opl4_midi_t; + +static opl4_midi_t *opl4_midi_cur; + +static void +opl4_write_wave_register(const uint8_t reg, const uint8_t value, opl4_midi_t *opl4_midi) +{ + opl4_midi->opl4.write(0x380, reg, opl4_midi->opl4.priv); + opl4_midi->opl4.write(0x381, value, opl4_midi->opl4.priv); +} + +VOICE_DATA * +get_voice(const YRW801_WAVE_DATA *wave_data, opl4_midi_t *opl4_midi) +{ + VOICE_DATA *free_voice = &opl4_midi->voice_data[0]; + VOICE_DATA *oldest_voice = &opl4_midi->voice_data[0]; + for (uint8_t voice = 0; voice < 24; voice++) { + if (opl4_midi_cur->voice_data[voice].is_active) { + if (opl4_midi_cur->voice_data[voice].activated < oldest_voice->activated) + oldest_voice = &opl4_midi_cur->voice_data[voice]; + } else { + if (opl4_midi_cur->voice_data[voice].wave_data == wave_data) { + free_voice = &opl4_midi_cur->voice_data[voice]; + break; + } + + if (opl4_midi_cur->voice_data[voice].activated < free_voice->activated) + free_voice = &opl4_midi_cur->voice_data[voice]; + } + } + + /* If no free voice found, deactivate the 'oldest' */ + if (free_voice->is_active) { + free_voice = oldest_voice; + free_voice->is_active = 0; + free_voice->activated = 0; + + free_voice->reg_misc &= ~OPL4_KEY_ON_BIT; + opl4_write_wave_register(OPL4_REG_MISC + free_voice->number, free_voice->reg_misc, opl4_midi); + } + + return free_voice; +} + +static void +update_pan(VOICE_DATA *voice, opl4_midi_t *opl4_midi) +{ + int8_t pan = voice->wave_data->panpot; + + if (!voice->midi_channel->drum_channel) + pan += voice->midi_channel->panpot; + if (pan < -7) + pan = -7; + else if (pan > 7) + pan = 7; + + voice->reg_misc = (voice->reg_misc & ~OPL4_PAN_POT_MASK) | (pan & OPL4_PAN_POT_MASK); + opl4_write_wave_register(OPL4_REG_MISC + voice->number, voice->reg_misc, opl4_midi); +} + +void +update_pitch(VOICE_DATA *voice, uint16_t pitch_bend, opl4_midi_t *opl4_midi) +{ + int32_t pitch = voice->midi_channel->drum_channel ? 0 : (voice->note - 60) * 128; + pitch = pitch * (int) voice->wave_data->key_scaling / 100; + pitch = pitch + 7680; + pitch += voice->wave_data->pitch_offset; + pitch += pitch_bend * 256 / 0x2000; + if (pitch < 0) + pitch = 0; + else if (pitch > 0x5FFF) + pitch = 0x5FFF; + + int8_t octave = pitch / 0x600 - 8; + uint16_t fnumber = g_wave_pitch_map[pitch % 0x600]; + + opl4_write_wave_register(OPL4_REG_OCTAVE + voice->number, (octave << 4) | ((fnumber >> 7) & 0x07), opl4_midi); + voice->reg_f_number = (voice->reg_f_number & OPL4_TONE_NUMBER_BIT8) | ((fnumber << 1) & OPL4_F_NUMBER_LOW_MASK); + opl4_write_wave_register(OPL4_REG_F_NUMBER + voice->number, voice->reg_f_number, opl4_midi); +} + +void +update_volume(VOICE_DATA *voice, opl4_midi_t *opl4_midi) +{ + int16_t att = voice->wave_data->tone_attenuate; + + att += g_volume_table[voice->velocity]; + att = 0x7F - (0x7F - att) * (voice->wave_data->volume_factor) / 0xFE; + att -= 16; + if (att < 0) + att = 0; + else if (att > 0x7E) + att = 0x7E; + + opl4_write_wave_register(OPL4_REG_LEVEL + voice->number, (att << 1) | voice->level_direct, opl4_midi); + voice->level_direct = 0; +} + +void +note_off(uint8_t note, uint8_t velocity, MIDI_CHANNEL_DATA *midi_channel, opl4_midi_t *opl4_midi) +{ + /* Velocity not used */ + (void) velocity; + + while (opl4_midi->gen_in_progress) { } + for (uint8_t i = 0; i < 24; i++) { + VOICE_DATA *voice = &opl4_midi->voice_data[i]; + if (voice->is_active && voice->midi_channel == midi_channel && voice->note == note) { + voice->is_active = false; + voice->activated = 0; + + voice->reg_misc &= ~OPL4_KEY_ON_BIT; + opl4_write_wave_register(OPL4_REG_MISC + voice->number, voice->reg_misc, opl4_midi); + } + } +} + +void +update_vibrato_depth(VOICE_DATA *voice, opl4_midi_t *opl4_midi) +{ + uint16_t depth; + + depth = (7 - voice->wave_data->vibrato) * (voice->midi_channel->vibrato & 0x7F); + depth = (depth >> 7) + voice->wave_data->vibrato; + voice->reg_lfo_vibrato &= ~OPL4_VIBRATO_DEPTH_MASK; + voice->reg_lfo_vibrato |= depth & OPL4_VIBRATO_DEPTH_MASK; + opl4_write_wave_register(OPL4_REG_LFO_VIBRATO + voice->number, voice->reg_lfo_vibrato, opl4_midi); +} + +void +note_on(uint8_t note, uint8_t velocity, MIDI_CHANNEL_DATA *midi_channel, opl4_midi_t *opl4_midi) +{ + const YRW801_REGION_DATA_PTR *region_ptr = &snd_yrw801_regions[0]; + const YRW801_WAVE_DATA *wave_data[2]; + VOICE_DATA *voice[2]; + uint8_t i = 0, voices = 0; + uint32_t j = 0; + static uint64_t activation_num = 0; + + while (opl4_midi->gen_in_progress) { } + + if (midi_channel->drum_channel) + wave_data[voices++] = ®ion_ptr[0x80].regions[note - 0x1A].wave_data; + else { + /* Determine the number of voices and voice parameters */ + const YRW801_REGION_DATA *region = region_ptr[midi_channel->instrument & 0x7F].regions; + + while (i < region_ptr[midi_channel->instrument & 0x7F].count) { + if (note >= region[i].key_min && note <= region[i].key_max) { + wave_data[voices] = ®ion[i].wave_data; + if (++voices >= 2) + break; + } + i++; + } + } + + /* Allocate and initialize needed voices */ + for (i = 0; i < voices; i++) { + voice[i] = get_voice(wave_data[i], opl4_midi); + voice[i]->is_active = true; + voice[i]->activated = activation_num++; + + voice[i]->midi_channel = midi_channel; + voice[i]->note = note; + voice[i]->velocity = velocity & 0x7F; + } + + for (i = 0; i < voices; i++) { + voice[i]->reg_f_number = (wave_data[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8; + opl4_write_wave_register(OPL4_REG_F_NUMBER + voice[i]->number, voice[i]->reg_f_number, opl4_midi); + + bool new_wave = (voice[i]->wave_data != wave_data[i]); + /* Set tone number (triggers header loading) */ + if (new_wave) { + opl4_write_wave_register(OPL4_REG_TONE_NUMBER + voice[i]->number, wave_data[i]->tone & 0xFF, opl4_midi); + voice[i]->wave_data = wave_data[i]; + } + + voice[i]->reg_misc = OPL4_LFO_RESET_BIT; + update_pan(voice[i], opl4_midi); + update_pitch(voice[i], 0, opl4_midi); + voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT; + update_volume(voice[i], opl4_midi); + if (new_wave) { + /* Set remaining parameters */ + opl4_write_wave_register(OPL4_REG_ATTACK_DECAY1 + voice[i]->number, voice[i]->wave_data->reg_attack_decay1, opl4_midi); + opl4_write_wave_register(OPL4_REG_LEVEL_DECAY2 + voice[i]->number, voice[i]->wave_data->reg_level_decay2, opl4_midi); + opl4_write_wave_register(OPL4_REG_RELEASE_CORRECTION + voice[i]->number, voice[i]->wave_data->reg_release_correction, opl4_midi); + opl4_write_wave_register(OPL4_REG_TREMOLO + voice[i]->number, voice[i]->wave_data->reg_tremolo, opl4_midi); + + voice[i]->reg_lfo_vibrato = voice[i]->wave_data->reg_lfo_vibrato; + + if (!midi_channel->drum_channel) + update_vibrato_depth(voice[i], opl4_midi); + } + } + + /* Finally, switch on all voices */ + for (i = 0; i < voices; i++) { + voice[i]->reg_misc = (voice[i]->reg_misc & 0x1F) | OPL4_KEY_ON_BIT; + opl4_write_wave_register(OPL4_REG_MISC + voice[i]->number, voice[i]->reg_misc, opl4_midi); + } +} + +void +control_change(uint8_t midi_channel, uint8_t id, uint8_t value, opl4_midi_t *opl4_midi) +{ + int i = 0; + switch (id) { + case 10: + /* Change stereo panning */ + if (midi_channel != DRUM_CHANNEL) { + opl4_midi->midi_channel_data[midi_channel].panpot = (value - 0x40) >> 3; + for (i = 0; i < NR_OF_WAVE_CHANNELS; i++) { + if (opl4_midi->voice_data[i].is_active && opl4_midi->voice_data[i].midi_channel == &opl4_midi->midi_channel_data[midi_channel]) { + update_pan(&opl4_midi->voice_data[i], opl4_midi); + } + } + } + break; + } +} + +void +pitch_wheel(uint8_t midi_channel, uint16_t value, opl4_midi_t *opl4_midi) +{ + int i = 0; + + for (i = 0; i < 24; i++) { + if (opl4_midi->voice_data[i].is_active && opl4_midi->voice_data[i].midi_channel == &opl4_midi->midi_channel_data[midi_channel]) { + update_pitch(&opl4_midi->voice_data[i], value, opl4_midi); + } + } +} + +void +channel_pressure(uint8_t midi_channel, uint8_t pressure) +{ + (void) midi_channel; + (void) pressure; +} + +void +key_pressure(uint8_t midi_channel, uint8_t note, uint8_t pressure) +{ + (void) midi_channel; + (void) note; + (void) pressure; +} + +void +program_change(uint8_t midi_channel, uint8_t program, opl4_midi_t *opl4_midi) +{ + opl4_midi->midi_channel_data[midi_channel].instrument = program; +} + +#define RENDER_RATE (48000 / 100) +static void +opl4_midi_thread(void *arg) +{ + opl4_midi_t *opl4_midi = opl4_midi_cur; + uint32_t i = 0; + uint32_t buf_size = RENDER_RATE * 2; + + int32_t buffer[RENDER_RATE * 2]; + + extern void givealbuffer_midi(void *buf, uint32_t size); + while (opl4_midi->on) { + thread_wait_event(opl4_midi->wait_event, -1); + thread_reset_event(opl4_midi->wait_event); + if (!opl4_midi->on) + break; + atomic_store(&opl4_midi->gen_in_progress, true); + opl4_midi->opl4.generate(opl4_midi->opl4.priv, buffer, RENDER_RATE); + atomic_store(&opl4_midi->gen_in_progress, false); + if (sound_is_float) { + for (i = 0; i < (buf_size / 2); i++) { + opl4_midi->buffer_float[i * 2] = buffer[i * 2] / 32768.0; + opl4_midi->buffer_float[(i * 2) + 1] = buffer[(i * 2) + 1] / 32768.0; + } + givealbuffer_midi(opl4_midi->buffer_float, buf_size); + } else { + for (i = 0; i < (buf_size / 2); i++) { + opl4_midi->buffer[i * 2] = buffer[i * 2] & 0xFFFF; /* Outputs are clamped beforehand. */ + opl4_midi->buffer[(i * 2) + 1] = buffer[(i * 2) + 1] & 0xFFFF; /* Outputs are clamped beforehand. */ + } + givealbuffer_midi(opl4_midi->buffer, buf_size); + } + } +} + +static void +opl4_midi_poll(void) +{ + opl4_midi_t *opl4_midi = opl4_midi_cur; + opl4_midi->midi_pos++; + if (opl4_midi->midi_pos == RENDER_RATE) { + opl4_midi->midi_pos = 0; + thread_set_event(opl4_midi->wait_event); + } +} + +void +opl4_midi_msg(uint8_t *val) +{ + opl4_midi_t *opl4_midi = opl4_midi_cur; + + uint32_t msg = *(uint32_t *) (val); + uint8_t data_byte_1 = msg & 0xFF; + uint8_t data_byte_2 = (msg >> 8) & 0xFF; + uint8_t data_byte_3 = (msg >> 16) & 0xFF; + + uint8_t midi_channel = data_byte_1 & 0x0F; + uint8_t midi_command = data_byte_1 >> 4; + + switch (midi_command) { + case 0x8: // Note OFF + note_off(data_byte_2 & 0x7F, data_byte_3, &opl4_midi->midi_channel_data[midi_channel], opl4_midi); + break; + case 0x9: // Note ON + note_on(data_byte_2 & 0x7F, data_byte_3, &opl4_midi->midi_channel_data[midi_channel], opl4_midi); + break; + case 0xA: // Key after-touch + break; + case 0xB: // Control change + control_change(midi_channel, data_byte_2, data_byte_3, opl4_midi); + break; + case 0xC: // Program change + program_change(midi_channel, data_byte_2 & 0x7F, opl4_midi); + break; + case 0xD: // Channel after-touch + break; + case 0xE: // Pitch wheel + pitch_wheel(midi_channel, ((data_byte_3 <<= 7) | data_byte_2), opl4_midi); + break; + } +} + +void +opl4_midi_sysex(uint8_t *data, unsigned int len) +{ +} + +void * +opl4_init(const device_t *info) +{ + midi_device_t *dev; + extern void al_set_midi(int freq, int buf_size); + + dev = malloc(sizeof(midi_device_t)); + memset(dev, 0, sizeof(midi_device_t)); + + dev->play_msg = opl4_midi_msg; + dev->play_sysex = opl4_midi_sysex; + dev->poll = opl4_midi_poll; + + al_set_midi(48000, 4800); + + opl4_midi_cur = calloc(1, sizeof(opl4_midi_t)); + + fm_driver_get(FM_YMF278B, &opl4_midi_cur->opl4); + + opl4_midi_cur->opl4.write(0x38A, 0x05, opl4_midi_cur->opl4.priv); + opl4_midi_cur->opl4.write(0x389, 0x3, opl4_midi_cur->opl4.priv); + midi_out_init(dev); + + opl4_midi_cur->on = true; + opl4_midi_cur->midi_channel_data[9].drum_channel = true; + atomic_init(&opl4_midi_cur->gen_in_progress, 0); + + for (uint8_t voice = 0; voice < NR_OF_WAVE_CHANNELS; voice++) { + opl4_midi_cur->voice_data[voice].number = voice; + opl4_midi_cur->voice_data[voice].is_active = false; + opl4_midi_cur->voice_data[voice].activated = 0; + opl4_midi_cur->voice_data[voice].midi_channel = NULL; + opl4_midi_cur->voice_data[voice].note = 0; + opl4_midi_cur->voice_data[voice].velocity = 0; + opl4_midi_cur->voice_data[voice].wave_data = NULL; + opl4_midi_cur->voice_data[voice].level_direct = 0; + opl4_midi_cur->voice_data[voice].reg_f_number = 0; + opl4_midi_cur->voice_data[voice].reg_misc = 0; + opl4_midi_cur->voice_data[voice].reg_lfo_vibrato = 0; + } + opl4_midi_cur->wait_event = thread_create_event(); + opl4_midi_cur->thread = thread_create(opl4_midi_thread, NULL); + return dev; +} + +void +opl4_close(void *p) +{ + if (!p) + return; + + opl4_midi_cur->on = false; + thread_set_event(opl4_midi_cur->wait_event); + thread_wait(opl4_midi_cur->thread); + free(opl4_midi_cur); + opl4_midi_cur = NULL; +} + +static int +opl4_midi_available(void) +{ + return rom_present("roms/sound/yamaha/yrw801.rom"); +} + +const device_t opl4_midi_device = { + .name = "OPL4-ML Daughterboard", + .internal_name = "opl4-ml", + .flags = 0, + .local = 0, + .init = opl4_init, + .close = opl4_close, + .reset = NULL, + { .available = opl4_midi_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sound/midi_opl4_yrw801.c b/src/sound/midi_opl4_yrw801.c new file mode 100644 index 000000000..96822b9af --- /dev/null +++ b/src/sound/midi_opl4_yrw801.c @@ -0,0 +1,1042 @@ +/* Table taken from linux/sound/drivers/opl4/yrw801.c */ +/* Macros from Linux source code as well */ + +#include "yrw801.h" + +static const YRW801_REGION_DATA regions_00[] = { + /* Acoustic Grand Piano */ + { 0x14, 0x27, { 0x12c, 7474, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6816, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5899, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5290, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4260, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3625, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3116, 100, 0, 0, 0x04, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2081, 100, 0, 0, 0x03, 0xc8, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1444, 100, 0, 0, 0x07, 0xc8, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1915, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_01[] = { + /* Bright Acoustic Piano */ + { 0x14, 0x2d, { 0x12c, 7474, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12d, 6816, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12e, 5899, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x12f, 5290, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x130, 4260, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x131, 3625, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x132, 3116, 100, 0, 0, 0x04, 0xc8, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x53, 0x58, { 0x133, 2081, 100, 0, 0, 0x07, 0xc8, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x59, 0x5e, { 0x134, 1444, 100, 0, 0, 0x0a, 0xc8, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x5f, 0x6d, { 0x135, 1915, 100, 0, 0, 0x00, 0xc8, 0x20, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_02[] = { + /* Electric Grand Piano */ + { 0x14, 0x2d, { 0x12c, 7476, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x13, 0x07, 0x0 } }, + { 0x2e, 0x33, { 0x12d, 6818, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x34, 0x39, { 0x12e, 5901, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x3a, 0x3f, { 0x12f, 5292, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x40, 0x45, { 0x130, 4262, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x46, 0x4b, { 0x131, 3627, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x4c, 0x52, { 0x132, 3118, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x07, 0x0 } }, + { 0x53, 0x58, { 0x133, 2083, 100, 1, 0, 0x00, 0xae, 0x20, 0xf2, 0x14, 0x17, 0x0 } }, + { 0x59, 0x5e, { 0x134, 1446, 100, 1, 0, 0x00, 0xae, 0x20, 0xf3, 0x14, 0x17, 0x0 } }, + { 0x5f, 0x6d, { 0x135, 1917, 100, 1, 0, 0x00, 0xae, 0x20, 0xf4, 0x15, 0x07, 0x0 } }, + { 0x00, 0x7f, { 0x06c, 6375, 100, -1, 0, 0x00, 0xc2, 0x28, 0xf4, 0x23, 0x18, 0x0 }} +}; +static const YRW801_REGION_DATA regions_03[] = { + /* Honky-Tonk Piano */ + { 0x14, 0x27, { 0x12c, 7474, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6816, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5899, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5290, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4260, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3625, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3116, 100, 0, 0, 0x04, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2081, 100, 0, 0, 0x03, 0xb4, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1444, 100, 0, 0, 0x07, 0xb4, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1915, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf4, 0x15, 0x08, 0x0 }}, + { 0x14, 0x27, { 0x12c, 7486, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6803, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5912, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5275, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4274, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3611, 100, 0, 0, 0x0a, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3129, 100, 0, 0, 0x04, 0xb4, 0x20, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2074, 100, 0, 0, 0x07, 0xb4, 0x20, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1457, 100, 0, 0, 0x01, 0xb4, 0x20, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1903, 100, 0, 0, 0x00, 0xb4, 0x20, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_04[] = { + /* Electric Piano 1 */ + { 0x15, 0x6c, { 0x00b, 6570, 100, 0, 0, 0x00, 0x28, 0x38, 0xf0, 0x00, 0x0c, 0x0 }}, + { 0x00, 0x7f, { 0x06c, 6375, 100, 0, 2, 0x00, 0xb0, 0x22, 0xf4, 0x23, 0x19, 0x0 }} +}; +static const YRW801_REGION_DATA regions_05[] = { + /* Electric Piano 2 */ + { 0x14, 0x27, { 0x12c, 7476, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x12d, 6818, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12e, 5901, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12f, 5292, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x130, 4262, 100, 0, 3, 0x0a, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x131, 3627, 100, 0, 3, 0x0a, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x132, 3118, 100, 0, 3, 0x04, 0xa2, 0x1b, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x133, 2083, 100, 0, 3, 0x03, 0xa2, 0x1b, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x53, 0x58, { 0x134, 1446, 100, 0, 3, 0x07, 0xa2, 0x1b, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x59, 0x6d, { 0x135, 1917, 100, 0, 3, 0x00, 0xa2, 0x1b, 0xf4, 0x15, 0x08, 0x0 }}, + { 0x14, 0x2d, { 0x12c, 7472, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x13, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x12d, 6814, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x12e, 5897, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x12f, 5288, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x130, 4258, 100, 0, 0, 0x0a, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x131, 3623, 100, 0, 0, 0x0a, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x4c, 0x52, { 0x132, 3114, 100, 0, 0, 0x04, 0xa2, 0x18, 0xf2, 0x14, 0x08, 0x0 }}, + { 0x53, 0x58, { 0x133, 2079, 100, 0, 0, 0x07, 0xa2, 0x18, 0xf2, 0x14, 0x18, 0x0 }}, + { 0x59, 0x5e, { 0x134, 1442, 100, 0, 0, 0x0a, 0xa2, 0x18, 0xf3, 0x14, 0x18, 0x0 }}, + { 0x5f, 0x6d, { 0x135, 1913, 100, 0, 0, 0x00, 0xa2, 0x18, 0xf4, 0x15, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_06[] = { + /* Harpsichord */ + { 0x15, 0x39, { 0x080, 5158, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x24, 0x19, 0x0 }}, + { 0x3a, 0x3f, { 0x081, 4408, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x09, 0x0 }}, + { 0x40, 0x45, { 0x082, 3622, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x09, 0x0 }}, + { 0x46, 0x4d, { 0x083, 2843, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x19, 0x0 }}, + { 0x4e, 0x6c, { 0x084, 1307, 100, 0, 0, 0x00, 0xb2, 0x20, 0xf5, 0x25, 0x29, 0x0 }} +}; +static const YRW801_REGION_DATA regions_07[] = { + /* Clavinet */ + { 0x15, 0x51, { 0x027, 5009, 100, 0, 0, 0x00, 0xd2, 0x28, 0xf5, 0x13, 0x2b, 0x0 }}, + { 0x52, 0x6c, { 0x028, 3495, 100, 0, 0, 0x00, 0xd2, 0x28, 0xf5, 0x13, 0x3b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_08[] = { + /* Celesta */ + { 0x15, 0x6c, { 0x02b, 3267, 100, 0, 0, 0x00, 0xdc, 0x20, 0xf4, 0x15, 0x07, 0x3 }} +}; +static const YRW801_REGION_DATA regions_09[] = { + /* Glockenspiel */ + { 0x15, 0x78, { 0x0f3, 285, 100, 0, 0, 0x00, 0xc2, 0x28, 0xf6, 0x25, 0x25, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0a[] = { + /* Music Box */ + { 0x15, 0x6c, { 0x0f3, 3362, 100, 0, 0, 0x00, 0xb6, 0x20, 0xa6, 0x25, 0x25, 0x0 }}, + { 0x15, 0x6c, { 0x101, 4773, 100, 0, 0, 0x00, 0xaa, 0x20, 0xd4, 0x14, 0x16, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0b[] = { + /* Vibraphone */ + { 0x15, 0x6c, { 0x101, 4778, 100, 0, 0, 0x00, 0xc0, 0x28, 0xf4, 0x14, 0x16, 0x4 }} +}; +static const YRW801_REGION_DATA regions_0c[] = { + /* Marimba */ + { 0x15, 0x3f, { 0x0f4, 4778, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x47, 0x08, 0x0 }}, + { 0x40, 0x4c, { 0x0f5, 3217, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x47, 0x08, 0x0 }}, + { 0x4d, 0x5a, { 0x0f5, 3217, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x48, 0x08, 0x0 }}, + { 0x5b, 0x7f, { 0x0f5, 3218, 100, 0, 0, 0x00, 0xc4, 0x38, 0xf7, 0x48, 0x18, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0d[] = { + /* Xylophone */ + { 0x00, 0x7f, { 0x136, 1729, 100, 0, 0, 0x00, 0xd2, 0x38, 0xf0, 0x06, 0x36, 0x0 }} +}; +static const YRW801_REGION_DATA regions_0e[] = { + /* Tubular Bell */ + { 0x01, 0x7f, { 0x0ff, 3999, 100, 0, 1, 0x00, 0x90, 0x21, 0xf4, 0xa3, 0x25, 0x1 }} +}; +static const YRW801_REGION_DATA regions_0f[] = { + /* Dulcimer */ + { 0x00, 0x7f, { 0x03f, 4236, 100, 0, 1, 0x00, 0xbc, 0x29, 0xf5, 0x16, 0x07, 0x0 }}, + { 0x00, 0x7f, { 0x040, 4236, 100, 0, 2, 0x0e, 0x94, 0x2a, 0xf5, 0x16, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_10[] = { + /* Drawbar Organ */ + { 0x01, 0x7f, { 0x08e, 4394, 100, 0, 2, 0x14, 0xc2, 0x3a, 0xf0, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_11[] = { + /* Percussive Organ */ + { 0x15, 0x3b, { 0x08c, 6062, 100, 0, 3, 0x00, 0xbe, 0x3b, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3c, 0x6c, { 0x08d, 2984, 100, 0, 3, 0x00, 0xbe, 0x3b, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_12[] = { + /* Rock Organ */ + { 0x15, 0x30, { 0x128, 6574, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x31, 0x3c, { 0x129, 5040, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x3d, 0x48, { 0x12a, 3498, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x49, 0x54, { 0x12b, 1957, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x55, 0x6c, { 0x127, 423, 100, 0, 1, 0x00, 0xcc, 0x39, 0xf0, 0x00, 0x0a, 0x0 } } +}; +static const YRW801_REGION_DATA regions_13[] = { + /* Church Organ */ + { 0x15, 0x29, { 0x087, 7466, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x2a, 0x30, { 0x088, 6456, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x31, 0x38, { 0x089, 5428, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x39, 0x41, { 0x08a, 4408, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x42, 0x6c, { 0x08b, 3406, 100, 0, 1, 0x00, 0xc4, 0x11, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_14[] = { + /* Reed Organ */ + { 0x00, 0x53, { 0x0ac, 5570, 100, 0, 0, 0x06, 0xc0, 0x38, 0xf0, 0x00, 0x09, 0x1 }}, + { 0x54, 0x7f, { 0x0ad, 2497, 100, 0, 0, 0x00, 0xc0, 0x38, 0xf0, 0x00, 0x09, 0x1 }} +}; +static const YRW801_REGION_DATA regions_15[] = { + /* Accordion */ + { 0x15, 0x4c, { 0x006, 4261, 100, 0, 2, 0x00, 0xa4, 0x22, 0x90, 0x00, 0x09, 0x0 }}, + { 0x4d, 0x6c, { 0x007, 1530, 100, 0, 2, 0x00, 0xa4, 0x22, 0x90, 0x00, 0x09, 0x0 }}, + { 0x15, 0x6c, { 0x070, 4391, 100, 0, 3, 0x00, 0x8a, 0x23, 0xa0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_16[] = { + /* Harmonica */ + { 0x15, 0x6c, { 0x070, 4408, 100, 0, 0, 0x00, 0xae, 0x30, 0xa0, 0x00, 0x09, 0x2 }} +}; +static const YRW801_REGION_DATA regions_17[] = { + /* Tango Accordion */ + { 0x00, 0x53, { 0x0ac, 5573, 100, 0, 0, 0x00, 0xae, 0x38, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x54, 0x7f, { 0x0ad, 2500, 100, 0, 0, 0x00, 0xae, 0x38, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x15, 0x6c, { 0x041, 8479, 100, 0, 2, 0x00, 0x6a, 0x3a, 0x75, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_18[] = { + /* Nylon Guitar */ + { 0x15, 0x2f, { 0x0b3, 6964, 100, 0, 0, 0x05, 0xca, 0x28, 0xf5, 0x34, 0x09, 0x0 }}, + { 0x30, 0x36, { 0x0b7, 5567, 100, 0, 0, 0x0c, 0xca, 0x28, 0xf5, 0x34, 0x09, 0x0 }}, + { 0x37, 0x3c, { 0x0b5, 4653, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }}, + { 0x3d, 0x43, { 0x0b4, 3892, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x35, 0x09, 0x0 }}, + { 0x44, 0x60, { 0x0b6, 2723, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x35, 0x19, 0x0 }} +}; +static const YRW801_REGION_DATA regions_19[] = { + /* Steel Guitar */ + { 0x15, 0x31, { 0x00c, 6937, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x04, 0x19, 0x0 }}, + { 0x32, 0x38, { 0x00d, 5410, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x05, 0x09, 0x0 }}, + { 0x39, 0x47, { 0x00e, 4379, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf5, 0x94, 0x09, 0x0 }}, + { 0x48, 0x6c, { 0x00f, 2843, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf6, 0x95, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1a[] = { + /* Jazz Guitar */ + { 0x15, 0x31, { 0x05a, 6832, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }}, + { 0x32, 0x3f, { 0x05b, 4897, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }}, + { 0x40, 0x6c, { 0x05c, 3218, 100, 0, 0, 0x00, 0xca, 0x28, 0xf6, 0x34, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1b[] = { + /* Clean Guitar */ + { 0x15, 0x2c, { 0x061, 7053, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x54, 0x0a, 0x0 }}, + { 0x2d, 0x31, { 0x060, 6434, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x54, 0x0a, 0x0 }}, + { 0x32, 0x38, { 0x063, 5764, 100, 0, 1, 0x00, 0xbe, 0x29, 0xf5, 0x55, 0x0a, 0x0 }}, + { 0x39, 0x3f, { 0x062, 4627, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x0a, 0x0 }}, + { 0x40, 0x44, { 0x065, 3963, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x1a, 0x0 }}, + { 0x45, 0x4b, { 0x064, 3313, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x1a, 0x0 }}, + { 0x4c, 0x54, { 0x066, 2462, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf5, 0x55, 0x2a, 0x0 }}, + { 0x55, 0x6c, { 0x067, 1307, 100, 0, 1, 0x00, 0xb4, 0x29, 0xf6, 0x56, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1c[] = { + /* Muted Guitar */ + { 0x01, 0x7f, { 0x068, 4408, 100, 0, 0, 0x00, 0xcc, 0x28, 0xf6, 0x15, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1d[] = { + /* Overdriven Guitar */ + { 0x00, 0x40, { 0x0a5, 6589, 100, 0, 1, 0x00, 0xc0, 0x29, 0xf2, 0x11, 0x09, 0x0 }}, + { 0x41, 0x7f, { 0x0a6, 5428, 100, 0, 1, 0x00, 0xc0, 0x29, 0xf2, 0x11, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1e[] = { + /* Distortion Guitar */ + { 0x15, 0x2a, { 0x051, 6928, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x2b, 0x2e, { 0x052, 6433, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x2f, 0x32, { 0x053, 5944, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x33, 0x36, { 0x054, 5391, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x37, 0x3a, { 0x055, 4897, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x3b, 0x3e, { 0x056, 4408, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x3f, 0x42, { 0x057, 3892, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x43, 0x46, { 0x058, 3361, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }}, + { 0x47, 0x6c, { 0x059, 2784, 100, 0, 1, 0x00, 0xbc, 0x21, 0xa2, 0x12, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_1f[] = { + /* Guitar Harmonics */ + { 0x15, 0x44, { 0x05e, 5499, 100, 0, 0, 0x00, 0xce, 0x28, 0xf4, 0x24, 0x09, 0x0 }}, + { 0x45, 0x49, { 0x05d, 4850, 100, 0, 0, 0x00, 0xe2, 0x28, 0xf4, 0x24, 0x09, 0x0 }}, + { 0x4a, 0x6c, { 0x05f, 4259, 100, 0, 0, 0x00, 0xce, 0x28, 0xf4, 0x24, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_20[] = { + /* Acoustic Bass */ + { 0x15, 0x30, { 0x004, 8053, 100, 0, 0, 0x00, 0xe2, 0x18, 0xf5, 0x15, 0x09, 0x0 }}, + { 0x31, 0x6c, { 0x005, 4754, 100, 0, 0, 0x00, 0xe2, 0x18, 0xf5, 0x15, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_21[] = { + /* Fingered Bass */ + { 0x01, 0x20, { 0x04a, 8762, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }}, + { 0x21, 0x25, { 0x04b, 8114, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }}, + { 0x26, 0x2a, { 0x04c, 7475, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }}, + { 0x2b, 0x7f, { 0x04d, 6841, 100, 0, 0, 0x00, 0xde, 0x18, 0xf6, 0x14, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_22[] = { + /* Picked Bass */ + { 0x15, 0x23, { 0x04f, 7954, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf3, 0x90, 0x0a, 0x0 }}, + { 0x24, 0x2a, { 0x050, 7318, 100, 0, 0, 0x05, 0xcc, 0x18, 0xf3, 0x90, 0x1a, 0x0 }}, + { 0x2b, 0x2f, { 0x06b, 6654, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf3, 0x90, 0x2a, 0x0 }}, + { 0x30, 0x47, { 0x069, 6031, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf5, 0xb0, 0x0a, 0x0 }}, + { 0x48, 0x6c, { 0x06a, 5393, 100, 0, 0, 0x00, 0xcc, 0x18, 0xf5, 0xb0, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_23[] = { + /* Fretless Bass */ + { 0x01, 0x7f, { 0x04e, 5297, 100, 0, 0, 0x00, 0xd2, 0x10, 0xf3, 0x63, 0x19, 0x0 }} +}; +static const YRW801_REGION_DATA regions_24[] = { + /* Slap Bass 1 */ + { 0x15, 0x6c, { 0x0a3, 7606, 100, 0, 1, 0x00, 0xde, 0x19, 0xf5, 0x32, 0x1a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_25[] = { + /* Slap Bass 2 */ + { 0x01, 0x7f, { 0x0a2, 6694, 100, 0, 0, 0x00, 0xda, 0x20, 0xb0, 0x02, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_26[] = { + /* Synth Bass 1 */ + { 0x15, 0x6c, { 0x0be, 7466, 100, 0, 1, 0x00, 0xb8, 0x39, 0xf4, 0x14, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_27[] = { + /* Synth Bass 2 */ + { 0x00, 0x7f, { 0x117, 8103, 100, 0, 1, 0x00, 0xca, 0x39, 0xf3, 0x50, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_28[] = { + /* Violin */ + { 0x15, 0x3a, { 0x105, 5158, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x3b, 0x3f, { 0x102, 4754, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x40, 0x41, { 0x106, 4132, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x42, 0x44, { 0x107, 4033, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x45, 0x47, { 0x108, 3580, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x48, 0x4a, { 0x10a, 2957, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4b, 0x4c, { 0x10b, 2724, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4d, 0x4e, { 0x10c, 2530, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4f, 0x51, { 0x10d, 2166, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x52, 0x6c, { 0x109, 1825, 100, 0, 3, 0x00, 0xcc, 0x3b, 0xf3, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_29[] = { + /* Viola */ + { 0x15, 0x32, { 0x103, 5780, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x33, 0x35, { 0x104, 5534, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x36, 0x38, { 0x105, 5158, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x39, 0x3d, { 0x102, 4754, 100, 0, 3, 0x00, 0xca, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x3e, 0x3f, { 0x106, 4132, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x40, 0x42, { 0x107, 4033, 100, 0, 3, 0x00, 0xc4, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x43, 0x45, { 0x108, 3580, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x46, 0x48, { 0x10a, 2957, 100, 0, 3, 0x00, 0xca, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x49, 0x4a, { 0x10b, 2724, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x4b, 0x4c, { 0x10c, 2530, 100, 0, 3, 0x00, 0xca, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x4d, 0x4f, { 0x10d, 2166, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }}, + { 0x50, 0x6c, { 0x109, 1825, 100, 0, 3, 0x00, 0xd0, 0x3b, 0xa3, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2a[] = { + /* Cello */ + { 0x15, 0x2d, { 0x112, 6545, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x08, 0x0 }}, + { 0x2e, 0x37, { 0x113, 5764, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x08, 0x0 }}, + { 0x38, 0x3e, { 0x115, 4378, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x18, 0x0 }}, + { 0x3f, 0x44, { 0x116, 3998, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x18, 0x0 }}, + { 0x45, 0x6c, { 0x114, 3218, 100, 0, 3, 0x00, 0xc0, 0x33, 0xa0, 0x00, 0x18, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2b[] = { + /* Contrabass */ + { 0x15, 0x29, { 0x110, 7713, 100, 0, 1, 0x00, 0xc2, 0x19, 0x90, 0x00, 0x09, 0x0 }}, + { 0x2a, 0x6c, { 0x111, 6162, 100, 0, 1, 0x00, 0xc2, 0x19, 0x90, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2c[] = { + /* Tremolo Strings */ + { 0x15, 0x3b, { 0x0b0, 4810, 100, 0, 0, 0x0a, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x3c, 0x41, { 0x035, 4035, 100, 0, 0, 0x05, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x42, 0x47, { 0x033, 3129, 100, 0, 0, 0x05, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x48, 0x52, { 0x034, 2625, 100, 0, 0, 0x05, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 }}, + { 0x53, 0x6c, { 0x0af, 936, 100, 0, 0, 0x00, 0xde, 0x38, 0xf0, 0x00, 0x07, 0x6 } } +}; +static const YRW801_REGION_DATA regions_2d[] = { + /* Pizzicato Strings */ + { 0x15, 0x32, { 0x0b8, 6186, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x33, 0x3b, { 0x0b9, 5031, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x3c, 0x42, { 0x0bb, 4146, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x43, 0x48, { 0x0ba, 3245, 100, 0, 0, 0x00, 0xc2, 0x28, 0xf0, 0x00, 0x05, 0x0 }}, + { 0x49, 0x6c, { 0x0bc, 2352, 100, 0, 0, 0x00, 0xbc, 0x28, 0xf0, 0x00, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2e[] = { + /* Harp */ + { 0x15, 0x46, { 0x07e, 3740, 100, 0, 1, 0x00, 0xd2, 0x29, 0xf5, 0x25, 0x07, 0x0 }}, + { 0x47, 0x6c, { 0x07f, 2319, 100, 0, 1, 0x00, 0xd2, 0x29, 0xf5, 0x25, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_2f[] = { + /* Timpani */ + { 0x15, 0x6c, { 0x100, 6570, 100, 0, 0, 0x00, 0xf8, 0x28, 0xf0, 0x05, 0x16, 0x0 }} +}; +static const YRW801_REGION_DATA regions_30[] = { + /* Strings */ + { 0x15, 0x3b, { 0x13c, 4806, 100, 0, 0, 0x00, 0xc8, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x3c, 0x41, { 0x13e, 4035, 100, 0, 0, 0x00, 0xc8, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x42, 0x47, { 0x13d, 3122, 100, 0, 0, 0x00, 0xc8, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x48, 0x52, { 0x13f, 2629, 100, 0, 0, 0x00, 0xbe, 0x20, 0x80, 0x00, 0x07, 0x0 }}, + { 0x53, 0x6c, { 0x140, 950, 100, 0, 0, 0x00, 0xbe, 0x20, 0x80, 0x00, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_31[] = { + /* Slow Strings */ + { 0x15, 0x3b, { 0x0b0, 4810, 100, 0, 1, 0x0a, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x3c, 0x41, { 0x035, 4035, 100, 0, 1, 0x05, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x42, 0x47, { 0x033, 3129, 100, 0, 1, 0x05, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x48, 0x52, { 0x034, 2625, 100, 0, 1, 0x05, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 }}, + { 0x53, 0x6c, { 0x0af, 936, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf0, 0x00, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_32[] = { + /* Synth Strings 1 */ + { 0x05, 0x71, { 0x002, 6045, 100, -2, 0, 0x00, 0xa6, 0x20, 0x93, 0x22, 0x06, 0x0 }}, + { 0x15, 0x6c, { 0x0ae, 3261, 100, 2, 0, 0x00, 0xc6, 0x20, 0x70, 0x01, 0x06, 0x0 } } +}; +static const YRW801_REGION_DATA regions_33[] = { + /* Synth Strings 2 */ + { 0x15, 0x6c, { 0x002, 4513, 100, 5, 1, 0x00, 0xb4, 0x19, 0x70, 0x00, 0x06, 0x0 } }, + { 0x15, 0x6c, { 0x002, 4501, 100, -5, 1, 0x00, 0xb4, 0x19, 0x70, 0x00, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_34[] = { + /* Choir Aahs */ + { 0x15, 0x3a, { 0x018, 5010, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }}, + { 0x3b, 0x40, { 0x019, 4370, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }}, + { 0x41, 0x47, { 0x01a, 3478, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }}, + { 0x48, 0x6c, { 0x01b, 2197, 100, 0, 2, 0x00, 0xc2, 0x1a, 0x70, 0x00, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_35[] = { + /* Voice Oohs */ + { 0x15, 0x6c, { 0x029, 3596, 100, 0, 0, 0x00, 0xe6, 0x20, 0xf7, 0x20, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_36[] = { + /* Synth Voice */ + { 0x15, 0x6c, { 0x02a, 3482, 100, 0, 1, 0x00, 0xc2, 0x19, 0x85, 0x21, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_37[] = { + /* Orchestra Hit */ + { 0x15, 0x6c, { 0x049, 4394, 100, 0, 0, 0x00, 0xfe, 0x30, 0x80, 0x05, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_38[] = { + /* Trumpet */ + { 0x15, 0x3c, { 0x0f6, 4706, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x3d, 0x43, { 0x0f8, 3894, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x44, 0x48, { 0x0f7, 3118, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x49, 0x4e, { 0x0fa, 2322, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x4f, 0x55, { 0x0f9, 1634, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x56, 0x6c, { 0x0fb, 786, 100, 0, 2, 0x00, 0xd6, 0x32, 0xf3, 0x20, 0x0a, 0x0 } } +}; +static const YRW801_REGION_DATA regions_39[] = { + /* Trombone */ + { 0x15, 0x3a, { 0x0f0, 5053, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3b, 0x3f, { 0x0f1, 4290, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x40, 0x6c, { 0x0f2, 3580, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3a[] = { + /* Tuba */ + { 0x15, 0x2d, { 0x085, 7096, 100, 0, 1, 0x00, 0xde, 0x21, 0xf5, 0x10, 0x09, 0x0 }}, + { 0x2e, 0x6c, { 0x086, 6014, 100, 0, 1, 0x00, 0xde, 0x21, 0xf5, 0x10, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3b[] = { + /* Muted Trumpet */ + { 0x15, 0x45, { 0x0b1, 4135, 100, 0, 0, 0x00, 0xcc, 0x28, 0xf3, 0x10, 0x0a, 0x1 }}, + { 0x46, 0x6c, { 0x0b2, 2599, 100, 0, 0, 0x00, 0xcc, 0x28, 0x83, 0x10, 0x0a, 0x1 }} +}; +static const YRW801_REGION_DATA regions_3c[] = { + /* French Horns */ + { 0x15, 0x49, { 0x07c, 3624, 100, 0, 2, 0x00, 0xd0, 0x1a, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x4a, 0x6c, { 0x07d, 2664, 100, 0, 2, 0x00, 0xd0, 0x1a, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3d[] = { + /* Brass Section */ + { 0x15, 0x42, { 0x0fc, 4375, 100, 0, 0, 0x00, 0xd6, 0x28, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x43, 0x6c, { 0x0fd, 2854, 100, 0, 0, 0x00, 0xd6, 0x28, 0xf0, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_3e[] = { + /* Synth Brass 1 */ + { 0x01, 0x27, { 0x0d3, 9094, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x0da, 8335, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x0d4, 7558, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x0db, 6785, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x0d5, 6042, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x0dc, 5257, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x0d6, 4493, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x4c, 0x51, { 0x0dd, 3741, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x52, 0x57, { 0x0d7, 3012, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x58, 0x5d, { 0x0de, 2167, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x5e, 0x63, { 0x0d8, 1421, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x64, 0x7f, { 0x0d9, -115, 100, -1, 0, 0x00, 0xbe, 0x18, 0xa5, 0x11, 0x08, 0x0 }}, + { 0x01, 0x27, { 0x118, 9103, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x28, 0x2d, { 0x119, 8340, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x2e, 0x33, { 0x11a, 7565, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x34, 0x39, { 0x11b, 6804, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x3a, 0x3f, { 0x11c, 6042, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x40, 0x45, { 0x11d, 5277, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x46, 0x4b, { 0x11e, 4520, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x4c, 0x51, { 0x11f, 3741, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x52, 0x57, { 0x120, 3012, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x58, 0x5d, { 0x121, 2166, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x5e, 0x64, { 0x122, 1421, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } }, + { 0x65, 0x7f, { 0x123, -115, 100, 1, 1, 0x00, 0xbe, 0x19, 0x85, 0x23, 0x08, 0x0 } } +}; +static const YRW801_REGION_DATA regions_3f[] = { + /* Synth Brass 2 */ + { 0x01, 0x27, { 0x118, 9113, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x28, 0x2d, { 0x119, 8350, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x2e, 0x33, { 0x11a, 7575, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x34, 0x39, { 0x11b, 6814, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x3a, 0x3f, { 0x11c, 6052, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x40, 0x45, { 0x11d, 5287, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x46, 0x4b, { 0x11e, 4530, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x4c, 0x51, { 0x11f, 3751, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x52, 0x57, { 0x120, 3022, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x58, 0x5d, { 0x121, 2176, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x5e, 0x64, { 0x122, 1431, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x65, 0x7f, { 0x123, -105, 100, 3, 6, 0x00, 0xae, 0x26, 0x85, 0x23, 0x08, 0x0 } }, + { 0x00, 0x7f, { 0x124, 4034, 100, -3, 2, 0x00, 0xea, 0x22, 0x85, 0x23, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_40[] = { + /* Soprano Sax */ + { 0x15, 0x3f, { 0x0e3, 4228, 100, 0, 1, 0x00, 0xc8, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x0e4, 3495, 100, 0, 1, 0x00, 0xc8, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x0e5, 2660, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x0e6, 2002, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x52, 0x59, { 0x0e7, 1186, 100, 0, 1, 0x00, 0xd6, 0x21, 0xf5, 0x20, 0x0a, 0x0 }}, + { 0x59, 0x6c, { 0x0e8, 1730, 100, 0, 1, 0x00, 0xc8, 0x21, 0xf5, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_41[] = { + /* Alto Sax */ + { 0x15, 0x32, { 0x092, 6204, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x33, 0x35, { 0x096, 5812, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x36, 0x3a, { 0x099, 5318, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x3b, 0x3b, { 0x08f, 5076, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x3c, 0x3e, { 0x093, 4706, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x3f, 0x41, { 0x097, 4321, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x42, 0x44, { 0x09a, 3893, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x45, 0x47, { 0x090, 3497, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x48, 0x4a, { 0x094, 3119, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x4b, 0x4d, { 0x098, 2726, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x4e, 0x50, { 0x09b, 2393, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x51, 0x53, { 0x091, 2088, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }}, + { 0x54, 0x6c, { 0x095, 1732, 100, 0, 1, 0x00, 0xbe, 0x19, 0xf5, 0x20, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_42[] = { + /* Tenor Sax */ + { 0x24, 0x30, { 0x0e9, 6301, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x31, 0x34, { 0x0ea, 5781, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x35, 0x3a, { 0x0eb, 5053, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x3b, 0x41, { 0x0ed, 4165, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x42, 0x47, { 0x0ec, 3218, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x48, 0x51, { 0x0ee, 2462, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }}, + { 0x52, 0x6c, { 0x0ef, 1421, 100, 0, 1, 0x00, 0xbc, 0x19, 0xf4, 0x10, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_43[] = { + /* Baritone Sax */ + { 0x15, 0x2d, { 0x0df, 6714, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x2e, 0x34, { 0x0e1, 5552, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x35, 0x39, { 0x0e2, 5178, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }}, + { 0x3a, 0x6c, { 0x0e0, 4437, 100, 0, 1, 0x00, 0xce, 0x19, 0xf0, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_44[] = { + /* Oboe */ + { 0x15, 0x3c, { 0x042, 4493, 100, 0, 1, 0x00, 0xe6, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x3d, 0x43, { 0x044, 3702, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x44, 0x49, { 0x043, 2956, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x4a, 0x4f, { 0x046, 2166, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x50, 0x55, { 0x045, 1420, 100, 0, 1, 0x00, 0xdc, 0x39, 0xf4, 0x10, 0x0a, 0x0 }}, + { 0x56, 0x6c, { 0x047, 630, 100, 0, 1, 0x00, 0xe6, 0x39, 0xf4, 0x10, 0x0a, 0x0 } } +}; +static const YRW801_REGION_DATA regions_45[] = { + /* English Horn */ + { 0x15, 0x38, { 0x03c, 5098, 100, 0, 1, 0x00, 0xc4, 0x31, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x39, 0x3e, { 0x03b, 4291, 100, 0, 1, 0x00, 0xc4, 0x31, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3f, 0x6c, { 0x03d, 3540, 100, 0, 1, 0x00, 0xc4, 0x31, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_46[] = { + /* Bassoon */ + { 0x15, 0x22, { 0x038, 7833, 100, 0, 1, 0x00, 0xc6, 0x31, 0xf0, 0x00, 0x0b, 0x0 }}, + { 0x23, 0x2e, { 0x03a, 7070, 100, 0, 1, 0x00, 0xc6, 0x31, 0xf0, 0x00, 0x0b, 0x0 }}, + { 0x2f, 0x6c, { 0x039, 6302, 100, 0, 1, 0x00, 0xc6, 0x31, 0xf0, 0x00, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_47[] = { + /* Clarinet */ + { 0x15, 0x3b, { 0x09e, 5900, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x3c, 0x41, { 0x0a0, 5158, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x42, 0x4a, { 0x09f, 4260, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }}, + { 0x4b, 0x6c, { 0x0a1, 2957, 100, 0, 1, 0x00, 0xc8, 0x29, 0xf3, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_48[] = { + /* Piccolo */ + { 0x15, 0x40, { 0x071, 4803, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x41, 0x4d, { 0x072, 3314, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x4e, 0x53, { 0x073, 1731, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x54, 0x5f, { 0x074, 2085, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x60, 0x6c, { 0x075, 1421, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }} +}; +static const YRW801_REGION_DATA regions_49[] = { + /* Flute */ + { 0x15, 0x40, { 0x071, 4803, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x41, 0x4d, { 0x072, 3314, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf0, 0x00, 0x0a, 0x2 }}, + { 0x4e, 0x6c, { 0x073, 1731, 100, 0, 0, 0x00, 0xe6, 0x38, 0xf0, 0x00, 0x0a, 0x2 }} +}; +static const YRW801_REGION_DATA regions_4a[] = { + /* Recorder */ + { 0x15, 0x6f, { 0x0bd, 4897, 100, 0, 0, 0x00, 0xec, 0x30, 0x70, 0x00, 0x09, 0x1 }} +}; +static const YRW801_REGION_DATA regions_4b[] = { + /* Pan Flute */ + { 0x15, 0x6c, { 0x077, 2359, 100, 0, 0, 0x00, 0xde, 0x38, 0xf0, 0x00, 0x09, 0x3 }} +}; +static const YRW801_REGION_DATA regions_4c[] = { + /* Bottle Blow */ + { 0x15, 0x6c, { 0x077, 2359, 100, 0, 0, 0x00, 0xc8, 0x38, 0xf0, 0x00, 0x09, 0x1 }}, + { 0x01, 0x7f, { 0x125, 7372, 100, 0, 0, 0x1e, 0x80, 0x00, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_4d[] = { + /* Shakuhachi */ + { 0x00, 0x7f, { 0x0ab, 4548, 100, 0, 0, 0x00, 0xd6, 0x30, 0xf0, 0x00, 0x0a, 0x3 }}, + { 0x15, 0x6c, { 0x076, 3716, 100, 0, 0, 0x00, 0xa2, 0x28, 0x70, 0x00, 0x09, 0x2 }} +}; +static const YRW801_REGION_DATA regions_4e[] = { + /* Whistle */ + { 0x00, 0x7f, { 0x0aa, 1731, 100, 0, 4, 0x00, 0xd2, 0x2c, 0x70, 0x00, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_4f[] = { + /* Ocarina */ + { 0x00, 0x7f, { 0x0aa, 1731, 100, 0, 1, 0x00, 0xce, 0x29, 0x90, 0x00, 0x0a, 0x1 }} +}; +static const YRW801_REGION_DATA regions_50[] = { + /* Square Lead */ + { 0x01, 0x2a, { 0x0cc, 9853, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x2b, 0x36, { 0x0cd, 6785, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x37, 0x42, { 0x0ca, 5248, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x43, 0x4e, { 0x0cf, 3713, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x4f, 0x5a, { 0x0ce, 2176, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x5b, 0x7f, { 0x0cb, 640, 100, 3, 0, 0x00, 0xac, 0x38, 0xc6, 0x21, 0x09, 0x0 } }, + { 0x01, 0x2a, { 0x0cc, 9844, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x2b, 0x36, { 0x0cd, 6776, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x37, 0x42, { 0x0ca, 5239, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x43, 0x4e, { 0x0cf, 3704, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x4f, 0x5a, { 0x0ce, 2167, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 }}, + { 0x5b, 0x7f, { 0x0cb, 631, 100, -3, 0, 0x00, 0xac, 0x08, 0xc6, 0x21, 0x09, 0x0 } } +}; +static const YRW801_REGION_DATA regions_51[] = { + /* Sawtooth Lead */ + { 0x01, 0x27, { 0x118, 9108, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8345, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7570, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6809, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6047, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5282, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4525, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3746, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x52, 0x57, { 0x120, 3017, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2171, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1426, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x67, 0x7f, { 0x123, -110, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x01, 0x27, { 0x118, 9098, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8335, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7560, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6799, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6037, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5272, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4515, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3736, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x52, 0x57, { 0x120, 3007, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2161, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1416, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }}, + { 0x67, 0x7f, { 0x123, -120, 100, 0, 0, 0x00, 0xc8, 0x30, 0xf2, 0x22, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_52[] = { + /* Calliope Lead */ + { 0x00, 0x7f, { 0x0aa, 1731, 100, 0, 0, 0x00, 0xc2, 0x28, 0x90, 0x00, 0x0a, 0x2 }}, + { 0x15, 0x6c, { 0x076, 3716, 100, 0, 0, 0x00, 0xb6, 0x28, 0xb0, 0x00, 0x09, 0x2 }} +}; +static const YRW801_REGION_DATA regions_53[] = { + /* Chiffer Lead */ + { 0x00, 0x7f, { 0x13a, 3665, 100, 0, 2, 0x00, 0xcc, 0x2a, 0xf0, 0x10, 0x09, 0x1 }}, + { 0x01, 0x7f, { 0x0fe, 3660, 100, 0, 0, 0x00, 0xbe, 0x28, 0xf3, 0x10, 0x17, 0x0 }} +}; +static const YRW801_REGION_DATA regions_54[] = { + /* Charang Lead */ + { 0x00, 0x40, { 0x0a5, 6594, 100, 0, 3, 0x00, 0xba, 0x33, 0xf2, 0x11, 0x09, 0x0 }}, + { 0x41, 0x7f, { 0x0a6, 5433, 100, 0, 3, 0x00, 0xba, 0x33, 0xf2, 0x11, 0x09, 0x0 }}, + { 0x01, 0x27, { 0x118, 9098, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8335, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7560, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6799, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6037, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5272, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4515, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3736, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x52, 0x57, { 0x120, 3007, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2161, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1416, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }}, + { 0x67, 0x7f, { 0x123, -120, 100, 0, 2, 0x00, 0xa4, 0x2a, 0xf2, 0x22, 0x0e, 0x0 }} +}; +static const YRW801_REGION_DATA regions_55[] = { + /* Voice Lead */ + { 0x00, 0x7f, { 0x0aa, 1739, 100, 0, 6, 0x00, 0x8c, 0x2e, 0x90, 0x00, 0x0a, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3474, 100, 0, 1, 0x00, 0xd8, 0x29, 0xf0, 0x05, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_56[] = { + /* 5ths Lead */ + { 0x01, 0x27, { 0x118, 8468, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x28, 0x2d, { 0x119, 7705, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 6930, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6169, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 5407, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x40, 0x45, { 0x11d, 4642, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 3885, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3106, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x52, 0x57, { 0x120, 2377, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x58, 0x5d, { 0x121, 1531, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x5e, 0x64, { 0x122, 786, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 } }, + { 0x65, 0x7f, { 0x123, -750, 100, 0, 2, 0x00, 0xd0, 0x32, 0xf5, 0x20, 0x08, 0x0 }}, + { 0x05, 0x71, { 0x002, 4503, 100, 0, 1, 0x00, 0xb8, 0x31, 0xb3, 0x20, 0x0b, 0x0 }} +}; +static const YRW801_REGION_DATA regions_57[] = { + /* Bass & Lead */ + { 0x00, 0x7f, { 0x117, 8109, 100, 0, 1, 0x00, 0xbc, 0x29, 0xf3, 0x50, 0x08, 0x0 }}, + { 0x01, 0x27, { 0x118, 9097, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x28, 0x2d, { 0x119, 8334, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x2e, 0x33, { 0x11a, 7559, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x34, 0x39, { 0x11b, 6798, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x3a, 0x3f, { 0x11c, 6036, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x40, 0x45, { 0x11d, 5271, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x46, 0x4b, { 0x11e, 4514, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x4c, 0x51, { 0x11f, 3735, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x52, 0x57, { 0x120, 3006, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x58, 0x5d, { 0x121, 2160, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x5e, 0x66, { 0x122, 1415, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }}, + { 0x67, 0x7f, { 0x123, -121, 100, 0, 2, 0x00, 0xbc, 0x2a, 0xf2, 0x20, 0x0a, 0x0 }} +}; +static const YRW801_REGION_DATA regions_58[] = { + /* New Age Pad */ + { 0x15, 0x6c, { 0x002, 4501, 100, 0, 4, 0x00, 0xa4, 0x24, 0x80, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x0f3, 4253, 100, 0, 3, 0x00, 0x8c, 0x23, 0xa2, 0x14, 0x06, 0x1 }} +}; +static const YRW801_REGION_DATA regions_59[] = { + /* Warm Pad */ + { 0x15, 0x6c, { 0x04e, 5306, 100, 2, 2, 0x00, 0x92, 0x2a, 0x34, 0x23, 0x05, 0x2 } }, + { 0x15, 0x6c, { 0x029, 3575, 100, -2, 2, 0x00, 0xbe, 0x22, 0x31, 0x23, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5a[] = { + /* Polysynth Pad */ + { 0x01, 0x27, { 0x118, 9111, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x28, 0x2d, { 0x119, 8348, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x2e, 0x33, { 0x11a, 7573, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x34, 0x39, { 0x11b, 6812, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x3a, 0x3f, { 0x11c, 6050, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x40, 0x45, { 0x11d, 5285, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x46, 0x4b, { 0x11e, 4528, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x4c, 0x51, { 0x11f, 3749, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x52, 0x57, { 0x120, 3020, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x58, 0x5d, { 0x121, 2174, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x5e, 0x66, { 0x122, 1429, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x67, 0x7f, { 0x123, -107, 100, 0, 3, 0x00, 0xae, 0x23, 0xf2, 0x20, 0x07, 0x1 }}, + { 0x00, 0x7f, { 0x124, 4024, 100, 0, 2, 0x00, 0xae, 0x22, 0xe5, 0x20, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5b[] = { + /* Choir Pad */ + { 0x15, 0x3a, { 0x018, 5010, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x3b, 0x40, { 0x019, 4370, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x41, 0x47, { 0x01a, 3478, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x48, 0x6c, { 0x01b, 2197, 100, 0, 5, 0x00, 0xb0, 0x25, 0x70, 0x00, 0x06, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3482, 100, 0, 4, 0x00, 0x98, 0x24, 0x65, 0x21, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5c[] = { + /* Bowed Pad */ + { 0x15, 0x6c, { 0x101, 4790, 100, -1, 1, 0x00, 0xbe, 0x19, 0x44, 0x14, 0x16, 0x0 }}, + { 0x00, 0x7f, { 0x0aa, 1720, 100, 1, 1, 0x00, 0x94, 0x19, 0x40, 0x00, 0x06, 0x0 } } +}; +static const YRW801_REGION_DATA regions_5d[] = { + /* Metallic Pad */ + { 0x15, 0x31, { 0x00c, 6943, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x32, 0x38, { 0x00d, 5416, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x39, 0x47, { 0x00e, 4385, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x48, 0x6c, { 0x00f, 2849, 100, 0, 2, 0x00, 0xa0, 0x0a, 0x60, 0x03, 0x06, 0x0 }}, + { 0x00, 0x7f, { 0x03f, 4224, 100, 0, 1, 0x00, 0x9c, 0x31, 0x65, 0x16, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5e[] = { + /* Halo Pad */ + { 0x00, 0x7f, { 0x124, 4038, 100, 0, 2, 0x00, 0xa6, 0x1a, 0x85, 0x23, 0x08, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3471, 100, 0, 3, 0x00, 0xc0, 0x1b, 0xc0, 0x05, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_5f[] = { + /* Sweep Pad */ + { 0x01, 0x27, { 0x0d3, 9100, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x28, 0x2d, { 0x0da, 8341, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x2e, 0x33, { 0x0d4, 7564, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x34, 0x39, { 0x0db, 6791, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x3a, 0x3f, { 0x0d5, 6048, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x40, 0x45, { 0x0dc, 5263, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x46, 0x4b, { 0x0d6, 4499, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x4c, 0x51, { 0x0dd, 3747, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x52, 0x57, { 0x0d7, 3018, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x58, 0x5d, { 0x0de, 2173, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x5e, 0x63, { 0x0d8, 1427, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x64, 0x7f, { 0x0d9, -109, 100, 0, 1, 0x00, 0xce, 0x19, 0x13, 0x11, 0x06, 0x0 }}, + { 0x01, 0x27, { 0x0d3, 9088, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x28, 0x2d, { 0x0da, 8329, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x2e, 0x33, { 0x0d4, 7552, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x34, 0x39, { 0x0db, 6779, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x3a, 0x3f, { 0x0d5, 6036, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x40, 0x45, { 0x0dc, 5251, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x46, 0x4b, { 0x0d6, 4487, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x4c, 0x51, { 0x0dd, 3735, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x52, 0x57, { 0x0d7, 3006, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x58, 0x5d, { 0x0de, 2161, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x5e, 0x63, { 0x0d8, 1415, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }}, + { 0x64, 0x7f, { 0x0d9, -121, 100, 0, 0, 0x00, 0xce, 0x18, 0x13, 0x11, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_60[] = { + /* Ice Rain */ + { 0x01, 0x7f, { 0x04e, 9345, 100, 0, 2, 0x00, 0xcc, 0x22, 0xa3, 0x63, 0x17, 0x0 }}, + { 0x00, 0x7f, { 0x143, 5586, 20, 0, 2, 0x00, 0x6e, 0x2a, 0xf0, 0x05, 0x05, 0x0 } } +}; +static const YRW801_REGION_DATA regions_61[] = { + /* Soundtrack */ + { 0x15, 0x6c, { 0x002, 4501, 100, 0, 2, 0x00, 0xb6, 0x2a, 0x60, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x0f3, 1160, 100, 0, 5, 0x00, 0xa8, 0x2d, 0x52, 0x14, 0x06, 0x2 }} +}; +static const YRW801_REGION_DATA regions_62[] = { + /* Crystal */ + { 0x15, 0x6c, { 0x0f3, 1826, 100, 0, 3, 0x00, 0xb8, 0x33, 0xf6, 0x25, 0x25, 0x0 }}, + { 0x15, 0x2c, { 0x06d, 7454, 100, 0, 3, 0x00, 0xac, 0x3b, 0x85, 0x24, 0x06, 0x0 }}, + { 0x2d, 0x36, { 0x06e, 5925, 100, 0, 3, 0x00, 0xac, 0x3b, 0x85, 0x24, 0x06, 0x0 }}, + { 0x37, 0x6c, { 0x06f, 4403, 100, 0, 3, 0x09, 0xac, 0x3b, 0x85, 0x24, 0x06, 0x0 }} +}; +static const YRW801_REGION_DATA regions_63[] = { + /* Atmosphere */ + { 0x05, 0x71, { 0x002, 4509, 100, 0, 2, 0x00, 0xc8, 0x32, 0x73, 0x22, 0x06, 0x1 }}, + { 0x15, 0x2f, { 0x0b3, 6964, 100, 0, 2, 0x05, 0xc2, 0x32, 0xf5, 0x34, 0x07, 0x2 }}, + { 0x30, 0x36, { 0x0b7, 5567, 100, 0, 2, 0x0c, 0xc2, 0x32, 0xf5, 0x34, 0x07, 0x2 }}, + { 0x37, 0x3c, { 0x0b5, 4653, 100, 0, 2, 0x00, 0xc2, 0x32, 0xf6, 0x34, 0x07, 0x2 }}, + { 0x3d, 0x43, { 0x0b4, 3892, 100, 0, 2, 0x00, 0xc2, 0x32, 0xf6, 0x35, 0x07, 0x2 }}, + { 0x44, 0x60, { 0x0b6, 2723, 100, 0, 2, 0x00, 0xc2, 0x32, 0xf6, 0x35, 0x17, 0x2 }} +}; +static const YRW801_REGION_DATA regions_64[] = { + /* Brightness */ + { 0x00, 0x7f, { 0x137, 5285, 100, 0, 2, 0x00, 0xbe, 0x2a, 0xa5, 0x18, 0x08, 0x0 }}, + { 0x15, 0x6c, { 0x02a, 3481, 100, 0, 1, 0x00, 0xc8, 0x29, 0x80, 0x05, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_65[] = { + /* Goblins */ + { 0x15, 0x6c, { 0x002, 4501, 100, -1, 2, 0x00, 0xca, 0x2a, 0x40, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x009, 9679, 20, 1, 4, 0x00, 0x3c, 0x0c, 0x22, 0x11, 0x06, 0x0 } } +}; +static const YRW801_REGION_DATA regions_66[] = { + /* Echoes */ + { 0x15, 0x6c, { 0x02a, 3487, 100, 0, 3, 0x00, 0xae, 0x2b, 0xf5, 0x21, 0x06, 0x0 }}, + { 0x00, 0x7f, { 0x124, 4027, 100, 0, 3, 0x00, 0xae, 0x2b, 0x85, 0x23, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_67[] = { + /* Sci-Fi */ + { 0x15, 0x31, { 0x00c, 6940, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x32, 0x38, { 0x00d, 5413, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x39, 0x47, { 0x00e, 4382, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x48, 0x6c, { 0x00f, 2846, 100, 0, 3, 0x00, 0xc8, 0x2b, 0x90, 0x05, 0x06, 0x3 }}, + { 0x15, 0x6c, { 0x002, 4498, 100, 0, 2, 0x00, 0xd4, 0x22, 0x80, 0x01, 0x05, 0x0 }} +}; +static const YRW801_REGION_DATA regions_68[] = { + /* Sitar */ + { 0x00, 0x7f, { 0x10f, 4408, 100, 0, 2, 0x00, 0xc4, 0x32, 0xf4, 0x15, 0x16, 0x1 }} +}; +static const YRW801_REGION_DATA regions_69[] = { + /* Banjo */ + { 0x15, 0x34, { 0x013, 5685, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x35, 0x38, { 0x014, 5009, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x39, 0x3c, { 0x012, 4520, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x3d, 0x44, { 0x015, 3622, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x45, 0x4c, { 0x017, 2661, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }}, + { 0x4d, 0x6d, { 0x016, 1632, 100, 0, 0, 0x00, 0xdc, 0x38, 0xf6, 0x15, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6a[] = { + /* Shamisen */ + { 0x15, 0x6c, { 0x10e, 3273, 100, 0, 0, 0x00, 0xc0, 0x28, 0xf7, 0x76, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6b[] = { + /* Koto */ + { 0x00, 0x7f, { 0x0a9, 4033, 100, 0, 0, 0x00, 0xc6, 0x20, 0xf0, 0x06, 0x07, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6c[] = { + /* Kalimba */ + { 0x00, 0x7f, { 0x137, 3749, 100, 0, 0, 0x00, 0xce, 0x38, 0xf5, 0x18, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6d[] = { + /* Bagpipe */ + { 0x15, 0x39, { 0x0a4, 7683, 100, 0, 4, 0x00, 0xc0, 0x1c, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x15, 0x39, { 0x0a7, 7680, 100, 0, 1, 0x00, 0xaa, 0x19, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3a, 0x6c, { 0x0a8, 3697, 100, 0, 1, 0x00, 0xaa, 0x19, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6e[] = { + /* Fiddle */ + { 0x15, 0x3a, { 0x105, 5158, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x3b, 0x3f, { 0x102, 4754, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x40, 0x41, { 0x106, 4132, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x42, 0x44, { 0x107, 4033, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x45, 0x47, { 0x108, 3580, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x48, 0x4a, { 0x10a, 2957, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4b, 0x4c, { 0x10b, 2724, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4d, 0x4e, { 0x10c, 2530, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x4f, 0x51, { 0x10d, 2166, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }}, + { 0x52, 0x6c, { 0x109, 1825, 100, 0, 1, 0x00, 0xca, 0x31, 0xf3, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_6f[] = { + /* Shanai */ + { 0x15, 0x6c, { 0x041, 6946, 100, 0, 1, 0x00, 0xc4, 0x31, 0x95, 0x20, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_70[] = { + /* Tinkle Bell */ + { 0x15, 0x73, { 0x0f3, 1821, 100, 0, 3, 0x00, 0xc8, 0x3b, 0xd6, 0x25, 0x25, 0x0 }}, + { 0x00, 0x7f, { 0x137, 5669, 100, 0, 3, 0x00, 0x66, 0x3b, 0xf5, 0x18, 0x08, 0x0 }} +}; +static const YRW801_REGION_DATA regions_71[] = { + /* Agogo */ + { 0x15, 0x74, { 0x00b, 2474, 100, 0, 0, 0x00, 0xd2, 0x38, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_72[] = { + /* Steel Drums */ + { 0x01, 0x7f, { 0x0fe, 3670, 100, 0, 0, 0x00, 0xca, 0x38, 0xf3, 0x06, 0x17, 0x1 }}, + { 0x15, 0x6c, { 0x100, 9602, 100, 0, 0, 0x00, 0x54, 0x38, 0xb0, 0x05, 0x16, 0x1 }} +}; +static const YRW801_REGION_DATA regions_73[] = { + /* Woodblock */ + { 0x15, 0x6c, { 0x02c, 2963, 50, 0, 0, 0x07, 0xd4, 0x00, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_74[] = { + /* Taiko Drum */ + { 0x13, 0x6c, { 0x03e, 1194, 50, 0, 0, 0x00, 0xaa, 0x38, 0xf0, 0x04, 0x04, 0x0 }} +}; +static const YRW801_REGION_DATA regions_75[] = { + /* Melodic Tom */ + { 0x15, 0x6c, { 0x0c7, 6418, 50, 0, 0, 0x00, 0xe4, 0x38, 0xf0, 0x05, 0x01, 0x0 }} +}; +static const YRW801_REGION_DATA regions_76[] = { + /* Synth Drum */ + { 0x15, 0x6c, { 0x026, 3898, 50, 0, 0, 0x00, 0xd0, 0x38, 0xf0, 0x04, 0x04, 0x0 }} +}; +static const YRW801_REGION_DATA regions_77[] = { + /* Reverse Cymbal */ + { 0x15, 0x6c, { 0x031, 4138, 50, 0, 0, 0x00, 0xfe, 0x38, 0x3a, 0xf0, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_78[] = { + /* Guitar Fret Noise */ + { 0x15, 0x6c, { 0x138, 5266, 100, 0, 0, 0x00, 0xa0, 0x38, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_79[] = { + /* Breath Noise */ + { 0x01, 0x7f, { 0x125, 4269, 100, 0, 0, 0x1e, 0xd0, 0x38, 0xf0, 0x00, 0x09, 0x0 }} +}; +static const YRW801_REGION_DATA regions_7a[] = { + /* Seashore */ + { 0x15, 0x6c, { 0x008, 2965, 20, -2, 0, 0x00, 0xfe, 0x00, 0x20, 0x03, 0x04, 0x0 }}, + { 0x01, 0x7f, { 0x037, 4394, 20, 2, 0, 0x14, 0xfe, 0x00, 0x20, 0x04, 0x05, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7b[] = { + /* Bird Tweet */ + { 0x15, 0x6c, { 0x009, 8078, 5, -4, 7, 0x00, 0xc2, 0x0f, 0x22, 0x12, 0x07, 0x0 }}, + { 0x15, 0x6c, { 0x009, 3583, 5, 4, 5, 0x00, 0xae, 0x15, 0x72, 0x12, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7c[] = { + /* Telephone Ring */ + { 0x15, 0x6c, { 0x003, 3602, 10, 0, 0, 0x00, 0xce, 0x00, 0xf0, 0x00, 0x0f, 0x0 }} +}; +static const YRW801_REGION_DATA regions_7d[] = { + /* Helicopter */ + { 0x0c, 0x7f, { 0x001, 2965, 10, -2, 0, 0x00, 0xe0, 0x08, 0x30, 0x01, 0x07, 0x0 }}, + { 0x01, 0x7f, { 0x037, 4394, 10, 2, 0, 0x44, 0x76, 0x00, 0x30, 0x01, 0x07, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7e[] = { + /* Applause */ + { 0x15, 0x6c, { 0x036, 8273, 20, -6, 7, 0x00, 0xc4, 0x0f, 0x70, 0x01, 0x05, 0x0 }}, + { 0x15, 0x6c, { 0x036, 8115, 5, 6, 7, 0x00, 0xc6, 0x07, 0x70, 0x01, 0x05, 0x0 } } +}; +static const YRW801_REGION_DATA regions_7f[] = { + /* Gun Shot */ + { 0x15, 0x6c, { 0x139, 2858, 20, 0, 0, 0x00, 0xbe, 0x38, 0xf0, 0x03, 0x00, 0x0 }} +}; +static const YRW801_REGION_DATA regions_drums[] = { + { 0x18, 0x18, { 0x0cb, 6397, 100, 3, 0, 0x00, 0xf4, 0x38, 0xc9, 0x1c, 0x0c, 0x0 } }, + { 0x19, 0x19, { 0x0c4, 3714, 100, 0, 0, 0x00, 0xe0, 0x00, 0x97, 0x19, 0x09, 0x0 } }, + { 0x1a, 0x1a, { 0x0c4, 3519, 100, 0, 0, 0x00, 0xea, 0x00, 0x61, 0x01, 0x07, 0x0 } }, + { 0x1b, 0x1b, { 0x0c4, 3586, 100, 0, 0, 0x00, 0xea, 0x00, 0xf7, 0x19, 0x09, 0x0 } }, + { 0x1c, 0x1c, { 0x0c4, 3586, 100, 0, 0, 0x00, 0xea, 0x00, 0x81, 0x01, 0x07, 0x0 } }, + { 0x1e, 0x1e, { 0x0c3, 4783, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x1f, 0x1f, { 0x0d1, 4042, 100, 0, 0, 0x00, 0xd6, 0x00, 0xf0, 0x05, 0x05, 0x0 } }, + { 0x20, 0x20, { 0x0d2, 5943, 100, 0, 0, 0x00, 0xcc, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x21, 0x21, { 0x011, 3842, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x16, 0x06, 0x0 } }, + { 0x23, 0x23, { 0x011, 4098, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x16, 0x06, 0x0 } }, + { 0x24, 0x24, { 0x011, 4370, 100, 0, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x06, 0x0 } }, + { 0x25, 0x25, { 0x0d2, 4404, 100, 0, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x06, 0x0 } }, + { 0x26, 0x26, { 0x0d1, 4298, 100, 0, 0, 0x00, 0xd6, 0x00, 0xf0, 0x05, 0x05, 0x0 } }, + { 0x27, 0x27, { 0x00a, 4403, 100, -1, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x28, 0x28, { 0x0d1, 4554, 100, 0, 0, 0x00, 0xdc, 0x00, 0xf0, 0x07, 0x07, 0x0 } }, + { 0x29, 0x29, { 0x0c8, 4242, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf6, 0x16, 0x06, 0x0 }}, + { 0x2a, 0x2a, { 0x079, 6160, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf5, 0x19, 0x09, 0x0 } }, + { 0x2b, 0x2b, { 0x0c8, 4626, 100, -3, 0, 0x00, 0xd6, 0x00, 0xf6, 0x16, 0x06, 0x0 }}, + { 0x2c, 0x2c, { 0x07b, 6039, 100, 2, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x2d, 0x2d, { 0x0c8, 5394, 100, -2, 0, 0x00, 0xd6, 0x00, 0xf6, 0x16, 0x06, 0x0 }}, + { 0x2e, 0x2e, { 0x07a, 5690, 100, 2, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x05, 0x0 } }, + { 0x2f, 0x2f, { 0x0c7, 5185, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf6, 0x17, 0x07, 0x0 } }, + { 0x30, 0x30, { 0x0c7, 5650, 100, 3, 0, 0x00, 0xe0, 0x00, 0xf6, 0x17, 0x07, 0x0 } }, + { 0x31, 0x31, { 0x031, 4395, 100, 2, 0, 0x00, 0xea, 0x00, 0xf0, 0x05, 0x05, 0x0 } }, + { 0x32, 0x32, { 0x0c7, 6162, 100, 4, 0, 0x00, 0xe0, 0x00, 0xf6, 0x17, 0x07, 0x0 } }, + { 0x33, 0x33, { 0x02e, 4391, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x05, 0x05, 0x0 }}, + { 0x34, 0x34, { 0x07a, 3009, 100, -2, 0, 0x00, 0xea, 0x00, 0xf2, 0x15, 0x05, 0x0 }}, + { 0x35, 0x35, { 0x021, 4522, 100, -3, 0, 0x00, 0xd6, 0x00, 0xf0, 0x05, 0x05, 0x0 }}, + { 0x36, 0x36, { 0x025, 5163, 100, 1, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x37, 0x37, { 0x031, 5287, 100, -1, 0, 0x00, 0xea, 0x00, 0xf5, 0x16, 0x06, 0x0 }}, + { 0x38, 0x38, { 0x01d, 4395, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x39, 0x39, { 0x031, 4647, 100, -2, 0, 0x00, 0xea, 0x00, 0xf4, 0x16, 0x06, 0x0 }}, + { 0x3a, 0x3a, { 0x09d, 4426, 100, -4, 0, 0x00, 0xe0, 0x00, 0xf4, 0x17, 0x07, 0x0 }}, + { 0x3b, 0x3b, { 0x02e, 4659, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x06, 0x06, 0x0 }}, + { 0x3c, 0x3c, { 0x01c, 4769, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x3d, 0x3d, { 0x01c, 4611, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x3e, 0x3e, { 0x01e, 4402, 100, -3, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x3f, 0x3f, { 0x01f, 4387, 100, -3, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x40, 0x40, { 0x01f, 3983, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x41, 0x41, { 0x09c, 4526, 100, 2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x42, 0x42, { 0x09c, 4016, 100, 2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x43, 0x43, { 0x00b, 4739, 100, -4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x44, 0x44, { 0x00b, 4179, 100, -4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x45, 0x45, { 0x02f, 4787, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x46, 0x46, { 0x030, 4665, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x47, 0x47, { 0x144, 4519, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x0b, 0x0 } }, + { 0x48, 0x48, { 0x144, 4111, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x0b, 0x0 } }, + { 0x49, 0x49, { 0x024, 6408, 100, 3, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4a, 0x4a, { 0x024, 4144, 100, 3, 0, 0x00, 0xcc, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4b, 0x4b, { 0x020, 4001, 100, 2, 0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4c, 0x4c, { 0x02c, 4402, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4d, 0x4d, { 0x02c, 3612, 100, 4, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 } }, + { 0x4e, 0x4e, { 0x022, 4129, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x4f, 0x4f, { 0x023, 4147, 100, -2, 0, 0x00, 0xea, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x50, 0x50, { 0x032, 4412, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x08, 0x09, 0x0 }}, + { 0x51, 0x51, { 0x032, 4385, 100, -4, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }}, + { 0x52, 0x52, { 0x02f, 5935, 100, -1, 0, 0x00, 0xd6, 0x00, 0xf0, 0x00, 0x09, 0x0 }} +}; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#define REGION(num) \ + { \ + ARRAY_SIZE(regions##num), regions##num \ + } +const YRW801_REGION_DATA_PTR snd_yrw801_regions[0x81] = { + REGION(_00), REGION(_01), REGION(_02), REGION(_03), + REGION(_04), REGION(_05), REGION(_06), REGION(_07), + REGION(_08), REGION(_09), REGION(_0a), REGION(_0b), + REGION(_0c), REGION(_0d), REGION(_0e), REGION(_0f), + REGION(_10), REGION(_11), REGION(_12), REGION(_13), + REGION(_14), REGION(_15), REGION(_16), REGION(_17), + REGION(_18), REGION(_19), REGION(_1a), REGION(_1b), + REGION(_1c), REGION(_1d), REGION(_1e), REGION(_1f), + REGION(_20), REGION(_21), REGION(_22), REGION(_23), + REGION(_24), REGION(_25), REGION(_26), REGION(_27), + REGION(_28), REGION(_29), REGION(_2a), REGION(_2b), + REGION(_2c), REGION(_2d), REGION(_2e), REGION(_2f), + REGION(_30), REGION(_31), REGION(_32), REGION(_33), + REGION(_34), REGION(_35), REGION(_36), REGION(_37), + REGION(_38), REGION(_39), REGION(_3a), REGION(_3b), + REGION(_3c), REGION(_3d), REGION(_3e), REGION(_3f), + REGION(_40), REGION(_41), REGION(_42), REGION(_43), + REGION(_44), REGION(_45), REGION(_46), REGION(_47), + REGION(_48), REGION(_49), REGION(_4a), REGION(_4b), + REGION(_4c), REGION(_4d), REGION(_4e), REGION(_4f), + REGION(_50), REGION(_51), REGION(_52), REGION(_53), + REGION(_54), REGION(_55), REGION(_56), REGION(_57), + REGION(_58), REGION(_59), REGION(_5a), REGION(_5b), + REGION(_5c), REGION(_5d), REGION(_5e), REGION(_5f), + REGION(_60), REGION(_61), REGION(_62), REGION(_63), + REGION(_64), REGION(_65), REGION(_66), REGION(_67), + REGION(_68), REGION(_69), REGION(_6a), REGION(_6b), + REGION(_6c), REGION(_6d), REGION(_6e), REGION(_6f), + REGION(_70), REGION(_71), REGION(_72), REGION(_73), + REGION(_74), REGION(_75), REGION(_76), REGION(_77), + REGION(_78), REGION(_79), REGION(_7a), REGION(_7b), + REGION(_7c), REGION(_7d), REGION(_7e), REGION(_7f), + REGION(_drums) +}; \ No newline at end of file diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index 3c0d22131..ee761e627 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -1622,4 +1622,5 @@ const fm_drv_t nuked_opl_drv = { &nuked_drv_reset_buffer, &nuked_drv_set_do_cycles, NULL, + NULL, }; \ No newline at end of file diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index bb52f3c55..b2466dcb5 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -368,6 +368,13 @@ ymfm_drv_set_do_cycles(void *priv, int8_t do_cycles) drv->set_do_cycles(do_cycles); } +static void +ymfm_drv_generate(void *priv, int32_t *data, uint32_t num_samples) +{ + YMFMChipBase *drv = (YMFMChipBase *) priv; + drv->generate_resampled(data, num_samples); +} + const device_t ym3812_ymfm_device = { .name = "Yamaha YM3812 OPL2 (YMFM)", .internal_name = "ym3812_ymfm", @@ -431,5 +438,6 @@ const fm_drv_t ymfm_drv { &ymfm_drv_reset_buffer, &ymfm_drv_set_do_cycles, NULL, + ymfm_drv_generate, }; } diff --git a/src/sound/yrw801.h b/src/sound/yrw801.h new file mode 100644 index 000000000..0df3c0343 --- /dev/null +++ b/src/sound/yrw801.h @@ -0,0 +1,45 @@ +/* + * RoboPlay for MSX + * Copyright (C) 2022 by RoboSoft Inc. + * + * yrw801.h + */ + +/* Cacodemon345: Added pointer structs from Linux */ + +#pragma once + +#include + +typedef struct +{ + uint16_t tone; + int16_t pitch_offset; + uint8_t key_scaling; + int8_t panpot; + uint8_t vibrato; + uint8_t tone_attenuate; + uint8_t volume_factor; + uint8_t reg_lfo_vibrato; + uint8_t reg_attack_decay1; + uint8_t reg_level_decay2; + uint8_t reg_release_correction; + uint8_t reg_tremolo; +} YRW801_WAVE_DATA; + +typedef struct +{ + uint8_t key_min; + uint8_t key_max; + + YRW801_WAVE_DATA wave_data; +} YRW801_REGION_DATA; + +typedef struct +{ + int count; + + const YRW801_REGION_DATA* regions; +} YRW801_REGION_DATA_PTR; + +extern const YRW801_REGION_DATA_PTR snd_yrw801_regions[0x81]; \ No newline at end of file From 4445f1f108d2fa26498ab8a9212dacb584866347 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Nov 2022 21:24:17 +0600 Subject: [PATCH 5/8] Fix OPL4 audio crackling --- src/sound/midi_opl4.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c index f816cff49..b75ac23b5 100644 --- a/src/sound/midi_opl4.c +++ b/src/sound/midi_opl4.c @@ -269,12 +269,15 @@ static const uint8_t g_volume_table[128] = { 2, 2, 2, 1, 1, 0, 0, 0 }; +#define BUFFER_SEGMENTS 10 +#define RENDER_RATE (48000 / 100) + typedef struct opl4_midi { fm_drv_t opl4; MIDI_CHANNEL_DATA midi_channel_data[16]; VOICE_DATA voice_data[24]; - int16_t buffer[SOUNDBUFLEN * 2]; - float buffer_float[SOUNDBUFLEN * 2]; + int16_t buffer[(48000 / 100) * 2 * BUFFER_SEGMENTS]; + float buffer_float[(48000 / 100) * 2 * BUFFER_SEGMENTS]; uint32_t midi_pos; bool on; atomic_bool gen_in_progress; @@ -537,13 +540,14 @@ program_change(uint8_t midi_channel, uint8_t program, opl4_midi_t *opl4_midi) opl4_midi->midi_channel_data[midi_channel].instrument = program; } -#define RENDER_RATE (48000 / 100) static void opl4_midi_thread(void *arg) { opl4_midi_t *opl4_midi = opl4_midi_cur; uint32_t i = 0; uint32_t buf_size = RENDER_RATE * 2; + uint32_t buf_size_segments = buf_size * BUFFER_SEGMENTS; + uint32_t buf_pos = 0; int32_t buffer[RENDER_RATE * 2]; @@ -558,16 +562,24 @@ opl4_midi_thread(void *arg) atomic_store(&opl4_midi->gen_in_progress, false); if (sound_is_float) { for (i = 0; i < (buf_size / 2); i++) { - opl4_midi->buffer_float[i * 2] = buffer[i * 2] / 32768.0; - opl4_midi->buffer_float[(i * 2) + 1] = buffer[(i * 2) + 1] / 32768.0; + opl4_midi->buffer_float[(i + buf_pos) * 2] = buffer[i * 2] / 32768.0; + opl4_midi->buffer_float[((i + buf_pos) * 2) + 1] = buffer[(i * 2) + 1] / 32768.0; + } + buf_pos += buf_size / 2; + if (buf_pos >= (buf_size_segments / 2)) { + givealbuffer_midi(opl4_midi->buffer_float, buf_size_segments); + buf_pos = 0; } - givealbuffer_midi(opl4_midi->buffer_float, buf_size); } else { for (i = 0; i < (buf_size / 2); i++) { - opl4_midi->buffer[i * 2] = buffer[i * 2] & 0xFFFF; /* Outputs are clamped beforehand. */ - opl4_midi->buffer[(i * 2) + 1] = buffer[(i * 2) + 1] & 0xFFFF; /* Outputs are clamped beforehand. */ + opl4_midi->buffer[(i + buf_pos) * 2] = buffer[i * 2] & 0xFFFF; /* Outputs are clamped beforehand. */ + opl4_midi->buffer[((i + buf_pos) * 2) + 1] = buffer[(i * 2) + 1] & 0xFFFF; /* Outputs are clamped beforehand. */ + } + buf_pos += buf_size / 2; + if (buf_pos >= (buf_size_segments / 2)) { + givealbuffer_midi(opl4_midi->buffer, buf_size_segments); + buf_pos = 0; } - givealbuffer_midi(opl4_midi->buffer, buf_size); } } } From 767d486aee07a28cdf422d42557ca5bd3d945cda Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 27 Nov 2022 21:35:08 +0600 Subject: [PATCH 6/8] OPL4 activation timestamp now comes from platform timestamp --- src/sound/midi_opl4.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c index b75ac23b5..5a4480835 100644 --- a/src/sound/midi_opl4.c +++ b/src/sound/midi_opl4.c @@ -270,7 +270,7 @@ static const uint8_t g_volume_table[128] = { }; #define BUFFER_SEGMENTS 10 -#define RENDER_RATE (48000 / 100) +#define RENDER_RATE (48000 / 100) typedef struct opl4_midi { fm_drv_t opl4; @@ -419,8 +419,7 @@ note_on(uint8_t note, uint8_t velocity, MIDI_CHANNEL_DATA *midi_channel, opl4_mi const YRW801_WAVE_DATA *wave_data[2]; VOICE_DATA *voice[2]; uint8_t i = 0, voices = 0; - uint32_t j = 0; - static uint64_t activation_num = 0; + uint32_t j = 0; while (opl4_midi->gen_in_progress) { } @@ -444,7 +443,7 @@ note_on(uint8_t note, uint8_t velocity, MIDI_CHANNEL_DATA *midi_channel, opl4_mi for (i = 0; i < voices; i++) { voice[i] = get_voice(wave_data[i], opl4_midi); voice[i]->is_active = true; - voice[i]->activated = activation_num++; + voice[i]->activated = plat_get_ticks(); voice[i]->midi_channel = midi_channel; voice[i]->note = note; @@ -543,11 +542,11 @@ program_change(uint8_t midi_channel, uint8_t program, opl4_midi_t *opl4_midi) static void opl4_midi_thread(void *arg) { - opl4_midi_t *opl4_midi = opl4_midi_cur; - uint32_t i = 0; - uint32_t buf_size = RENDER_RATE * 2; + opl4_midi_t *opl4_midi = opl4_midi_cur; + uint32_t i = 0; + uint32_t buf_size = RENDER_RATE * 2; uint32_t buf_size_segments = buf_size * BUFFER_SEGMENTS; - uint32_t buf_pos = 0; + uint32_t buf_pos = 0; int32_t buffer[RENDER_RATE * 2]; From 83f256bed9f2da4cf34149d052e9b94360e92c60 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 29 Nov 2022 12:08:01 +0600 Subject: [PATCH 7/8] Attempt minimizing polyphony problems --- src/sound/midi_opl4.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c index 5a4480835..25984e832 100644 --- a/src/sound/midi_opl4.c +++ b/src/sound/midi_opl4.c @@ -314,7 +314,23 @@ get_voice(const YRW801_WAVE_DATA *wave_data, opl4_midi_t *opl4_midi) } } - /* If no free voice found, deactivate the 'oldest' */ + /* If no free voice is found, look for one with the same instrument */ + if (free_voice->is_active) { + for (uint8_t voice = 0; voice < 24; voice++) { + if (opl4_midi_cur->voice_data[voice].is_active + && opl4_midi_cur->voice_data[voice].wave_data == wave_data) { + free_voice = &opl4_midi_cur->voice_data[voice]; + free_voice->is_active = 0; + free_voice->activated = 0; + + free_voice->reg_misc &= ~OPL4_KEY_ON_BIT; + opl4_write_wave_register(OPL4_REG_MISC + free_voice->number, free_voice->reg_misc, opl4_midi); + return free_voice; + } + } + } + + /* If still no free voice found, deactivate the 'oldest' */ if (free_voice->is_active) { free_voice = oldest_voice; free_voice->is_active = 0; From 7ac1867222e779bbdb29591478bfdf86d16e9b4f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 30 Nov 2022 00:20:03 +0600 Subject: [PATCH 8/8] Make free voice behaviour more aggressive --- src/sound/midi_opl4.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c index 25984e832..ba641701c 100644 --- a/src/sound/midi_opl4.c +++ b/src/sound/midi_opl4.c @@ -309,8 +309,10 @@ get_voice(const YRW801_WAVE_DATA *wave_data, opl4_midi_t *opl4_midi) break; } - if (opl4_midi_cur->voice_data[voice].activated < free_voice->activated) + if (opl4_midi_cur->voice_data[voice].activated < free_voice->activated) { free_voice = &opl4_midi_cur->voice_data[voice]; + break; + } } }