mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-01 08:23:15 +00:00
ALL: synced with ScummVM
This commit is contained in:
parent
9bf27c050d
commit
022c027ab4
@ -112,9 +112,10 @@ Tim Phillips
|
||||
Edward Rudd
|
||||
Eugene Sandulenko
|
||||
Johannes Schickel
|
||||
Keith Scroggins
|
||||
Won Star
|
||||
Ludvig Strigeus
|
||||
Keith Scroggins
|
||||
Fedor Strizhniou
|
||||
David Symonds
|
||||
Jordi Vilalta
|
||||
Robin Watts
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -34,70 +34,143 @@ static const Bit32u PROCESS_DELAY = 1;
|
||||
static const Bit32u MODE_3_ADDITIONAL_DELAY = 1;
|
||||
static const Bit32u MODE_3_FEEDBACK_DELAY = 1;
|
||||
|
||||
// Default reverb settings for modes 0-2. These correspond to CM-32L / LAPC-I "new" reverb settings. MT-32 reverb is a bit different.
|
||||
// Default reverb settings for "new" reverb model implemented in CM-32L / LAPC-I.
|
||||
// Found by tracing reverb RAM data lines (thanks go to Lord_Nightmare & balrog).
|
||||
const BReverbSettings &BReverbModel::getCM32L_LAPCSettings(const ReverbMode mode) {
|
||||
static const Bit32u MODE_0_NUMBER_OF_ALLPASSES = 3;
|
||||
static const Bit32u MODE_0_ALLPASSES[] = {994, 729, 78};
|
||||
static const Bit32u MODE_0_NUMBER_OF_COMBS = 4; // Well, actually there are 3 comb filters, but the entrance LPF + delay can be processed via a hacked comb.
|
||||
static const Bit32u MODE_0_COMBS[] = {705 + PROCESS_DELAY, 2349, 2839, 3632};
|
||||
static const Bit32u MODE_0_OUTL[] = {2349, 141, 1960};
|
||||
static const Bit32u MODE_0_OUTR[] = {1174, 1570, 145};
|
||||
static const Bit32u MODE_0_COMB_FACTOR[] = {0xA0, 0x60, 0x60, 0x60};
|
||||
static const Bit32u MODE_0_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
|
||||
static const Bit32u MODE_0_DRY_AMP[] = {0xA0, 0xA0, 0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xD0};
|
||||
static const Bit32u MODE_0_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0};
|
||||
static const Bit32u MODE_0_LPF_AMP = 0x60;
|
||||
|
||||
static const Bit32u MODE_0_NUMBER_OF_ALLPASSES = 3;
|
||||
static const Bit32u MODE_0_ALLPASSES[] = {994, 729, 78};
|
||||
static const Bit32u MODE_0_NUMBER_OF_COMBS = 4; // Well, actually there are 3 comb filters, but the entrance LPF + delay can be processed via a hacked comb.
|
||||
static const Bit32u MODE_0_COMBS[] = {705 + PROCESS_DELAY, 2349, 2839, 3632};
|
||||
static const Bit32u MODE_0_OUTL[] = {2349, 141, 1960};
|
||||
static const Bit32u MODE_0_OUTR[] = {1174, 1570, 145};
|
||||
static const Bit32u MODE_0_COMB_FACTOR[] = {0xA0, 0x60, 0x60, 0x60};
|
||||
static const Bit32u MODE_0_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
|
||||
static const Bit32u MODE_0_DRY_AMP[] = {0xA0, 0xA0, 0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xD0};
|
||||
static const Bit32u MODE_0_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0};
|
||||
static const Bit32u MODE_0_LPF_AMP = 0x60;
|
||||
static const Bit32u MODE_1_NUMBER_OF_ALLPASSES = 3;
|
||||
static const Bit32u MODE_1_ALLPASSES[] = {1324, 809, 176};
|
||||
static const Bit32u MODE_1_NUMBER_OF_COMBS = 4; // Same as for mode 0 above
|
||||
static const Bit32u MODE_1_COMBS[] = {961 + PROCESS_DELAY, 2619, 3545, 4519};
|
||||
static const Bit32u MODE_1_OUTL[] = {2618, 1760, 4518};
|
||||
static const Bit32u MODE_1_OUTR[] = {1300, 3532, 2274};
|
||||
static const Bit32u MODE_1_COMB_FACTOR[] = {0x80, 0x60, 0x60, 0x60};
|
||||
static const Bit32u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
|
||||
static const Bit32u MODE_1_DRY_AMP[] = {0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xE0};
|
||||
static const Bit32u MODE_1_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0};
|
||||
static const Bit32u MODE_1_LPF_AMP = 0x60;
|
||||
|
||||
static const Bit32u MODE_1_NUMBER_OF_ALLPASSES = 3;
|
||||
static const Bit32u MODE_1_ALLPASSES[] = {1324, 809, 176};
|
||||
static const Bit32u MODE_1_NUMBER_OF_COMBS = 4; // Same as for mode 0 above
|
||||
static const Bit32u MODE_1_COMBS[] = {961 + PROCESS_DELAY, 2619, 3545, 4519};
|
||||
static const Bit32u MODE_1_OUTL[] = {2618, 1760, 4518};
|
||||
static const Bit32u MODE_1_OUTR[] = {1300, 3532, 2274};
|
||||
static const Bit32u MODE_1_COMB_FACTOR[] = {0x80, 0x60, 0x60, 0x60};
|
||||
static const Bit32u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
|
||||
static const Bit32u MODE_1_DRY_AMP[] = {0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xE0};
|
||||
static const Bit32u MODE_1_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0};
|
||||
static const Bit32u MODE_1_LPF_AMP = 0x60;
|
||||
static const Bit32u MODE_2_NUMBER_OF_ALLPASSES = 3;
|
||||
static const Bit32u MODE_2_ALLPASSES[] = {969, 644, 157};
|
||||
static const Bit32u MODE_2_NUMBER_OF_COMBS = 4; // Same as for mode 0 above
|
||||
static const Bit32u MODE_2_COMBS[] = {116 + PROCESS_DELAY, 2259, 2839, 3539};
|
||||
static const Bit32u MODE_2_OUTL[] = {2259, 718, 1769};
|
||||
static const Bit32u MODE_2_OUTR[] = {1136, 2128, 1};
|
||||
static const Bit32u MODE_2_COMB_FACTOR[] = {0, 0x20, 0x20, 0x20};
|
||||
static const Bit32u MODE_2_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0,
|
||||
0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0,
|
||||
0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0};
|
||||
static const Bit32u MODE_2_DRY_AMP[] = {0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xB0, 0xC0, 0xE0};
|
||||
static const Bit32u MODE_2_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0};
|
||||
static const Bit32u MODE_2_LPF_AMP = 0x80;
|
||||
|
||||
static const Bit32u MODE_2_NUMBER_OF_ALLPASSES = 3;
|
||||
static const Bit32u MODE_2_ALLPASSES[] = {969, 644, 157};
|
||||
static const Bit32u MODE_2_NUMBER_OF_COMBS = 4; // Same as for mode 0 above
|
||||
static const Bit32u MODE_2_COMBS[] = {116 + PROCESS_DELAY, 2259, 2839, 3539};
|
||||
static const Bit32u MODE_2_OUTL[] = {2259, 718, 1769};
|
||||
static const Bit32u MODE_2_OUTR[] = {1136, 2128, 1};
|
||||
static const Bit32u MODE_2_COMB_FACTOR[] = {0, 0x20, 0x20, 0x20};
|
||||
static const Bit32u MODE_2_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0,
|
||||
0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0,
|
||||
0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0};
|
||||
static const Bit32u MODE_2_DRY_AMP[] = {0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xB0, 0xC0, 0xE0};
|
||||
static const Bit32u MODE_2_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0};
|
||||
static const Bit32u MODE_2_LPF_AMP = 0x80;
|
||||
static const Bit32u MODE_3_NUMBER_OF_ALLPASSES = 0;
|
||||
static const Bit32u MODE_3_NUMBER_OF_COMBS = 1;
|
||||
static const Bit32u MODE_3_DELAY[] = {16000 + MODE_3_FEEDBACK_DELAY + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY};
|
||||
static const Bit32u MODE_3_OUTL[] = {400, 624, 960, 1488, 2256, 3472, 5280, 8000};
|
||||
static const Bit32u MODE_3_OUTR[] = {800, 1248, 1920, 2976, 4512, 6944, 10560, 16000};
|
||||
static const Bit32u MODE_3_COMB_FACTOR[] = {0x68};
|
||||
static const Bit32u MODE_3_COMB_FEEDBACK[] = {0x68, 0x60};
|
||||
static const Bit32u MODE_3_DRY_AMP[] = {0x20, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
|
||||
0x20, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50};
|
||||
static const Bit32u MODE_3_WET_AMP[] = {0x18, 0x18, 0x28, 0x40, 0x60, 0x80, 0xA8, 0xF8};
|
||||
|
||||
static const Bit32u MODE_3_NUMBER_OF_ALLPASSES = 0;
|
||||
static const Bit32u MODE_3_NUMBER_OF_COMBS = 1;
|
||||
static const Bit32u MODE_3_DELAY[] = {16000 + MODE_3_FEEDBACK_DELAY + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY};
|
||||
static const Bit32u MODE_3_OUTL[] = {400, 624, 960, 1488, 2256, 3472, 5280, 8000};
|
||||
static const Bit32u MODE_3_OUTR[] = {800, 1248, 1920, 2976, 4512, 6944, 10560, 16000};
|
||||
static const Bit32u MODE_3_COMB_FACTOR[] = {0x68};
|
||||
static const Bit32u MODE_3_COMB_FEEDBACK[] = {0x68, 0x60};
|
||||
static const Bit32u MODE_3_DRY_AMP[] = {0x20, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50};
|
||||
static const Bit32u MODE_3_WET_AMP[] = {0x18, 0x18, 0x28, 0x40, 0x60, 0x80, 0xA8, 0xF8};
|
||||
static const BReverbSettings REVERB_MODE_0_SETTINGS = {MODE_0_NUMBER_OF_ALLPASSES, MODE_0_ALLPASSES, MODE_0_NUMBER_OF_COMBS, MODE_0_COMBS, MODE_0_OUTL, MODE_0_OUTR, MODE_0_COMB_FACTOR, MODE_0_COMB_FEEDBACK, MODE_0_DRY_AMP, MODE_0_WET_AMP, MODE_0_LPF_AMP};
|
||||
static const BReverbSettings REVERB_MODE_1_SETTINGS = {MODE_1_NUMBER_OF_ALLPASSES, MODE_1_ALLPASSES, MODE_1_NUMBER_OF_COMBS, MODE_1_COMBS, MODE_1_OUTL, MODE_1_OUTR, MODE_1_COMB_FACTOR, MODE_1_COMB_FEEDBACK, MODE_1_DRY_AMP, MODE_1_WET_AMP, MODE_1_LPF_AMP};
|
||||
static const BReverbSettings REVERB_MODE_2_SETTINGS = {MODE_2_NUMBER_OF_ALLPASSES, MODE_2_ALLPASSES, MODE_2_NUMBER_OF_COMBS, MODE_2_COMBS, MODE_2_OUTL, MODE_2_OUTR, MODE_2_COMB_FACTOR, MODE_2_COMB_FEEDBACK, MODE_2_DRY_AMP, MODE_2_WET_AMP, MODE_2_LPF_AMP};
|
||||
static const BReverbSettings REVERB_MODE_3_SETTINGS = {MODE_3_NUMBER_OF_ALLPASSES, NULL, MODE_3_NUMBER_OF_COMBS, MODE_3_DELAY, MODE_3_OUTL, MODE_3_OUTR, MODE_3_COMB_FACTOR, MODE_3_COMB_FEEDBACK, MODE_3_DRY_AMP, MODE_3_WET_AMP, 0};
|
||||
|
||||
static const BReverbSettings REVERB_MODE_0_SETTINGS = {MODE_0_NUMBER_OF_ALLPASSES, MODE_0_ALLPASSES, MODE_0_NUMBER_OF_COMBS, MODE_0_COMBS, MODE_0_OUTL, MODE_0_OUTR, MODE_0_COMB_FACTOR, MODE_0_COMB_FEEDBACK, MODE_0_DRY_AMP, MODE_0_WET_AMP, MODE_0_LPF_AMP};
|
||||
static const BReverbSettings REVERB_MODE_1_SETTINGS = {MODE_1_NUMBER_OF_ALLPASSES, MODE_1_ALLPASSES, MODE_1_NUMBER_OF_COMBS, MODE_1_COMBS, MODE_1_OUTL, MODE_1_OUTR, MODE_1_COMB_FACTOR, MODE_1_COMB_FEEDBACK, MODE_1_DRY_AMP, MODE_1_WET_AMP, MODE_1_LPF_AMP};
|
||||
static const BReverbSettings REVERB_MODE_2_SETTINGS = {MODE_2_NUMBER_OF_ALLPASSES, MODE_2_ALLPASSES, MODE_2_NUMBER_OF_COMBS, MODE_2_COMBS, MODE_2_OUTL, MODE_2_OUTR, MODE_2_COMB_FACTOR, MODE_2_COMB_FEEDBACK, MODE_2_DRY_AMP, MODE_2_WET_AMP, MODE_2_LPF_AMP};
|
||||
static const BReverbSettings REVERB_MODE_3_SETTINGS = {MODE_3_NUMBER_OF_ALLPASSES, NULL, MODE_3_NUMBER_OF_COMBS, MODE_3_DELAY, MODE_3_OUTL, MODE_3_OUTR, MODE_3_COMB_FACTOR, MODE_3_COMB_FEEDBACK, MODE_3_DRY_AMP, MODE_3_WET_AMP, 0};
|
||||
static const BReverbSettings * const REVERB_SETTINGS[] = {&REVERB_MODE_0_SETTINGS, &REVERB_MODE_1_SETTINGS, &REVERB_MODE_2_SETTINGS, &REVERB_MODE_3_SETTINGS};
|
||||
|
||||
static const BReverbSettings * const REVERB_SETTINGS[] = {&REVERB_MODE_0_SETTINGS, &REVERB_MODE_1_SETTINGS, &REVERB_MODE_2_SETTINGS, &REVERB_MODE_3_SETTINGS};
|
||||
return *REVERB_SETTINGS[mode];
|
||||
}
|
||||
|
||||
// Default reverb settings for "old" reverb model implemented in MT-32.
|
||||
// Found by tracing reverb RAM data lines (thanks go to Lord_Nightmare & balrog).
|
||||
const BReverbSettings &BReverbModel::getMT32Settings(const ReverbMode mode) {
|
||||
static const Bit32u MODE_0_NUMBER_OF_ALLPASSES = 3;
|
||||
static const Bit32u MODE_0_ALLPASSES[] = {994, 729, 78};
|
||||
static const Bit32u MODE_0_NUMBER_OF_COMBS = 4; // Same as above in the new model implementation
|
||||
static const Bit32u MODE_0_COMBS[] = {575 + PROCESS_DELAY, 2040, 2752, 3629};
|
||||
static const Bit32u MODE_0_OUTL[] = {2040, 687, 1814};
|
||||
static const Bit32u MODE_0_OUTR[] = {1019, 2072, 1};
|
||||
static const Bit32u MODE_0_COMB_FACTOR[] = {0xB0, 0x60, 0x60, 0x60};
|
||||
static const Bit32u MODE_0_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
|
||||
static const Bit32u MODE_0_DRY_AMP[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80};
|
||||
static const Bit32u MODE_0_WET_AMP[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x70, 0xA0, 0xE0};
|
||||
static const Bit32u MODE_0_LPF_AMP = 0x80;
|
||||
|
||||
static const Bit32u MODE_1_NUMBER_OF_ALLPASSES = 3;
|
||||
static const Bit32u MODE_1_ALLPASSES[] = {1324, 809, 176};
|
||||
static const Bit32u MODE_1_NUMBER_OF_COMBS = 4; // Same as above in the new model implementation
|
||||
static const Bit32u MODE_1_COMBS[] = {961 + PROCESS_DELAY, 2619, 3545, 4519};
|
||||
static const Bit32u MODE_1_OUTL[] = {2618, 1760, 4518};
|
||||
static const Bit32u MODE_1_OUTR[] = {1300, 3532, 2274};
|
||||
static const Bit32u MODE_1_COMB_FACTOR[] = {0x90, 0x60, 0x60, 0x60};
|
||||
static const Bit32u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
|
||||
static const Bit32u MODE_1_DRY_AMP[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80};
|
||||
static const Bit32u MODE_1_WET_AMP[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x70, 0xA0, 0xE0};
|
||||
static const Bit32u MODE_1_LPF_AMP = 0x80;
|
||||
|
||||
static const Bit32u MODE_2_NUMBER_OF_ALLPASSES = 3;
|
||||
static const Bit32u MODE_2_ALLPASSES[] = {969, 644, 157};
|
||||
static const Bit32u MODE_2_NUMBER_OF_COMBS = 4; // Same as above in the new model implementation
|
||||
static const Bit32u MODE_2_COMBS[] = {116 + PROCESS_DELAY, 2259, 2839, 3539};
|
||||
static const Bit32u MODE_2_OUTL[] = {2259, 718, 1769};
|
||||
static const Bit32u MODE_2_OUTR[] = {1136, 2128, 1};
|
||||
static const Bit32u MODE_2_COMB_FACTOR[] = {0, 0x60, 0x60, 0x60};
|
||||
static const Bit32u MODE_2_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
|
||||
0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
|
||||
static const Bit32u MODE_2_DRY_AMP[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80};
|
||||
static const Bit32u MODE_2_WET_AMP[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x70, 0xA0, 0xE0};
|
||||
static const Bit32u MODE_2_LPF_AMP = 0x80;
|
||||
|
||||
static const Bit32u MODE_3_NUMBER_OF_ALLPASSES = 0;
|
||||
static const Bit32u MODE_3_NUMBER_OF_COMBS = 1;
|
||||
static const Bit32u MODE_3_DELAY[] = {16000 + MODE_3_FEEDBACK_DELAY + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY};
|
||||
static const Bit32u MODE_3_OUTL[] = {400, 624, 960, 1488, 2256, 3472, 5280, 8000};
|
||||
static const Bit32u MODE_3_OUTR[] = {800, 1248, 1920, 2976, 4512, 6944, 10560, 16000};
|
||||
static const Bit32u MODE_3_COMB_FACTOR[] = {0x68};
|
||||
static const Bit32u MODE_3_COMB_FEEDBACK[] = {0x68, 0x60};
|
||||
static const Bit32u MODE_3_DRY_AMP[] = {0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x10, 0x20, 0x20, 0x10, 0x20, 0x10, 0x20, 0x10};
|
||||
static const Bit32u MODE_3_WET_AMP[] = {0x08, 0x18, 0x28, 0x40, 0x60, 0x80, 0xA8, 0xF8};
|
||||
|
||||
static const BReverbSettings REVERB_MODE_0_SETTINGS = {MODE_0_NUMBER_OF_ALLPASSES, MODE_0_ALLPASSES, MODE_0_NUMBER_OF_COMBS, MODE_0_COMBS, MODE_0_OUTL, MODE_0_OUTR, MODE_0_COMB_FACTOR, MODE_0_COMB_FEEDBACK, MODE_0_DRY_AMP, MODE_0_WET_AMP, MODE_0_LPF_AMP};
|
||||
static const BReverbSettings REVERB_MODE_1_SETTINGS = {MODE_1_NUMBER_OF_ALLPASSES, MODE_1_ALLPASSES, MODE_1_NUMBER_OF_COMBS, MODE_1_COMBS, MODE_1_OUTL, MODE_1_OUTR, MODE_1_COMB_FACTOR, MODE_1_COMB_FEEDBACK, MODE_1_DRY_AMP, MODE_1_WET_AMP, MODE_1_LPF_AMP};
|
||||
static const BReverbSettings REVERB_MODE_2_SETTINGS = {MODE_2_NUMBER_OF_ALLPASSES, MODE_2_ALLPASSES, MODE_2_NUMBER_OF_COMBS, MODE_2_COMBS, MODE_2_OUTL, MODE_2_OUTR, MODE_2_COMB_FACTOR, MODE_2_COMB_FEEDBACK, MODE_2_DRY_AMP, MODE_2_WET_AMP, MODE_2_LPF_AMP};
|
||||
static const BReverbSettings REVERB_MODE_3_SETTINGS = {MODE_3_NUMBER_OF_ALLPASSES, NULL, MODE_3_NUMBER_OF_COMBS, MODE_3_DELAY, MODE_3_OUTL, MODE_3_OUTR, MODE_3_COMB_FACTOR, MODE_3_COMB_FEEDBACK, MODE_3_DRY_AMP, MODE_3_WET_AMP, 0};
|
||||
|
||||
static const BReverbSettings * const REVERB_SETTINGS[] = {&REVERB_MODE_0_SETTINGS, &REVERB_MODE_1_SETTINGS, &REVERB_MODE_2_SETTINGS, &REVERB_MODE_3_SETTINGS};
|
||||
|
||||
return *REVERB_SETTINGS[mode];
|
||||
}
|
||||
|
||||
// This algorithm tries to emulate exactly Boss multiplication operation (at least this is what we see on reverb RAM data lines).
|
||||
// Also LA32 is suspected to use the similar one to perform PCM interpolation and ring modulation.
|
||||
@ -153,14 +226,7 @@ bool RingBuffer::isEmpty() const {
|
||||
}
|
||||
|
||||
void RingBuffer::mute() {
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
Sample *buf = buffer;
|
||||
for (Bit32u i = 0; i < size; i++) {
|
||||
*buf++ = 0;
|
||||
}
|
||||
#else
|
||||
memset(buffer, 0, size * sizeof(Sample));
|
||||
#endif
|
||||
Synth::muteSampleBuffer(buffer, size);
|
||||
}
|
||||
|
||||
AllpassFilter::AllpassFilter(const Bit32u useSize) : RingBuffer(useSize) {}
|
||||
@ -195,10 +261,10 @@ void CombFilter::process(const Sample in) {
|
||||
const Sample last = buffer[index];
|
||||
|
||||
// prepare input + feedback
|
||||
const Sample filterIn = in + weirdMul(next(), feedbackFactor, 0xF0 /* Maybe 0x80 ? */);
|
||||
const Sample filterIn = in + weirdMul(next(), feedbackFactor, 0xF0);
|
||||
|
||||
// store input + feedback processed by a low-pass filter
|
||||
buffer[index] = weirdMul(last, filterFactor, 0x40) - filterIn;
|
||||
buffer[index] = weirdMul(last, filterFactor, 0xC0) - filterIn;
|
||||
}
|
||||
|
||||
Sample CombFilter::getOutputAt(const Bit32u outIndex) const {
|
||||
@ -256,8 +322,10 @@ void TapDelayCombFilter::setOutputPositions(const Bit32u useOutL, const Bit32u u
|
||||
outR = useOutR;
|
||||
}
|
||||
|
||||
BReverbModel::BReverbModel(const ReverbMode mode)
|
||||
: allpasses(NULL), combs(NULL), currentSettings(*REVERB_SETTINGS[mode]), tapDelayMode(mode == REVERB_MODE_TAP_DELAY) {}
|
||||
BReverbModel::BReverbModel(const ReverbMode mode, const bool mt32CompatibleModel) :
|
||||
allpasses(NULL), combs(NULL),
|
||||
currentSettings(mt32CompatibleModel ? getMT32Settings(mode) : getCM32L_LAPCSettings(mode)),
|
||||
tapDelayMode(mode == REVERB_MODE_TAP_DELAY) {}
|
||||
|
||||
BReverbModel::~BReverbModel() {
|
||||
close();
|
||||
@ -334,12 +402,21 @@ void BReverbModel::setParameters(Bit8u time, Bit8u level) {
|
||||
if (time == 0 && level == 0) {
|
||||
dryAmp = wetLevel = 0;
|
||||
} else {
|
||||
dryAmp = currentSettings.dryAmps[level];
|
||||
if (tapDelayMode && ((time == 0) || (time == 1 && level == 1))) {
|
||||
// Looks like MT-32 implementation has some minor quirks in this mode:
|
||||
// for odd level values, the output level changes sometimes depending on the time value which doesn't seem right.
|
||||
dryAmp = currentSettings.dryAmps[level + 8];
|
||||
} else {
|
||||
dryAmp = currentSettings.dryAmps[level];
|
||||
}
|
||||
wetLevel = currentSettings.wetLevels[level];
|
||||
}
|
||||
}
|
||||
|
||||
bool BReverbModel::isActive() const {
|
||||
if (combs == NULL) {
|
||||
return false;
|
||||
}
|
||||
for (Bit32u i = 0; i < currentSettings.numberOfAllpasses; i++) {
|
||||
if (!allpasses[i]->isEmpty()) return true;
|
||||
}
|
||||
@ -349,14 +426,34 @@ bool BReverbModel::isActive() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BReverbModel::isMT32Compatible(const ReverbMode mode) const {
|
||||
return ¤tSettings == &getMT32Settings(mode);
|
||||
}
|
||||
|
||||
void BReverbModel::process(const Sample *inLeft, const Sample *inRight, Sample *outLeft, Sample *outRight, unsigned long numSamples) {
|
||||
if (combs == NULL) {
|
||||
Synth::muteSampleBuffer(outLeft, numSamples);
|
||||
Synth::muteSampleBuffer(outRight, numSamples);
|
||||
return;
|
||||
}
|
||||
|
||||
Sample dry;
|
||||
|
||||
while (numSamples > 0) {
|
||||
while ((numSamples--) > 0) {
|
||||
if (tapDelayMode) {
|
||||
dry = *inLeft + *inRight;
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
dry = (*(inLeft++) * 0.5f) + (*(inRight++) * 0.5f);
|
||||
#else
|
||||
dry = (*(inLeft++) >> 1) + (*(inRight++) >> 1);
|
||||
#endif
|
||||
} else {
|
||||
dry = *inLeft / 2 + *inRight / 2;
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
dry = (*(inLeft++) * 0.25f) + (*(inRight++) * 0.25f);
|
||||
#elif MT32EMU_BOSS_REVERB_PRECISE_MODE
|
||||
dry = (*(inLeft++) >> 1) / 2 + (*(inRight++) >> 1) / 2;
|
||||
#else
|
||||
dry = (*(inLeft++) >> 2) + (*(inRight++) >> 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Looks like dryAmp doesn't change in MT-32 but it does in CM-32L / LAPC-I
|
||||
@ -365,8 +462,12 @@ void BReverbModel::process(const Sample *inLeft, const Sample *inRight, Sample *
|
||||
if (tapDelayMode) {
|
||||
TapDelayCombFilter *comb = static_cast<TapDelayCombFilter *> (*combs);
|
||||
comb->process(dry);
|
||||
*outLeft = weirdMul(comb->getLeftOutput(), wetLevel, 0xFF);
|
||||
*outRight = weirdMul(comb->getRightOutput(), wetLevel, 0xFF);
|
||||
if (outLeft != NULL) {
|
||||
*(outLeft++) = weirdMul(comb->getLeftOutput(), wetLevel, 0xFF);
|
||||
}
|
||||
if (outRight != NULL) {
|
||||
*(outRight++) = weirdMul(comb->getRightOutput(), wetLevel, 0xFF);
|
||||
}
|
||||
} else {
|
||||
// If the output position is equal to the comb size, get it now in order not to loose it
|
||||
Sample link = combs[0]->getOutputAt(currentSettings.combSizes[0] - 1);
|
||||
@ -389,33 +490,38 @@ void BReverbModel::process(const Sample *inLeft, const Sample *inRight, Sample *
|
||||
combs[2]->process(link);
|
||||
combs[3]->process(link);
|
||||
|
||||
Sample outL2 = combs[2]->getOutputAt(currentSettings.outLPositions[1]);
|
||||
Sample outL3 = combs[3]->getOutputAt(currentSettings.outLPositions[2]);
|
||||
Sample outR1 = combs[1]->getOutputAt(currentSettings.outRPositions[0]);
|
||||
Sample outR2 = combs[2]->getOutputAt(currentSettings.outRPositions[1]);
|
||||
Sample outR3 = combs[3]->getOutputAt(currentSettings.outRPositions[2]);
|
||||
|
||||
if (outLeft != NULL) {
|
||||
Sample outL2 = combs[2]->getOutputAt(currentSettings.outLPositions[1]);
|
||||
Sample outL3 = combs[3]->getOutputAt(currentSettings.outLPositions[2]);
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
*outLeft = 1.5f * (outL1 + outL2) + outL3;
|
||||
*outRight = 1.5f * (outR1 + outR2) + outR3;
|
||||
Sample outSample = 1.5f * (outL1 + outL2) + outL3;
|
||||
#elif MT32EMU_BOSS_REVERB_PRECISE_MODE
|
||||
/* NOTE:
|
||||
* Thanks to Mok for discovering, the adder in BOSS reverb chip is found to perform addition with saturation to avoid integer overflow.
|
||||
* Analysing of the algorithm suggests that the overflow is most probable when the combs output is added below.
|
||||
* So, despite this isn't actually accurate, we only add the check here for performance reasons.
|
||||
*/
|
||||
Sample outSample = Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s((Bit32s)outL1 + Bit32s(outL1 >> 1)) + (Bit32s)outL2) + Bit32s(outL2 >> 1)) + (Bit32s)outL3);
|
||||
#else
|
||||
outL1 += outL1 >> 1;
|
||||
outL2 += outL2 >> 1;
|
||||
*outLeft = outL1 + outL2 + outL3;
|
||||
|
||||
outR1 += outR1 >> 1;
|
||||
outR2 += outR2 >> 1;
|
||||
*outRight = outR1 + outR2 + outR3;
|
||||
Sample outSample = Synth::clipBit16s((Bit32s)outL1 + Bit32s(outL1 >> 1) + (Bit32s)outL2 + Bit32s(outL2 >> 1) + (Bit32s)outL3);
|
||||
#endif
|
||||
*outLeft = weirdMul(*outLeft, wetLevel, 0xFF);
|
||||
*outRight = weirdMul(*outRight, wetLevel, 0xFF);
|
||||
*(outLeft++) = weirdMul(outSample, wetLevel, 0xFF);
|
||||
}
|
||||
if (outRight != NULL) {
|
||||
Sample outR1 = combs[1]->getOutputAt(currentSettings.outRPositions[0]);
|
||||
Sample outR2 = combs[2]->getOutputAt(currentSettings.outRPositions[1]);
|
||||
Sample outR3 = combs[3]->getOutputAt(currentSettings.outRPositions[2]);
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
Sample outSample = 1.5f * (outR1 + outR2) + outR3;
|
||||
#elif MT32EMU_BOSS_REVERB_PRECISE_MODE
|
||||
// See the note above for the left channel output.
|
||||
Sample outSample = Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s(Synth::clipBit16s((Bit32s)outR1 + Bit32s(outR1 >> 1)) + (Bit32s)outR2) + Bit32s(outR2 >> 1)) + (Bit32s)outR3);
|
||||
#else
|
||||
Sample outSample = Synth::clipBit16s((Bit32s)outR1 + Bit32s(outR1 >> 1) + (Bit32s)outR2 + Bit32s(outR2 >> 1) + (Bit32s)outR3);
|
||||
#endif
|
||||
*(outRight++) = weirdMul(outSample, wetLevel, 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
numSamples--;
|
||||
inLeft++;
|
||||
inRight++;
|
||||
outLeft++;
|
||||
outRight++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -97,8 +97,11 @@ class BReverbModel {
|
||||
Bit32u wetLevel;
|
||||
void mute();
|
||||
|
||||
static const BReverbSettings &getCM32L_LAPCSettings(const ReverbMode mode);
|
||||
static const BReverbSettings &getMT32Settings(const ReverbMode mode);
|
||||
|
||||
public:
|
||||
BReverbModel(const ReverbMode mode);
|
||||
BReverbModel(const ReverbMode mode, const bool mt32CompatibleModel = false);
|
||||
~BReverbModel();
|
||||
// After construction or a close(), open() must be called at least once before any other call (with the exception of close()).
|
||||
void open();
|
||||
@ -107,6 +110,7 @@ public:
|
||||
void setParameters(Bit8u time, Bit8u level);
|
||||
void process(const Sample *inLeft, const Sample *inRight, Sample *outLeft, Sample *outRight, unsigned long numSamples);
|
||||
bool isActive() const;
|
||||
bool isMT32Compatible(const ReverbMode mode) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -33,14 +33,6 @@ static const Bit8u PartialMixStruct[13] = {
|
||||
1, 3, 3, 2, 2, 2, 2
|
||||
};
|
||||
|
||||
static const float floatKeyfollow[17] = {
|
||||
-1.0f, -1.0f / 2.0f, -1.0f / 4.0f, 0.0f,
|
||||
1.0f / 8.0f, 1.0f / 4.0f, 3.0f / 8.0f, 1.0f / 2.0f, 5.0f / 8.0f, 3.0f / 4.0f, 7.0f / 8.0f, 1.0f,
|
||||
5.0f / 4.0f, 3.0f / 2.0f, 2.0f,
|
||||
1.0009765625f, 1.0048828125f
|
||||
};
|
||||
|
||||
|
||||
RhythmPart::RhythmPart(Synth *useSynth, unsigned int usePartNum): Part(useSynth, usePartNum) {
|
||||
strcpy(name, "Rhythm");
|
||||
rhythmTemp = &synth->mt32ram.rhythmTemp[0];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -20,20 +20,24 @@
|
||||
|
||||
namespace MT32Emu {
|
||||
|
||||
// Known ROMs
|
||||
static const ROMInfo CTRL_MT32_V1_04 = {65536, "5a5cb5a77d7d55ee69657c2f870416daed52dea7", ROMInfo::Control, "ctrl_mt32_1_04", "MT-32 Control v1.04", ROMInfo::Full, NULL, NULL};
|
||||
static const ROMInfo CTRL_MT32_V1_05 = {65536, "e17a3a6d265bf1fa150312061134293d2b58288c", ROMInfo::Control, "ctrl_mt32_1_05", "MT-32 Control v1.05", ROMInfo::Full, NULL, NULL};
|
||||
static const ROMInfo CTRL_MT32_V1_06 = {65536, "a553481f4e2794c10cfe597fef154eef0d8257de", ROMInfo::Control, "ctrl_mt32_1_06", "MT-32 Control v1.06", ROMInfo::Full, NULL, NULL};
|
||||
static const ROMInfo CTRL_MT32_V1_07 = {65536, "b083518fffb7f66b03c23b7eb4f868e62dc5a987", ROMInfo::Control, "ctrl_mt32_1_07", "MT-32 Control v1.07", ROMInfo::Full, NULL, NULL};
|
||||
static const ROMInfo CTRL_MT32_BLUER = {65536, "7b8c2a5ddb42fd0732e2f22b3340dcf5360edf92", ROMInfo::Control, "ctrl_mt32_bluer", "MT-32 Control BlueRidge", ROMInfo::Full, NULL, NULL};
|
||||
static const ROMInfo *getKnownROMInfoFromList(unsigned int index) {
|
||||
static const ControlROMFeatureSet MT32_COMPATIBLE(true);
|
||||
static const ControlROMFeatureSet CM32L_COMPATIBLE(false);
|
||||
|
||||
static const ROMInfo CTRL_CM32L_V1_00 = {65536, "73683d585cd6948cc19547942ca0e14a0319456d", ROMInfo::Control, "ctrl_cm32l_1_00", "CM-32L/LAPC-I Control v1.00", ROMInfo::Full, NULL, NULL};
|
||||
static const ROMInfo CTRL_CM32L_V1_02 = {65536, "a439fbb390da38cada95a7cbb1d6ca199cd66ef8", ROMInfo::Control, "ctrl_cm32l_1_02", "CM-32L/LAPC-I Control v1.02", ROMInfo::Full, NULL, NULL};
|
||||
// Known ROMs
|
||||
static const ROMInfo CTRL_MT32_V1_04 = {65536, "5a5cb5a77d7d55ee69657c2f870416daed52dea7", ROMInfo::Control, "ctrl_mt32_1_04", "MT-32 Control v1.04", ROMInfo::Full, NULL, &MT32_COMPATIBLE};
|
||||
static const ROMInfo CTRL_MT32_V1_05 = {65536, "e17a3a6d265bf1fa150312061134293d2b58288c", ROMInfo::Control, "ctrl_mt32_1_05", "MT-32 Control v1.05", ROMInfo::Full, NULL, &MT32_COMPATIBLE};
|
||||
static const ROMInfo CTRL_MT32_V1_06 = {65536, "a553481f4e2794c10cfe597fef154eef0d8257de", ROMInfo::Control, "ctrl_mt32_1_06", "MT-32 Control v1.06", ROMInfo::Full, NULL, &MT32_COMPATIBLE};
|
||||
static const ROMInfo CTRL_MT32_V1_07 = {65536, "b083518fffb7f66b03c23b7eb4f868e62dc5a987", ROMInfo::Control, "ctrl_mt32_1_07", "MT-32 Control v1.07", ROMInfo::Full, NULL, &MT32_COMPATIBLE};
|
||||
static const ROMInfo CTRL_MT32_BLUER = {65536, "7b8c2a5ddb42fd0732e2f22b3340dcf5360edf92", ROMInfo::Control, "ctrl_mt32_bluer", "MT-32 Control BlueRidge", ROMInfo::Full, NULL, &MT32_COMPATIBLE};
|
||||
|
||||
static const ROMInfo PCM_MT32 = {524288, "f6b1eebc4b2d200ec6d3d21d51325d5b48c60252", ROMInfo::PCM, "pcm_mt32", "MT-32 PCM ROM", ROMInfo::Full, NULL, NULL};
|
||||
static const ROMInfo PCM_CM32L = {1048576, "289cc298ad532b702461bfc738009d9ebe8025ea", ROMInfo::PCM, "pcm_cm32l", "CM-32L/CM-64/LAPC-I PCM ROM", ROMInfo::Full, NULL, NULL};
|
||||
static const ROMInfo CTRL_CM32L_V1_00 = {65536, "73683d585cd6948cc19547942ca0e14a0319456d", ROMInfo::Control, "ctrl_cm32l_1_00", "CM-32L/LAPC-I Control v1.00", ROMInfo::Full, NULL, &CM32L_COMPATIBLE};
|
||||
static const ROMInfo CTRL_CM32L_V1_02 = {65536, "a439fbb390da38cada95a7cbb1d6ca199cd66ef8", ROMInfo::Control, "ctrl_cm32l_1_02", "CM-32L/LAPC-I Control v1.02", ROMInfo::Full, NULL, &CM32L_COMPATIBLE};
|
||||
|
||||
static const ROMInfo * const ROM_INFOS[] = {
|
||||
static const ROMInfo PCM_MT32 = {524288, "f6b1eebc4b2d200ec6d3d21d51325d5b48c60252", ROMInfo::PCM, "pcm_mt32", "MT-32 PCM ROM", ROMInfo::Full, NULL, NULL};
|
||||
static const ROMInfo PCM_CM32L = {1048576, "289cc298ad532b702461bfc738009d9ebe8025ea", ROMInfo::PCM, "pcm_cm32l", "CM-32L/CM-64/LAPC-I PCM ROM", ROMInfo::Full, NULL, NULL};
|
||||
|
||||
static const ROMInfo * const ROM_INFOS[] = {
|
||||
&CTRL_MT32_V1_04,
|
||||
&CTRL_MT32_V1_05,
|
||||
&CTRL_MT32_V1_06,
|
||||
@ -45,13 +49,16 @@ static const ROMInfo * const ROM_INFOS[] = {
|
||||
&PCM_CM32L,
|
||||
NULL};
|
||||
|
||||
return ROM_INFOS[index];
|
||||
}
|
||||
|
||||
const ROMInfo* ROMInfo::getROMInfo(Common::File *file) {
|
||||
size_t fileSize = file->size();
|
||||
// We haven't added the SHA1 checksum code in ScummVM, as the file size
|
||||
// suffices for our needs for now.
|
||||
//const char *fileDigest = file->getSHA1();
|
||||
for (int i = 0; ROM_INFOS[i] != NULL; i++) {
|
||||
const ROMInfo *romInfo = ROM_INFOS[i];
|
||||
for (int i = 0; getKnownROMInfoFromList(i) != NULL; i++) {
|
||||
const ROMInfo *romInfo = getKnownROMInfoFromList(i);
|
||||
if (fileSize == romInfo->fileSize /*&& !strcmp(fileDigest, romInfo->sha1Digest)*/) {
|
||||
return romInfo;
|
||||
}
|
||||
@ -65,7 +72,7 @@ void ROMInfo::freeROMInfo(const ROMInfo *romInfo) {
|
||||
|
||||
static int getROMCount() {
|
||||
int count;
|
||||
for(count = 0; ROM_INFOS[count] != NULL; count++) {
|
||||
for(count = 0; getKnownROMInfoFromList(count) != NULL; count++) {
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@ -73,8 +80,8 @@ static int getROMCount() {
|
||||
const ROMInfo** ROMInfo::getROMInfoList(unsigned int types, unsigned int pairTypes) {
|
||||
const ROMInfo **romInfoList = new const ROMInfo*[getROMCount() + 1];
|
||||
const ROMInfo **currentROMInList = romInfoList;
|
||||
for(int i = 0; ROM_INFOS[i] != NULL; i++) {
|
||||
const ROMInfo *romInfo = ROM_INFOS[i];
|
||||
for(int i = 0; getKnownROMInfoFromList(i) != NULL; i++) {
|
||||
const ROMInfo *romInfo = getKnownROMInfoFromList(i);
|
||||
if ((types & (1 << romInfo->type)) && (pairTypes & (1 << romInfo->pairType))) {
|
||||
*currentROMInList++ = romInfo;
|
||||
}
|
||||
@ -108,4 +115,11 @@ const ROMInfo* ROMImage::getROMInfo() const {
|
||||
return romInfo;
|
||||
}
|
||||
|
||||
ControlROMFeatureSet::ControlROMFeatureSet(bool useDefaultReverbMT32Compatible) : defaultReverbMT32Compatible(useDefaultReverbMT32Compatible) {
|
||||
}
|
||||
|
||||
bool ControlROMFeatureSet::isDefaultReverbMT32Compatible() const {
|
||||
return defaultReverbMT32Compatible;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -23,6 +23,8 @@
|
||||
|
||||
namespace MT32Emu {
|
||||
|
||||
struct ControlROMFeatureSet;
|
||||
|
||||
// Defines vital info about ROM file to be used by synth and applications
|
||||
|
||||
struct ROMInfo {
|
||||
@ -34,7 +36,7 @@ public:
|
||||
const char *description;
|
||||
enum PairType {Full, FirstHalf, SecondHalf, Mux0, Mux1} pairType;
|
||||
ROMInfo *pairROMInfo;
|
||||
void *controlROMInfo;
|
||||
const ControlROMFeatureSet *controlROMFeatures;
|
||||
|
||||
// Returns a ROMInfo struct by inspecting the size and the SHA1 hash
|
||||
static const ROMInfo* getROMInfo(Common::File *file);
|
||||
@ -72,6 +74,15 @@ public:
|
||||
const ROMInfo *getROMInfo() const;
|
||||
};
|
||||
|
||||
struct ControlROMFeatureSet {
|
||||
private:
|
||||
unsigned int defaultReverbMT32Compatible : 1;
|
||||
|
||||
public:
|
||||
ControlROMFeatureSet(bool defaultReverbMT32Compatible);
|
||||
bool isDefaultReverbMT32Compatible() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -20,13 +20,11 @@
|
||||
//#include <cstdlib>
|
||||
//#include <cstring>
|
||||
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_printf
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_vprintf
|
||||
|
||||
#include "mt32emu.h"
|
||||
#include "mmath.h"
|
||||
#include "PartialManager.h"
|
||||
#include "BReverbModel.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace MT32Emu {
|
||||
|
||||
@ -42,19 +40,6 @@ static const ControlROMMap ControlROMMaps[7] = {
|
||||
// (Note that all but CM-32L ROM actually have 86 entries for rhythmTemp)
|
||||
};
|
||||
|
||||
static inline void muteStream(Sample *stream, Bit32u len) {
|
||||
if (stream == NULL) return;
|
||||
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
// FIXME: Use memset() where compatibility is guaranteed (if this turns out to be a win)
|
||||
while (len--) {
|
||||
*stream++ = 0.0f;
|
||||
}
|
||||
#else
|
||||
memset(stream, 0, len * sizeof(Sample));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void advanceStreamPosition(Sample *&stream, Bit32u posDelta) {
|
||||
if (stream != NULL) {
|
||||
stream += posDelta;
|
||||
@ -74,9 +59,9 @@ Bit8u Synth::calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum) {
|
||||
|
||||
Synth::Synth(ReportHandler *useReportHandler) {
|
||||
isOpen = false;
|
||||
reverbEnabled = true;
|
||||
reverbOverridden = false;
|
||||
partialCount = DEFAULT_MAX_PARTIALS;
|
||||
controlROMFeatures = NULL;
|
||||
|
||||
if (useReportHandler == NULL) {
|
||||
reportHandler = new ReportHandler;
|
||||
@ -86,11 +71,9 @@ Synth::Synth(ReportHandler *useReportHandler) {
|
||||
isDefaultReportHandler = false;
|
||||
}
|
||||
|
||||
reverbModels[REVERB_MODE_ROOM] = new BReverbModel(REVERB_MODE_ROOM);
|
||||
reverbModels[REVERB_MODE_HALL] = new BReverbModel(REVERB_MODE_HALL);
|
||||
reverbModels[REVERB_MODE_PLATE] = new BReverbModel(REVERB_MODE_PLATE);
|
||||
reverbModels[REVERB_MODE_TAP_DELAY] = new BReverbModel(REVERB_MODE_TAP_DELAY);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
reverbModels[i] = NULL;
|
||||
}
|
||||
reverbModel = NULL;
|
||||
setDACInputMode(DACInputMode_NICE);
|
||||
setMIDIDelayMode(MIDIDelayMode_DELAY_SHORT_MESSAGES_ONLY);
|
||||
@ -106,22 +89,29 @@ Synth::Synth(ReportHandler *useReportHandler) {
|
||||
|
||||
Synth::~Synth() {
|
||||
close(); // Make sure we're closed and everything is freed
|
||||
for (int i = 0; i < 4; i++) {
|
||||
delete reverbModels[i];
|
||||
}
|
||||
if (isDefaultReportHandler) {
|
||||
delete reportHandler;
|
||||
}
|
||||
}
|
||||
|
||||
void ReportHandler::showLCDMessage(const char *data) {
|
||||
// We cannot use printf here. Since we already implement our own
|
||||
// ReportHandler we simply disable the default implementation since it is
|
||||
// never called anyway.
|
||||
#if 0
|
||||
printf("WRITE-LCD: %s", data);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void ReportHandler::printDebug(const char *fmt, va_list list) {
|
||||
// We cannot use (v)printf here. Since we already implement our own
|
||||
// ReportHandler we simply disable the default implementation since it is
|
||||
// never called anyway.
|
||||
#if 0
|
||||
vprintf(fmt, list);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Synth::polyStateChanged(int partNum) {
|
||||
@ -143,11 +133,22 @@ void Synth::printDebug(const char *fmt, ...) {
|
||||
}
|
||||
|
||||
void Synth::setReverbEnabled(bool newReverbEnabled) {
|
||||
reverbEnabled = newReverbEnabled;
|
||||
if (isReverbEnabled() == newReverbEnabled) return;
|
||||
if (newReverbEnabled) {
|
||||
bool oldReverbOverridden = reverbOverridden;
|
||||
reverbOverridden = false;
|
||||
refreshSystemReverbParameters();
|
||||
reverbOverridden = oldReverbOverridden;
|
||||
} else {
|
||||
#if MT32EMU_REDUCE_REVERB_MEMORY
|
||||
reverbModel->close();
|
||||
#endif
|
||||
reverbModel = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool Synth::isReverbEnabled() const {
|
||||
return reverbEnabled;
|
||||
return reverbModel != NULL;
|
||||
}
|
||||
|
||||
void Synth::setReverbOverridden(bool newReverbOverridden) {
|
||||
@ -158,7 +159,40 @@ bool Synth::isReverbOverridden() const {
|
||||
return reverbOverridden;
|
||||
}
|
||||
|
||||
void Synth::setReverbCompatibilityMode(bool mt32CompatibleMode) {
|
||||
if (reverbModels[REVERB_MODE_ROOM] != NULL) {
|
||||
if (isMT32ReverbCompatibilityMode() == mt32CompatibleMode) return;
|
||||
setReverbEnabled(false);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
delete reverbModels[i];
|
||||
}
|
||||
}
|
||||
reverbModels[REVERB_MODE_ROOM] = new BReverbModel(REVERB_MODE_ROOM, mt32CompatibleMode);
|
||||
reverbModels[REVERB_MODE_HALL] = new BReverbModel(REVERB_MODE_HALL, mt32CompatibleMode);
|
||||
reverbModels[REVERB_MODE_PLATE] = new BReverbModel(REVERB_MODE_PLATE, mt32CompatibleMode);
|
||||
reverbModels[REVERB_MODE_TAP_DELAY] = new BReverbModel(REVERB_MODE_TAP_DELAY, mt32CompatibleMode);
|
||||
#if !MT32EMU_REDUCE_REVERB_MEMORY
|
||||
for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) {
|
||||
reverbModels[i]->open();
|
||||
}
|
||||
#endif
|
||||
if (isOpen) {
|
||||
setReverbOutputGain(reverbOutputGain);
|
||||
setReverbEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool Synth::isMT32ReverbCompatibilityMode() const {
|
||||
return isOpen && (reverbModels[REVERB_MODE_ROOM]->isMT32Compatible(REVERB_MODE_ROOM));
|
||||
}
|
||||
|
||||
void Synth::setDACInputMode(DACInputMode mode) {
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
// We aren't emulating these in float mode, so better to inform the invoker
|
||||
if ((mode == DACInputMode_GENERATION1) || (mode == DACInputMode_GENERATION2)) {
|
||||
mode = DACInputMode_NICE;
|
||||
}
|
||||
#endif
|
||||
dacInputMode = mode;
|
||||
}
|
||||
|
||||
@ -174,10 +208,13 @@ MIDIDelayMode Synth::getMIDIDelayMode() const {
|
||||
return midiDelayMode;
|
||||
}
|
||||
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
|
||||
void Synth::setOutputGain(float newOutputGain) {
|
||||
if (newOutputGain < 0.0f) newOutputGain = -newOutputGain;
|
||||
outputGain = newOutputGain;
|
||||
#if !MT32EMU_USE_FLOAT_SAMPLES
|
||||
if (256.0f < newOutputGain) newOutputGain = 256.0f;
|
||||
effectiveOutputGain = int(newOutputGain * 256.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
float Synth::getOutputGain() const {
|
||||
@ -185,38 +222,21 @@ float Synth::getOutputGain() const {
|
||||
}
|
||||
|
||||
void Synth::setReverbOutputGain(float newReverbOutputGain) {
|
||||
if (newReverbOutputGain < 0.0f) newReverbOutputGain = -newReverbOutputGain;
|
||||
reverbOutputGain = newReverbOutputGain;
|
||||
if (!isMT32ReverbCompatibilityMode()) newReverbOutputGain *= CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR;
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
effectiveReverbOutputGain = newReverbOutputGain;
|
||||
#else
|
||||
if (256.0f < newReverbOutputGain) newReverbOutputGain = 256.0f;
|
||||
effectiveReverbOutputGain = int(newReverbOutputGain * 256.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
float Synth::getReverbOutputGain() const {
|
||||
return reverbOutputGain;
|
||||
}
|
||||
|
||||
#else // #if MT32EMU_USE_FLOAT_SAMPLES
|
||||
|
||||
void Synth::setOutputGain(float newOutputGain) {
|
||||
if (newOutputGain < 0.0f) newOutputGain = -newOutputGain;
|
||||
if (256.0f < newOutputGain) newOutputGain = 256.0f;
|
||||
outputGain = int(newOutputGain * 256.0f);
|
||||
}
|
||||
|
||||
float Synth::getOutputGain() const {
|
||||
return outputGain / 256.0f;
|
||||
}
|
||||
|
||||
void Synth::setReverbOutputGain(float newReverbOutputGain) {
|
||||
if (newReverbOutputGain < 0.0f) newReverbOutputGain = -newReverbOutputGain;
|
||||
float maxValue = 256.0f / CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR;
|
||||
if (maxValue < newReverbOutputGain) newReverbOutputGain = maxValue;
|
||||
reverbOutputGain = int(newReverbOutputGain * 256.0f);
|
||||
}
|
||||
|
||||
float Synth::getReverbOutputGain() const {
|
||||
return reverbOutputGain / 256.0f;
|
||||
}
|
||||
|
||||
#endif // #if MT32EMU_USE_FLOAT_SAMPLES
|
||||
|
||||
void Synth::setReversedStereoEnabled(bool enabled) {
|
||||
reversedStereoEnabled = enabled;
|
||||
}
|
||||
@ -226,7 +246,6 @@ bool Synth::isReversedStereoEnabled() {
|
||||
}
|
||||
|
||||
bool Synth::loadControlROM(const ROMImage &controlROMImage) {
|
||||
if (&controlROMImage == NULL) return false;
|
||||
Common::File *file = controlROMImage.getFile();
|
||||
const ROMInfo *controlROMInfo = controlROMImage.getROMInfo();
|
||||
if ((controlROMInfo == NULL)
|
||||
@ -234,6 +253,14 @@ bool Synth::loadControlROM(const ROMImage &controlROMImage) {
|
||||
|| (controlROMInfo->pairType != ROMInfo::Full)) {
|
||||
return false;
|
||||
}
|
||||
controlROMFeatures = controlROMImage.getROMInfo()->controlROMFeatures;
|
||||
if (controlROMFeatures == NULL) {
|
||||
#if MT32EMU_MONITOR_INIT
|
||||
printDebug("Invalid Control ROM Info provided without feature set");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#if MT32EMU_MONITOR_INIT
|
||||
printDebug("Found Control ROM: %s, %s", controlROMInfo->shortName, controlROMInfo->description);
|
||||
#endif
|
||||
@ -254,7 +281,6 @@ bool Synth::loadControlROM(const ROMImage &controlROMImage) {
|
||||
}
|
||||
|
||||
bool Synth::loadPCMROM(const ROMImage &pcmROMImage) {
|
||||
if (&pcmROMImage == NULL) return false;
|
||||
Common::File *file = pcmROMImage.getFile();
|
||||
const ROMInfo *pcmROMInfo = pcmROMImage.getROMInfo();
|
||||
if ((pcmROMInfo == NULL)
|
||||
@ -373,14 +399,6 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, u
|
||||
}
|
||||
partialCount = usePartialCount;
|
||||
abortingPoly = NULL;
|
||||
#if MT32EMU_MONITOR_INIT
|
||||
printDebug("Initialising Constant Tables");
|
||||
#endif
|
||||
#if !MT32EMU_REDUCE_REVERB_MEMORY
|
||||
for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) {
|
||||
reverbModels[i]->open();
|
||||
}
|
||||
#endif
|
||||
|
||||
// This is to help detect bugs
|
||||
memset(&mt32ram, '?', sizeof(mt32ram));
|
||||
@ -411,6 +429,15 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, u
|
||||
return false;
|
||||
}
|
||||
|
||||
#if MT32EMU_MONITOR_INIT
|
||||
printDebug("Initialising Reverb Models");
|
||||
#endif
|
||||
bool mt32CompatibleReverb = controlROMFeatures->isDefaultReverbMT32Compatible();
|
||||
#if MT32EMU_MONITOR_INIT
|
||||
printDebug("Using %s Compatible Reverb Models", mt32CompatibleReverb ? "MT-32" : "CM-32L");
|
||||
#endif
|
||||
setReverbCompatibilityMode(mt32CompatibleReverb);
|
||||
|
||||
#if MT32EMU_MONITOR_INIT
|
||||
printDebug("Initialising Timbre Bank A");
|
||||
#endif
|
||||
@ -484,7 +511,11 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, u
|
||||
mt32ram.system.chanAssign[i] = i + 1;
|
||||
}
|
||||
mt32ram.system.masterVol = 100; // Confirmed
|
||||
|
||||
bool oldReverbOverridden = reverbOverridden;
|
||||
reverbOverridden = false;
|
||||
refreshSystem();
|
||||
reverbOverridden = oldReverbOverridden;
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
MemParams::PatchTemp *patchTemp = &mt32ram.patchTemp[i];
|
||||
@ -526,8 +557,8 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, u
|
||||
return true;
|
||||
}
|
||||
|
||||
void Synth::close() {
|
||||
if (!isOpen) {
|
||||
void Synth::close(bool forced) {
|
||||
if (!forced && !isOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -548,9 +579,11 @@ void Synth::close() {
|
||||
deleteMemoryRegions();
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
reverbModels[i]->close();
|
||||
delete reverbModels[i];
|
||||
reverbModels[i] = NULL;
|
||||
}
|
||||
reverbModel = NULL;
|
||||
controlROMFeatures = NULL;
|
||||
isOpen = false;
|
||||
}
|
||||
|
||||
@ -1249,7 +1282,7 @@ void Synth::refreshSystemReverbParameters() {
|
||||
#if MT32EMU_MONITOR_SYSEX > 0
|
||||
printDebug(" Reverb: mode=%d, time=%d, level=%d", mt32ram.system.reverbMode, mt32ram.system.reverbTime, mt32ram.system.reverbLevel);
|
||||
#endif
|
||||
if (reverbOverridden && reverbModel != NULL) {
|
||||
if (reverbOverridden) {
|
||||
#if MT32EMU_MONITOR_SYSEX > 0
|
||||
printDebug(" (Reverb overridden - ignoring)");
|
||||
#endif
|
||||
@ -1259,17 +1292,31 @@ void Synth::refreshSystemReverbParameters() {
|
||||
reportHandler->onNewReverbTime(mt32ram.system.reverbTime);
|
||||
reportHandler->onNewReverbLevel(mt32ram.system.reverbLevel);
|
||||
|
||||
BReverbModel *newReverbModel = reverbModels[mt32ram.system.reverbMode];
|
||||
#if MT32EMU_REDUCE_REVERB_MEMORY
|
||||
if (reverbModel != newReverbModel) {
|
||||
if (reverbModel != NULL) {
|
||||
reverbModel->close();
|
||||
}
|
||||
newReverbModel->open();
|
||||
BReverbModel *oldReverbModel = reverbModel;
|
||||
if (mt32ram.system.reverbTime == 0 && mt32ram.system.reverbLevel == 0) {
|
||||
// Setting both time and level to 0 effectively disables wet reverb output on real devices.
|
||||
// Take a shortcut in this case to reduce CPU load.
|
||||
reverbModel = NULL;
|
||||
} else {
|
||||
reverbModel = reverbModels[mt32ram.system.reverbMode];
|
||||
}
|
||||
if (reverbModel != oldReverbModel) {
|
||||
#if MT32EMU_REDUCE_REVERB_MEMORY
|
||||
if (oldReverbModel != NULL) {
|
||||
oldReverbModel->close();
|
||||
}
|
||||
if (isReverbEnabled()) {
|
||||
reverbModel->open();
|
||||
}
|
||||
#else
|
||||
if (isReverbEnabled()) {
|
||||
reverbModel->mute();
|
||||
}
|
||||
#endif
|
||||
reverbModel = newReverbModel;
|
||||
reverbModel->setParameters(mt32ram.system.reverbTime, mt32ram.system.reverbLevel);
|
||||
}
|
||||
if (isReverbEnabled()) {
|
||||
reverbModel->setParameters(mt32ram.system.reverbTime, mt32ram.system.reverbLevel);
|
||||
}
|
||||
}
|
||||
|
||||
void Synth::refreshSystemReserveSettings() {
|
||||
@ -1468,94 +1515,103 @@ void Synth::renderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample
|
||||
}
|
||||
}
|
||||
|
||||
void Synth::convertSamplesToOutput(Sample *target, const Sample *source, Bit32u len, bool reverb) {
|
||||
if (target == NULL) return;
|
||||
|
||||
if (dacInputMode == DACInputMode_PURE) {
|
||||
memcpy(target, source, len * sizeof(Sample));
|
||||
return;
|
||||
}
|
||||
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
float gain = reverb ? reverbOutputGain * CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR : 2.0f * outputGain;
|
||||
while (len--) {
|
||||
*(target++) = *(source++) * gain;
|
||||
}
|
||||
#else
|
||||
int gain;
|
||||
if (reverb) {
|
||||
gain = int(reverbOutputGain * CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR);
|
||||
} else {
|
||||
gain = outputGain;
|
||||
switch (dacInputMode) {
|
||||
case DACInputMode_NICE:
|
||||
// Since we're not shooting for accuracy here, don't worry about the rounding mode.
|
||||
gain <<= 1;
|
||||
break;
|
||||
case DACInputMode_GENERATION1:
|
||||
while (len--) {
|
||||
*target = clipBit16s(Bit32s((*source * gain) >> 8));
|
||||
*target = (*target & 0x8000) | ((*target << 1) & 0x7FFE);
|
||||
source++;
|
||||
target++;
|
||||
}
|
||||
return;
|
||||
// In GENERATION2 units, the output from LA32 goes to the Boss chip already bit-shifted.
|
||||
// In NICE mode, it's also better to increase volume before the reverb processing to preserve accuracy.
|
||||
void Synth::produceLA32Output(Sample *buffer, Bit32u len) {
|
||||
#if !MT32EMU_USE_FLOAT_SAMPLES
|
||||
switch (dacInputMode) {
|
||||
case DACInputMode_GENERATION2:
|
||||
while (len--) {
|
||||
*target = clipBit16s(Bit32s((*source * gain) >> 8));
|
||||
*target = (*target & 0x8000) | ((*target << 1) & 0x7FFE) | ((*target >> 14) & 0x0001);
|
||||
source++;
|
||||
target++;
|
||||
*buffer = (*buffer & 0x8000) | ((*buffer << 1) & 0x7FFE) | ((*buffer >> 14) & 0x0001);
|
||||
++buffer;
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case DACInputMode_NICE:
|
||||
while (len--) {
|
||||
*buffer = clipBit16s(Bit32s(*buffer) << 1);
|
||||
++buffer;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Synth::convertSamplesToOutput(Sample *buffer, Bit32u len, bool reverb) {
|
||||
if (dacInputMode == DACInputMode_PURE) return;
|
||||
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
float gain = reverb ? effectiveReverbOutputGain : outputGain;
|
||||
while (len--) {
|
||||
*(buffer++) *= gain;
|
||||
}
|
||||
#else
|
||||
int gain = reverb ? effectiveReverbOutputGain : effectiveOutputGain;
|
||||
if (dacInputMode == DACInputMode_GENERATION1) {
|
||||
while (len--) {
|
||||
Bit32s target = Bit16s((*buffer & 0x8000) | ((*buffer << 1) & 0x7FFE));
|
||||
*(buffer++) = clipBit16s((target * gain) >> 8);
|
||||
}
|
||||
return;
|
||||
}
|
||||
while (len--) {
|
||||
*(target++) = clipBit16s(Bit32s((*(source++) * gain) >> 8));
|
||||
*buffer = clipBit16s((Bit32s(*buffer) * gain) >> 8);
|
||||
++buffer;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Synth::doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len) {
|
||||
if (isEnabled) {
|
||||
Sample tmpBufMixLeft[MAX_SAMPLES_PER_RUN], tmpBufMixRight[MAX_SAMPLES_PER_RUN];
|
||||
muteStream(tmpBufMixLeft, len);
|
||||
muteStream(tmpBufMixRight, len);
|
||||
for (unsigned int i = 0; i < getPartialCount(); i++) {
|
||||
if (!reverbEnabled || !partialManager->shouldReverb(i)) {
|
||||
partialManager->produceOutput(i, tmpBufMixLeft, tmpBufMixRight, len);
|
||||
}
|
||||
}
|
||||
convertSamplesToOutput(nonReverbLeft, tmpBufMixLeft, len, false);
|
||||
convertSamplesToOutput(nonReverbRight, tmpBufMixRight, len, false);
|
||||
} else {
|
||||
muteStream(nonReverbLeft, len);
|
||||
muteStream(nonReverbRight, len);
|
||||
}
|
||||
// Even if LA32 output isn't desired, we proceed anyway with temp buffers
|
||||
Sample tmpBufNonReverbLeft[MAX_SAMPLES_PER_RUN], tmpBufNonReverbRight[MAX_SAMPLES_PER_RUN];
|
||||
if (nonReverbLeft == NULL) nonReverbLeft = tmpBufNonReverbLeft;
|
||||
if (nonReverbLeft == NULL) nonReverbRight = tmpBufNonReverbRight;
|
||||
|
||||
if (isEnabled && reverbEnabled) {
|
||||
Sample tmpBufMixLeft[MAX_SAMPLES_PER_RUN], tmpBufMixRight[MAX_SAMPLES_PER_RUN];
|
||||
muteStream(tmpBufMixLeft, len);
|
||||
muteStream(tmpBufMixRight, len);
|
||||
Sample tmpBufReverbDryLeft[MAX_SAMPLES_PER_RUN], tmpBufReverbDryRight[MAX_SAMPLES_PER_RUN];
|
||||
if (reverbDryLeft == NULL) reverbDryLeft = tmpBufReverbDryLeft;
|
||||
if (reverbDryRight == NULL) reverbDryRight = tmpBufReverbDryRight;
|
||||
|
||||
muteSampleBuffer(nonReverbLeft, len);
|
||||
muteSampleBuffer(nonReverbRight, len);
|
||||
muteSampleBuffer(reverbDryLeft, len);
|
||||
muteSampleBuffer(reverbDryRight, len);
|
||||
|
||||
if (isEnabled) {
|
||||
for (unsigned int i = 0; i < getPartialCount(); i++) {
|
||||
if (partialManager->shouldReverb(i)) {
|
||||
partialManager->produceOutput(i, tmpBufMixLeft, tmpBufMixRight, len);
|
||||
partialManager->produceOutput(i, reverbDryLeft, reverbDryRight, len);
|
||||
} else {
|
||||
partialManager->produceOutput(i, nonReverbLeft, nonReverbRight, len);
|
||||
}
|
||||
}
|
||||
convertSamplesToOutput(reverbDryLeft, tmpBufMixLeft, len, false);
|
||||
convertSamplesToOutput(reverbDryRight, tmpBufMixRight, len, false);
|
||||
|
||||
Sample tmpBufReverbOutLeft[MAX_SAMPLES_PER_RUN], tmpBufReverbOutRight[MAX_SAMPLES_PER_RUN];
|
||||
reverbModel->process(tmpBufMixLeft, tmpBufMixRight, tmpBufReverbOutLeft, tmpBufReverbOutRight, len);
|
||||
convertSamplesToOutput(reverbWetLeft, tmpBufReverbOutLeft, len, true);
|
||||
convertSamplesToOutput(reverbWetRight, tmpBufReverbOutRight, len, true);
|
||||
produceLA32Output(reverbDryLeft, len);
|
||||
produceLA32Output(reverbDryRight, len);
|
||||
|
||||
if (isReverbEnabled()) {
|
||||
reverbModel->process(reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, len);
|
||||
if (reverbWetLeft != NULL) convertSamplesToOutput(reverbWetLeft, len, true);
|
||||
if (reverbWetRight != NULL) convertSamplesToOutput(reverbWetRight, len, true);
|
||||
} else {
|
||||
muteSampleBuffer(reverbWetLeft, len);
|
||||
muteSampleBuffer(reverbWetRight, len);
|
||||
}
|
||||
|
||||
// Don't bother with conversion if the output is going to be unused
|
||||
if (nonReverbLeft != tmpBufNonReverbLeft) {
|
||||
produceLA32Output(nonReverbLeft, len);
|
||||
convertSamplesToOutput(nonReverbLeft, len, false);
|
||||
}
|
||||
if (nonReverbRight != tmpBufNonReverbRight) {
|
||||
produceLA32Output(nonReverbRight, len);
|
||||
convertSamplesToOutput(nonReverbRight, len, false);
|
||||
}
|
||||
if (reverbDryLeft != tmpBufReverbDryLeft) convertSamplesToOutput(reverbDryLeft, len, false);
|
||||
if (reverbDryRight != tmpBufReverbDryRight) convertSamplesToOutput(reverbDryRight, len, false);
|
||||
} else {
|
||||
muteStream(reverbDryLeft, len);
|
||||
muteStream(reverbDryRight, len);
|
||||
muteStream(reverbWetLeft, len);
|
||||
muteStream(reverbWetRight, len);
|
||||
muteSampleBuffer(reverbWetLeft, len);
|
||||
muteSampleBuffer(reverbWetRight, len);
|
||||
}
|
||||
|
||||
partialManager->clearAlreadyOutputed();
|
||||
@ -1589,7 +1645,7 @@ bool Synth::isActive() const {
|
||||
if (hasActivePartials()) {
|
||||
return true;
|
||||
}
|
||||
if (reverbEnabled) {
|
||||
if (isReverbEnabled()) {
|
||||
return reverbModel->isActive();
|
||||
}
|
||||
return false;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -322,6 +322,7 @@ private:
|
||||
|
||||
PCMWaveEntry *pcmWaves; // Array
|
||||
|
||||
const ControlROMFeatureSet *controlROMFeatures;
|
||||
const ControlROMMap *controlROMMap;
|
||||
Bit8u controlROMData[CONTROL_ROM_SIZE];
|
||||
Bit16s *pcmROMData;
|
||||
@ -338,18 +339,18 @@ private:
|
||||
|
||||
BReverbModel *reverbModels[4];
|
||||
BReverbModel *reverbModel;
|
||||
bool reverbEnabled;
|
||||
bool reverbOverridden;
|
||||
|
||||
MIDIDelayMode midiDelayMode;
|
||||
DACInputMode dacInputMode;
|
||||
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
float outputGain;
|
||||
float reverbOutputGain;
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
float effectiveReverbOutputGain;
|
||||
#else
|
||||
int outputGain;
|
||||
int reverbOutputGain;
|
||||
int effectiveOutputGain;
|
||||
int effectiveReverbOutputGain;
|
||||
#endif
|
||||
|
||||
bool reversedStereoEnabled;
|
||||
@ -370,7 +371,8 @@ private:
|
||||
Bit32u getShortMessageLength(Bit32u msg);
|
||||
Bit32u addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp);
|
||||
|
||||
void convertSamplesToOutput(Sample *target, const Sample *source, Bit32u len, bool reverb);
|
||||
void produceLA32Output(Sample *buffer, Bit32u len);
|
||||
void convertSamplesToOutput(Sample *buffer, Bit32u len, bool reverb);
|
||||
bool isAbortingPoly() const;
|
||||
void doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len);
|
||||
|
||||
@ -405,10 +407,23 @@ private:
|
||||
public:
|
||||
static inline Bit16s clipBit16s(Bit32s sample) {
|
||||
// Clamp values above 32767 to 32767, and values below -32768 to -32768
|
||||
if ((sample + 32768) & ~65535) {
|
||||
return (sample >> 31) ^ 32767;
|
||||
// FIXME: Do we really need this stuff? I think these branches are very well predicted. Instead, this introduces a chain.
|
||||
// The version below is actually a bit faster on my system...
|
||||
//return ((sample + 0x8000) & ~0xFFFF) ? (sample >> 31) ^ 0x7FFF : (Bit16s)sample;
|
||||
return ((-0x8000 <= sample) && (sample <= 0x7FFF)) ? (Bit16s)sample : (sample >> 31) ^ 0x7FFF;
|
||||
}
|
||||
|
||||
static inline void muteSampleBuffer(Sample *buffer, Bit32u len) {
|
||||
if (buffer == NULL) return;
|
||||
|
||||
#if MT32EMU_USE_FLOAT_SAMPLES
|
||||
// FIXME: Use memset() where compatibility is guaranteed (if this turns out to be a win)
|
||||
while (len--) {
|
||||
*(buffer++) = 0.0f;
|
||||
}
|
||||
return (Bit16s)sample;
|
||||
#else
|
||||
memset(buffer, 0, len * sizeof(Sample));
|
||||
#endif
|
||||
}
|
||||
|
||||
static Bit8u calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum);
|
||||
@ -424,7 +439,7 @@ public:
|
||||
bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount = DEFAULT_MAX_PARTIALS);
|
||||
|
||||
// Closes the MT-32 and deallocates any memory used by the synthesizer
|
||||
void close(void);
|
||||
void close(bool forced = false);
|
||||
|
||||
// All the enqueued events are processed by the synth immediately.
|
||||
void flushMIDIQueue();
|
||||
@ -464,8 +479,17 @@ public:
|
||||
|
||||
void setReverbEnabled(bool reverbEnabled);
|
||||
bool isReverbEnabled() const;
|
||||
// Sets override reverb mode. In this mode, emulation ignores sysexes (or the related part of them) which control the reverb parameters.
|
||||
// This mode is in effect until it is turned off. When the synth is re-opened, the override mode is unchanged but the state
|
||||
// of the reverb model is reset to default.
|
||||
void setReverbOverridden(bool reverbOverridden);
|
||||
bool isReverbOverridden() const;
|
||||
// Forces reverb model compatibility mode. By default, the compatibility mode corresponds to the used control ROM version.
|
||||
// Invoking this method with the argument set to true forces emulation of old MT-32 reverb circuit.
|
||||
// When the argument is false, emulation of the reverb circuit used in new generation of MT-32 compatible modules is enforced
|
||||
// (these include CM-32L and LAPC-I).
|
||||
void setReverbCompatibilityMode(bool mt32CompatibleMode);
|
||||
bool isMT32ReverbCompatibilityMode() const;
|
||||
void setDACInputMode(DACInputMode mode);
|
||||
DACInputMode getDACInputMode() const;
|
||||
void setMIDIDelayMode(MIDIDelayMode mode);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
|
||||
* Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
* Copyright (C) 2011, 2012, 2013, 2014 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
2
configure
vendored
2
configure
vendored
@ -1832,7 +1832,7 @@ fi
|
||||
echo $_global_constructors
|
||||
|
||||
echo_n "Checking for $_host_alias-strings... " >> "$TMPLOG"
|
||||
if test ! "x$(which $_host_alias-strings 2>/dev/null)" = "x"; then
|
||||
if `which $_host_alias-strings >/dev/null 2>&1`; then
|
||||
_strings=$_host_alias-strings
|
||||
echo yes >> "$TMPLOG"
|
||||
else
|
||||
|
@ -352,7 +352,7 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea
|
||||
"\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_Global</_PropertySheetDisplayName>\n"
|
||||
"\t\t<ExecutablePath>$(" << LIBS_DEFINE << ")\\bin;$(ExecutablePath)</ExecutablePath>\n"
|
||||
"\t\t<LibraryPath>$(" << LIBS_DEFINE << ")\\lib\\" << (bits == 32 ? "x86" : "x64") << ";$(LibraryPath)</LibraryPath>\n"
|
||||
"\t\t<IncludePath>$(" << LIBS_DEFINE << ")\\include;$(IncludePath)</IncludePath>\n"
|
||||
"\t\t<IncludePath>$(" << LIBS_DEFINE << ")\\include;$(" << LIBS_DEFINE << ")\\include\\SDL;$(IncludePath)</IncludePath>\n"
|
||||
"\t\t<OutDir>$(Configuration)" << bits << "\\</OutDir>\n"
|
||||
"\t\t<IntDir>$(Configuration)" << bits << "/$(ProjectName)\\</IntDir>\n"
|
||||
"\t</PropertyGroup>\n"
|
||||
|
@ -228,7 +228,7 @@ void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::of
|
||||
"\t\tName=\"VCCLCompilerTool\"\n"
|
||||
"\t\tDisableLanguageExtensions=\"" << (setup.devTools ? "false" : "true") << "\"\n"
|
||||
"\t\tDisableSpecificWarnings=\"" << warnings << "\"\n"
|
||||
"\t\tAdditionalIncludeDirectories=\".\\;" << prefix << ";" << prefix << "\\engines;$(" << LIBS_DEFINE << ")\\include;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir)\"\n"
|
||||
"\t\tAdditionalIncludeDirectories=\".\\;" << prefix << ";" << prefix << "\\engines;$(" << LIBS_DEFINE << ")\\include;$(" << LIBS_DEFINE << ")\\include\\SDL;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir)\"\n"
|
||||
"\t\tPreprocessorDefinitions=\"" << definesList << "\"\n"
|
||||
"\t\tExceptionHandling=\"" << ((setup.devTools || setup.tests) ? "1" : "0") << "\"\n";
|
||||
|
||||
|
@ -34,7 +34,8 @@ BuildRequires: SDL-devel >= 1.2.2
|
||||
# install scripts
|
||||
#------------------------------------------------------------------------------
|
||||
%prep
|
||||
%setup -q -a 1 -a 2 -n residualvm-%{version}
|
||||
%setup -q -a 1 -a 2 -a 3 -n residualvm-%{version}
|
||||
patch0 -p0
|
||||
mkdir tmp
|
||||
|
||||
%build
|
||||
|
@ -34,7 +34,8 @@ BuildRequires: SDL-devel >= 1.2.2
|
||||
# install scripts
|
||||
#------------------------------------------------------------------------------
|
||||
%prep
|
||||
%setup -q -a 1 -a 2 -n residualvm-%{version}
|
||||
%setup -q -a 1 -a 2 -a 3 -n residualvm-%{version}
|
||||
patch0 -p0
|
||||
mkdir tmp
|
||||
|
||||
%build
|
||||
|
@ -127,6 +127,8 @@ int BrowserDialog::runModal() {
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setCanChooseFiles:!_isDirBrowser];
|
||||
[panel setCanChooseDirectories:_isDirBrowser];
|
||||
if (_isDirBrowser)
|
||||
[panel setTreatsFilePackagesAsDirectories:true];
|
||||
[panel setTitle:(NSString *)_titleRef];
|
||||
[panel setPrompt:(NSString *)_chooseRef];
|
||||
|
||||
|
@ -159,7 +159,7 @@ bool TGADecoder::readHeader(Common::SeekableReadStream &tga, byte &imageType, by
|
||||
warning("Unsupported pixel depth: %d, %d", imageType, pixelDepth);
|
||||
return false;
|
||||
}
|
||||
} else if (imageType == TYPE_BW || TYPE_RLE_BW) {
|
||||
} else if (imageType == TYPE_BW || imageType == TYPE_RLE_BW) {
|
||||
if (pixelDepth == 8) {
|
||||
_format = Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 0);
|
||||
} else {
|
||||
|
@ -108,20 +108,18 @@ bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
|
||||
uint32 audioTrackCount = _bink->readUint32LE();
|
||||
|
||||
if (audioTrackCount > 0) {
|
||||
_audioTracks.reserve(audioTrackCount);
|
||||
_audioTracks.resize(audioTrackCount);
|
||||
|
||||
_bink->skip(4 * audioTrackCount);
|
||||
|
||||
// Reading audio track properties
|
||||
for (uint32 i = 0; i < audioTrackCount; i++) {
|
||||
AudioInfo track;
|
||||
AudioInfo &track = _audioTracks[i];
|
||||
|
||||
track.sampleRate = _bink->readUint16LE();
|
||||
track.flags = _bink->readUint16LE();
|
||||
|
||||
_audioTracks.push_back(track);
|
||||
|
||||
initAudioTrack(_audioTracks[i]);
|
||||
initAudioTrack(track);
|
||||
}
|
||||
|
||||
_bink->skip(4 * audioTrackCount);
|
||||
|
Loading…
x
Reference in New Issue
Block a user