added support for panning editing of notes (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@1948 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
@@ -26,8 +26,8 @@
|
||||
#ifndef _MIDI_H
|
||||
#define _MIDI_H
|
||||
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "panning_constants.h"
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ enum MidiEventTypes
|
||||
|
||||
enum MidiMetaEvents
|
||||
{
|
||||
MidiMetaInvalid = 0x00,
|
||||
MidiCopyright = 0x02,
|
||||
MidiTrackName = 0x03,
|
||||
MidiInstName = 0x04,
|
||||
@@ -75,7 +76,9 @@ enum MidiMetaEvents
|
||||
MidiSMPTEOffset = 0x54,
|
||||
MidiTimeSignature = 0x58,
|
||||
MidiKeySignature = 0x59,
|
||||
MidiSequencerEvent = 0x7f
|
||||
MidiSequencerEvent = 0x7f,
|
||||
MidiMetaCustom = 0x80,
|
||||
MidiNotePanning
|
||||
} ;
|
||||
|
||||
|
||||
@@ -84,6 +87,9 @@ const int MidiControllerCount = 128;
|
||||
const int MidiProgramCount = 128;
|
||||
const int MidiMaxVelocity = 127;
|
||||
|
||||
const int MidiMaxPanning = 127;
|
||||
const int MidiMinPanning = -128;
|
||||
|
||||
|
||||
struct midiEvent
|
||||
{
|
||||
@@ -92,6 +98,7 @@ struct midiEvent
|
||||
Sint16 _param1 = 0,
|
||||
Sint16 _param2 = 0 ) :
|
||||
m_type( _type ),
|
||||
m_metaEvent( MidiMetaInvalid ),
|
||||
m_channel( _channel ),
|
||||
m_sysExData( NULL )
|
||||
{
|
||||
@@ -101,6 +108,7 @@ struct midiEvent
|
||||
midiEvent( MidiEventTypes _type, const char * _sysex_data,
|
||||
int _data_len ) :
|
||||
m_type( _type ),
|
||||
m_metaEvent( MidiMetaInvalid ),
|
||||
m_channel( 0 ),
|
||||
m_sysExData( _sysex_data )
|
||||
{
|
||||
@@ -109,6 +117,7 @@ struct midiEvent
|
||||
|
||||
midiEvent( const midiEvent & _copy ) :
|
||||
m_type( _copy.m_type ),
|
||||
m_metaEvent( _copy.m_metaEvent ),
|
||||
m_channel( _copy.m_channel ),
|
||||
m_data( _copy.m_data ),
|
||||
m_sysExData( _copy.m_sysExData )
|
||||
@@ -139,14 +148,28 @@ struct midiEvent
|
||||
{
|
||||
return m_data.m_param[1];
|
||||
}
|
||||
|
||||
inline Sint16 midiPanning( void ) const
|
||||
{
|
||||
return m_data.m_param[1];
|
||||
}
|
||||
|
||||
inline volume getVolume( void ) const
|
||||
{
|
||||
return (volume)( velocity() * 100 / MidiMaxVelocity );
|
||||
}
|
||||
|
||||
inline panning getPanning( void ) const
|
||||
{
|
||||
return (panning) ( PanningLeft +
|
||||
( (float)( midiPanning() - MidiMinPanning ) ) /
|
||||
( (float)( MidiMaxPanning - MidiMinPanning ) ) *
|
||||
( (float)( PanningRight - PanningLeft ) ) );
|
||||
}
|
||||
|
||||
|
||||
MidiEventTypes m_type; // MIDI event type
|
||||
MidiMetaEvents m_metaEvent; // Meta event (mostly unused)
|
||||
Sint8 m_channel; // MIDI channel
|
||||
union
|
||||
{
|
||||
|
||||
@@ -90,7 +90,21 @@ public:
|
||||
detuningHelper * _detuning = NULL );
|
||||
note( const note & _note );
|
||||
virtual ~note();
|
||||
|
||||
|
||||
// used by GUI
|
||||
inline void setSelected( const bool _selected ){ m_selected = _selected; }
|
||||
inline void setOldKey( const int _oldKey ){ m_oldKey = _oldKey; }
|
||||
inline void setOldPos( const midiTime & _oldPos ){ m_oldPos = _oldPos; }
|
||||
inline void setOldLength( const midiTime & _oldLength )
|
||||
{
|
||||
m_oldLength = _oldLength;
|
||||
}
|
||||
inline void setIsPlaying( const bool _isPlaying )
|
||||
{
|
||||
m_isPlaying = _isPlaying;
|
||||
}
|
||||
|
||||
|
||||
void setLength( const midiTime & _length );
|
||||
void setPos( const midiTime & _pos );
|
||||
void setKey( const int _key );
|
||||
@@ -99,6 +113,38 @@ public:
|
||||
void quantizeLength( const int _q_grid );
|
||||
void quantizePos( const int _q_grid );
|
||||
|
||||
static inline bool lessThan(note * &lhs, note * &rhs)
|
||||
{
|
||||
// function to compare two notes - must be called explictly when
|
||||
// using qSort
|
||||
return (bool) ((int) ( *lhs ).pos() < (int) ( *rhs ).pos());
|
||||
}
|
||||
|
||||
inline bool selected( void ) const
|
||||
{
|
||||
return m_selected;
|
||||
}
|
||||
|
||||
inline int oldKey( void ) const
|
||||
{
|
||||
return m_oldKey;
|
||||
}
|
||||
|
||||
inline midiTime oldPos( void ) const
|
||||
{
|
||||
return m_oldPos;
|
||||
}
|
||||
|
||||
inline midiTime oldLength( void ) const
|
||||
{
|
||||
return m_oldLength;
|
||||
}
|
||||
|
||||
inline bool isPlaying( void ) const
|
||||
{
|
||||
return m_isPlaying;
|
||||
}
|
||||
|
||||
inline midiTime endPos( void ) const
|
||||
{
|
||||
const int l = length();
|
||||
@@ -177,7 +223,14 @@ private:
|
||||
ChangePosition
|
||||
} ;*/
|
||||
|
||||
|
||||
|
||||
// for piano roll editing
|
||||
bool m_selected;
|
||||
int m_oldKey;
|
||||
midiTime m_oldPos;
|
||||
midiTime m_oldLength;
|
||||
bool m_isPlaying;
|
||||
|
||||
int m_key;
|
||||
volume m_volume;
|
||||
panning m_panning;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* panning.h - declaration of some constants and types, concerning the
|
||||
* panning.h - declaration of some types, concerning the
|
||||
* panning of a note
|
||||
*
|
||||
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
@@ -29,11 +29,8 @@
|
||||
#include "lmms_basics.h"
|
||||
#include "volume.h"
|
||||
#include "templates.h"
|
||||
|
||||
const panning PanningRight = ( 0 + 100 );
|
||||
const panning PanningLeft = - PanningRight;
|
||||
const panning PanningCenter = 0;
|
||||
const panning DefaultPanning = PanningCenter;
|
||||
#include "panning_constants.h"
|
||||
#include "midi.h"
|
||||
|
||||
inline stereoVolumeVector panningToVolumeVector( panning _p,
|
||||
float _scale = 1.0f )
|
||||
@@ -44,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
|
||||
|
||||
34
include/panning_constants.h
Normal file
34
include/panning_constants.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* panning_constants.h - declaration of some constants, concerning the
|
||||
* panning of a note
|
||||
*
|
||||
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PANNING_CONSTANTS_H
|
||||
#define _PANNING_CONSTANTS_H
|
||||
|
||||
const panning PanningRight = ( 0 + 100 );
|
||||
const panning PanningLeft = - PanningRight;
|
||||
const panning PanningCenter = 0;
|
||||
const panning DefaultPanning = PanningCenter;
|
||||
|
||||
#endif
|
||||
@@ -68,13 +68,14 @@ public:
|
||||
virtual midiTime length( void ) const;
|
||||
midiTime beatPatternLength( void ) const;
|
||||
|
||||
// note management
|
||||
note * addNote( const note & _new_note, const bool _quant_pos = true );
|
||||
|
||||
void removeNote( const note * _note_to_del );
|
||||
|
||||
note * rearrangeNote( const note * _note_to_proc,
|
||||
const bool _quant_pos = true );
|
||||
|
||||
void rearrangeAllNotes( void );
|
||||
void clearNotes( void );
|
||||
|
||||
inline const noteVector & notes( void )
|
||||
@@ -132,6 +133,10 @@ public:
|
||||
|
||||
|
||||
using model::dataChanged;
|
||||
|
||||
|
||||
void printNotes( void ); // for debugging purposes
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* can set and edit notes in an easy way
|
||||
*
|
||||
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2008 Andrew Kelley <superjoe30/at/gmail/dot/com>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -38,6 +39,9 @@
|
||||
class QPainter;
|
||||
class QPixmap;
|
||||
class QScrollBar;
|
||||
class QString;
|
||||
class QMenu;
|
||||
class QSignalMapper;
|
||||
|
||||
class comboBox;
|
||||
class notePlayHandle;
|
||||
@@ -54,17 +58,17 @@ public:
|
||||
|
||||
inline bool isRecording( void ) const
|
||||
{
|
||||
return( m_recording );
|
||||
return m_recording;
|
||||
}
|
||||
|
||||
inline const pattern * currentPattern( void ) const
|
||||
{
|
||||
return( m_pattern );
|
||||
return m_pattern;
|
||||
}
|
||||
|
||||
inline bool validPattern( void ) const
|
||||
{
|
||||
return( m_pattern != NULL );
|
||||
return m_pattern != NULL;
|
||||
}
|
||||
|
||||
int quantization( void ) const;
|
||||
@@ -75,7 +79,7 @@ public:
|
||||
|
||||
inline virtual QString nodeName( void ) const
|
||||
{
|
||||
return( "pianoroll" );
|
||||
return "pianoroll";
|
||||
}
|
||||
|
||||
|
||||
@@ -85,20 +89,16 @@ protected:
|
||||
virtual void keyReleaseEvent( QKeyEvent * _ke );
|
||||
virtual void leaveEvent( QEvent * _e );
|
||||
virtual void mousePressEvent( QMouseEvent * _me );
|
||||
virtual void mouseDoubleClickEvent( QMouseEvent * _me );
|
||||
virtual void mouseReleaseEvent( QMouseEvent * _me );
|
||||
virtual void mouseMoveEvent( QMouseEvent * _me );
|
||||
virtual void paintEvent( QPaintEvent * _pe );
|
||||
virtual void resizeEvent( QResizeEvent * _re );
|
||||
virtual void wheelEvent( QWheelEvent * _we );
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
virtual bool x11Event( XEvent * _xe );
|
||||
#endif
|
||||
|
||||
int getKey( int _y ) const;
|
||||
static inline void drawNoteRect( QPainter & _p, int _x, int _y,
|
||||
int _width,
|
||||
const bool _is_selected,
|
||||
const bool _is_step_note );
|
||||
int _width, note * _n );
|
||||
void removeSelection( void );
|
||||
void selectAll( void );
|
||||
void getSelectedNotes( noteVector & _selected_notes );
|
||||
@@ -118,7 +118,7 @@ protected slots:
|
||||
void drawButtonToggled( void );
|
||||
void eraseButtonToggled( void );
|
||||
void selectButtonToggled( void );
|
||||
void moveButtonToggled( void );
|
||||
void detuneButtonToggled( void );
|
||||
|
||||
void copySelectedNotes( void );
|
||||
void cutSelectedNotes( void );
|
||||
@@ -129,6 +129,8 @@ protected slots:
|
||||
|
||||
void zoomingChanged( void );
|
||||
void quantizeChanged( void );
|
||||
|
||||
void changeNoteEditMode( int i );
|
||||
|
||||
|
||||
private:
|
||||
@@ -138,9 +140,8 @@ private:
|
||||
ModeDraw,
|
||||
ModeErase,
|
||||
ModeSelect,
|
||||
ModeMove,
|
||||
ModeOpen
|
||||
} ;
|
||||
};
|
||||
|
||||
enum actions
|
||||
{
|
||||
@@ -148,26 +149,54 @@ private:
|
||||
ActionMoveNote,
|
||||
ActionResizeNote,
|
||||
ActionSelectNotes,
|
||||
ActionMoveSelection,
|
||||
ActionChangeNoteVolume,
|
||||
ActionChangeNotePanning
|
||||
} ;
|
||||
ActionChangeNoteProperty,
|
||||
ActionResizeNoteEditArea
|
||||
};
|
||||
|
||||
enum noteEditMode
|
||||
{
|
||||
NoteEditVolume,
|
||||
NoteEditPanning,
|
||||
NoteEditCount // make sure this one is always last
|
||||
};
|
||||
|
||||
enum pianoRollKeyTypes
|
||||
{
|
||||
PR_WHITE_KEY_SMALL,
|
||||
PR_WHITE_KEY_BIG,
|
||||
PR_BLACK_KEY
|
||||
} ;
|
||||
};
|
||||
|
||||
QVector<QString> m_nemStr; // gui names of each edit mode
|
||||
QMenu * m_noteEditMenu; // when you right click below the key area
|
||||
QSignalMapper * m_signalMapper; // to keep track of edit mode events
|
||||
|
||||
pianoRoll( void );
|
||||
pianoRoll( const pianoRoll & );
|
||||
virtual ~pianoRoll();
|
||||
|
||||
midiTime newNoteLen( void ) const;
|
||||
|
||||
|
||||
|
||||
void shiftPos(int amount);
|
||||
void shiftSemiTone(int amount);
|
||||
bool isSelection() const;
|
||||
int selectionCount() 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;
|
||||
inline int noteEditBottom() const;
|
||||
inline int keyAreaTop() const;
|
||||
inline int noteEditRight() const;
|
||||
inline int noteEditLeft() const;
|
||||
|
||||
void dragNotes( int x, int y, bool alt );
|
||||
|
||||
static const int cm_scrollAmtHoriz = 10;
|
||||
static const int cm_scrollAmtVert = 1;
|
||||
|
||||
static QPixmap * s_whiteKeyBigPm;
|
||||
static QPixmap * s_whiteKeySmallPm;
|
||||
static QPixmap * s_blackKeyPm;
|
||||
@@ -190,8 +219,8 @@ private:
|
||||
toolButton * m_drawButton;
|
||||
toolButton * m_eraseButton;
|
||||
toolButton * m_selectButton;
|
||||
toolButton * m_moveButton;
|
||||
|
||||
toolButton * m_detuneButton;
|
||||
|
||||
toolButton * m_cutButton;
|
||||
toolButton * m_copyButton;
|
||||
toolButton * m_pasteButton;
|
||||
@@ -215,30 +244,51 @@ private:
|
||||
|
||||
note * m_currentNote;
|
||||
actions m_action;
|
||||
noteEditMode m_noteEditMode;
|
||||
|
||||
Uint32 m_selectStartTick;
|
||||
int m_selectedTick;
|
||||
int m_selectStartKey;
|
||||
int m_selectedKeys;
|
||||
|
||||
// boundary box around all selected notes when dragging
|
||||
int m_moveBoundaryLeft;
|
||||
int m_moveBoundaryTop;
|
||||
int m_moveBoundaryRight;
|
||||
int m_moveBoundaryBottom;
|
||||
|
||||
// remember where the scrolling started when dragging so that
|
||||
// we can handle dragging while scrolling with arrow keys
|
||||
int m_mouseDownKey;
|
||||
int m_mouseDownTick;
|
||||
|
||||
// remember the last x and y of a mouse movement
|
||||
int m_lastMouseX;
|
||||
int m_lastMouseY;
|
||||
|
||||
// x,y of when the user starts a drag
|
||||
int m_moveStartX;
|
||||
int m_moveStartY;
|
||||
|
||||
int m_moveStartKey;
|
||||
int m_moveStartTick;
|
||||
int m_moveXOffset;
|
||||
|
||||
int m_oldNotesEditHeight;
|
||||
int m_notesEditHeight;
|
||||
int m_ppt;
|
||||
int m_totalKeysToScroll;
|
||||
|
||||
// remember these values to use them
|
||||
// for the next note that is set
|
||||
midiTime m_lenOfNewNotes;
|
||||
volume m_lastNoteVolume;
|
||||
panning m_lastNotePanning;
|
||||
|
||||
int m_startKey; // first key when drawing
|
||||
int m_lastKey;
|
||||
|
||||
noteVector m_selNotesForMove;
|
||||
|
||||
|
||||
editModes m_editMode;
|
||||
|
||||
editModes m_ctrlMode; // mode they were in before they hit ctrl
|
||||
|
||||
bool m_mouseDownLeft; //true if left click is being held down
|
||||
bool m_mouseDownRight; //true if right click is being held down
|
||||
|
||||
timeLine * m_timeLine;
|
||||
bool m_scrollBack;
|
||||
@@ -249,8 +299,10 @@ private:
|
||||
bool mouseOverNote( void );
|
||||
note * noteUnderMouse( void );
|
||||
noteVector::const_iterator noteIteratorUnderMouse( void );
|
||||
|
||||
|
||||
|
||||
// turn a selection rectangle into selected notes
|
||||
void computeSelectedNotes( bool shift );
|
||||
void clearSelectedNotes( void );
|
||||
|
||||
friend class engine;
|
||||
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
note::note( const midiTime & _length, const midiTime & _pos,
|
||||
int _key, volume _volume, panning _panning,
|
||||
detuningHelper * _detuning ) :
|
||||
m_selected( false ),
|
||||
m_oldKey( tLimit( _key, 0, NumKeys ) ),
|
||||
m_oldPos( _pos ),
|
||||
m_oldLength( _length ),
|
||||
m_isPlaying( false ),
|
||||
m_key( tLimit( _key, 0, NumKeys ) ),
|
||||
m_volume( tLimit( _volume, MinVolume, MaxVolume ) ),
|
||||
m_panning( tLimit( _panning, PanningLeft, PanningRight ) ),
|
||||
@@ -48,7 +53,6 @@ note::note( const midiTime & _length, const midiTime & _pos,
|
||||
{
|
||||
//saveJournallingState( FALSE );
|
||||
// setJournalling( FALSE );
|
||||
|
||||
if( _detuning )
|
||||
{
|
||||
m_detuning = sharedObject::ref( _detuning );
|
||||
@@ -65,6 +69,11 @@ note::note( const midiTime & _length, const midiTime & _pos,
|
||||
|
||||
note::note( const note & _note ) :
|
||||
serializingObject( _note ),
|
||||
m_selected( _note.m_selected ),
|
||||
m_oldKey( _note.m_oldKey ),
|
||||
m_oldPos( _note.m_oldPos ),
|
||||
m_oldLength( _note.m_oldLength ),
|
||||
m_isPlaying( _note.m_isPlaying ),
|
||||
m_key( _note.m_key),
|
||||
m_volume( _note.m_volume ),
|
||||
m_panning( _note.m_panning ),
|
||||
|
||||
@@ -506,7 +506,7 @@ void pianoView::mousePressEvent( QMouseEvent * _me )
|
||||
}
|
||||
else
|
||||
{
|
||||
if( engine::getMainWindow()->isCtrlPressed() )
|
||||
if( _me->modifiers() & Qt::ControlModifier )
|
||||
{
|
||||
new stringPairDrag( "automatable_model",
|
||||
QString::number( m_piano->
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QProgressBar>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtAlgorithms>
|
||||
|
||||
|
||||
|
||||
#include "pattern.h"
|
||||
@@ -96,8 +98,6 @@ pattern::pattern( const pattern & _pat_to_copy ) :
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pattern::~pattern()
|
||||
{
|
||||
for( noteVector::iterator it = m_notes.begin();
|
||||
@@ -183,6 +183,17 @@ midiTime pattern::beatPatternLength( void ) const
|
||||
|
||||
|
||||
|
||||
void pattern::printNotes( void )
|
||||
{
|
||||
for( noteVector::iterator it = m_notes.begin(); it != m_notes.end();
|
||||
++it )
|
||||
{
|
||||
printf("note (pos = %i)\n", (int) ( *it )->pos() );
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
note * pattern::addNote( const note & _new_note, const bool _quant_pos )
|
||||
{
|
||||
@@ -270,6 +281,13 @@ note * pattern::rearrangeNote( const note * _note_to_proc,
|
||||
|
||||
|
||||
|
||||
void pattern::rearrangeAllNotes( void )
|
||||
{
|
||||
// sort notes by start time
|
||||
qSort(m_notes.begin(), m_notes.end(), note::lessThan );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void pattern::clearNotes( void )
|
||||
{
|
||||
@@ -1034,7 +1052,7 @@ void patternView::mousePressEvent( QMouseEvent * _me )
|
||||
}
|
||||
else if( m_pat->m_frozenPattern != NULL &&
|
||||
_me->button() == Qt::LeftButton &&
|
||||
engine::getMainWindow()->isShiftPressed() == true )
|
||||
_me->modifiers() & Qt::ShiftModifier )
|
||||
{
|
||||
QString s;
|
||||
new stringPairDrag( "sampledata",
|
||||
|
||||
Reference in New Issue
Block a user