1 /*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 *
5 * http://www.hydrogen-music.org
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY, without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23 #ifndef H2C_NOTE_H
24 #define H2C_NOTE_H
25
26 #include <hydrogen/object.h>
27 #include <hydrogen/basics/instrument.h>
28
29 #define KEY_MIN 0
30 #define KEY_MAX 11
31 #define OCTAVE_MIN -3
32 #define OCTAVE_MAX 3
33 #define OCTAVE_OFFSET 3
34 #define OCTAVE_DEFAULT 0
35 #define KEYS_PER_OCTAVE 12
36
37 #define MIDI_MIDDLE_C 60
38 #define MIDI_FACTOR 127
39
40 #define VELOCITY_MIN 0.0f
41 #define VELOCITY_MAX 1.0f
42 #define PAN_MIN 0.0f
43 #define PAN_MAX 0.5f
44 #define LEAD_LAG_MIN -1.0f
45 #define LEAD_LAG_MAX 1.0f
46
47 /* Should equal (default __octave + OCTAVE_OFFSET) * KEYS_PER_OCTAVE + default __key */
48 #define MIDI_DEFAULT_OFFSET 36
49
50 namespace H2Core
51 {
52
53 class XMLNode;
54 class ADSR;
55 class Instrument;
56 class InstrumentList;
57
58 struct SelectedLayerInfo {
59 int SelectedLayer; ///< selected layer during layer selection
60 float SamplePosition; ///< place marker for overlapping process() cycles
61 };
62
63 /**
64 * A note plays an associated instrument with a velocity left and right pan
65 */
66 class Note : public H2Core::Object
67 {
68 H2_OBJECT
69 public:
70 /** possible keys */
71 enum Key { C=KEY_MIN, Cs, D, Ef, E, F, Fs, G, Af, A, Bf, B };
72 /** possible octaves */
73 enum Octave { P8Z=-3, P8Y=-2, P8X=-1, P8=OCTAVE_DEFAULT, P8A=1, P8B=2, P8C=3 };
74
75 /**
76 * constructor
77 * \param instrument the instrument played by this note
78 * \param position the position of the note within the pattern
79 * \param velocity it's velocity
80 * \param pan_l left pan
81 * \param pan_r right pan
82 * \param length it's length
83 * \param pitch it's pitch
84 */
85 Note( Instrument* instrument, int position, float velocity, float pan_l, float pan_r, int length, float pitch );
86
87 /**
88 * copy constructor with an optional parameter
89 * \param other
90 * \param instrument if set will be used as note instrument
91 */
92 Note( Note* other, Instrument* instrument=nullptr );
93 /** destructor */
94 ~Note();
95
96 /*
97 * save the note within the given XMLNode
98 * \param node the XMLNode to feed
99 */
100 void save_to( XMLNode* node );
101 /**
102 * load a note from an XMLNode
103 * \param node the XMLDode to read from
104 * \param instruments the current instrument list to search instrument into
105 * \return a new Note instance
106 */
107 static Note* load_from( XMLNode* node, InstrumentList* instruments );
108
109 /** output details through logger with DEBUG severity */
110 void dump();
111
112 /**
113 * find the corresponding instrument and point to it, or an empty instrument
114 * \param instruments the list of instrument to look into
115 */
116 void map_instrument( InstrumentList* instruments );
117 /** #__instrument accessor */
118 Instrument* get_instrument();
119 /** return true if #__instrument is set */
120 bool has_instrument() const;
121 /**
122 * #__instrument_id setter
123 * \param value the new value
124 */
125 void set_instrument_id( int value );
126 /** #__instrument_id accessor */
127 int get_instrument_id() const;
128 /**
129 * #__specific_compo_id setter
130 * \param value the new value
131 */
132 void set_specific_compo_id( int value );
133 /** #__specific_compo_id accessor */
134 int get_specific_compo_id() const;
135 /**
136 * #__position setter
137 * \param value the new value
138 */
139 void set_position( int value );
140 /** #__position accessor */
141 int get_position() const;
142 /**
143 * #__velocity setter
144 * \param value the new value
145 */
146 void set_velocity( float value );
147 /** #__velocity accessor */
148 float get_velocity() const;
149 /**
150 * #__pan_l setter
151 * \param value the new value
152 */
153 void set_pan_l( float value );
154 /** #__pan_l accessor */
155 float get_pan_l() const;
156 /**
157 * #__pan_r setter
158 * \param value the new value
159 */
160 void set_pan_r( float value );
161 /** #__pan_r accessor */
162 float get_pan_r() const;
163 /**
164 * #__lead_lag setter
165 * \param value the new value
166 */
167 void set_lead_lag( float value );
168 /** #__lead_lag accessor */
169 float get_lead_lag() const;
170 /**
171 * #__length setter
172 * \param value the new value
173 */
174 void set_length( int value );
175 /** #__length accessor */
176 int get_length() const;
177 /**
178 * #__pitch setter
179 * \param value the new value
180 */
181 void set_pitch( float value );
182 /** #__pitch accessor */
183 float get_pitch() const;
184 /**
185 * #__note_off setter
186 * \param value the new value
187 */
188 void set_note_off( bool value );
189 /** #__note_off accessor */
190 bool get_note_off() const;
191 /** #__midi_msg accessor */
192 int get_midi_msg() const;
193 /**
194 * #__pattern_idx setter
195 * \param value the new value
196 */
197 void set_pattern_idx( int value );
198 /** #__pattern_idx accessor */
199 int get_pattern_idx() const;
200 /**
201 * #__just_recorded setter
202 * \param value the new value
203 */
204 void set_just_recorded( bool value );
205 /** #__just_recorded accessor */
206 bool get_just_recorded() const;
207
208 /*
209 * selected sample
210 * */
211 SelectedLayerInfo* get_layer_selected( int CompoID );
212
213
214 void set_probability( float value );
215 float get_probability() const;
216
217 /**
218 * #__humanize_delay setter
219 * \param value the new value
220 */
221 void set_humanize_delay( int value );
222 /** #__humanize_delay accessor */
223 int get_humanize_delay() const;
224 /** #__cut_off accessor */
225 float get_cut_off() const;
226 /** #__resonance accessor */
227 float get_resonance() const;
228 /** #__bpfb_l accessor */
229 float get_bpfb_l() const;
230 /** #__bpfb_r accessor */
231 float get_bpfb_r() const;
232 /** #__lpfb_l accessor */
233 float get_lpfb_l() const;
234 /** #__lpfb_r accessor */
235 float get_lpfb_r() const;
236 /** #__key accessor */
237 Key get_key();
238 /** #__octave accessor */
239 Octave get_octave();
240 /** return scaled key for midi output, !!! DO NOT CHECK IF INSTRUMENT IS SET !!! */
241 int get_midi_key() const;
242 /** midi velocity accessor
243 * \code{.cpp}
244 * __velocity * #MIDI_FACTOR
245 * \endcode */
246 int get_midi_velocity() const;
247 /** note key pitch accessor
248 * \code{.cpp}
249 * __octave * KEYS_PER_OCTAVE + __key
250 * \endcode */
251 float get_notekey_pitch() const;
252 /** returns
253 * \code{.cpp}
254 * __octave * 12 + __key + __pitch
255 * \endcode*/
256 float get_total_pitch() const;
257
258 /** return a string representation of key-octave */
259 QString key_to_string();
260 /**
261 * parse str and set #__key and #__octave
262 * \param str the string to be parsed
263 */
264 void set_key_octave( const QString& str );
265 /**
266 * set #__key and #__octave only if within acceptable range
267 * \param key the key to set
268 * \param octave the octave to be set
269 */
270 void set_key_octave( Key key, Octave octave );
271 /**
272 * set #__key, #__octave and #__midi_msg only if within acceptable range
273 * \param key the key to set
274 * \param octave the octave to be set
275 * \param msg
276 */
277 void set_midi_info( Key key, Octave octave, int msg );
278
279 /** get the ADSR of the note */
280 ADSR* get_adsr() const;
281 /** call release on adsr */
282 //float release_adsr() const { return __adsr->release(); }
283 /** call get value on adsr */
284 //float get_adsr_value(float v) const { return __adsr->get_value( v ); }
285
286 /** return true if instrument, key and octave matches with internal
287 * \param instrument the instrument to match with #__instrument
288 * \param key the key to match with #__key
289 * \param octave the octave to match with #__octave
290 */
291 bool match( Instrument* instrument, Key key, Octave octave ) const;
292
293 /**
294 * compute left and right output based on filters
295 * \param val_l the left channel value
296 * \param val_r the right channel value
297 */
298 void compute_lr_values( float* val_l, float* val_r );
299
300 private:
301 Instrument* __instrument; ///< the instrument to be played by this note
302 int __instrument_id; ///< the id of the instrument played by this note
303 int __specific_compo_id; ///< play a specific component, -1 if playing all
304 int __position; ///< note position inside the pattern
305 float __velocity; ///< velocity (intensity) of the note [0;1]
306 float __pan_l; ///< pan of the note (left volume) [0;0.5]
307 float __pan_r; ///< pan of the note (right volume) [0;0.5]
308 int __length; ///< the length of the note
309 float __pitch; ///< the frequency of the note
310 Key __key; ///< the key, [0;11]==[C;B]
311 Octave __octave; ///< the octave [-3;3]
312 ADSR* __adsr; ///< attack decay sustain release
313 float __lead_lag; ///< lead or lag offset of the note
314 float __cut_off; ///< filter cutoff [0;1]
315 float __resonance; ///< filter resonant frequency [0;1]
316 int __humanize_delay; ///< used in "humanize" function
317 std::map< int, SelectedLayerInfo* > __layers_selected;
318 float __bpfb_l; ///< left band pass filter buffer
319 float __bpfb_r; ///< right band pass filter buffer
320 float __lpfb_l; ///< left low pass filter buffer
321 float __lpfb_r; ///< right low pass filter buffer
322 int __pattern_idx; ///< index of the pattern holding this note for undo actions
323 int __midi_msg; ///< TODO
324 bool __note_off; ///< note type on|off
325 bool __just_recorded; ///< used in record+delete
326 float __probability; ///< note probability
327 static const char* __key_str[]; ///< used to build QString from #__key an #__octave
328 };
329
330 // DEFINITIONS
331
get_adsr()332 inline ADSR* Note::get_adsr() const
333 {
334 return __adsr;
335 }
336
get_instrument()337 inline Instrument* Note::get_instrument()
338 {
339 return __instrument;
340 }
341
has_instrument()342 inline bool Note::has_instrument() const
343 {
344 return __instrument!=nullptr;
345 }
346
set_instrument_id(int value)347 inline void Note::set_instrument_id( int value )
348 {
349 __instrument_id = value;
350 }
351
get_instrument_id()352 inline int Note::get_instrument_id() const
353 {
354 return __instrument_id;
355 }
356
set_specific_compo_id(int value)357 inline void Note::set_specific_compo_id( int value )
358 {
359 __specific_compo_id = value;
360 }
361
get_specific_compo_id()362 inline int Note::get_specific_compo_id() const
363 {
364 return __specific_compo_id;
365 }
366
set_position(int value)367 inline void Note::set_position( int value )
368 {
369 __position = value;
370 }
371
get_position()372 inline int Note::get_position() const
373 {
374 return __position;
375 }
376
get_velocity()377 inline float Note::get_velocity() const
378 {
379 return __velocity;
380 }
381
get_pan_l()382 inline float Note::get_pan_l() const
383 {
384 return __pan_l;
385 }
386
get_pan_r()387 inline float Note::get_pan_r() const
388 {
389 return __pan_r;
390 }
391
get_lead_lag()392 inline float Note::get_lead_lag() const
393 {
394 return __lead_lag;
395 }
396
set_length(int value)397 inline void Note::set_length( int value )
398 {
399 __length = value;
400 }
401
get_length()402 inline int Note::get_length() const
403 {
404 return __length;
405 }
406
set_pitch(float value)407 inline void Note::set_pitch( float value )
408 {
409 __pitch = value;
410 }
411
get_pitch()412 inline float Note::get_pitch() const
413 {
414 return __pitch;
415 }
416
set_note_off(bool value)417 inline void Note::set_note_off( bool value )
418 {
419 __note_off = value;
420 }
421
get_note_off()422 inline bool Note::get_note_off() const
423 {
424 return __note_off;
425 }
426
get_midi_msg()427 inline int Note::get_midi_msg() const
428 {
429 return __midi_msg;
430 }
431
set_pattern_idx(int value)432 inline void Note::set_pattern_idx( int value )
433 {
434 __pattern_idx = value;
435 }
436
get_pattern_idx()437 inline int Note::get_pattern_idx() const
438 {
439 return __pattern_idx;
440 }
441
set_just_recorded(bool value)442 inline void Note::set_just_recorded( bool value )
443 {
444 __just_recorded = value;
445 }
446
get_just_recorded()447 inline bool Note::get_just_recorded() const
448 {
449 return __just_recorded;
450 }
451
get_probability()452 inline float Note::get_probability() const
453 {
454 return __probability;
455 }
456
set_probability(float value)457 inline void Note::set_probability( float value )
458 {
459 __probability = value;
460 }
461
get_layer_selected(int CompoID)462 inline SelectedLayerInfo* Note::get_layer_selected( int CompoID )
463 {
464 return __layers_selected[ CompoID ];
465 }
466
set_humanize_delay(int value)467 inline void Note::set_humanize_delay( int value )
468 {
469 __humanize_delay = value;
470 }
471
get_humanize_delay()472 inline int Note::get_humanize_delay() const
473 {
474 return __humanize_delay;
475 }
476
get_cut_off()477 inline float Note::get_cut_off() const
478 {
479 return __cut_off;
480 }
481
get_resonance()482 inline float Note::get_resonance() const
483 {
484 return __resonance;
485 }
486
get_bpfb_l()487 inline float Note::get_bpfb_l() const
488 {
489 return __bpfb_l;
490 }
491
get_bpfb_r()492 inline float Note::get_bpfb_r() const
493 {
494 return __bpfb_r;
495 }
496
get_lpfb_l()497 inline float Note::get_lpfb_l() const
498 {
499 return __lpfb_l;
500 }
501
get_lpfb_r()502 inline float Note::get_lpfb_r() const
503 {
504 return __lpfb_r;
505 }
506
get_key()507 inline Note::Key Note::get_key()
508 {
509 return __key;
510 }
511
get_octave()512 inline Note::Octave Note::get_octave()
513 {
514 return __octave;
515 }
516
get_midi_key()517 inline int Note::get_midi_key() const
518 {
519 /* TODO ???
520 if( !has_instrument() ) { return (__octave + OCTAVE_OFFSET ) * KEYS_PER_OCTAVE + __key; }
521 */
522 return ( __octave + OCTAVE_OFFSET ) * KEYS_PER_OCTAVE + __key + __instrument->get_midi_out_note() - MIDI_DEFAULT_OFFSET;
523 }
524
get_midi_velocity()525 inline int Note::get_midi_velocity() const
526 {
527 return __velocity * MIDI_FACTOR;
528 }
529
get_notekey_pitch()530 inline float Note::get_notekey_pitch() const
531 {
532 return __octave * KEYS_PER_OCTAVE + __key;
533 }
534
get_total_pitch()535 inline float Note::get_total_pitch() const
536 {
537 return __octave * KEYS_PER_OCTAVE + __key + __pitch;
538 }
539
set_key_octave(Key key,Octave octave)540 inline void Note::set_key_octave( Key key, Octave octave )
541 {
542 if( key>=KEY_MIN && key<=KEY_MAX ) __key = key;
543 if( octave>=OCTAVE_MIN && octave<=OCTAVE_MAX ) __octave = octave;
544 }
545
set_midi_info(Key key,Octave octave,int msg)546 inline void Note::set_midi_info( Key key, Octave octave, int msg )
547 {
548 if( key>=KEY_MIN && key<=KEY_MAX ) __key = key;
549 if( octave>=OCTAVE_MIN && octave<=OCTAVE_MAX ) __octave = octave;
550 __midi_msg = msg;
551 }
552
match(Instrument * instrument,Key key,Octave octave)553 inline bool Note::match( Instrument* instrument, Key key, Octave octave ) const
554 {
555 return ( ( __instrument==instrument ) && ( __key==key ) && ( __octave==octave ) );
556 }
557
compute_lr_values(float * val_l,float * val_r)558 inline void Note::compute_lr_values( float* val_l, float* val_r )
559 {
560 /* TODO ???
561 if( !has_instrument() ) {
562 *val_l = 0.0f;
563 *val_r = 0.0f;
564 return;
565 }
566 */
567 float cut_off = __instrument->get_filter_cutoff();
568 float resonance = __instrument->get_filter_resonance();
569 __bpfb_l = resonance * __bpfb_l + cut_off * ( *val_l - __lpfb_l );
570 __lpfb_l += cut_off * __bpfb_l;
571 __bpfb_r = resonance * __bpfb_r + cut_off * ( *val_r - __lpfb_r );
572 __lpfb_r += cut_off * __bpfb_r;
573 *val_l = __lpfb_l;
574 *val_r = __lpfb_r;
575 }
576
577 };
578
579 #endif // H2C_NOTE_H
580
581 /* vim: set softtabstop=4 noexpandtab: */
582