mirror of
https://github.com/LMMS/lmms.git
synced 2026-05-07 22:33:01 -04:00
NotePlayHandle, InstrumentFunctions: reworked stacking and arpeggio handling
Instead of having various flags for realizing the arpeggion functionality use a more generic approach here using the recently introduced "origin" property.
This commit is contained in:
@@ -51,6 +51,8 @@ public:
|
||||
{
|
||||
OriginPattern, /*! playback of a note from a pattern */
|
||||
OriginMidiInput, /*! playback of a MIDI note input event */
|
||||
OriginNoteStacking, /*! created by note stacking instrument function */
|
||||
OriginArpeggio, /*! created by arpeggio instrument function */
|
||||
OriginCount
|
||||
};
|
||||
typedef Origins Origin;
|
||||
@@ -60,7 +62,6 @@ public:
|
||||
const f_cnt_t frames,
|
||||
const note& noteToPlay,
|
||||
NotePlayHandle* parent = NULL,
|
||||
const bool isPartOfArp = false,
|
||||
int midiEventChannel = -1,
|
||||
Origin origin = OriginPattern );
|
||||
virtual ~NotePlayHandle();
|
||||
@@ -160,27 +161,24 @@ public:
|
||||
return m_instrumentTrack;
|
||||
}
|
||||
|
||||
/*! Returns whether note is a top note, e.g. is not part of an arpeggio or a chord */
|
||||
bool isTopNote() const
|
||||
/*! Returns whether note has a parent, e.g. is not part of an arpeggio or a chord */
|
||||
bool hasParent() const
|
||||
{
|
||||
return m_topNote;
|
||||
return m_hasParent;
|
||||
}
|
||||
|
||||
/*! Returns whether note is part of an arpeggio playback */
|
||||
bool isPartOfArpeggio() const
|
||||
/*! Returns origin of note */
|
||||
Origin origin() const
|
||||
{
|
||||
return m_partOfArpeggio;
|
||||
return m_origin;
|
||||
}
|
||||
|
||||
/*! Sets whether note is part of an arpeggio playback */
|
||||
void setPartOfArpeggio( const bool _on )
|
||||
/*! Returns whether note has children */
|
||||
bool isMasterNote() const
|
||||
{
|
||||
m_partOfArpeggio = _on;
|
||||
return m_subNotes.size() > 0 || m_hadChildren;
|
||||
}
|
||||
|
||||
/*! Returns whether note is base note for arpeggio */
|
||||
bool isArpeggioBaseNote() const;
|
||||
|
||||
/*! Returns whether note is muted */
|
||||
bool isMuted() const
|
||||
{
|
||||
@@ -268,11 +266,8 @@ private:
|
||||
// release of note
|
||||
NotePlayHandleList m_subNotes; // used for chords and arpeggios
|
||||
volatile bool m_released; // indicates whether note is released
|
||||
bool m_topNote; // indicates whether note is a
|
||||
// base-note (i.e. no sub-note)
|
||||
bool m_partOfArpeggio; // indicates whether note is part of
|
||||
// an arpeggio (either base-note or
|
||||
// sub-note)
|
||||
bool m_hasParent;
|
||||
bool m_hadChildren;
|
||||
bool m_muted; // indicates whether note is muted
|
||||
track* m_bbTrack; // related BB track
|
||||
|
||||
|
||||
@@ -713,7 +713,7 @@ void lb302Synth::playNote( NotePlayHandle * _n, sampleFrame * _working_buffer )
|
||||
{
|
||||
//fpp_t framesPerPeriod = engine::mixer()->framesPerPeriod();
|
||||
|
||||
if( _n->isArpeggioBaseNote() )
|
||||
if( _n->isMasterNote() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -231,30 +231,24 @@ void InstrumentFunctionNoteStacking::processNote( NotePlayHandle * _n )
|
||||
// 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 )
|
||||
if( ( _n->origin() == NotePlayHandle::OriginArpeggio || ( _n->hasParent() == false && _n->instrumentTrack()->isArpeggioEnabled() == false ) ) &&
|
||||
_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 )
|
||||
for( int octave_cnt = 0; octave_cnt < m_chordRangeModel.value(); ++octave_cnt )
|
||||
{
|
||||
const int sub_note_key_base = base_note_key +
|
||||
octave_cnt * KeysPerOctave;
|
||||
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 )
|
||||
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];
|
||||
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 )
|
||||
@@ -262,16 +256,12 @@ void InstrumentFunctionNoteStacking::processNote( NotePlayHandle * _n )
|
||||
break;
|
||||
}
|
||||
// create copy of base-note
|
||||
note note_copy( _n->length(), 0, sub_note_key,
|
||||
_n->getVolume(),
|
||||
_n->getPanning(),
|
||||
_n->detuning() );
|
||||
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 );
|
||||
new NotePlayHandle( _n->instrumentTrack(), _n->offset(), _n->frames(), note_copy,
|
||||
_n, -1, NotePlayHandle::OriginNoteStacking );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,10 +300,8 @@ InstrumentFunctionArpeggio::InstrumentFunctionArpeggio( Model * _parent ) :
|
||||
m_arpEnabledModel( false ),
|
||||
m_arpModel( this, tr( "Arpeggio type" ) ),
|
||||
m_arpRangeModel( 1.0f, 1.0f, 9.0f, 1.0f, this, tr( "Arpeggio range" ) ),
|
||||
m_arpTimeModel( 100.0f, 25.0f, 2000.0f, 1.0f, 2000, this,
|
||||
tr( "Arpeggio time" ) ),
|
||||
m_arpGateModel( 100.0f, 1.0f, 200.0f, 1.0f, this,
|
||||
tr( "Arpeggio gate" ) ),
|
||||
m_arpTimeModel( 100.0f, 25.0f, 2000.0f, 1.0f, 2000, this, tr( "Arpeggio time" ) ),
|
||||
m_arpGateModel( 100.0f, 1.0f, 200.0f, 1.0f, this, tr( "Arpeggio gate" ) ),
|
||||
m_arpDirectionModel( this, tr( "Arpeggio direction" ) ),
|
||||
m_arpModeModel( this, tr( "Arpeggio mode" ) )
|
||||
{
|
||||
@@ -325,10 +313,8 @@ InstrumentFunctionArpeggio::InstrumentFunctionArpeggio( Model * _parent ) :
|
||||
|
||||
m_arpDirectionModel.addItem( tr( "Up" ), new PixmapLoader( "arp_up" ) );
|
||||
m_arpDirectionModel.addItem( tr( "Down" ), new PixmapLoader( "arp_down" ) );
|
||||
m_arpDirectionModel.addItem( tr( "Up and down" ),
|
||||
new PixmapLoader( "arp_up_and_down" ) );
|
||||
m_arpDirectionModel.addItem( tr( "Random" ),
|
||||
new PixmapLoader( "arp_random" ) );
|
||||
m_arpDirectionModel.addItem( tr( "Up and down" ), new PixmapLoader( "arp_up_and_down" ) );
|
||||
m_arpDirectionModel.addItem( tr( "Random" ), new PixmapLoader( "arp_random" ) );
|
||||
m_arpDirectionModel.setInitValue( ArpDirUp );
|
||||
|
||||
m_arpModeModel.addItem( tr( "Free" ), new PixmapLoader( "arp_free" ) );
|
||||
@@ -349,9 +335,10 @@ InstrumentFunctionArpeggio::~InstrumentFunctionArpeggio()
|
||||
void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
|
||||
{
|
||||
const int base_note_key = _n->key();
|
||||
if( _n->isTopNote() == false ||
|
||||
!m_arpEnabledModel.value() ||
|
||||
( _n->isReleased() && _n->releaseFramesDone() >= _n->actualReleaseFramesToDo() ) )
|
||||
if( _n->origin() == NotePlayHandle::OriginArpeggio ||
|
||||
_n->origin() == NotePlayHandle::OriginNoteStacking ||
|
||||
!m_arpEnabledModel.value() ||
|
||||
( _n->isReleased() && _n->releaseFramesDone() >= _n->actualReleaseFramesToDo() ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -359,8 +346,8 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
|
||||
|
||||
const int selected_arp = m_arpModel.value();
|
||||
|
||||
ConstNotePlayHandleList cnphv = NotePlayHandle::nphsOfInstrumentTrack(
|
||||
_n->instrumentTrack() );
|
||||
ConstNotePlayHandleList cnphv = NotePlayHandle::nphsOfInstrumentTrack( _n->instrumentTrack() );
|
||||
|
||||
if( m_arpModeModel.value() != FreeMode && cnphv.size() == 0 )
|
||||
{
|
||||
// maybe we're playing only a preset-preview-note?
|
||||
@@ -379,27 +366,23 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
|
||||
const int total_range = range * cnphv.size();
|
||||
|
||||
// number of frames that every note should be played
|
||||
const f_cnt_t arp_frames = (f_cnt_t)( m_arpTimeModel.value() / 1000.0f *
|
||||
engine::mixer()->processingSampleRate() );
|
||||
const f_cnt_t gated_frames = (f_cnt_t)( m_arpGateModel.value() *
|
||||
arp_frames / 100.0f );
|
||||
const f_cnt_t arp_frames = (f_cnt_t)( m_arpTimeModel.value() / 1000.0f * engine::mixer()->processingSampleRate() );
|
||||
const f_cnt_t gated_frames = (f_cnt_t)( m_arpGateModel.value() * arp_frames / 100.0f );
|
||||
|
||||
// used for calculating remaining frames for arp-note, we have to add
|
||||
// arp_frames-1, otherwise the first arp-note will not be setup
|
||||
// correctly... -> arp_frames frames silence at the start of every note!
|
||||
int cur_frame = ( ( m_arpModeModel.value() != FreeMode ) ?
|
||||
cnphv.first()->totalFramesPlayed() :
|
||||
_n->totalFramesPlayed() ) + arp_frames - 1;
|
||||
cnphv.first()->totalFramesPlayed() :
|
||||
_n->totalFramesPlayed() ) + arp_frames - 1;
|
||||
// used for loop
|
||||
f_cnt_t frames_processed = 0;
|
||||
|
||||
while( frames_processed < engine::mixer()->framesPerPeriod() )
|
||||
{
|
||||
const f_cnt_t remaining_frames_for_cur_arp = arp_frames -
|
||||
( cur_frame % arp_frames );
|
||||
const f_cnt_t remaining_frames_for_cur_arp = arp_frames - ( cur_frame % arp_frames );
|
||||
// does current arp-note fill whole audio-buffer?
|
||||
if( remaining_frames_for_cur_arp >
|
||||
engine::mixer()->framesPerPeriod() )
|
||||
if( remaining_frames_for_cur_arp > engine::mixer()->framesPerPeriod() )
|
||||
{
|
||||
// then we don't have to do something!
|
||||
break;
|
||||
@@ -413,8 +396,7 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
|
||||
// in sorted mode: is it our turn or do we have to be quiet for
|
||||
// now?
|
||||
if( m_arpModeModel.value() == SortMode &&
|
||||
( ( cur_frame / arp_frames ) % total_range ) /
|
||||
range != (f_cnt_t) _n->index() )
|
||||
( ( cur_frame / arp_frames ) % total_range ) / range != (f_cnt_t) _n->index() )
|
||||
{
|
||||
// update counters
|
||||
frames_processed += arp_frames;
|
||||
@@ -439,33 +421,28 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
|
||||
// once down -> makes 2 * range possible notes...
|
||||
// because we don't play the lower and upper notes
|
||||
// twice, we have to subtract 2
|
||||
cur_arp_idx = ( cur_frame / arp_frames ) %
|
||||
( range * 2 - 2 );
|
||||
cur_arp_idx = ( cur_frame / arp_frames ) % ( range * 2 - 2 );
|
||||
// if greater than range, we have to play down...
|
||||
// looks like the code for arp_dir==DOWN... :)
|
||||
if( cur_arp_idx >= range )
|
||||
{
|
||||
cur_arp_idx = range - cur_arp_idx %
|
||||
( range - 1 ) - 1;
|
||||
cur_arp_idx = range - cur_arp_idx % ( range - 1 ) - 1;
|
||||
}
|
||||
}
|
||||
else if( dir == ArpDirRandom )
|
||||
{
|
||||
// just pick a random chord-index
|
||||
cur_arp_idx = (int)( range * ( (float) rand() /
|
||||
(float) RAND_MAX ) );
|
||||
cur_arp_idx = (int)( range * ( (float) rand() / (float) RAND_MAX ) );
|
||||
}
|
||||
|
||||
// now calculate final key for our arp-note
|
||||
const int sub_note_key = base_note_key + (cur_arp_idx /
|
||||
cur_chord_size ) *
|
||||
KeysPerOctave +
|
||||
chord_table[selected_arp][cur_arp_idx % cur_chord_size];
|
||||
const int sub_note_key = base_note_key + (cur_arp_idx / cur_chord_size ) *
|
||||
KeysPerOctave + chord_table[selected_arp][cur_arp_idx % cur_chord_size];
|
||||
|
||||
// range-checking
|
||||
if( sub_note_key >= NumKeys ||
|
||||
sub_note_key < 0 ||
|
||||
engine::mixer()->criticalXRuns() )
|
||||
engine::mixer()->criticalXRuns() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -477,34 +454,20 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
|
||||
}
|
||||
|
||||
// create new arp-note
|
||||
note new_note( MidiTime( 0 ), MidiTime( 0 ),
|
||||
sub_note_key,
|
||||
(volume_t)
|
||||
qRound( _n->getVolume() * vol_level ),
|
||||
_n->getPanning(), _n->detuning() );
|
||||
|
||||
// create sub-note-play-handle, only ptr to note is different
|
||||
// and is_arp_note=true
|
||||
new NotePlayHandle( _n->instrumentTrack(),
|
||||
( ( m_arpModeModel.value() != FreeMode ) ?
|
||||
cnphv.first()->offset() :
|
||||
_n->offset() ) +
|
||||
frames_processed,
|
||||
gated_frames,
|
||||
new_note,
|
||||
_n, true );
|
||||
( ( m_arpModeModel.value() != FreeMode ) ? cnphv.first()->offset() : _n->offset() ) + frames_processed,
|
||||
gated_frames,
|
||||
note( MidiTime( 0 ), MidiTime( 0 ), sub_note_key, (volume_t) qRound( _n->getVolume() * vol_level ),
|
||||
_n->getPanning(), _n->detuning() ),
|
||||
_n, -1, NotePlayHandle::OriginArpeggio );
|
||||
|
||||
// update counters
|
||||
frames_processed += arp_frames;
|
||||
cur_frame += arp_frames;
|
||||
}
|
||||
|
||||
// make sure, note is handled as arp-base-note, even if we didn't add a
|
||||
// sub-note so far
|
||||
if( m_arpModeModel.value() != FreeMode )
|
||||
{
|
||||
_n->setPartOfArpeggio( true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
|
||||
const f_cnt_t _frames,
|
||||
const note& n,
|
||||
NotePlayHandle *parent,
|
||||
const bool _part_of_arp,
|
||||
int midiEventChannel,
|
||||
Origin origin ) :
|
||||
PlayHandle( TypeNotePlayHandle, _offset ),
|
||||
@@ -63,8 +62,8 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
|
||||
m_releaseFramesToDo( 0 ),
|
||||
m_releaseFramesDone( 0 ),
|
||||
m_released( false ),
|
||||
m_topNote( parent == NULL ),
|
||||
m_partOfArpeggio( _part_of_arp ),
|
||||
m_hasParent( parent != NULL ),
|
||||
m_hadChildren( false ),
|
||||
m_muted( false ),
|
||||
m_bbTrack( NULL ),
|
||||
m_origTempo( engine::getSong()->getTempo() ),
|
||||
@@ -76,7 +75,7 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
|
||||
m_midiChannel( midiEventChannel >= 0 ? midiEventChannel : instrumentTrack->midiPort()->realOutputChannel() ),
|
||||
m_origin( origin )
|
||||
{
|
||||
if( isTopNote() )
|
||||
if( hasParent() == false )
|
||||
{
|
||||
m_baseDetuning = new BaseDetuning( detuning() );
|
||||
m_instrumentTrack->m_processHandles.push_back( this );
|
||||
@@ -86,10 +85,7 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
|
||||
m_baseDetuning = parent->m_baseDetuning;
|
||||
|
||||
parent->m_subNotes.push_back( this );
|
||||
// if there was an arp-note added and parent is a base-note
|
||||
// we set arp-note-flag for indicating that parent is an
|
||||
// arpeggio-base-note
|
||||
parent->m_partOfArpeggio = isPartOfArpeggio() && parent->isTopNote();
|
||||
parent->m_hadChildren = true;
|
||||
|
||||
m_bbTrack = parent->m_bbTrack;
|
||||
}
|
||||
@@ -104,7 +100,7 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
|
||||
m_instrumentTrack->midiNoteOn( *this );
|
||||
}
|
||||
|
||||
if( !isTopNote() || !instrumentTrack->isArpeggioEnabled() )
|
||||
if( !isMasterNote() || !instrumentTrack->isArpeggioEnabled() )
|
||||
{
|
||||
const int baseVelocity = m_instrumentTrack->midiPort()->baseVelocity();
|
||||
|
||||
@@ -122,7 +118,7 @@ NotePlayHandle::~NotePlayHandle()
|
||||
{
|
||||
noteOff( 0 );
|
||||
|
||||
if( isTopNote() )
|
||||
if( hasParent() == false )
|
||||
{
|
||||
delete m_baseDetuning;
|
||||
m_instrumentTrack->m_processHandles.removeAll( this );
|
||||
@@ -209,12 +205,13 @@ void NotePlayHandle::play( sampleFrame * _working_buffer )
|
||||
if( m_released )
|
||||
{
|
||||
f_cnt_t todo = engine::mixer()->framesPerPeriod();
|
||||
|
||||
// if this note is base-note for arpeggio, always set
|
||||
// m_releaseFramesToDo to bigger value than m_releaseFramesDone
|
||||
// because we do not allow NotePlayHandle::isFinished() to be true
|
||||
// until all sub-notes are completely played and no new ones
|
||||
// are inserted by arpAndChordsTabWidget::processNote()
|
||||
if( isArpeggioBaseNote() )
|
||||
if( isMasterNote() )
|
||||
{
|
||||
m_releaseFramesToDo = m_releaseFramesDone + 2 * engine::mixer()->framesPerPeriod();
|
||||
}
|
||||
@@ -274,16 +271,6 @@ void NotePlayHandle::play( sampleFrame * _working_buffer )
|
||||
}
|
||||
}
|
||||
|
||||
// if this note is a base-note and there're no more sub-notes left we
|
||||
// can set m_releaseFramesDone to m_releaseFramesToDo so that
|
||||
// NotePlayHandle::isFinished() returns true and also this base-note is
|
||||
// removed from mixer's active note vector
|
||||
if( m_released && isArpeggioBaseNote() && m_subNotes.size() == 0 )
|
||||
{
|
||||
m_releaseFramesDone = m_releaseFramesToDo;
|
||||
m_frames = 0;
|
||||
}
|
||||
|
||||
// update internal data
|
||||
m_totalFramesPlayed += engine::mixer()->framesPerPeriod();
|
||||
}
|
||||
@@ -344,7 +331,7 @@ void NotePlayHandle::noteOff( const f_cnt_t _s )
|
||||
m_framesBeforeRelease = _s;
|
||||
m_releaseFramesToDo = qMax<f_cnt_t>( 0, m_instrumentTrack->m_soundShaping.releaseFrames() );
|
||||
|
||||
if( !isTopNote() || !instrumentTrack()->isArpeggioEnabled() )
|
||||
if( hasParent() || !instrumentTrack()->isArpeggioEnabled() )
|
||||
{
|
||||
// send MidiNoteOff event
|
||||
m_instrumentTrack->processOutEvent(
|
||||
@@ -367,8 +354,7 @@ void NotePlayHandle::noteOff( const f_cnt_t _s )
|
||||
|
||||
f_cnt_t NotePlayHandle::actualReleaseFramesToDo() const
|
||||
{
|
||||
return m_instrumentTrack->m_soundShaping.releaseFrames(/*
|
||||
isArpeggioBaseNote()*/ );
|
||||
return m_instrumentTrack->m_soundShaping.releaseFrames();
|
||||
}
|
||||
|
||||
|
||||
@@ -395,19 +381,10 @@ float NotePlayHandle::volumeLevel( const f_cnt_t _frame )
|
||||
|
||||
|
||||
|
||||
bool NotePlayHandle::isArpeggioBaseNote() const
|
||||
{
|
||||
return isTopNote() && ( m_partOfArpeggio || m_instrumentTrack->isArpeggioEnabled() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void NotePlayHandle::mute()
|
||||
{
|
||||
// mute all sub-notes
|
||||
for( NotePlayHandleList::Iterator it = m_subNotes.begin();
|
||||
it != m_subNotes.end(); ++it )
|
||||
for( NotePlayHandleList::Iterator it = m_subNotes.begin(); it != m_subNotes.end(); ++it )
|
||||
{
|
||||
( *it )->mute();
|
||||
}
|
||||
@@ -471,10 +448,11 @@ bool NotePlayHandle::operator==( const NotePlayHandle & _nph ) const
|
||||
offset() == _nph.offset() &&
|
||||
m_totalFramesPlayed == _nph.m_totalFramesPlayed &&
|
||||
m_released == _nph.m_released &&
|
||||
m_topNote == _nph.m_topNote &&
|
||||
m_partOfArpeggio == _nph.m_partOfArpeggio &&
|
||||
m_hasParent == _nph.m_hasParent &&
|
||||
m_origBaseNote == _nph.m_origBaseNote &&
|
||||
m_muted == _nph.m_muted;
|
||||
m_muted == _nph.m_muted &&
|
||||
m_midiChannel == _nph.m_midiChannel &&
|
||||
m_origin == _nph.m_origin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& ti
|
||||
NotePlayHandle* nph = new NotePlayHandle( this, time.frames( engine::framesPerTick() ),
|
||||
typeInfo<f_cnt_t>::max() / 2,
|
||||
note( MidiTime(), MidiTime(), event.key(), event.volume( midiPort()->baseVelocity() ) ),
|
||||
NULL, false, event.channel(),
|
||||
NULL, event.channel(),
|
||||
NotePlayHandle::OriginMidiInput );
|
||||
if( engine::mixer()->addPlayHandle( nph ) )
|
||||
{
|
||||
@@ -431,18 +431,17 @@ f_cnt_t InstrumentTrack::beatLen( NotePlayHandle * _n ) const
|
||||
|
||||
|
||||
|
||||
void InstrumentTrack::playNote( NotePlayHandle * _n,
|
||||
sampleFrame * _working_buffer )
|
||||
void InstrumentTrack::playNote( NotePlayHandle* n, sampleFrame* workingBuffer )
|
||||
{
|
||||
// arpeggio- and chord-widget has to do its work -> adding sub-notes
|
||||
// for chords/arpeggios
|
||||
m_noteStacking.processNote( _n );
|
||||
m_arpeggio.processNote( _n );
|
||||
m_noteStacking.processNote( n );
|
||||
m_arpeggio.processNote( n );
|
||||
|
||||
if( !_n->isArpeggioBaseNote() && m_instrument != NULL )
|
||||
if( n->isMasterNote() == false && m_instrument != NULL )
|
||||
{
|
||||
// all is done, so now lets play the note!
|
||||
m_instrument->playNote( _n, _working_buffer );
|
||||
m_instrument->playNote( n, workingBuffer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user