added panningToMidi function to easily convert panning to a midi value, dragging around a note in the piano roll makes the correct volume and panning noises
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1921 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
@@ -8,6 +8,11 @@
|
||||
- switching between note edit modes is more clear with label text and
|
||||
a right click menu
|
||||
- note volume bars are painted blue if selected
|
||||
- dragging around a note in the piano roll makes the correct volume
|
||||
and panning noises
|
||||
|
||||
* include/panning.h:
|
||||
added panningToMidi function to easily convert panning to a midi value
|
||||
|
||||
2008-12-14 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
|
||||
|
||||
|
||||
2
TODO
2
TODO
@@ -52,7 +52,6 @@
|
||||
- add FLAC as export-format?
|
||||
|
||||
Andrew Kelley's todo:
|
||||
- when you click on a note in the piano roll, it plays the note, but not the correct panning
|
||||
- fix ctrl+mousewheel zooming in
|
||||
- if you press both controls at the same time, the piano roll gets stuck in selection mode
|
||||
- change my modifier code to use mainwindows modifier info
|
||||
@@ -65,6 +64,7 @@ Andrew Kelley's todo:
|
||||
* look through FL Studio's tools and implement some of them
|
||||
- when looking at a piano roll, if the song is playing that pattern, move the position ticker to where it should be
|
||||
- double-click in note edit area to clear selection (assuming the intent of editing all notes)
|
||||
- when setting a new note, set panning and volume to that of last note
|
||||
|
||||
- recording automation
|
||||
- make knobs easier to tune (less sensitive)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "volume.h"
|
||||
#include "templates.h"
|
||||
#include "panning_constants.h"
|
||||
#include "midi.h"
|
||||
|
||||
inline stereoVolumeVector panningToVolumeVector( panning _p,
|
||||
float _scale = 1.0f )
|
||||
@@ -40,4 +41,12 @@ inline stereoVolumeVector panningToVolumeVector( panning _p,
|
||||
return v;
|
||||
}
|
||||
|
||||
inline Sint16 panningToMidi( panning _p )
|
||||
{
|
||||
return MidiMinPanning +
|
||||
( (float)( _p - PanningLeft ) ) /
|
||||
( (float)( PanningRight - PanningLeft ) ) *
|
||||
( (float)( MidiMaxPanning - MidiMinPanning ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -182,6 +182,8 @@ private:
|
||||
void shiftSemiTone(int amount);
|
||||
bool isSelection() const;
|
||||
void testPlayNote( note * n );
|
||||
void testPlayKey( int _key, int _vol, int _pan );
|
||||
void pauseTestNotes( bool _pause = true );
|
||||
|
||||
inline int noteEditTop() const;
|
||||
inline int keyAreaBottom() const;
|
||||
|
||||
@@ -1515,11 +1515,68 @@ void pianoRoll::testPlayNote( note * n )
|
||||
m_pattern->getInstrumentTrack()->processInEvent(
|
||||
midiEvent( MidiNoteOn, 0, n->key(),
|
||||
n->getVolume() * 127 / 100 ), midiTime() );
|
||||
|
||||
|
||||
midiEvent evt( MidiMetaEvent, 0, n->key(),
|
||||
panningToMidi( n->getPanning() ) );
|
||||
|
||||
evt.m_metaEvent = MidiNotePanning;
|
||||
m_pattern->getInstrumentTrack()->processInEvent(
|
||||
evt, midiTime() );
|
||||
m_pattern->getInstrumentTrack()->processInEvent(evt, midiTime() );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pianoRoll::pauseTestNotes( bool _pause )
|
||||
{
|
||||
const noteVector & notes = m_pattern->notes();
|
||||
noteVector::const_iterator it = notes.begin();
|
||||
while( it != notes.end() )
|
||||
{
|
||||
if( ( *it )->isPlaying() )
|
||||
{
|
||||
if( _pause )
|
||||
{
|
||||
// stop note
|
||||
m_pattern->getInstrumentTrack()->processInEvent(
|
||||
midiEvent( MidiNoteOff, 0,
|
||||
( *it )->key(), 0 ), midiTime() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// start note
|
||||
( *it )->setIsPlaying( false );
|
||||
testPlayNote( *it );
|
||||
}
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pianoRoll::testPlayKey( int _key, int _vol, int _pan )
|
||||
{
|
||||
// turn off old key
|
||||
m_pattern->getInstrumentTrack()->processInEvent(
|
||||
midiEvent( MidiNoteOff, 0, m_lastKey, 0 ), midiTime() );
|
||||
|
||||
// remember which one we're playing
|
||||
m_lastKey = _key;
|
||||
|
||||
// play new key
|
||||
m_pattern->getInstrumentTrack()->processInEvent(
|
||||
midiEvent( MidiNoteOn, 0, _key, _vol ), midiTime() );
|
||||
|
||||
// set panning of newly played key
|
||||
midiEvent evt( MidiMetaEvent, 0, _key, _pan );
|
||||
evt.m_metaEvent = MidiNotePanning;
|
||||
m_pattern->getInstrumentTrack()->processInEvent( evt, midiTime() );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void pianoRoll::computeSelectedNotes(bool shift)
|
||||
{
|
||||
@@ -1713,36 +1770,19 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
|
||||
int key_num = getKey( _me->y() );
|
||||
int x = _me->x();
|
||||
|
||||
// is the calculated key different from current key?
|
||||
// (could be the user just moved the cursor one pixel up/down
|
||||
// but is still on the same key)
|
||||
if( key_num != m_lastKey && edit_note == false &&
|
||||
_me->buttons() & Qt::LeftButton &&
|
||||
( m_action == ActionMoveNote ||
|
||||
( x < WHITE_KEY_WIDTH && m_action == ActionNone ) ) )
|
||||
{
|
||||
m_pattern->getInstrumentTrack()->processInEvent(
|
||||
midiEvent( MidiNoteOff, 0, m_lastKey, 0 ),
|
||||
midiTime() );
|
||||
if( _me->buttons() & Qt::LeftButton )
|
||||
{
|
||||
m_lastKey = key_num;
|
||||
|
||||
int v = DefaultVolume * 127 / 100;
|
||||
if( x < WHITE_KEY_WIDTH )
|
||||
{
|
||||
v = ( (float) x ) / ( (float) WHITE_KEY_WIDTH ) * 127;
|
||||
}
|
||||
|
||||
m_pattern->getInstrumentTrack()->processInEvent(
|
||||
midiEvent( MidiNoteOn, 0, key_num, v ), midiTime() );
|
||||
}
|
||||
}
|
||||
if( x < WHITE_KEY_WIDTH && m_action == ActionNone )
|
||||
// see if they clicked on the keyboard on the left
|
||||
if( x < WHITE_KEY_WIDTH && m_action == ActionNone
|
||||
&& ! edit_note && key_num != m_lastKey
|
||||
&& _me->buttons() & Qt::LeftButton )
|
||||
{
|
||||
// clicked on a key, play the note
|
||||
testPlayKey( key_num,
|
||||
( (float) x ) / ( (float) WHITE_KEY_WIDTH ) * 127,
|
||||
0 );
|
||||
update();
|
||||
return;
|
||||
}
|
||||
|
||||
x -= WHITE_KEY_WIDTH;
|
||||
|
||||
if( _me->buttons() & Qt::LeftButton
|
||||
@@ -1750,7 +1790,20 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
|
||||
&& (m_action == ActionMoveNote || m_action == ActionResizeNote ) )
|
||||
{
|
||||
// handle moving notes and resizing them
|
||||
bool replay_note = key_num != m_lastKey
|
||||
&& m_action == ActionMoveNote;
|
||||
|
||||
if( replay_note )
|
||||
{
|
||||
pauseTestNotes();
|
||||
}
|
||||
|
||||
dragNotes(_me->x(), _me->y(), _me->modifiers() & Qt::AltModifier);
|
||||
|
||||
if( replay_note && m_action == ActionMoveNote )
|
||||
{
|
||||
pauseTestNotes( false );
|
||||
}
|
||||
}
|
||||
else if( ( edit_note == true || m_action == ActionChangeNoteProperty ) &&
|
||||
_me->buttons() & Qt::LeftButton )
|
||||
@@ -1759,7 +1812,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
|
||||
|
||||
// Change notes within a certain pixel range of where
|
||||
// the mouse cursor is
|
||||
int pixel_range = 20;
|
||||
int pixel_range = 14;
|
||||
|
||||
// convert to ticks so that we can check which notes
|
||||
// are in the range
|
||||
@@ -1813,11 +1866,8 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
|
||||
else if( m_noteEditMode == NoteEditPanning )
|
||||
{
|
||||
( *it )->setPanning( pan );
|
||||
midiEvent evt( MidiMetaEvent, 0, ( *it )->key(),
|
||||
MidiMinPanning +
|
||||
( (float)( pan - PanningLeft ) ) /
|
||||
( (float)( PanningRight - PanningLeft ) ) *
|
||||
( (float)( MidiMaxPanning - MidiMinPanning ) ) );
|
||||
midiEvent evt( MidiMetaEvent, 0,
|
||||
( *it )->key(), panningToMidi( pan ) );
|
||||
evt.m_metaEvent = MidiNotePanning;
|
||||
m_pattern->getInstrumentTrack()->processInEvent(
|
||||
evt, midiTime() );
|
||||
|
||||
Reference in New Issue
Block a user