void InstrumentFunctionNoteStacking::processNote( NotePlayHandle * _n ) { const int base_note_key = _n->key(); const ChordTable & chord_table = ChordTable::getInstance(); // we add chord-subnotes to note if either note is a base-note and // arpeggio is not used or note is part of an arpeggio // at the same time we only add sub-notes if nothing of the note was // played yet, because otherwise we would add chord-subnotes every // time an audio-buffer is rendered... if( ( ( _n->isTopNote() && _n->instrumentTrack()->isArpeggioEnabled() == false ) || _n->isPartOfArpeggio() ) && _n->totalFramesPlayed() == 0 && m_chordsEnabledModel.value() == true ) { // then insert sub-notes for chord const int selected_chord = m_chordsModel.value(); for( int octave_cnt = 0; octave_cnt < m_chordRangeModel.value(); ++octave_cnt ) { const int sub_note_key_base = base_note_key + octave_cnt * KeysPerOctave; // if octave_cnt == 1 we're in the first octave and // the base-note is already done, so we don't have to // create it in the following loop, then we loop until // there's a -1 in the interval-array for( int i = ( octave_cnt == 0 ) ? 1 : 0; i < chord_table[selected_chord].size(); ++i ) { // add interval to sub-note-key const int sub_note_key = sub_note_key_base + (int) chord_table[ selected_chord][i]; // maybe we're out of range -> let's get outta // here! if( sub_note_key > NumKeys ) { break; } // create copy of base-note note note_copy( _n->length(), 0, sub_note_key, _n->getVolume(), _n->getPanning(), _n->detuning() ); // create sub-note-play-handle, only note is // different new NotePlayHandle( _n->instrumentTrack(), _n->offset(), _n->frames(), note_copy, _n ); } } } }
void InstrumentFunctionNoteStacking::processNote( NotePlayHandle * _n ) { const int base_note_key = _n->key(); const ChordTable & chord_table = ChordTable::getInstance(); // we add chord-subnotes to note if either note is a base-note and // arpeggio is not used or note is part of an arpeggio // at the same time we only add sub-notes if nothing of the note was // played yet, because otherwise we would add chord-subnotes every // time an audio-buffer is rendered... if( ( _n->origin() == NotePlayHandle::OriginArpeggio || ( _n->hasParent() == false && _n->instrumentTrack()->isArpeggioEnabled() == false ) ) && _n->totalFramesPlayed() == 0 && m_chordsEnabledModel.value() == true && ! _n->isReleased() ) { // then insert sub-notes for chord const int selected_chord = m_chordsModel.value(); for( int octave_cnt = 0; octave_cnt < m_chordRangeModel.value(); ++octave_cnt ) { const int sub_note_key_base = base_note_key + octave_cnt * KeysPerOctave; // process all notes in the chord for( int i = 0; i < chord_table[selected_chord].size(); ++i ) { // add interval to sub-note-key const int sub_note_key = sub_note_key_base + (int) chord_table[selected_chord][i]; // maybe we're out of range -> let's get outta // here! if( sub_note_key > NumKeys ) { break; } // create copy of base-note Note note_copy( _n->length(), 0, sub_note_key, _n->getVolume(), _n->getPanning(), _n->detuning() ); // create sub-note-play-handle, only note is // different Engine::mixer()->addPlayHandle( NotePlayHandleManager::acquire( _n->instrumentTrack(), _n->offset(), _n->frames(), note_copy, _n, -1, NotePlayHandle::OriginNoteStacking ) ); } } } }