hydrogen 1.2.3
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-2024 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#define KEY_MIN 0
33#define KEY_MAX 11
34#define OCTAVE_MIN -3
35#define OCTAVE_MAX 3
36#define OCTAVE_OFFSET 3
37#define OCTAVE_DEFAULT 0
38#define KEYS_PER_OCTAVE 12
39
40#define MIDI_MIDDLE_C 60
41#define MIDI_FACTOR 127
42
43#define VELOCITY_MIN 0.0f
44#define VELOCITY_MAX 1.0f
45#define PAN_MIN 0.0f
46#define PAN_MAX 0.5f
47#define LEAD_LAG_MIN -1.0f
48#define LEAD_LAG_MAX 1.0f
49
50/* Should equal (default __octave + OCTAVE_OFFSET) * KEYS_PER_OCTAVE + default __key */
51#define MIDI_DEFAULT_OFFSET 36
52
53namespace H2Core
54{
55
56class XMLNode;
57class ADSR;
58class Instrument;
59class InstrumentList;
60
96
101class Note : public H2Core::Object<Note>
102{
104 public:
106 enum Key { C=KEY_MIN, Cs, D, Ef, E, F, Fs, G, Af, A, Bf, B };
107 static QString KeyToQString( Key key );
108
110 enum Octave { P8Z=-3, P8Y=-2, P8X=-1, P8=OCTAVE_DEFAULT, P8A=1, P8B=2, P8C=3 };
111
124 Note( std::shared_ptr<Instrument> pInstrument, int nPosition = 0, float fVelocity = 0.8, float fPan = 0.0, int nLength = -1, float fPitch = 0.0 );
125
131 Note( Note* pOther, std::shared_ptr<Instrument> pInstrument = nullptr );
133 ~Note();
134
135 /*
136 * save the note within the given XMLNode
137 * \param node the XMLNode to feed
138 */
139 void save_to( XMLNode* node );
148 static Note* load_from( XMLNode* node, std::shared_ptr<InstrumentList> instruments, bool bSilent = false );
149
154 void map_instrument( std::shared_ptr<InstrumentList> instruments );
156 std::shared_ptr<Instrument> get_instrument();
158 bool has_instrument() const;
163 void set_instrument_id( int value );
165 int get_instrument_id() const;
170 void set_specific_compo_id( int value );
172 int get_specific_compo_id() const;
177 void set_position( int value );
179 int get_position() const;
184 void set_velocity( float value );
186 float get_velocity() const;
187
189 void setPan( float val );
191 void setPanWithRangeFrom0To1( float fVal ) {
192 this->setPan( -1.f + 2.f * fVal ); // scale and translate into [-1;1]
193 };
195 float getPan() const;
198 return 0.5f * ( 1.f + m_fPan );
199 }
200
205 void set_lead_lag( float value );
207 float get_lead_lag() const;
212 void set_length( int value );
214 int get_length() const;
219 void set_pitch( float value );
221 float get_pitch() const;
226 void set_note_off( bool value );
228 bool get_note_off() const;
230 int get_midi_msg() const;
235 void set_pattern_idx( int value );
237 int get_pattern_idx() const;
242 void set_just_recorded( bool value );
244 bool get_just_recorded() const;
245
246 /*
247 * selected sample
248 * */
249 std::shared_ptr<SelectedLayerInfo> get_layer_selected( int CompoID );
250 std::map<int, std::shared_ptr<SelectedLayerInfo>> get_layers_selected() const;
251
252
253 void set_probability( float value );
254 float get_probability() const;
255
260 void set_humanize_delay( int value );
262 int get_humanize_delay() const;
264 float get_cut_off() const;
266 float get_resonance() const;
268 float get_bpfb_l() const;
270 float get_bpfb_r() const;
272 float get_lpfb_l() const;
274 float get_lpfb_r() const;
276 bool filter_sustain() const;
278 Key get_key();
282 int get_midi_key() const;
287 int get_midi_velocity() const;
292 float get_notekey_pitch() const;
299 float get_total_pitch() const;
300
302 QString key_to_string();
307 void set_key_octave( const QString& str );
313 void set_key_octave( Key key, Octave octave );
320 void set_midi_info( Key key, Octave octave, int msg );
321
323 std::shared_ptr<ADSR> get_adsr() const;
324
330 bool match( std::shared_ptr<Instrument> instrument, Key key, Octave octave ) const;
331
333 bool match( const Note *pNote ) const;
334 bool match( const std::shared_ptr<Note> pNote ) const;
335
341 void compute_lr_values( float* val_l, float* val_r );
342
343 long long getNoteStart() const;
344 float getUsedTickSize() const;
345
350 bool isPartiallyRendered() const;
351
361 void computeNoteStart();
362
367 void humanize();
368
375 void swing();
376
385 QString toQString( const QString& sPrefix = "", bool bShort = true ) const override;
386
388 static inline double pitchToFrequency( double fPitch ) {
389 // Equivalent to, but quicker to compute than, pow( 2.0, ( fPitch/12 ) )
390 return pow( 1.0594630943593, fPitch );
391 }
392
393 static inline Octave pitchToOctave( int nPitch ) {
394 if ( nPitch >= 0 ) {
395 return (Octave)(nPitch / 12);
396 } else {
397 return (Octave)((nPitch-11) / 12);
398 }
399 }
400 static inline Key pitchToKey( int nPitch ) {
401 return (Key)(nPitch - 12 * pitchToOctave( nPitch ));
402 }
403 static inline int octaveKeyToPitch( Octave octave, Key key ) {
404 return 12 * (int)octave + (int)key;
405 }
406
422 std::shared_ptr<Sample> getSample( int nComponentID, int nSelectedLayer = -1 );
423
424 private:
425 std::shared_ptr<Instrument> __instrument;
431 float m_fPan;
434
440 float __pitch;
443 std::shared_ptr<ADSR> __adsr;
445 float __cut_off;
448
458 std::map< int, std::shared_ptr<SelectedLayerInfo>> __layers_selected;
459 float __bpfb_l;
460 float __bpfb_r;
461 float __lpfb_l;
462 float __lpfb_r;
468 static const char* __key_str[];
470
476 long long m_nNoteStart;
491};
492
493// DEFINITIONS
494
495inline std::shared_ptr<ADSR> Note::get_adsr() const
496{
497 return __adsr;
498}
499
500inline std::shared_ptr<Instrument> Note::get_instrument()
501{
502 return __instrument;
503}
504
505inline bool Note::has_instrument() const
506{
507 return __instrument!=nullptr;
508}
509
510inline void Note::set_instrument_id( int value )
511{
512 __instrument_id = value;
513}
514
515inline int Note::get_instrument_id() const
516{
517 return __instrument_id;
518}
519
520inline void Note::set_specific_compo_id( int value )
521{
522 __specific_compo_id = value;
523}
524
526{
527 return __specific_compo_id;
528}
529
530inline void Note::set_position( int value )
531{
532 __position = value;
533}
534
535inline int Note::get_position() const
536{
537 return __position;
538}
539
540inline float Note::get_velocity() const
541{
542 return __velocity;
543}
544
545inline float Note::getPan() const
546{
547 return m_fPan;
548}
549
550inline float Note::get_lead_lag() const
551{
552 return __lead_lag;
553}
554
555inline void Note::set_length( int value )
556{
557 __length = value;
558}
559
560inline int Note::get_length() const
561{
562 return __length;
563}
564
565inline void Note::set_pitch( float value )
566{
567 __pitch = value;
568}
569
570inline float Note::get_pitch() const
571{
572 return __pitch;
573}
574
575inline void Note::set_note_off( bool value )
576{
577 __note_off = value;
578}
579
580inline bool Note::get_note_off() const
581{
582 return __note_off;
583}
584
585inline int Note::get_midi_msg() const
586{
587 return __midi_msg;
588}
589
590inline void Note::set_pattern_idx( int value )
591{
592 __pattern_idx = value;
593}
594
595inline int Note::get_pattern_idx() const
596{
597 return __pattern_idx;
598}
599
600inline void Note::set_just_recorded( bool value )
601{
602 __just_recorded = value;
603}
604
605inline bool Note::get_just_recorded() const
606{
607 return __just_recorded;
608}
609
610inline float Note::get_probability() const
611{
612 return __probability;
613}
614
615inline void Note::set_probability( float value )
616{
617 __probability = value;
618}
619
620inline std::shared_ptr<SelectedLayerInfo> Note::get_layer_selected( int CompoID )
621{
622 return __layers_selected[ CompoID ];
623}
624
625inline std::map<int, std::shared_ptr<SelectedLayerInfo>> Note::get_layers_selected() const
626{
627 return __layers_selected;
628}
629
630inline int Note::get_humanize_delay() const
631{
632 return __humanize_delay;
633}
634
635inline float Note::get_cut_off() const
636{
637 return __cut_off;
638}
639
640inline float Note::get_resonance() const
641{
642 return __resonance;
643}
644
645inline float Note::get_bpfb_l() const
646{
647 return __bpfb_l;
648}
649
650inline float Note::get_bpfb_r() const
651{
652 return __bpfb_r;
653}
654
655inline float Note::get_lpfb_l() const
656{
657 return __lpfb_l;
658}
659
660inline float Note::get_lpfb_r() const
661{
662 return __lpfb_r;
663}
664
665inline bool Note::filter_sustain() const
666{
667 const double fLimit = 0.001;
668 return ( fabs( __lpfb_l ) > fLimit || fabs( __lpfb_r ) > fLimit ||
669 fabs( __bpfb_l ) > fLimit || fabs( __bpfb_r ) > fLimit );
670}
671
673{
674 return __key;
675}
676
678{
679 return __octave;
680}
681
682inline int Note::get_midi_key() const
683{
684 /* TODO ???
685 if( !has_instrument() ) { return (__octave + OCTAVE_OFFSET ) * KEYS_PER_OCTAVE + __key; }
686 */
687 return ( __octave + OCTAVE_OFFSET ) * KEYS_PER_OCTAVE + __key + __instrument->get_midi_out_note() - MIDI_DEFAULT_OFFSET;
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:38
#define KEY_MAX
Definition Note.h:33
#define OCTAVE_MIN
Definition Note.h:34
#define OCTAVE_OFFSET
Definition Note.h:36
#define OCTAVE_MAX
Definition Note.h:35
#define OCTAVE_DEFAULT
Definition Note.h:37
#define KEY_MIN
Definition Note.h:32
#define MIDI_DEFAULT_OFFSET
Definition Note.h:51
#define MIDI_FACTOR
Definition Note.h:41
#define H2_OBJECT(name)
Definition Object.h:224
A note plays an associated instrument with a velocity left and right pan.
Definition Note.h:102
int get_position() const
__position accessor
Definition Note.h:535
int __humanize_delay
frequency [0;1]
Definition Note.h:457
static int octaveKeyToPitch(Octave octave, Key key)
Definition Note.h:403
float m_fUsedTickSize
TransportPosition::m_fTickSize used to calculate m_nNoteStart.
Definition Note.h:490
static Key pitchToKey(int nPitch)
Definition Note.h:400
void set_length(int value)
__length setter
Definition Note.h:555
std::shared_ptr< SelectedLayerInfo > get_layer_selected(int CompoID)
Definition Note.h:620
float getPanWithRangeFrom0To1() const
get pan of the note, scaling and translating the range from [-1;1] to [0;1]
Definition Note.h:197
float get_lpfb_r() const
__lpfb_r accessor
Definition Note.h:660
void swing()
Add swing contribution to __humanize_delay.
Definition Note.cpp:462
bool isPartiallyRendered() const
Definition Note.cpp:221
int __pattern_idx
index of the pattern holding this note for undo actions
Definition Note.h:463
float get_bpfb_r() const
__bpfb_r accessor
Definition Note.h:650
std::shared_ptr< Instrument > __instrument
the instrument to be played by this note
Definition Note.h:425
void set_lead_lag(float value)
__lead_lag setter
Definition Note.cpp:148
float get_resonance() const
__resonance accessor
Definition Note.h:640
static QString KeyToQString(Key key)
Definition Note.cpp:652
float m_fPan
pan of the note, [-1;1] from
Definition Note.h:431
float __lpfb_l
left low pass filter buffer
Definition Note.h:461
int __midi_msg
TODO.
Definition Note.h:464
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:428
static Octave pitchToOctave(int nPitch)
Definition Note.h:393
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:502
bool filter_sustain() const
Filter output is sustaining note.
Definition Note.h:665
float __resonance
filter resonant
Definition Note.h:446
Octave get_octave()
__octave accessor
Definition Note.h:677
void set_probability(float value)
Definition Note.h:615
int get_humanize_delay() const
__humanize_delay accessor
Definition Note.h:630
float __lead_lag
lead or lag offset of the note
Definition Note.h:444
int get_specific_compo_id() const
__specific_compo_id accessor
Definition Note.h:525
void set_position(int value)
__position setter
Definition Note.h:530
std::shared_ptr< Instrument > get_instrument()
__instrument accessor
Definition Note.h:500
float get_bpfb_l() const
__bpfb_l accessor
Definition Note.h:645
int get_midi_msg() const
__midi_msg accessor
Definition Note.h:585
float get_total_pitch() const
Definition Note.cpp:423
bool __just_recorded
used in record+delete
Definition Note.h:466
float get_lead_lag() const
__lead_lag accessor
Definition Note.h:550
~Note()
destructor
Definition Note.cpp:134
float getUsedTickSize() const
Definition Note.h:749
void save_to(XMLNode *node)
Definition Note.cpp:488
float get_pitch() const
__pitch accessor
Definition Note.h:570
void humanize()
Add random contributions to __pitch, __humanize_delay, and __velocity.
Definition Note.cpp:433
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:600
int __length
left to right, as requested by Sampler PanLaws
Definition Note.h:439
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:560
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:510
float __pitch
the frequency of the note
Definition Note.h:440
float __velocity
ticks inside the pattern
Definition Note.h:430
int get_midi_key() const
return scaled key for midi output, !!! DO NOT CHECK IF INSTRUMENT IS SET !!!
Definition Note.h:682
bool has_instrument() const
return true if __instrument is set
Definition Note.h:505
int get_pattern_idx() const
__pattern_idx accessor
Definition Note.h:595
float __probability
note probability
Definition Note.h:467
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:605
float get_velocity() const
__velocity accessor
Definition Note.h:540
void setPanWithRangeFrom0To1(float fVal)
set pan of the note, assuming the input range in [0;1]
Definition Note.h:191
Key
possible keys
Definition Note.h:106
bool get_note_off() const
__note_off accessor
Definition Note.h:580
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:590
void setPan(float val)
set pan of the note.
Definition Note.cpp:153
float __lpfb_r
right low pass filter buffer
Definition Note.h:462
void set_specific_compo_id(int value)
__specific_compo_id setter
Definition Note.h:520
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:388
QString toQString(const QString &sPrefix="", bool bShort=true) const override
Formatted string version for debugging purposes.
Definition Note.cpp:536
float __cut_off
filter cutoff [0;1]
Definition Note.h:445
std::shared_ptr< ADSR > get_adsr() const
get the ADSR of the note
Definition Note.h:495
std::map< int, std::shared_ptr< SelectedLayerInfo > > __layers_selected
Definition Note.h:458
long long getNoteStart() const
Definition Note.h:746
std::shared_ptr< ADSR > __adsr
attack decay sustain release
Definition Note.h:443
void set_note_off(bool value)
__note_off setter
Definition Note.h:575
float get_cut_off() const
__cut_off accessor
Definition Note.h:635
bool __note_off
note type on|off
Definition Note.h:465
long long m_nNoteStart
from __key an __octave
Definition Note.h:476
Key get_key()
__key accessor
Definition Note.h:672
float __bpfb_l
left band pass filter buffer
Definition Note.h:459
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:441
float get_probability() const
Definition Note.h:610
Octave __octave
the octave [-3;3]
Definition Note.h:442
float get_lpfb_l() const
__lpfb_l accessor
Definition Note.h:655
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:110
float getPan() const
get pan of the note.
Definition Note.h:545
int get_midi_velocity() const
midi velocity accessor
Definition Note.h:690
float __bpfb_r
right band pass filter buffer
Definition Note.h:460
int get_instrument_id() const
__instrument_id accessor
Definition Note.h:515
int __instrument_id
the id of the instrument played by this note
Definition Note.h:426
int __specific_compo_id
play a specific component, -1 if playing all
Definition Note.h:427
void set_pitch(float value)
__pitch setter
Definition Note.h:565
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:625
static const char * __key_str[]
used to build QString
Definition Note.h:468
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:63
int nSelectedLayer
Selected layer during rendering in the H2Core::Sampler.
Definition Note.h:69
float fSamplePosition
Stores the frame till which the H2Core::Sample of the selected H2Core::InstrumentLayer using nSelecte...
Definition Note.h:79
int nNoteLength
Frame / fSamplePosition at which rendering of the current note is considered done.
Definition Note.h:94