hydrogen 1.2.6
Note.h
Go to the documentation of this file.
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 * Copyright(c) 2008-2025 The hydrogen development team [hydrogen-devel@lists.sourceforge.net]
5 *
6 * http://www.hydrogen-music.org
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY, without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see https://www.gnu.org/licenses
20 *
21 */
22
23#ifndef H2C_NOTE_H
24#define H2C_NOTE_H
25
26#include <memory>
27
28#include <core/Object.h>
30#include <core/Basics/Sample.h>
31
32#include <core/IO/MidiCommon.h>
33
34#define KEY_MIN 0
35#define KEY_MAX 11
36#define OCTAVE_MIN -3
37#define OCTAVE_MAX 3
38#define OCTAVE_OFFSET 3
39#define OCTAVE_DEFAULT 0
40#define KEYS_PER_OCTAVE 12
41
42#define MIDI_MIDDLE_C 60
43#define MIDI_FACTOR 127
44
45#define VELOCITY_MIN 0.0f
46#define VELOCITY_MAX 1.0f
47#define PAN_MIN 0.0f
48#define PAN_MAX 0.5f
49#define LEAD_LAG_MIN -1.0f
50#define LEAD_LAG_MAX 1.0f
51
52namespace H2Core
53{
54
55class XMLNode;
56class ADSR;
57class Instrument;
58class InstrumentList;
59
95
100class Note : public H2Core::Object<Note>
101{
103 public:
105 enum Key { C=KEY_MIN, Cs, D, Ef, E, F, Fs, G, Af, A, Bf, B };
106 static QString KeyToQString( Key key );
107
109 enum Octave { P8Z=-3, P8Y=-2, P8X=-1, P8=OCTAVE_DEFAULT, P8A=1, P8B=2, P8C=3 };
110
123 Note( std::shared_ptr<Instrument> pInstrument, int nPosition = 0, float fVelocity = 0.8, float fPan = 0.0, int nLength = -1, float fPitch = 0.0 );
124
130 Note( Note* pOther, std::shared_ptr<Instrument> pInstrument = nullptr );
132 ~Note();
133
134 /*
135 * save the note within the given XMLNode
136 * \param node the XMLNode to feed
137 */
138 void save_to( XMLNode* node );
147 static Note* load_from( XMLNode* node, std::shared_ptr<InstrumentList> instruments, bool bSilent = false );
148
153 void map_instrument( std::shared_ptr<InstrumentList> instruments );
155 std::shared_ptr<Instrument> get_instrument();
157 bool has_instrument() const;
162 void set_instrument_id( int value );
164 int get_instrument_id() const;
169 void set_specific_compo_id( int value );
171 int get_specific_compo_id() const;
176 void set_position( int value );
178 int get_position() const;
183 void set_velocity( float value );
185 float get_velocity() const;
186
188 void setPan( float val );
190 void setPanWithRangeFrom0To1( float fVal ) {
191 this->setPan( -1.f + 2.f * fVal ); // scale and translate into [-1;1]
192 };
193
194 float getPan() const;
197 return 0.5f * ( 1.f + m_fPan );
198 }
199
204 void set_lead_lag( float value );
206 float get_lead_lag() const;
211 void set_length( int value );
213 int get_length() const;
218 void set_pitch( float value );
220 float get_pitch() const;
225 void set_note_off( bool value );
227 bool get_note_off() const;
229 int get_midi_msg() const;
234 void set_pattern_idx( int value );
236 int get_pattern_idx() const;
241 void set_just_recorded( bool value );
243 bool get_just_recorded() const;
244
245 /*
246 * selected sample
247 * */
248 std::shared_ptr<SelectedLayerInfo> get_layer_selected( int CompoID );
249 std::map<int, std::shared_ptr<SelectedLayerInfo>> get_layers_selected() const;
250
251
252 void set_probability( float value );
253 float get_probability() const;
254
259 void set_humanize_delay( int value );
261 int get_humanize_delay() const;
263 float get_cut_off() const;
265 float get_resonance() const;
267 float get_bpfb_l() const;
269 float get_bpfb_r() const;
271 float get_lpfb_l() const;
273 float get_lpfb_r() const;
275 bool filter_sustain() const;
277 Key get_key();
281 int get_midi_key() const;
286 int get_midi_velocity() const;
291 float get_notekey_pitch() const;
298 float get_total_pitch() const;
299
301 QString key_to_string();
306 void set_key_octave( const QString& str );
312 void set_key_octave( Key key, Octave octave );
319 void set_midi_info( Key key, Octave octave, int msg );
320
322 std::shared_ptr<ADSR> get_adsr() const;
323
329 bool match( std::shared_ptr<Instrument> instrument, Key key, Octave octave ) const;
330
332 bool match( const Note *pNote ) const;
333 bool match( const std::shared_ptr<Note> pNote ) const;
334
340 void compute_lr_values( float* val_l, float* val_r );
341
342 long long getNoteStart() const;
343 float getUsedTickSize() const;
344
349 bool isPartiallyRendered() const;
350
360 void computeNoteStart();
361
366 void humanize();
367
374 void swing();
375
384 QString toQString( const QString& sPrefix = "", bool bShort = true ) const override;
385
387 static inline double pitchToFrequency( double fPitch ) {
388 // Equivalent to, but quicker to compute than, pow( 2.0, ( fPitch/12 ) )
389 return pow( 1.0594630943593, fPitch );
390 }
391
392 static inline Octave pitchToOctave( int nPitch ) {
393 if ( nPitch >= 0 ) {
394 return (Octave)(nPitch / 12);
395 } else {
396 return (Octave)((nPitch-11) / 12);
397 }
398 }
399 static inline Key pitchToKey( int nPitch ) {
400 return (Key)(nPitch - 12 * pitchToOctave( nPitch ));
401 }
402 static inline int octaveKeyToPitch( Octave octave, Key key ) {
403 return 12 * (int)octave + (int)key;
404 }
405
421 std::shared_ptr<Sample> getSample( int nComponentID, int nSelectedLayer = -1 );
422
423 private:
424 std::shared_ptr<Instrument> __instrument;
430 float m_fPan;
433
439 float __pitch;
442 std::shared_ptr<ADSR> __adsr;
444 float __cut_off;
447
457 std::map< int, std::shared_ptr<SelectedLayerInfo>> __layers_selected;
458 float __bpfb_l;
459 float __bpfb_r;
460 float __lpfb_l;
461 float __lpfb_r;
467 static const char* __key_str[];
469
475 long long m_nNoteStart;
490};
491
492// DEFINITIONS
493
494inline std::shared_ptr<ADSR> Note::get_adsr() const
495{
496 return __adsr;
497}
498
499inline std::shared_ptr<Instrument> Note::get_instrument()
500{
501 return __instrument;
502}
503
504inline bool Note::has_instrument() const
505{
506 return __instrument!=nullptr;
507}
508
509inline void Note::set_instrument_id( int value )
510{
511 __instrument_id = value;
512}
513
514inline int Note::get_instrument_id() const
515{
516 return __instrument_id;
517}
518
519inline void Note::set_specific_compo_id( int value )
520{
521 __specific_compo_id = value;
522}
523
525{
526 return __specific_compo_id;
527}
528
529inline void Note::set_position( int value )
530{
531 __position = value;
532}
533
534inline int Note::get_position() const
535{
536 return __position;
537}
538
539inline float Note::get_velocity() const
540{
541 return __velocity;
542}
543
544inline float Note::getPan() const
545{
546 return m_fPan;
547}
548
549inline float Note::get_lead_lag() const
550{
551 return __lead_lag;
552}
553
554inline void Note::set_length( int value )
555{
556 __length = value;
557}
558
559inline int Note::get_length() const
560{
561 return __length;
562}
563
564inline void Note::set_pitch( float value )
565{
566 __pitch = value;
567}
568
569inline float Note::get_pitch() const
570{
571 return __pitch;
572}
573
574inline void Note::set_note_off( bool value )
575{
576 __note_off = value;
577}
578
579inline bool Note::get_note_off() const
580{
581 return __note_off;
582}
583
584inline int Note::get_midi_msg() const
585{
586 return __midi_msg;
587}
588
589inline void Note::set_pattern_idx( int value )
590{
591 __pattern_idx = value;
592}
593
594inline int Note::get_pattern_idx() const
595{
596 return __pattern_idx;
597}
598
599inline void Note::set_just_recorded( bool value )
600{
601 __just_recorded = value;
602}
603
604inline bool Note::get_just_recorded() const
605{
606 return __just_recorded;
607}
608
609inline float Note::get_probability() const
610{
611 return __probability;
612}
613
614inline void Note::set_probability( float value )
615{
616 __probability = value;
617}
618
619inline std::shared_ptr<SelectedLayerInfo> Note::get_layer_selected( int CompoID )
620{
621 return __layers_selected[ CompoID ];
622}
623
624inline std::map<int, std::shared_ptr<SelectedLayerInfo>> Note::get_layers_selected() const
625{
626 return __layers_selected;
627}
628
629inline int Note::get_humanize_delay() const
630{
631 return __humanize_delay;
632}
633
634inline float Note::get_cut_off() const
635{
636 return __cut_off;
637}
638
639inline float Note::get_resonance() const
640{
641 return __resonance;
642}
643
644inline float Note::get_bpfb_l() const
645{
646 return __bpfb_l;
647}
648
649inline float Note::get_bpfb_r() const
650{
651 return __bpfb_r;
652}
653
654inline float Note::get_lpfb_l() const
655{
656 return __lpfb_l;
657}
658
659inline float Note::get_lpfb_r() const
660{
661 return __lpfb_r;
662}
663
664inline bool Note::filter_sustain() const
665{
666 const double fLimit = 0.001;
667 return ( fabs( __lpfb_l ) > fLimit || fabs( __lpfb_r ) > fLimit ||
668 fabs( __bpfb_l ) > fLimit || fabs( __bpfb_r ) > fLimit );
669}
670
672{
673 return __key;
674}
675
677{
678 return __octave;
679}
680
681inline int Note::get_midi_key() const
682{
683 /* TODO ???
684 if( !has_instrument() ) { return (__octave + OCTAVE_OFFSET ) * KEYS_PER_OCTAVE + __key; }
685 */
687 __instrument->get_midi_out_note() - MidiMessage::instrumentOffset;
688}
689
690inline int Note::get_midi_velocity() const
691{
692 return __velocity * MIDI_FACTOR;
693}
694
695inline float Note::get_notekey_pitch() const
696{
697 return __octave * KEYS_PER_OCTAVE + __key;
698}
699
700inline void Note::set_key_octave( Key key, Octave octave )
701{
702 if( key>=KEY_MIN && key<=KEY_MAX ) __key = key;
703 if( octave>=OCTAVE_MIN && octave<=OCTAVE_MAX ) __octave = octave;
704}
705
706inline void Note::set_midi_info( Key key, Octave octave, int msg )
707{
708 if( key>=KEY_MIN && key<=KEY_MAX ) __key = key;
709 if( octave>=OCTAVE_MIN && octave<=OCTAVE_MAX ) __octave = octave;
710 __midi_msg = msg;
711}
712
713inline bool Note::match( std::shared_ptr<Instrument> instrument, Key key, Octave octave ) const
714{
715 return ( ( __instrument==instrument ) && ( __key==key ) && ( __octave==octave ) );
716}
717
718inline bool Note::match( const Note *pNote ) const
719{
720 return match( pNote->__instrument, pNote->__key, pNote->__octave );
721}
722inline bool Note::match( const std::shared_ptr<Note> pNote ) const
723{
724 return match( pNote->__instrument, pNote->__key, pNote->__octave );
725}
726
727inline void Note::compute_lr_values( float* val_l, float* val_r )
728{
729 /* TODO ???
730 if( !has_instrument() ) {
731 *val_l = 0.0f;
732 *val_r = 0.0f;
733 return;
734 }
735 */
736 float cut_off = __instrument->get_filter_cutoff();
737 float resonance = __instrument->get_filter_resonance();
738 __bpfb_l = resonance * __bpfb_l + cut_off * ( *val_l - __lpfb_l );
739 __lpfb_l += cut_off * __bpfb_l;
740 __bpfb_r = resonance * __bpfb_r + cut_off * ( *val_r - __lpfb_r );
741 __lpfb_r += cut_off * __bpfb_r;
742 *val_l = __lpfb_l;
743 *val_r = __lpfb_r;
744}
745
746inline long long Note::getNoteStart() const {
747 return m_nNoteStart;
748}
749inline float Note::getUsedTickSize() const {
750 return m_fUsedTickSize;
751}
752};
753
754#endif // H2C_NOTE_H
755
756/* vim: set softtabstop=4 noexpandtab: */
#define KEYS_PER_OCTAVE
Definition Note.h:40
#define KEY_MAX
Definition Note.h:35
#define OCTAVE_MIN
Definition Note.h:36
#define OCTAVE_OFFSET
Definition Note.h:38
#define OCTAVE_MAX
Definition Note.h:37
#define OCTAVE_DEFAULT
Definition Note.h:39
#define KEY_MIN
Definition Note.h:34
#define MIDI_FACTOR
Definition Note.h:43
#define H2_OBJECT(name)
Definition Object.h:227
static constexpr int instrumentOffset
When recording notes using MIDI NOTE_ON events this offset will be applied to the provided pitch in o...
Definition MidiCommon.h:91
A note plays an associated instrument with a velocity left and right pan.
Definition Note.h:101
int get_position() const
__position accessor
Definition Note.h:534
int __humanize_delay
frequency [0;1]
Definition Note.h:456
static int octaveKeyToPitch(Octave octave, Key key)
Definition Note.h:402
float m_fUsedTickSize
TransportPosition::m_fTickSize used to calculate m_nNoteStart.
Definition Note.h:489
static Key pitchToKey(int nPitch)
Definition Note.h:399
void set_length(int value)
__length setter
Definition Note.h:554
std::shared_ptr< SelectedLayerInfo > get_layer_selected(int CompoID)
Definition Note.h:619
float getPanWithRangeFrom0To1() const
get pan of the note, scaling and translating the range from [-1;1] to [0;1]
Definition Note.h:196
float get_lpfb_r() const
__lpfb_r accessor
Definition Note.h:659
void swing()
Add swing contribution to __humanize_delay.
Definition Note.cpp:460
bool isPartiallyRendered() const
Definition Note.cpp:221
int __pattern_idx
index of the pattern holding this note for undo actions
Definition Note.h:462
float get_bpfb_r() const
__bpfb_r accessor
Definition Note.h:649
std::shared_ptr< Instrument > __instrument
the instrument to be played by this note
Definition Note.h:424
void set_lead_lag(float value)
__lead_lag setter
Definition Note.cpp:148
float get_resonance() const
__resonance accessor
Definition Note.h:639
static QString KeyToQString(Key key)
Definition Note.cpp:650
float m_fPan
pan of the note, [-1;1] from
Definition Note.h:430
float __lpfb_l
left low pass filter buffer
Definition Note.h:460
int __midi_msg
TODO.
Definition Note.h:463
void set_humanize_delay(int value)
__humanize_delay setter
Definition Note.cpp:157
void set_key_octave(const QString &str)
parse str and set __key and __octave
Definition Note.cpp:202
int __position
note position in
Definition Note.h:427
static Octave pitchToOctave(int nPitch)
Definition Note.h:392
void map_instrument(std::shared_ptr< InstrumentList > instruments)
find the corresponding instrument and point to it, or an empty instrument
Definition Note.cpp:168
static Note * load_from(XMLNode *node, std::shared_ptr< InstrumentList > instruments, bool bSilent=false)
load a note from an XMLNode
Definition Note.cpp:500
bool filter_sustain() const
Filter output is sustaining note.
Definition Note.h:664
float __resonance
filter resonant
Definition Note.h:445
Octave get_octave()
__octave accessor
Definition Note.h:676
void set_probability(float value)
Definition Note.h:614
int get_humanize_delay() const
__humanize_delay accessor
Definition Note.h:629
float __lead_lag
lead or lag offset of the note
Definition Note.h:443
int get_specific_compo_id() const
__specific_compo_id accessor
Definition Note.h:524
void set_position(int value)
__position setter
Definition Note.h:529
std::shared_ptr< Instrument > get_instrument()
__instrument accessor
Definition Note.h:499
float get_bpfb_l() const
__bpfb_l accessor
Definition Note.h:644
int get_midi_msg() const
__midi_msg accessor
Definition Note.h:584
float get_total_pitch() const
Definition Note.cpp:421
bool __just_recorded
used in record+delete
Definition Note.h:465
float get_lead_lag() const
__lead_lag accessor
Definition Note.h:549
~Note()
destructor
Definition Note.cpp:134
float getUsedTickSize() const
Definition Note.h:749
void save_to(XMLNode *node)
Definition Note.cpp:486
float get_pitch() const
__pitch accessor
Definition Note.h:569
void humanize()
Add random contributions to __pitch, __humanize_delay, and __velocity.
Definition Note.cpp:431
void compute_lr_values(float *val_l, float *val_r)
compute left and right output based on filters
Definition Note.h:727
void set_just_recorded(bool value)
__just_recorded setter
Definition Note.h:599
int __length
left to right, as requested by Sampler PanLaws
Definition Note.h:438
std::shared_ptr< Sample > getSample(int nComponentID, int nSelectedLayer=-1)
Returns the sample associated with the note for a specific InstrumentComponent nComponentID.
Definition Note.cpp:262
int get_length() const
__length accessor
Definition Note.h:559
float get_notekey_pitch() const
note key pitch accessor
Definition Note.h:695
void set_instrument_id(int value)
__instrument_id setter
Definition Note.h:509
float __pitch
the frequency of the note
Definition Note.h:439
float __velocity
ticks inside the pattern
Definition Note.h:429
int get_midi_key() const
return scaled key for midi output, !
Definition Note.h:681
bool has_instrument() const
return true if __instrument is set
Definition Note.h:504
int get_pattern_idx() const
__pattern_idx accessor
Definition Note.h:594
float __probability
note probability
Definition Note.h:466
QString key_to_string()
return a string representation of key-octave
Definition Note.cpp:197
bool get_just_recorded() const
__just_recorded accessor
Definition Note.h:604
float get_velocity() const
__velocity accessor
Definition Note.h:539
void setPanWithRangeFrom0To1(float fVal)
set pan of the note, assuming the input range in [0;1]
Definition Note.h:190
Key
possible keys
Definition Note.h:105
bool get_note_off() const
__note_off accessor
Definition Note.h:579
void computeNoteStart()
Calculates the m_nNoteStart in frames corresponding to the __position in ticks and storing the used t...
Definition Note.cpp:234
void set_pattern_idx(int value)
__pattern_idx setter
Definition Note.h:589
void setPan(float val)
set pan of the note.
Definition Note.cpp:153
float __lpfb_r
right low pass filter buffer
Definition Note.h:461
void set_specific_compo_id(int value)
__specific_compo_id setter
Definition Note.h:519
void set_velocity(float value)
__velocity setter
Definition Note.cpp:143
static double pitchToFrequency(double fPitch)
Convert a logarithmic pitch-space value in semitones to a frequency-domain value.
Definition Note.h:387
QString toQString(const QString &sPrefix="", bool bShort=true) const override
Formatted string version for debugging purposes.
Definition Note.cpp:534
float __cut_off
filter cutoff [0;1]
Definition Note.h:444
std::shared_ptr< ADSR > get_adsr() const
get the ADSR of the note
Definition Note.h:494
std::map< int, std::shared_ptr< SelectedLayerInfo > > __layers_selected
Definition Note.h:457
long long getNoteStart() const
Definition Note.h:746
std::shared_ptr< ADSR > __adsr
attack decay sustain release
Definition Note.h:442
void set_note_off(bool value)
__note_off setter
Definition Note.h:574
float get_cut_off() const
__cut_off accessor
Definition Note.h:634
bool __note_off
note type on|off
Definition Note.h:464
long long m_nNoteStart
from __key an __octave
Definition Note.h:475
Key get_key()
__key accessor
Definition Note.h:671
float __bpfb_l
left band pass filter buffer
Definition Note.h:458
void set_midi_info(Key key, Octave octave, int msg)
set __key, __octave and __midi_msg only if within acceptable range
Definition Note.h:706
Key __key
the key, [0;11]==[C;B]
Definition Note.h:440
float get_probability() const
Definition Note.h:609
Octave __octave
the octave [-3;3]
Definition Note.h:441
float get_lpfb_l() const
__lpfb_l accessor
Definition Note.h:654
Note(std::shared_ptr< Instrument > pInstrument, int nPosition=0, float fVelocity=0.8, float fPan=0.0, int nLength=-1, float fPitch=0.0)
constructor
Definition Note.cpp:45
Octave
possible octaves
Definition Note.h:109
float getPan() const
get pan of the note.
Definition Note.h:544
int get_midi_velocity() const
midi velocity accessor
Definition Note.h:690
float __bpfb_r
right band pass filter buffer
Definition Note.h:459
int get_instrument_id() const
__instrument_id accessor
Definition Note.h:514
int __instrument_id
the id of the instrument played by this note
Definition Note.h:425
int __specific_compo_id
play a specific component, -1 if playing all
Definition Note.h:426
void set_pitch(float value)
__pitch setter
Definition Note.h:564
bool match(std::shared_ptr< Instrument > instrument, Key key, Octave octave) const
return true if instrument, key and octave matches with internal
Definition Note.h:713
std::map< int, std::shared_ptr< SelectedLayerInfo > > get_layers_selected() const
Definition Note.h:624
static const char * __key_str[]
used to build QString
Definition Note.h:467
XMLNode is a subclass of QDomNode with read and write values methods.
Definition Xml.h:39
Auxiliary variables storing the rendering state of a H2Core::Note within the H2Core::Sampler.
Definition Note.h:62
int nSelectedLayer
Selected layer during rendering in the H2Core::Sampler.
Definition Note.h:68
float fSamplePosition
Stores the frame till which the H2Core::Sample of the selected H2Core::InstrumentLayer using nSelecte...
Definition Note.h:78
int nNoteLength
Frame / fSamplePosition at which rendering of the current note is considered done.
Definition Note.h:93