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:
Tobias Doerffel
2008-12-17 11:49:28 +00:00
parent 3e0f9d0216
commit f62830c1ee
9 changed files with 247 additions and 48 deletions

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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

View 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

View File

@@ -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:

View File

@@ -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;