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_INSTRUMENT_H
24 #define H2C_INSTRUMENT_H
25 
26 #include <cassert>
27 
28 #include <hydrogen/object.h>
29 #include <hydrogen/basics/adsr.h>
30 
31 #define EMPTY_INSTR_ID          -1
32 /** Created Instrument will be used as metronome. */
33 #define METRONOME_INSTR_ID      -2
34 #define PLAYBACK_INSTR_ID       -3
35 
36 namespace H2Core
37 {
38 
39 class XMLNode;
40 class ADSR;
41 class Drumkit;
42 class DrumkitComponent;
43 class InstrumentLayer;
44 class InstrumentComponent;
45 
46 
47 /**
48 Instrument class
49 */
50 class Instrument : public H2Core::Object
51 {
52 		H2_OBJECT
53 	public:
54 		enum SampleSelectionAlgo {
55 			VELOCITY,
56 			ROUND_ROBIN,
57 			RANDOM
58 		};
59 
60 		/**
61 		 * constructor
62 		 * \param id the id of this instrument
63 		 * \param name the name of the instrument
64 		 * \param adsr attack decay sustain release instance
65 		 */
66 		Instrument( const int id=EMPTY_INSTR_ID, const QString& name="Empty Instrument", ADSR* adsr=nullptr );
67 		/** copy constructor */
68 		Instrument( Instrument* other );
69 		/** destructor */
70 		~Instrument();
71 
72 		/**
73 		 * creates a new Instrument, loads samples from a given instrument within a given drumkit
74 		 * \param drumkit_name the drumkit to search the instrument in
75 		 * \param instrument_name the instrument within the drumkit to load samples from
76 		 * \return a new Instrument instance
77 		 */
78 		static Instrument* load_instrument( const QString& drumkit_name, const QString& instrument_name );
79 
80 		/**
81 		 * loads instrument from a given instrument within a given drumkit into a `live` Instrument object.
82 		 * \param drumkit_name the drumkit to search the instrument in
83 		 * \param instrument_name the instrument within the drumkit to load samples from
84 		 * \param is_live is it performed while playing
85 		 */
86 		void load_from( const QString& drumkit_name, const QString& instrument_name, bool is_live = true );
87 
88 		/**
89 		 * loads instrument from a given instrument into a `live` Instrument object.
90 		 * \param drumkit the drumkit the instrument belongs to
91 		 * \param instrument to load samples and members from
92 		 * \param is_live is it performed while playing
93 		 */
94 		void load_from( Drumkit* drumkit, Instrument* instrument, bool is_live = true );
95 
96 		/**
97 		 * Calls the InstrumentLayer::load_sample() member
98 		 * function of all layers of each component of the
99 		 * Instrument.
100 		 */
101 		void load_samples();
102 		/**
103 		 * Calls the InstrumentLayer::unload_sample() member
104 		 * function of all layers of each component of the
105 		 * Instrument.
106 		 */
107 		void unload_samples();
108 
109 		/**
110 		 * save the instrument within the given XMLNode
111 		 * \param node the XMLNode to feed
112 		 * \param component_id Identifier of the corresponding
113 		 * component.
114 		 */
115 		void save_to( XMLNode* node, int component_id );
116 		/**
117 		 * load an instrument from an XMLNode
118 		 * \param node the XMLDode to read from
119 		 * \param dk_path the directory holding the drumkit data
120 		 * \param dk_name the name of the drumkit
121 		 * \return a new Instrument instance
122 		 */
123 		static Instrument* load_from( XMLNode* node, const QString& dk_path, const QString& dk_name );
124 
125 		///< set the name of the instrument
126 		void set_name( const QString& name );
127 		///< get the name of the instrument
128 		const QString& get_name() const;
129 
130 		///< set the id of the instrument
131 		void set_id( const int id );
132 		///< get the id of the instrument
133 		int get_id() const;
134 
135 		/** set the ADSR of the instrument */
136 		void set_adsr( ADSR* adsr );
137 		/** get the ADSR of the instrument */
138 		ADSR* get_adsr() const;
139 		/** get a copy of the ADSR of the instrument */
140 		ADSR* copy_adsr() const;
141 
142 		/** set the mute group of the instrument */
143 		void set_mute_group( int group );
144 		/** get the mute group of the instrument */
145 		int get_mute_group() const;
146 
147 		/** set the midi out channel of the instrument */
148 		void set_midi_out_channel( int channel );
149 		/** get the midi out channel of the instrument */
150 		int get_midi_out_channel() const;
151 
152 		/** set the midi out note of the instrument */
153 		void set_midi_out_note( int note );
154 		/** get the midi out note of the instrument */
155 		int get_midi_out_note() const;
156 
157 		/** set muted status of the instrument */
158 		void set_muted( bool muted );
159 		/** get muted status of the instrument */
160 		bool is_muted() const;
161 
162 		/** set left pan of the instrument */
163 		void set_pan_l( float val );
164 		/** get left pan of the instrument */
165 		float get_pan_l() const;
166 
167 		/** set right pan of the instrument */
168 		void set_pan_r( float val );
169 		/** get right pan of the instrument */
170 		float get_pan_r() const;
171 
172 		/** set gain of the instrument */
173 		void set_gain( float gain );
174 		/** get gain of the instrument */
175 		float get_gain() const;
176 		/** set the volume of the instrument */
177 		void set_volume( float volume );
178 		/** get the volume of the instrument */
179 		float get_volume() const;
180 
181 		/** activate the filter of the instrument */
182 		void set_filter_active( bool active );
183 		/** get the status of the filter of the instrument */
184 		bool is_filter_active() const;
185 
186 		/** set the filter resonance of the instrument */
187 		void set_filter_resonance( float val );
188 		/** get the filter resonance of the instrument */
189 		float get_filter_resonance() const;
190 
191 		/** set the filter cutoff of the instrument */
192 		void set_filter_cutoff( float val );
193 		/** get the filter cutoff of the instrument */
194 		float get_filter_cutoff() const;
195 
196 		/** set the left peak of the instrument */
197 		void set_peak_l( float val );
198 		/** get the left peak of the instrument */
199 		float get_peak_l() const;
200 		/** set the right peak of the instrument */
201 		void set_peak_r( float val );
202 		/** get the right peak of the instrument */
203 		float get_peak_r() const;
204 
205 		/** set the fx level of the instrument */
206 		void set_fx_level( float level, int index );
207 		/** get the fx level of the instrument */
208 		float get_fx_level( int index ) const;
209 
210 		/** set the random pitch factor of the instrument */
211 		void set_random_pitch_factor( float val );
212 		/** get the random pitch factor of the instrument */
213 		float get_random_pitch_factor() const;
214 
215 		/** set the active status of the instrument */
216 		void set_active( bool active );
217 		/** get the active status of the instrument */
218 		bool is_active() const;
219 
220 		/** set the soloed status of the instrument */
221 		void set_soloed( bool soloed );
222 		/** get the soloed status of the instrument */
223 		bool is_soloed() const;
224 
225 		/** enqueue the instrument */
226 		void enqueue();
227 		/** dequeue the instrument */
228 		void dequeue();
229 		/** get the queued status of the instrument */
230 		bool is_queued() const;
231 
232 		/** set the stop notes status of the instrument */
233 		void set_stop_notes( bool stopnotes );
234 		/** get the stop notes of the instrument */
235 		bool is_stop_notes() const;
236 
237 		void set_sample_selection_alg( SampleSelectionAlgo selected_algo);
238 		SampleSelectionAlgo sample_selection_alg() const;
239 
240 		void set_hihat_grp( int hihat_grp );
241 		int get_hihat_grp() const;
242 
243 		void set_lower_cc( int message );
244 		int get_lower_cc() const;
245 
246 		void set_higher_cc( int message );
247 		int get_higher_cc() const;
248 
249 		///< set the name of the related drumkit
250 		void set_drumkit_name( const QString& name );
251 		///< get the name of the related drumkits
252 		const QString& get_drumkit_name() const;
253 
254 		/** Mark the instrument as hydrogen's preview instrument */
255 		void set_is_preview_instrument(bool isPreview);
256 		bool is_preview_instrument() const;
257 
258 		/** Mark the instrument as metronome instrument */
259 		void set_is_metronome_instrument(bool isMetronome);
260 		bool is_metronome_instrument() const;
261 
262 		std::vector<InstrumentComponent*>* get_components();
263 		InstrumentComponent* get_component( int DrumkitComponentID );
264 
265 		void set_apply_velocity( bool apply_velocity );
266 		bool get_apply_velocity() const;
267 
268 		bool is_currently_exported() const;
269 		void set_currently_exported( bool isCurrentlyExported );
270 
271 
272 	private:
273 	        /** Identifier of an instrument, which should be
274 		    unique. It is set by set_id() and accessed via
275 	        get_id().*/
276 		int					__id;
277 	        /** Name of the Instrument. It is set by set_name()
278 		    and accessed via get_name().*/
279 		QString					__name;
280 		QString					__drumkit_name;			///< the name of the drumkit this instrument belongs to
281 		float					__gain;					///< gain of the instrument
282 		float					__volume;				///< volume of the instrument
283 		float					__pan_l;				///< left pan of the instrument
284 		float					__pan_r;				///< right pan of the instrument
285 		float					__peak_l;				///< left current peak value
286 		float					__peak_r;				///< right current peak value
287 		ADSR*					__adsr;					///< attack delay sustain release instance
288 		bool					__filter_active;		///< is filter active?
289 		float					__filter_cutoff;		///< filter cutoff (0..1)
290 		float					__filter_resonance;		///< filter resonant frequency (0..1)
291 		float					__random_pitch_factor;	///< random pitch factor
292 		int						__midi_out_note;		///< midi out note
293 		int						__midi_out_channel;		///< midi out channel
294 		bool					__stop_notes;			///< will the note automatically generate a note off after being on
295 		SampleSelectionAlgo		__sample_selection_alg;	///< how Hydrogen will chose the sample to use
296 		bool					__active;				///< is the instrument active?
297 		bool					__soloed;				///< is the instrument in solo mode?
298 		bool					__muted;				///< is the instrument muted?
299 		int						__mute_group;			///< mute group of the instrument
300 		int						__queued;				///< count the number of notes queued within Sampler::__playing_notes_queue or std::priority_queue m_songNoteQueue
301 		float					__fx_level[MAX_FX];		///< Ladspa FX level array
302 		int						__hihat_grp;			///< the instrument is part of a hihat
303 		int						__lower_cc;				///< lower cc level
304 		int						__higher_cc;			///< higher cc level
305 		bool					__is_preview_instrument;		///< is the instrument an hydrogen preview instrument?
306 		bool					__is_metronome_instrument;		///< is the instrument an metronome instrument?
307 		std::vector<InstrumentComponent*>* __components;		///< InstrumentLayer array
308 		bool					__apply_velocity;				///< change the sample gain based on velocity
309 		bool					__current_instr_for_export;		///< is the instrument currently being exported?
310 };
311 // DEFINITIONS
312 /** Sets the name of the Instrument #__name.
313  * \param name New name. */
set_name(const QString & name)314 inline void Instrument::set_name( const QString& name )
315 {
316 	__name = name;
317 }
318 /** Access the name of the Instrument.
319  * \return #__name */
get_name()320 inline const QString& Instrument::get_name() const
321 {
322 	return __name;
323 }
324 /** Sets #__id to @a id.
325  * \param id Unique identifier of the instrument. */
set_id(const int id)326 inline void Instrument::set_id( const int id )
327 {
328 	__id = id;
329 }
330 /** Returns #__id.
331 * \return #__id. */
get_id()332 inline int Instrument::get_id() const
333 {
334 	return __id;
335 }
336 
get_adsr()337 inline ADSR* Instrument::get_adsr() const
338 {
339 	return __adsr;
340 }
341 
copy_adsr()342 inline ADSR* Instrument::copy_adsr() const
343 {
344 	return new ADSR( __adsr );
345 }
346 
set_mute_group(int group)347 inline void Instrument::set_mute_group( int group )
348 {
349 	__mute_group = ( group<-1 ? -1 : group );
350 }
351 
get_mute_group()352 inline int Instrument::get_mute_group() const
353 {
354 	return __mute_group;
355 }
356 
get_midi_out_channel()357 inline int Instrument::get_midi_out_channel() const
358 {
359 	return __midi_out_channel;
360 }
361 
set_midi_out_channel(int channel)362 inline void Instrument::set_midi_out_channel( int channel )
363 {
364 	if ( ( channel >= MIDI_OUT_CHANNEL_MIN ) && ( channel <= MIDI_OUT_CHANNEL_MAX ) ) {
365 		__midi_out_channel = channel;
366 	} else {
367 		ERRORLOG( QString( "midi out channel %1 out of bounds" ).arg( channel ) );
368 	}
369 }
370 
get_midi_out_note()371 inline int Instrument::get_midi_out_note() const
372 {
373 	return __midi_out_note;
374 }
375 
set_midi_out_note(int note)376 inline void Instrument::set_midi_out_note( int note )
377 {
378 	if ( ( note >= MIDI_OUT_NOTE_MIN ) && ( note <= MIDI_OUT_NOTE_MAX ) ) {
379 		__midi_out_note = note;
380 	} else {
381 		ERRORLOG( QString( "midi out note %1 out of bounds" ).arg( note ) );
382 	}
383 }
384 
set_muted(bool muted)385 inline void Instrument::set_muted( bool muted )
386 {
387 	__muted = muted;
388 }
389 
is_muted()390 inline bool Instrument::is_muted() const
391 {
392 	return __muted;
393 }
394 
set_pan_l(float val)395 inline void Instrument::set_pan_l( float val )
396 {
397 	__pan_l = val;
398 }
399 
get_pan_l()400 inline float Instrument::get_pan_l() const
401 {
402 	return __pan_l;
403 }
404 
set_pan_r(float val)405 inline void Instrument::set_pan_r( float val )
406 {
407 	__pan_r = val;
408 }
409 
get_pan_r()410 inline float Instrument::get_pan_r() const
411 {
412 	return __pan_r;
413 }
414 
set_gain(float gain)415 inline void Instrument::set_gain( float gain )
416 {
417 	__gain = gain;
418 }
419 
get_gain()420 inline float Instrument::get_gain() const
421 {
422 	return __gain;
423 }
424 
set_volume(float volume)425 inline void Instrument::set_volume( float volume )
426 {
427 	__volume = volume;
428 }
429 
get_volume()430 inline float Instrument::get_volume() const
431 {
432 	return __volume;
433 }
434 
set_filter_active(bool active)435 inline void Instrument::set_filter_active( bool active )
436 {
437 	__filter_active = active;
438 }
439 
is_filter_active()440 inline bool Instrument::is_filter_active() const
441 {
442 	return __filter_active;
443 }
444 
set_filter_resonance(float val)445 inline void Instrument::set_filter_resonance( float val )
446 {
447 	__filter_resonance = val;
448 }
449 
get_filter_resonance()450 inline float Instrument::get_filter_resonance() const
451 {
452 	return __filter_resonance;
453 }
454 
set_filter_cutoff(float val)455 inline void Instrument::set_filter_cutoff( float val )
456 {
457 	__filter_cutoff = val;
458 }
459 
get_filter_cutoff()460 inline float Instrument::get_filter_cutoff() const
461 {
462 	return __filter_cutoff;
463 }
464 
set_peak_l(float val)465 inline void Instrument::set_peak_l( float val )
466 {
467 	__peak_l = val;
468 }
469 
get_peak_l()470 inline float Instrument::get_peak_l() const
471 {
472 	return __peak_l;
473 }
474 
set_peak_r(float val)475 inline void Instrument::set_peak_r( float val )
476 {
477 	__peak_r = val;
478 }
479 
get_peak_r()480 inline float Instrument::get_peak_r() const
481 {
482 	return __peak_r;
483 }
484 
set_fx_level(float level,int index)485 inline void Instrument::set_fx_level( float level, int index )
486 {
487 	__fx_level[index] = level;
488 }
489 
get_fx_level(int index)490 inline float Instrument::get_fx_level( int index ) const
491 {
492 	return __fx_level[index];
493 }
494 
set_random_pitch_factor(float val)495 inline void Instrument::set_random_pitch_factor( float val )
496 {
497 	__random_pitch_factor = val;
498 }
499 
get_random_pitch_factor()500 inline float Instrument::get_random_pitch_factor() const
501 {
502 	return __random_pitch_factor;
503 }
504 
set_active(bool active)505 inline void Instrument::set_active( bool active )
506 {
507 	__active = active;
508 }
509 
is_active()510 inline bool Instrument::is_active() const
511 {
512 	return __active;
513 }
514 
set_soloed(bool soloed)515 inline void Instrument::set_soloed( bool soloed )
516 {
517 	__soloed = soloed;
518 }
519 
is_soloed()520 inline bool Instrument::is_soloed() const
521 {
522 	return __soloed;
523 }
524 
enqueue()525 inline void Instrument::enqueue()
526 {
527 	__queued++;
528 }
529 
dequeue()530 inline void Instrument::dequeue()
531 {
532 	assert( __queued > 0 );
533 	__queued--;
534 }
535 
is_queued()536 inline bool Instrument::is_queued() const
537 {
538 	return ( __queued > 0 );
539 }
540 
set_stop_notes(bool stopnotes)541 inline void Instrument::set_stop_notes( bool stopnotes )
542 {
543 	__stop_notes = stopnotes;
544 }
545 
is_stop_notes()546 inline bool Instrument::is_stop_notes() const
547 {
548 	return __stop_notes;
549 }
550 
set_sample_selection_alg(SampleSelectionAlgo selected_algo)551 inline void Instrument::set_sample_selection_alg( SampleSelectionAlgo selected_algo)
552 {
553 	__sample_selection_alg = selected_algo;
554 }
555 
sample_selection_alg()556 inline Instrument::SampleSelectionAlgo Instrument::sample_selection_alg() const
557 {
558 	return __sample_selection_alg;
559 }
560 
set_hihat_grp(int hihat_grp)561 inline void Instrument::set_hihat_grp( int hihat_grp )
562 {
563 	__hihat_grp = hihat_grp;
564 }
565 
get_hihat_grp()566 inline int Instrument::get_hihat_grp() const
567 {
568 	return __hihat_grp;
569 }
570 
set_lower_cc(int message)571 inline void Instrument::set_lower_cc( int message )
572 {
573 	__lower_cc = message;
574 }
575 
get_lower_cc()576 inline int Instrument::get_lower_cc() const
577 {
578 	return __lower_cc;
579 }
580 
set_higher_cc(int message)581 inline void Instrument::set_higher_cc( int message )
582 {
583 	__higher_cc = message;
584 }
585 
get_higher_cc()586 inline int Instrument::get_higher_cc() const
587 {
588 	return __higher_cc;
589 }
590 
set_drumkit_name(const QString & name)591 inline void Instrument::set_drumkit_name( const QString& name )
592 {
593 	__drumkit_name = name;
594 }
595 
get_drumkit_name()596 inline const QString& Instrument::get_drumkit_name() const
597 {
598 	return __drumkit_name;
599 }
600 
is_preview_instrument()601 inline bool Instrument::is_preview_instrument() const
602 {
603 	return __is_preview_instrument;
604 }
605 
set_is_preview_instrument(bool isPreview)606 inline void Instrument::set_is_preview_instrument(bool isPreview)
607 {
608 	__is_preview_instrument = isPreview;
609 }
610 
is_metronome_instrument()611 inline bool Instrument::is_metronome_instrument() const
612 {
613 	return __is_metronome_instrument;
614 }
615 
set_is_metronome_instrument(bool isMetronome)616 inline void Instrument::set_is_metronome_instrument(bool isMetronome)
617 {
618 	__is_metronome_instrument = isMetronome;
619 }
620 
get_components()621 inline std::vector<InstrumentComponent*>* Instrument::get_components()
622 {
623 	return __components;
624 }
625 
set_apply_velocity(bool apply_velocity)626 inline void Instrument::set_apply_velocity( bool apply_velocity )
627 {
628 	__apply_velocity = apply_velocity;
629 }
630 
get_apply_velocity()631 inline bool Instrument::get_apply_velocity() const
632 {
633 	return __apply_velocity;
634 }
635 
is_currently_exported()636 inline bool Instrument::is_currently_exported() const
637 {
638 	return __current_instr_for_export;
639 }
640 
set_currently_exported(bool isCurrentlyExported)641 inline void Instrument::set_currently_exported( bool isCurrentlyExported )
642 {
643 	__current_instr_for_export = isCurrentlyExported;
644 }
645 
646 };
647 
648 
649 
650 #endif // H2C_INSTRUMENT_H
651 
652 /* vim: set softtabstop=4 noexpandtab:  */
653