* improved the way, MIDI-events are internally sent and handled
* fixed names of various member methods of notePlayHandle class * full MIDI velocity when pressing key on test piano * send volume changes of a notePlayHandle as MidiKeyPressure events * send pitch changes of instrument track as MidiPitchBend events * added detection for running MIDI notes * correct calculation of MIDI key - makes remotePlugins respect base note settings git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1562 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
40
ChangeLog
40
ChangeLog
@@ -1,3 +1,43 @@
|
||||
2008-09-06 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
|
||||
|
||||
* plugins/ladspa_effect/ladspa_subplugin_features.cpp:
|
||||
* include/ladspa_base.h:
|
||||
save LADSPA effect filenames without extension and add correct
|
||||
one (depending on platform built for) when loading settings - fixes
|
||||
missing effects when loading songs in Windows which were made in Linux
|
||||
and vice versa
|
||||
|
||||
* include/audio_pulseaudio.h:
|
||||
added information about bad latency when using PulseAudio output
|
||||
|
||||
* plugins/vestige/vestige.cpp:
|
||||
* plugins/vestige/vestige.h:
|
||||
only use MIDI anymore for controlling VST instruments
|
||||
|
||||
* plugins/lb302/lb302.cpp:
|
||||
* include/note.h:
|
||||
* include/instrument_track.h:
|
||||
* include/midi.h:
|
||||
* include/note_play_handle.h:
|
||||
* src/tracks/instrument_track.cpp:
|
||||
* src/core/preset_preview_play_handle.cpp:
|
||||
* src/core/note_play_handle.cpp:
|
||||
* src/core/instrument_functions.cpp:
|
||||
* src/core/piano.cpp:
|
||||
- improved the way, MIDI-events are internally sent and handled
|
||||
- fixed names of various member methods of notePlayHandle class
|
||||
- full MIDI velocity when pressing key on test piano
|
||||
- send volume changes of a notePlayHandle as MidiKeyPressure events
|
||||
- send pitch changes of instrument track as MidiPitchBend events
|
||||
- added detection for running MIDI notes
|
||||
- correct calculation of MIDI key - makes remotePlugins respect
|
||||
base note settings
|
||||
|
||||
* src/core/midi/midi_port.cpp:
|
||||
* src/core/midi/midi_alsa_seq.cpp:
|
||||
fixed broken MIDI-output (when masking output events it didn't match
|
||||
against correct output MIDI channel)
|
||||
|
||||
2008-09-06 Csaba Hruska <csaba.hruska/at/gmail.com>
|
||||
|
||||
* plugins/sid/sid_instrument.cpp:
|
||||
|
||||
@@ -70,6 +70,8 @@ public:
|
||||
void processAudioBuffer( sampleFrame * _buf, const fpp_t _frames,
|
||||
notePlayHandle * _n );
|
||||
|
||||
midiEvent applyMasterKey( const midiEvent & _me );
|
||||
|
||||
virtual void processInEvent( const midiEvent & _me,
|
||||
const midiTime & _time );
|
||||
virtual void processOutEvent( const midiEvent & _me,
|
||||
@@ -100,9 +102,9 @@ public:
|
||||
// name-stuff
|
||||
virtual void setName( const QString & _new_name );
|
||||
|
||||
// translate key of given notePlayHandle to absolute key (i.e.
|
||||
// add global master-pitch and base-note in piano)
|
||||
int masterKey( notePlayHandle * _n ) const;
|
||||
// translate given key of a note-event to absolute key (i.e.
|
||||
// add global master-pitch and base-note of this instrument track)
|
||||
int masterKey( int _midi_key ) const;
|
||||
|
||||
// translate pitch to midi-pitch [0,16383]
|
||||
inline int midiPitch( void ) const
|
||||
@@ -181,6 +183,7 @@ protected:
|
||||
|
||||
protected slots:
|
||||
void updateBaseNote( void );
|
||||
void updatePitch( void );
|
||||
|
||||
|
||||
private:
|
||||
@@ -188,6 +191,7 @@ private:
|
||||
midiPort m_midiPort;
|
||||
|
||||
notePlayHandle * m_notes[NumKeys];
|
||||
int m_runningMidiNotes[NumKeys];
|
||||
|
||||
intModel m_baseNoteModel;
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ enum MidiMetaEvents
|
||||
|
||||
const int MidiChannelCount = 16;
|
||||
const int MidiControllerCount = 128;
|
||||
const int MidiMaxVelocity = 127;
|
||||
|
||||
|
||||
struct midiEvent
|
||||
@@ -105,6 +106,14 @@ struct midiEvent
|
||||
m_data.m_sysExDataLen = _data_len;
|
||||
}
|
||||
|
||||
midiEvent( const midiEvent & _copy ) :
|
||||
m_type( _copy.m_type ),
|
||||
m_channel( _copy.m_channel ),
|
||||
m_data( _copy.m_data ),
|
||||
m_sysExData( _copy.m_sysExData )
|
||||
{
|
||||
}
|
||||
|
||||
inline Uint16 key( void ) const
|
||||
{
|
||||
return( m_data.m_param[0] );
|
||||
@@ -125,6 +134,12 @@ struct midiEvent
|
||||
return( m_data.m_param[1] );
|
||||
}
|
||||
|
||||
inline volume getVolume( void ) const
|
||||
{
|
||||
return( velocity() * 100 / MidiMaxVelocity );
|
||||
}
|
||||
|
||||
|
||||
MidiEventTypes m_type; // MIDI event type
|
||||
Sint8 m_channel; // MIDI channel
|
||||
union
|
||||
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
void setLength( const midiTime & _length );
|
||||
void setPos( const midiTime & _pos );
|
||||
void setKey( const int _key );
|
||||
void setVolume( const volume _volume = DefaultVolume );
|
||||
virtual void setVolume( const volume _volume = DefaultVolume );
|
||||
void setPanning( const panning _panning = DefaultPanning );
|
||||
void quantizeLength( const int _q_grid );
|
||||
void quantizePos( const int _q_grid );
|
||||
|
||||
@@ -52,9 +52,12 @@ public:
|
||||
const f_cnt_t _offset,
|
||||
const f_cnt_t _frames, const note & _n,
|
||||
notePlayHandle * _parent = NULL,
|
||||
const bool _arp_note = FALSE );
|
||||
const bool _part_of_arp = false );
|
||||
virtual ~notePlayHandle();
|
||||
|
||||
virtual void setVolume( const volume _volume = DefaultVolume );
|
||||
|
||||
int getMidiVelocity( void ) const;
|
||||
|
||||
const float & frequency( void ) const
|
||||
{
|
||||
@@ -85,7 +88,7 @@ public:
|
||||
if( m_released == TRUE )
|
||||
{
|
||||
f_cnt_t todo = engine::getMixer()->framesPerPeriod();
|
||||
if( arpBaseNote() == TRUE )
|
||||
if( isArpeggioBaseNote() )
|
||||
{
|
||||
rftd = rfd + 2 *
|
||||
engine::getMixer()->framesPerPeriod();
|
||||
@@ -118,7 +121,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if( arpBaseNote() == TRUE && m_subNotes.size() == 0 )
|
||||
if( isArpeggioBaseNote() && m_subNotes.size() == 0 )
|
||||
{
|
||||
rfd = rftd;
|
||||
}
|
||||
@@ -184,29 +187,29 @@ public:
|
||||
|
||||
// returns whether note is a base-note, e.g. is not part of an arpeggio
|
||||
// or a chord
|
||||
inline bool baseNote( void ) const
|
||||
inline bool isBaseNote( void ) const
|
||||
{
|
||||
return( m_baseNote );
|
||||
}
|
||||
|
||||
// returns whether note is part of an arpeggio
|
||||
inline bool arpNote( void ) const
|
||||
inline bool isPartOfArpeggio( void ) const
|
||||
{
|
||||
return( m_arpNote );
|
||||
return( m_partOfArpeggio );
|
||||
}
|
||||
|
||||
inline void setArpNote( const bool _on )
|
||||
inline void setPartOfArpeggio( const bool _on )
|
||||
{
|
||||
m_arpNote = _on;
|
||||
m_partOfArpeggio = _on;
|
||||
}
|
||||
|
||||
// returns whether note is base-note for arpeggio
|
||||
inline bool arpBaseNote( void ) const
|
||||
inline bool isArpeggioBaseNote( void ) const
|
||||
{
|
||||
return( baseNote() && arpNote() );
|
||||
return( isBaseNote() && ( m_partOfArpeggio ||
|
||||
m_instrumentTrack->arpeggiatorEnabled() ) );
|
||||
}
|
||||
|
||||
inline bool muted( void ) const
|
||||
inline bool isMuted( void ) const
|
||||
{
|
||||
return( m_muted );
|
||||
}
|
||||
@@ -214,7 +217,7 @@ public:
|
||||
void mute( void );
|
||||
|
||||
// returns index of note-play-handle in vector of note-play-handles
|
||||
// belonging to this channel
|
||||
// belonging to this instrument-track - used by arpeggiator
|
||||
int index( void ) const;
|
||||
|
||||
// note-play-handles belonging to given channel, if _all_ph = TRUE,
|
||||
@@ -255,7 +258,7 @@ public:
|
||||
}
|
||||
|
||||
void processMidiTime( const midiTime & _time );
|
||||
void resize( const bpm_t _new_bpm );
|
||||
void resize( const bpm_t _new_tempo );
|
||||
|
||||
#if LMMS_SINGERBOT_SUPPORT
|
||||
int patternIndex( void )
|
||||
@@ -310,7 +313,7 @@ private:
|
||||
volatile bool m_released; // indicates whether note is released
|
||||
bool m_baseNote; // indicates whether note is a
|
||||
// base-note (i.e. no sub-note)
|
||||
bool m_arpNote; // indicates whether note is part of
|
||||
bool m_partOfArpeggio; // indicates whether note is part of
|
||||
// an arpeggio (either base-note or
|
||||
// sub-note)
|
||||
bool m_muted; // indicates whether note is muted
|
||||
@@ -320,8 +323,8 @@ private:
|
||||
#endif
|
||||
|
||||
// tempo reaction
|
||||
bpm_t m_orig_bpm; // original bpm
|
||||
f_cnt_t m_orig_frames; // original m_frames
|
||||
bpm_t m_origTempo; // original tempo
|
||||
f_cnt_t m_origFrames; // original m_frames
|
||||
|
||||
float m_frequency;
|
||||
float m_unpitchedFrequency;
|
||||
|
||||
@@ -706,7 +706,7 @@ void lb302Synth::playNote( notePlayHandle * _n, bool,
|
||||
{
|
||||
fpp_t framesPerPeriod = engine::getMixer()->framesPerPeriod();
|
||||
|
||||
if( _n->arpBaseNote() )
|
||||
if( _n->isArpeggioBaseNote() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -187,9 +187,9 @@ void chordCreator::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->baseNote() &&
|
||||
if( ( ( _n->isBaseNote() &&
|
||||
_n->getInstrumentTrack()->arpeggiatorEnabled() == FALSE ) ||
|
||||
_n->arpNote() ) &&
|
||||
_n->isPartOfArpeggio() ) &&
|
||||
_n->totalFramesPlayed() == 0 &&
|
||||
m_chordsEnabledModel.value() == TRUE )
|
||||
{
|
||||
@@ -310,7 +310,7 @@ arpeggiator::~arpeggiator()
|
||||
void arpeggiator::processNote( notePlayHandle * _n )
|
||||
{
|
||||
const int base_note_key = _n->key();
|
||||
if( _n->baseNote() == FALSE ||
|
||||
if( _n->isBaseNote() == FALSE ||
|
||||
!m_arpEnabledModel.value() ||
|
||||
( _n->released() && _n->releaseFramesDone() >=
|
||||
_n->actualReleaseFramesToDo() ) )
|
||||
@@ -467,7 +467,7 @@ void arpeggiator::processNote( notePlayHandle * _n )
|
||||
// sub-note so far
|
||||
if( m_arpModeModel.value() != FreeMode )
|
||||
{
|
||||
_n->setArpNote( TRUE );
|
||||
_n->setPartOfArpeggio( true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ notePlayHandle::notePlayHandle( instrumentTrack * _it,
|
||||
const f_cnt_t _frames,
|
||||
const note & _n,
|
||||
notePlayHandle * _parent,
|
||||
const bool _arp_note ) :
|
||||
const bool _part_of_arp ) :
|
||||
playHandle( NotePlayHandle, _offset ),
|
||||
note( _n.length(), _n.pos(), _n.key(),
|
||||
_n.getVolume(), _n.getPanning(), _n.detuning() ),
|
||||
@@ -67,13 +67,13 @@ notePlayHandle::notePlayHandle( instrumentTrack * _it,
|
||||
m_releaseFramesDone( 0 ),
|
||||
m_released( FALSE ),
|
||||
m_baseNote( _parent == NULL ),
|
||||
m_arpNote( _arp_note ),
|
||||
m_partOfArpeggio( _part_of_arp ),
|
||||
m_muted( FALSE ),
|
||||
m_bbTrack( NULL ),
|
||||
#if LMMS_SINGERBOT_SUPPORT
|
||||
m_patternIndex( 0 ),
|
||||
#endif
|
||||
m_orig_bpm( engine::getSong()->getTempo() )
|
||||
m_origTempo( engine::getSong()->getTempo() )
|
||||
{
|
||||
if( m_baseNote )
|
||||
{
|
||||
@@ -88,7 +88,8 @@ notePlayHandle::notePlayHandle( instrumentTrack * _it,
|
||||
// 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_arpNote = arpNote() && _parent->baseNote();
|
||||
_parent->m_partOfArpeggio = isPartOfArpeggio() &&
|
||||
_parent->isBaseNote();
|
||||
|
||||
m_bbTrack = _parent->m_bbTrack;
|
||||
#if LMMS_SINGERBOT_SUPPORT
|
||||
@@ -99,16 +100,17 @@ notePlayHandle::notePlayHandle( instrumentTrack * _it,
|
||||
updateFrequency();
|
||||
|
||||
setFrames( _frames );
|
||||
// send MIDI-note-on-event
|
||||
m_instrumentTrack->processOutEvent( midiEvent( MidiNoteOn,
|
||||
|
||||
|
||||
if( !isBaseNote() || !getInstrumentTrack()->arpeggiatorEnabled() )
|
||||
{
|
||||
// send MIDI-note-on-event
|
||||
m_instrumentTrack->processOutEvent( midiEvent( MidiNoteOn,
|
||||
m_instrumentTrack->getMidiPort()->outputChannel(),
|
||||
key(),
|
||||
tLimit<Uint16>(
|
||||
(Uint16) ( ( getVolume() / 100.0f ) *
|
||||
( m_instrumentTrack->getVolume() / 100.0f ) *
|
||||
127 ), 0, 127 ) ),
|
||||
midiTime::fromFrames( offset(),
|
||||
key(), getMidiVelocity() ),
|
||||
midiTime::fromFrames( offset(),
|
||||
engine::framesPerTick() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,6 +149,29 @@ notePlayHandle::~notePlayHandle()
|
||||
|
||||
|
||||
|
||||
void notePlayHandle::setVolume( const volume _volume )
|
||||
{
|
||||
note::setVolume( _volume );
|
||||
m_instrumentTrack->processOutEvent( midiEvent( MidiKeyPressure,
|
||||
m_instrumentTrack->getMidiPort()->outputChannel(),
|
||||
key(), getMidiVelocity() ), 0 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int notePlayHandle::getMidiVelocity( void ) const
|
||||
{
|
||||
return tLimit<Uint16>( (Uint16) ( ( getVolume() / 100.0f ) *
|
||||
( m_instrumentTrack->getVolume() / 100.0f ) *
|
||||
MidiMaxVelocity ),
|
||||
0, MidiMaxVelocity );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void notePlayHandle::play( bool _try_parallelizing,
|
||||
sampleFrame * _working_buffer )
|
||||
{
|
||||
@@ -180,7 +205,7 @@ void notePlayHandle::play( bool _try_parallelizing,
|
||||
// because we do not allow notePlayHandle::done() to be true
|
||||
// until all sub-notes are completely played and no new ones
|
||||
// are inserted by arpAndChordsTabWidget::processNote()
|
||||
if( arpBaseNote() == TRUE )
|
||||
if( isArpeggioBaseNote() )
|
||||
{
|
||||
m_releaseFramesToDo = m_releaseFramesDone + 2 *
|
||||
engine::getMixer()->framesPerPeriod();
|
||||
@@ -246,7 +271,7 @@ void notePlayHandle::play( bool _try_parallelizing,
|
||||
// can set m_releaseFramesDone to m_releaseFramesToDo so that
|
||||
// notePlayHandle::done() returns true and also this base-note is
|
||||
// removed from mixer's active note vector
|
||||
if( arpBaseNote() == TRUE && m_subNotes.size() == 0 )
|
||||
if( isArpeggioBaseNote() && m_subNotes.size() == 0 )
|
||||
{
|
||||
m_releaseFramesDone = m_releaseFramesToDo;
|
||||
}
|
||||
@@ -301,12 +326,16 @@ void notePlayHandle::noteOff( const f_cnt_t _s )
|
||||
m_framesBeforeRelease = _s;
|
||||
m_releaseFramesToDo = tMax<f_cnt_t>( 0, // 10,
|
||||
m_instrumentTrack->m_soundShaping.releaseFrames() );
|
||||
// send MIDI-note-off-event
|
||||
m_instrumentTrack->processOutEvent( midiEvent( MidiNoteOff,
|
||||
|
||||
if( !isBaseNote() || !getInstrumentTrack()->arpeggiatorEnabled() )
|
||||
{
|
||||
// send MIDI-note-off-event
|
||||
m_instrumentTrack->processOutEvent( midiEvent( MidiNoteOff,
|
||||
m_instrumentTrack->getMidiPort()->outputChannel(),
|
||||
key(), 0 ),
|
||||
midiTime::fromFrames( m_framesBeforeRelease,
|
||||
engine::framesPerTick() ) );
|
||||
}
|
||||
|
||||
m_released = TRUE;
|
||||
}
|
||||
@@ -317,7 +346,7 @@ void notePlayHandle::noteOff( const f_cnt_t _s )
|
||||
f_cnt_t notePlayHandle::actualReleaseFramesToDo( void ) const
|
||||
{
|
||||
return( m_instrumentTrack->m_soundShaping.releaseFrames(
|
||||
arpBaseNote() ) );
|
||||
isArpeggioBaseNote() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -330,7 +359,7 @@ void notePlayHandle::setFrames( const f_cnt_t _frames )
|
||||
{
|
||||
m_frames = m_instrumentTrack->beatLen( this );
|
||||
}
|
||||
m_orig_frames = m_frames;
|
||||
m_origFrames = m_frames;
|
||||
}
|
||||
|
||||
|
||||
@@ -421,7 +450,7 @@ bool notePlayHandle::operator==( const notePlayHandle & _nph ) const
|
||||
m_totalFramesPlayed == _nph.m_totalFramesPlayed &&
|
||||
m_released == _nph.m_released &&
|
||||
m_baseNote == _nph.m_baseNote &&
|
||||
m_arpNote == _nph.m_arpNote &&
|
||||
m_partOfArpeggio == _nph.m_partOfArpeggio &&
|
||||
m_muted == _nph.m_muted );
|
||||
}
|
||||
|
||||
@@ -430,14 +459,9 @@ bool notePlayHandle::operator==( const notePlayHandle & _nph ) const
|
||||
|
||||
void notePlayHandle::updateFrequency( void )
|
||||
{
|
||||
const int base_tone = m_instrumentTrack->baseNoteModel()->value() %
|
||||
KeysPerOctave;
|
||||
const int base_octave = m_instrumentTrack->baseNoteModel()->value() /
|
||||
KeysPerOctave;
|
||||
const float pitch = ( key() % KeysPerOctave - base_tone +
|
||||
engine::getSong()->masterPitch() ) / 12.0f +
|
||||
( key() / KeysPerOctave - base_octave ) +
|
||||
m_baseDetuning->value() / 12.0f;
|
||||
const float pitch =
|
||||
( key() - m_instrumentTrack->baseNoteModel()->value() +
|
||||
engine::getSong()->masterPitch() ) / 12.0f;
|
||||
m_frequency = BaseFreq * powf( 2.0f, pitch +
|
||||
m_instrumentTrack->m_pitchModel.value() / ( 100 * 12.0 ) );
|
||||
m_unpitchedFrequency = BaseFreq * powf( 2.0f, pitch );
|
||||
@@ -469,17 +493,17 @@ void notePlayHandle::processMidiTime( const midiTime & _time )
|
||||
|
||||
|
||||
|
||||
void notePlayHandle::resize( const bpm_t _new_bpm )
|
||||
void notePlayHandle::resize( const bpm_t _new_tempo )
|
||||
{
|
||||
double completed = m_totalFramesPlayed / (double)m_frames;
|
||||
double new_frames = m_orig_frames * m_orig_bpm / (double)_new_bpm;
|
||||
double completed = m_totalFramesPlayed / (double) m_frames;
|
||||
double new_frames = m_origFrames * m_origTempo / (double) _new_tempo;
|
||||
m_frames = (f_cnt_t)new_frames;
|
||||
m_totalFramesPlayed = (f_cnt_t)( completed * new_frames );
|
||||
|
||||
for( notePlayHandleVector::iterator it = m_subNotes.begin();
|
||||
it != m_subNotes.end(); ++it )
|
||||
{
|
||||
( *it )->resize( _new_bpm );
|
||||
( *it )->resize( _new_tempo );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ void piano::setKeyState( int _key, bool _on )
|
||||
void piano::handleKeyPress( int _key )
|
||||
{
|
||||
m_instrumentTrack->processInEvent( midiEvent( MidiNoteOn, 0, _key,
|
||||
DefaultVolume ), midiTime() );
|
||||
MidiMaxVelocity ), midiTime() );
|
||||
m_pressedKeys[_key] = TRUE;
|
||||
}
|
||||
|
||||
@@ -478,26 +478,26 @@ void pianoView::mousePressEvent( QMouseEvent * _me )
|
||||
if( _me->pos().y() > PIANO_BASE )
|
||||
{
|
||||
int y_diff = _me->pos().y() - PIANO_BASE;
|
||||
volume vol = (volume)( ( float ) y_diff /
|
||||
int velocity = (int)( ( float ) y_diff /
|
||||
( ( KEY_ORDER[key_num % KeysPerOctave] ==
|
||||
WhiteKey ) ?
|
||||
PW_WHITE_KEY_HEIGHT : PW_BLACK_KEY_HEIGHT ) *
|
||||
(float) DefaultVolume );
|
||||
(float) MidiMaxVelocity );
|
||||
if( y_diff < 0 )
|
||||
{
|
||||
vol = 0;
|
||||
velocity = 0;
|
||||
}
|
||||
else if( y_diff > ( ( KEY_ORDER[key_num %
|
||||
KeysPerOctave] ==
|
||||
WhiteKey ) ?
|
||||
PW_WHITE_KEY_HEIGHT : PW_BLACK_KEY_HEIGHT ) )
|
||||
{
|
||||
vol = DefaultVolume;
|
||||
velocity = MidiMaxVelocity;
|
||||
}
|
||||
// set note on
|
||||
m_piano->m_instrumentTrack->processInEvent(
|
||||
midiEvent( MidiNoteOn, 0, key_num,
|
||||
vol * 127 / 100 ),
|
||||
velocity ),
|
||||
midiTime() );
|
||||
m_piano->m_pressedKeys[key_num] = TRUE;
|
||||
m_lastKey = key_num;
|
||||
@@ -581,22 +581,22 @@ void pianoView::mouseMoveEvent( QMouseEvent * _me )
|
||||
|
||||
int key_num = getKeyFromMouse( _me->pos() );
|
||||
int y_diff = _me->pos().y() - PIANO_BASE;
|
||||
volume vol = (volume)( (float) y_diff /
|
||||
int velocity = (int)( (float) y_diff /
|
||||
( ( KEY_ORDER[key_num % KeysPerOctave] == WhiteKey ) ?
|
||||
PW_WHITE_KEY_HEIGHT : PW_BLACK_KEY_HEIGHT ) *
|
||||
(float)DefaultVolume );
|
||||
(float) MidiMaxVelocity );
|
||||
// maybe the user moved the mouse-cursor above or under the
|
||||
// piano-widget while holding left button so check that and
|
||||
// correct volume if necessary
|
||||
if( y_diff < 0 )
|
||||
{
|
||||
vol = 0;
|
||||
velocity = 0;
|
||||
}
|
||||
else if( y_diff >
|
||||
( ( KEY_ORDER[key_num % KeysPerOctave] == WhiteKey ) ?
|
||||
PW_WHITE_KEY_HEIGHT : PW_BLACK_KEY_HEIGHT ) )
|
||||
{
|
||||
vol = DefaultVolume;
|
||||
velocity = MidiMaxVelocity;
|
||||
}
|
||||
|
||||
// is the calculated key different from current key? (could be the
|
||||
@@ -616,7 +616,8 @@ void pianoView::mouseMoveEvent( QMouseEvent * _me )
|
||||
if( _me->pos().y() > PIANO_BASE )
|
||||
{
|
||||
m_piano->m_instrumentTrack->processInEvent(
|
||||
midiEvent( MidiNoteOn, 0, key_num, vol ),
|
||||
midiEvent( MidiNoteOn, 0, key_num,
|
||||
velocity ),
|
||||
midiTime() );
|
||||
m_piano->m_pressedKeys[key_num] = TRUE;
|
||||
m_lastKey = key_num;
|
||||
@@ -633,7 +634,8 @@ void pianoView::mouseMoveEvent( QMouseEvent * _me )
|
||||
else if( m_piano->m_pressedKeys[key_num] == TRUE )
|
||||
{
|
||||
m_piano->m_instrumentTrack->processInEvent(
|
||||
midiEvent( MidiKeyPressure, 0, key_num, vol ),
|
||||
midiEvent( MidiKeyPressure, 0, key_num,
|
||||
velocity ),
|
||||
midiTime() );
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ presetPreviewPlayHandle::~presetPreviewPlayHandle()
|
||||
{
|
||||
s_previewTC->lockData();
|
||||
// not muted by other preset-preview-handle?
|
||||
if( m_previewNote->muted() == FALSE )
|
||||
if( !m_previewNote->isMuted() )
|
||||
{
|
||||
// then set according state
|
||||
s_previewTC->setPreviewNote( NULL );
|
||||
@@ -193,7 +193,7 @@ void presetPreviewPlayHandle::play( bool _try_parallelizing,
|
||||
|
||||
bool presetPreviewPlayHandle::done( void ) const
|
||||
{
|
||||
return( m_previewNote->muted() );
|
||||
return( m_previewNote->isMuted() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -116,12 +116,13 @@ instrumentTrack::instrumentTrack( trackContainer * _tc ) :
|
||||
connect( &m_baseNoteModel, SIGNAL( dataChanged() ),
|
||||
this, SLOT( updateBaseNote() ) );
|
||||
connect( &m_pitchModel, SIGNAL( dataChanged() ),
|
||||
this, SLOT( updateBaseNote() ) );
|
||||
this, SLOT( updatePitch() ) );
|
||||
|
||||
|
||||
for( int i = 0; i < NumKeys; ++i )
|
||||
{
|
||||
m_notes[i] = NULL;
|
||||
m_runningMidiNotes[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,24 +142,6 @@ instrumentTrack::~instrumentTrack()
|
||||
|
||||
|
||||
|
||||
f_cnt_t instrumentTrack::beatLen( notePlayHandle * _n ) const
|
||||
{
|
||||
if( m_instrument != NULL )
|
||||
{
|
||||
const f_cnt_t len = m_instrument->beatLen( _n );
|
||||
if( len > 0 )
|
||||
{
|
||||
return( len );
|
||||
}
|
||||
}
|
||||
return( m_soundShaping.envFrames() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void instrumentTrack::processAudioBuffer( sampleFrame * _buf,
|
||||
const fpp_t _frames,
|
||||
notePlayHandle * _n )
|
||||
@@ -197,15 +180,37 @@ void instrumentTrack::processAudioBuffer( sampleFrame * _buf,
|
||||
|
||||
|
||||
|
||||
midiEvent instrumentTrack::applyMasterKey( const midiEvent & _me )
|
||||
{
|
||||
midiEvent copy( _me );
|
||||
switch( _me.m_type )
|
||||
{
|
||||
case MidiNoteOn:
|
||||
case MidiNoteOff:
|
||||
case MidiKeyPressure:
|
||||
copy.key() = masterKey( _me.key() );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void instrumentTrack::processInEvent( const midiEvent & _me,
|
||||
const midiTime & _time )
|
||||
{
|
||||
engine::getMixer()->lock();
|
||||
switch( _me.m_type )
|
||||
{
|
||||
// we don't send MidiNoteOn, MidiNoteOff and MidiKeyPressure
|
||||
// events to instrument as notePlayHandle will send them on its
|
||||
// own
|
||||
case MidiNoteOn:
|
||||
if( _me.velocity() > 0 )
|
||||
{
|
||||
m_instrument->handleMidiEvent( _me, _time );
|
||||
if( m_notes[_me.key()] == NULL )
|
||||
{
|
||||
if( !configManager::inst()->value( "ui",
|
||||
@@ -217,8 +222,8 @@ void instrumentTrack::processInEvent( const midiEvent & _me,
|
||||
// create temporary note
|
||||
note n;
|
||||
n.setKey( _me.key() );
|
||||
n.setVolume( _me.velocity() * 100 /
|
||||
127 );
|
||||
n.setVolume( _me.getVolume() );
|
||||
|
||||
// create (timed) note-play-handle
|
||||
notePlayHandle * nph = new
|
||||
notePlayHandle( this,
|
||||
@@ -231,14 +236,12 @@ void instrumentTrack::processInEvent( const midiEvent & _me,
|
||||
{
|
||||
m_notes[_me.key()] = nph;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MidiNoteOff:
|
||||
{
|
||||
m_instrument->handleMidiEvent( _me, _time );
|
||||
notePlayHandle * n = m_notes[_me.key()];
|
||||
if( n != NULL )
|
||||
{
|
||||
@@ -248,11 +251,13 @@ void instrumentTrack::processInEvent( const midiEvent & _me,
|
||||
// this is for example needed by piano-roll for
|
||||
// recording notes into a pattern
|
||||
note done_note(
|
||||
midiTime( static_cast<f_cnt_t>(
|
||||
n->totalFramesPlayed() /
|
||||
engine::framesPerTick() ) ),
|
||||
0, n->key(),
|
||||
n->getVolume(), n->getPanning() );
|
||||
midiTime( static_cast<f_cnt_t>(
|
||||
n->totalFramesPlayed() /
|
||||
engine::framesPerTick() ) ),
|
||||
0,
|
||||
n->key(),
|
||||
n->getVolume(),
|
||||
n->getPanning() );
|
||||
|
||||
n->noteOff();
|
||||
m_notes[_me.key()] = NULL;
|
||||
@@ -263,16 +268,16 @@ void instrumentTrack::processInEvent( const midiEvent & _me,
|
||||
}
|
||||
|
||||
case MidiKeyPressure:
|
||||
if( !m_instrument->handleMidiEvent( _me, _time ) &&
|
||||
m_notes[_me.key()] != NULL )
|
||||
if( m_notes[_me.key()] != NULL )
|
||||
{
|
||||
m_notes[_me.key()]->setVolume( _me.velocity() *
|
||||
100 / 127 );
|
||||
m_notes[_me.key()]->setVolume( _me.getVolume() );
|
||||
}
|
||||
break;
|
||||
|
||||
case MidiPitchBend:
|
||||
m_instrument->handleMidiEvent( _me, _time );
|
||||
// updatePitch() is connected to
|
||||
// m_pitchModel::dataChanged() which will send out
|
||||
// MidiPitchBend events
|
||||
m_pitchModel.setValue( m_pitchModel.minValue() +
|
||||
_me.m_data.m_param[0] *
|
||||
m_pitchModel.range() / 16384 );
|
||||
@@ -291,6 +296,7 @@ void instrumentTrack::processInEvent( const midiEvent & _me,
|
||||
}
|
||||
break;
|
||||
}
|
||||
engine::getMixer()->unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -299,6 +305,8 @@ void instrumentTrack::processInEvent( const midiEvent & _me,
|
||||
void instrumentTrack::processOutEvent( const midiEvent & _me,
|
||||
const midiTime & _time )
|
||||
{
|
||||
int k;
|
||||
|
||||
switch( _me.m_type )
|
||||
{
|
||||
case MidiNoteOn:
|
||||
@@ -310,11 +318,23 @@ void instrumentTrack::processOutEvent( const midiEvent & _me,
|
||||
if( !configManager::inst()->value( "ui",
|
||||
"disablechannelactivityindicators" ).toInt() )
|
||||
{
|
||||
if( m_notes[_me.key()] != NULL )
|
||||
if( m_notes[_me.key()] == NULL )
|
||||
{
|
||||
return;
|
||||
emit newNote();
|
||||
}
|
||||
emit newNote();
|
||||
}
|
||||
k = masterKey( _me.key() );
|
||||
if( k >= 0 && k < NumKeys )
|
||||
{
|
||||
if( m_runningMidiNotes[k] > 0 )
|
||||
{
|
||||
m_instrument->handleMidiEvent(
|
||||
midiEvent( MidiNoteOff, getMidiPort()->outputChannel(), k, 0 ), _time );
|
||||
}
|
||||
++m_runningMidiNotes[k];
|
||||
m_instrument->handleMidiEvent(
|
||||
midiEvent( MidiNoteOn, getMidiPort()->outputChannel(), k,
|
||||
_me.velocity() ), _time );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -324,12 +344,25 @@ void instrumentTrack::processOutEvent( const midiEvent & _me,
|
||||
{
|
||||
m_piano.setKeyState( _me.key(), FALSE );
|
||||
}
|
||||
k = masterKey( _me.key() );
|
||||
if( k >= 0 && k < NumKeys &&
|
||||
--m_runningMidiNotes[k] <= 0 )
|
||||
{
|
||||
m_instrument->handleMidiEvent(
|
||||
midiEvent( MidiNoteOff, getMidiPort()->outputChannel(), k, 0 ), _time );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if( m_instrument != NULL )
|
||||
{
|
||||
m_instrument->handleMidiEvent(
|
||||
applyMasterKey( _me ),
|
||||
_time );
|
||||
}
|
||||
break;
|
||||
}
|
||||
m_instrument->handleMidiEvent( _me, _time );
|
||||
|
||||
// if appropriate, midi-port does futher routing
|
||||
m_midiPort.processOutEvent( _me, _time );
|
||||
}
|
||||
@@ -337,6 +370,22 @@ void instrumentTrack::processOutEvent( const midiEvent & _me,
|
||||
|
||||
|
||||
|
||||
f_cnt_t instrumentTrack::beatLen( notePlayHandle * _n ) const
|
||||
{
|
||||
if( m_instrument != NULL )
|
||||
{
|
||||
const f_cnt_t len = m_instrument->beatLen( _n );
|
||||
if( len > 0 )
|
||||
{
|
||||
return( len );
|
||||
}
|
||||
}
|
||||
return( m_soundShaping.envFrames() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void instrumentTrack::playNote( notePlayHandle * _n, bool _try_parallelizing,
|
||||
sampleFrame * _working_buffer )
|
||||
{
|
||||
@@ -345,7 +394,7 @@ void instrumentTrack::playNote( notePlayHandle * _n, bool _try_parallelizing,
|
||||
m_chordCreator.processNote( _n );
|
||||
m_arpeggiator.processNote( _n );
|
||||
|
||||
if( _n->arpBaseNote() == FALSE && m_instrument != NULL )
|
||||
if( !_n->isArpeggioBaseNote() && m_instrument != NULL )
|
||||
{
|
||||
// all is done, so now lets play the note!
|
||||
m_instrument->playNote( _n, _try_parallelizing,
|
||||
@@ -431,11 +480,22 @@ void instrumentTrack::updateBaseNote( void )
|
||||
|
||||
|
||||
|
||||
int instrumentTrack::masterKey( notePlayHandle * _n ) const
|
||||
void instrumentTrack::updatePitch( void )
|
||||
{
|
||||
updateBaseNote();
|
||||
processOutEvent( midiEvent( MidiPitchBend,
|
||||
getMidiPort()->outputChannel(),
|
||||
midiPitch() ), 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int instrumentTrack::masterKey( int _midi_key ) const
|
||||
{
|
||||
int key = m_baseNoteModel.value() + engine::getSong()->masterPitch();
|
||||
return( tLimit<int>( _n->key() -
|
||||
( key - Key_A - DefaultOctave * KeysPerOctave ), 0, NumKeys ) );
|
||||
return( tLimit<int>( _midi_key -
|
||||
( key - DefaultKey ), 0, NumKeys ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -986,7 +1046,8 @@ void instrumentTrackView::toggleInstrumentWindow( bool _on )
|
||||
|
||||
void instrumentTrackView::activityIndicatorPressed( void )
|
||||
{
|
||||
model()->processInEvent( midiEvent( MidiNoteOn, 0, DefaultKey, 127 ),
|
||||
model()->processInEvent(
|
||||
midiEvent( MidiNoteOn, 0, DefaultKey, MidiMaxVelocity ),
|
||||
midiTime() );
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user