1 /* 2 Copyright (c) 2003-2006 yuno 3 All rights reserved. 4 5 Redistribution and use in source and binary forms, with or without 6 modification, are permitted provided that the following conditions are met: 7 1. Redistributions of source code must retain the above copyright notice, 8 this list of conditions and the following disclaimer. 9 2. Redistributions in binary form must reproduce the above copyright notice, 10 this list of conditions and the following disclaimer in the documentation 11 and/or other materials provided with the distribution. 12 3. Neither the name of copyright holders nor the names of its contributors 13 may be used to endorse or promote products derived from this software 14 without specific prior written permission. 15 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' 17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE 20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 // MIDI software synthesizer. 29 #ifndef midisynth_h 30 #define midisynth_h 31 32 #include <stdint.h> 33 #include <map> 34 #include <memory> 35 #include <vector> 36 37 namespace midisynth{ 38 /* 39 typedef short int_least16_t; 40 typedef unsigned short uint_least16_t; 41 typedef long int_least32_t; 42 typedef unsigned long uint_least32_t; 43 typedef __int64 int_least64_t; 44 */ 45 class channel; 46 47 // System mode enumeration type. 48 enum system_mode_t{ system_mode_default, system_mode_gm, system_mode_gm2, system_mode_gs, system_mode_xg }; 49 50 // Basic uncopyable class. 51 class uncopyable{ 52 public: uncopyable()53 uncopyable(){} 54 private: uncopyable(const uncopyable &)55 uncopyable(const uncopyable&){} 56 void operator=(const uncopyable&){} 57 }; 58 59 // Note. Sound notes related. 60 class note:uncopyable{ 61 public: note(int assign_,int panpot_)62 note(int assign_, int panpot_):assign(assign_), panpot(panpot_){} ~note()63 virtual ~note(){} get_assign()64 int get_assign()const{ return assign; } get_panpot()65 int get_panpot()const{ return panpot; } 66 virtual bool synthesize(int_least32_t* buf, std::size_t samples, float rate, int_least32_t left, int_least32_t right) = 0; 67 virtual void note_off(int velocity) = 0; 68 virtual void sound_off() = 0; 69 virtual void set_frequency_multiplier(float value) = 0; 70 virtual void set_tremolo(int depth, float freq) = 0; 71 virtual void set_vibrato(float depth, float freq) = 0; 72 virtual void set_damper(int value) = 0; 73 virtual void set_sostenute(int value) = 0; 74 virtual void set_freeze(int value) = 0; 75 private: 76 int assign; 77 int panpot; 78 }; 79 80 // Notes factory. 81 // Creates the appropriate note to the note-on message. 82 class note_factory:uncopyable{ 83 public: 84 virtual note* note_on(int_least32_t program, int note, int velocity, float frequency_multiplier)=0; 85 protected: ~note_factory()86 virtual ~note_factory(){} 87 }; 88 89 // MIDI channel. 90 class channel:uncopyable{ 91 enum{ NUM_NOTES = 128 }; 92 public: 93 channel(note_factory* factory, int bank); 94 ~channel(); 95 96 int synthesize(int_least32_t* out, std::size_t samples, float rate, int_least32_t master_volume, int master_balance); 97 void reset_all_parameters(); 98 void reset_all_controller(); 99 void all_note_off(); 100 void all_sound_off(); 101 void all_sound_off_immediately(); 102 103 void note_off(int note, int velocity); 104 void note_on(int note, int velocity); 105 void polyphonic_key_pressure(int note, int value); program_change(int value)106 void program_change(int value){ set_program(128 * bank + value); } 107 void channel_pressure(int value); pitch_bend_change(int value)108 void pitch_bend_change(int value){ pitch_bend = value; update_frequency_multiplier(); } 109 void control_change(int control, int value); 110 void bank_select(int value); 111 set_bank(int value)112 void set_bank(int value){ bank = value; } set_program(int value)113 void set_program(int value){ program = value; } set_panpot(int value)114 void set_panpot(int value){ panpot = value; } set_volume(int value)115 void set_volume(int value){ volume = value; } set_expression(int value)116 void set_expression(int value){ expression = value; } set_pitch_bend_sensitivity(int value)117 void set_pitch_bend_sensitivity(int value){ pitch_bend_sensitivity = value; update_frequency_multiplier(); } set_modulation_depth(int value)118 void set_modulation_depth(int value){ modulation_depth = value; update_modulation(); } set_modulation_depth_range(int value)119 void set_modulation_depth_range(int value){ modulation_depth_range = value; update_modulation(); } 120 void set_damper(int value); 121 void set_sostenute(int value); 122 void set_freeze(int value); set_fine_tuning(int value)123 void set_fine_tuning(int value){ fine_tuning = value; update_frequency_multiplier(); } set_coarse_tuning(int value)124 void set_coarse_tuning(int value){ coarse_tuning = value; update_frequency_multiplier(); } set_RPN(int value)125 void set_RPN(int value){ RPN = value; NRPN = 0x3FFF; } set_NRPN(int value)126 void set_NRPN(int value){ NRPN = value; RPN = 0x3FFF; } set_tremolo_frequency(float value)127 void set_tremolo_frequency(float value){ tremolo_frequency = value; } set_vibrato_frequency(float value)128 void set_vibrato_frequency(float value){ vibrato_frequency = value; } set_master_frequency_multiplier(float value)129 void set_master_frequency_multiplier(float value){ master_frequency_multiplier = value; update_frequency_multiplier(); } set_mute(bool mute_)130 void set_mute(bool mute_){ mute = mute_; } set_system_mode(system_mode_t mode)131 void set_system_mode(system_mode_t mode){ system_mode = mode; } mono_mode_on()132 void mono_mode_on(){ all_note_off(); mono = true; } poly_mode_on()133 void poly_mode_on(){ all_note_off(); mono = false; } 134 get_program()135 int get_program()const{ return program; } get_bank()136 int get_bank()const{ return bank; } get_panpot()137 int get_panpot()const{ return panpot; } get_volume()138 int get_volume()const{ return volume; } get_expression()139 int get_expression()const{ return expression; } get_channel_pressure()140 int get_channel_pressure()const{ return pressure; } get_pitch_bend()141 int get_pitch_bend()const{ return pitch_bend; } get_pitch_bend_sensitivity()142 int get_pitch_bend_sensitivity()const{ return pitch_bend_sensitivity; } get_modulation_depth()143 int get_modulation_depth()const{ return modulation_depth; } get_modulation_depth_range()144 int get_modulation_depth_range()const{ return modulation_depth_range; } get_damper()145 int get_damper()const{ return damper; } get_sostenute()146 int get_sostenute()const{ return sostenute; } get_freeze()147 int get_freeze()const{ return freeze; } get_fine_tuning()148 int get_fine_tuning()const{ return fine_tuning; } get_coarse_tuning()149 int get_coarse_tuning()const{ return coarse_tuning; } get_RPN()150 int get_RPN()const{ return RPN; } get_NRPN()151 int get_NRPN()const{ return NRPN; } get_tremolo_frequency()152 float get_tremolo_frequency()const{ return tremolo_frequency; } get_vibrato_frequency()153 float get_vibrato_frequency()const{ return vibrato_frequency; } get_mute()154 bool get_mute()const{ return mute; } get_mono_mode()155 bool get_mono_mode()const{ return mono; } 156 157 private: 158 struct NOTE{ 159 class note* note; 160 int key; 161 enum STATUS{ 162 NOTEON, NOTEOFF, SOUNDOFF 163 }status; NOTENOTE164 NOTE(class note* p, int key_):note(p),key(key_),status(NOTEON){} 165 }; 166 std::vector<NOTE> notes; 167 note_factory* factory; 168 int default_bank; 169 int program; 170 int bank; 171 int panpot; 172 int volume; 173 int expression; 174 int pressure; 175 int pitch_bend; 176 int pitch_bend_sensitivity; 177 int modulation_depth; 178 int modulation_depth_range; 179 int damper; 180 int sostenute; 181 int freeze; 182 int fine_tuning; 183 int coarse_tuning; 184 int RPN; 185 int NRPN; 186 bool mono; 187 bool mute; 188 float tremolo_frequency; 189 float vibrato_frequency; 190 float frequency_multiplier; 191 float master_frequency_multiplier; 192 system_mode_t system_mode; 193 194 int get_registered_parameter(); 195 void set_registered_parameter(int value); 196 void update_frequency_multiplier(); 197 void update_modulation(); 198 }; 199 200 // MIDI synthesizer. 201 class synthesizer:uncopyable{ 202 enum{ NUM_CHANNELS = 16 }; 203 public: 204 synthesizer(note_factory* factory); 205 206 channel* get_channel(int ch); 207 208 int synthesize(int_least16_t* output, std::size_t samples, float rate); 209 int synthesize_mixing(int_least32_t* output, std::size_t samples, float rate); 210 void reset(); 211 void reset_all_parameters(); 212 void reset_all_controller(); 213 void all_note_off(); 214 void all_sound_off(); 215 void all_sound_off_immediately(); 216 note_on(int channel,int note,int velocity)217 void note_on(int channel, int note, int velocity){ get_channel(channel)->note_on(note, velocity); } note_off(int channel,int note,int velocity)218 void note_off(int channel, int note, int velocity){ get_channel(channel)->note_off(note, velocity); } polyphonic_key_pressure(int channel,int note,int value)219 void polyphonic_key_pressure(int channel, int note, int value){ get_channel(channel)->polyphonic_key_pressure(note, value); } control_change(int channel,int control,int value)220 void control_change(int channel, int control, int value){ get_channel(channel)->control_change(control, value); } program_change(int channel,int program)221 void program_change(int channel, int program){ get_channel(channel)->program_change(program); } channel_pressure(int channel,int value)222 void channel_pressure(int channel, int value){ get_channel(channel)->channel_pressure(value); } pitch_bend_change(int channel,int value)223 void pitch_bend_change(int channel, int value){ get_channel(channel)->pitch_bend_change(value); } 224 void sysex_message(const void* data, std::size_t size); 225 void midi_event(int command, int param1, int param2); midi_event(uint_least32_t message)226 void midi_event(uint_least32_t message){ midi_event(message & 0xFF, (message >> 8) & 0x7F, (message >> 16) & 0x7F); } 227 set_main_volume(int value)228 void set_main_volume(int value){ main_volume = value; } set_master_volume(int value)229 void set_master_volume(int value){ master_volume = value; } set_master_balance(int value)230 void set_master_balance(int value){ master_balance = value; } set_master_fine_tuning(int value)231 void set_master_fine_tuning(int value){ master_fine_tuning = value; update_master_frequency_multiplier(); } set_master_coarse_tuning(int value)232 void set_master_coarse_tuning(int value){ master_coarse_tuning = value; update_master_frequency_multiplier(); } 233 void set_system_mode(system_mode_t mode); 234 get_main_volume()235 int get_main_volume()const{ return main_volume; } get_master_volume()236 int get_master_volume()const{ return master_volume; } get_master_balance()237 int get_master_balance()const{ return master_balance; } get_master_fine_tuning()238 int get_master_fine_tuning()const{ return master_fine_tuning; } get_master_coarse_tuning()239 int get_master_coarse_tuning()const{ return master_coarse_tuning; } get_system_mode()240 system_mode_t get_system_mode()const{ return system_mode; } 241 242 private: 243 std::unique_ptr<channel> channels[NUM_CHANNELS]; 244 float active_sensing; 245 int main_volume; 246 int master_volume; 247 int master_balance; 248 int master_fine_tuning; 249 int master_coarse_tuning; 250 float master_frequency_multiplier; 251 system_mode_t system_mode; 252 void update_master_frequency_multiplier(); 253 }; 254 255 // Sine wave generator. 256 // Generates a sine wave with an amplitude of 32768 (-32767...32767). 257 class sine_wave_generator{ 258 public: 259 sine_wave_generator(); 260 sine_wave_generator(float cycle); 261 void set_cycle(float cycle); 262 void add_modulation(int_least32_t x); 263 int get_next(); 264 int get_next(int_least32_t modulation); 265 private: 266 uint_least32_t position; 267 uint_least32_t step; 268 }; 269 270 // Envelope generator. 271 // Generates 0 to 32767 values when the TL = 0. 272 class envelope_generator{ 273 public: 274 envelope_generator(int AR, int DR, int SR, int RR, int SL, int TL); 275 void set_rate(float rate); 276 void set_hold(float value); 277 void set_freeze(float value); 278 void key_off(); 279 void sound_off(); is_finished()280 bool is_finished()const{ return state == FINISHED; } 281 int get_next(); 282 private: 283 enum{ ATTACK, ATTACK_RELEASE, DECAY, DECAY_RELEASE, SASTAIN, RELEASE, SOUNDOFF, FINISHED }state; 284 int AR, DR, SR, RR, TL; 285 uint_least32_t fAR, fDR, fSR, fRR, fSL, fTL, fOR, fSS, fDRR, fDSS; 286 uint_least32_t current; 287 float rate; 288 float hold; 289 float freeze; 290 void update_parameters(); 291 }; 292 293 // FM operator (modulator and carrier). 294 class fm_operator{ 295 public: 296 fm_operator(int AR, int DR, int SR, int RR, int SL, int TL, int KS, int ML, int DT, int AMS, int key); 297 void set_freq_rate(float freq, float rate); set_hold(float value)298 void set_hold(float value){ eg.set_hold(value); } set_freeze(float value)299 void set_freeze(float value){ eg.set_freeze(value); } add_modulation(int_least32_t x)300 void add_modulation(int_least32_t x){ swg.add_modulation(x); } key_off()301 void key_off(){ eg.key_off(); } sound_off()302 void sound_off(){ eg.sound_off(); } is_finished()303 bool is_finished()const{ return eg.is_finished(); } 304 int get_next(); 305 int get_next(int modulate); 306 int get_next(int lfo, int modulate); operator()307 inline int operator()(){ return get_next(); } operator()308 inline int operator()(int m){ return get_next(m); } operator()309 inline int operator()(int lfo, int m){ return get_next(lfo, m); } 310 private: 311 sine_wave_generator swg; 312 envelope_generator eg; 313 float ML; 314 float DT; 315 int_least32_t ams_factor; 316 int_least32_t ams_bias; 317 }; 318 319 // FM sound source parameters. 320 struct FMPARAMETER{ 321 int ALG, FB, LFO; 322 struct{ 323 int AR, DR, SR, RR, SL, TL, KS, ML, DT, AMS; 324 }op1, op2, op3, op4; 325 }; 326 // Drum parameters. 327 struct DRUMPARAMETER:FMPARAMETER{ 328 int key, panpot, assign; 329 }; 330 331 // FM sound generator. 332 class fm_sound_generator{ 333 public: 334 fm_sound_generator(const FMPARAMETER& params, int note, float frequency_multiplier); 335 void set_rate(float rate); 336 void set_frequency_multiplier(float value); 337 void set_damper(int damper); 338 void set_sostenute(int sostenute); 339 void set_freeze(int freeze); 340 void set_tremolo(int depth, float frequency); 341 void set_vibrato(float depth, float frequency); 342 void key_off(); 343 void sound_off(); 344 bool is_finished()const; 345 int get_next(); 346 private: 347 fm_operator op1; 348 fm_operator op2; 349 fm_operator op3; 350 fm_operator op4; 351 sine_wave_generator ams_lfo; 352 sine_wave_generator vibrato_lfo; 353 sine_wave_generator tremolo_lfo; 354 int ALG; 355 int FB; 356 float freq; 357 float freq_mul; 358 float ams_freq; 359 bool ams_enable; 360 int tremolo_depth; 361 float tremolo_freq; 362 int vibrato_depth; 363 float vibrato_freq; 364 float rate; 365 int feedback; 366 int damper; 367 int sostenute; 368 }; 369 370 // FM sound generator notes. 371 class fm_note:public note{ 372 public: 373 fm_note(const FMPARAMETER& params, int note, int velocity, int panpot, int assign, float frequency_multiplier); release()374 virtual void release(){ delete this; } 375 virtual bool synthesize(int_least32_t* buf, std::size_t samples, float rate, int_least32_t left, int_least32_t right); 376 virtual void note_off(int velocity); 377 virtual void sound_off(); 378 virtual void set_frequency_multiplier(float value); 379 virtual void set_tremolo(int depth, float freq); 380 virtual void set_vibrato(float depth, float freq); 381 virtual void set_damper(int value); 382 virtual void set_sostenute(int value); 383 virtual void set_freeze(int value); 384 public: 385 fm_sound_generator fm; 386 int velocity; 387 }; 388 389 // FM sound generator note factory. 390 class fm_note_factory:public note_factory{ 391 public: 392 fm_note_factory(); 393 void clear(); 394 void get_program(int number, FMPARAMETER& p); 395 bool set_program(int number, const FMPARAMETER& p); 396 bool set_drum_program(int number, const DRUMPARAMETER& p); 397 virtual note* note_on(int_least32_t program, int note, int velocity, float frequency_multiplier); 398 private: 399 std::map<int, FMPARAMETER> programs; 400 std::map<int, DRUMPARAMETER> drums; 401 }; 402 } 403 404 #endif 405