Merge branch 'master' into refac/memory
This commit is contained in:
@@ -71,7 +71,7 @@ public:
|
||||
|
||||
inline static QString name()
|
||||
{
|
||||
return QT_TRANSLATE_NOOP( "setupWidget",
|
||||
return QT_TRANSLATE_NOOP( "AudioDeviceSetupWidget",
|
||||
"ALSA (Advanced Linux Sound Architecture)" );
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ protected:
|
||||
const fpp_t _frames );
|
||||
|
||||
// resample given buffer from samplerate _src_sr to samplerate _dst_sr
|
||||
void resample( const surroundSampleFrame * _src,
|
||||
fpp_t resample( const surroundSampleFrame * _src,
|
||||
const fpp_t _frames,
|
||||
surroundSampleFrame * _dst,
|
||||
const sample_rate_t _src_sr,
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
|
||||
inline static QString name()
|
||||
{
|
||||
return QT_TRANSLATE_NOOP( "setupWidget", "Dummy (no sound output)" );
|
||||
return QT_TRANSLATE_NOOP( "AudioDeviceSetupWidget", "Dummy (no sound output)" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "weak_libjack.h"
|
||||
#endif
|
||||
|
||||
#include <atomic>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
@@ -57,11 +58,12 @@ public:
|
||||
// the jack callback is handled here, we call the midi client so that it can read
|
||||
// it's midi data during the callback
|
||||
AudioJack * addMidiClient(MidiJack *midiClient);
|
||||
void removeMidiClient(void) { m_midiClient = nullptr; }
|
||||
jack_client_t * jackClient() {return m_client;};
|
||||
|
||||
inline static QString name()
|
||||
{
|
||||
return QT_TRANSLATE_NOOP( "setupWidget",
|
||||
return QT_TRANSLATE_NOOP( "AudioDeviceSetupWidget",
|
||||
"JACK (JACK Audio Connection Kit)" );
|
||||
}
|
||||
|
||||
@@ -106,9 +108,9 @@ private:
|
||||
jack_client_t * m_client;
|
||||
|
||||
bool m_active;
|
||||
bool m_stopped;
|
||||
std::atomic<bool> m_stopped;
|
||||
|
||||
MidiJack *m_midiClient;
|
||||
std::atomic<MidiJack *> m_midiClient;
|
||||
QVector<jack_port_t *> m_outputPorts;
|
||||
jack_default_audio_sample_t * * m_tempOutBufs;
|
||||
surroundSampleFrame * m_outBuf;
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
|
||||
inline static QString name()
|
||||
{
|
||||
return QT_TRANSLATE_NOOP( "setupWidget", "OSS (Open Sound System)" );
|
||||
return QT_TRANSLATE_NOOP( "AudioDeviceSetupWidget", "OSS (Open Sound System)" );
|
||||
}
|
||||
|
||||
static QString probeDevice();
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
|
||||
inline static QString name()
|
||||
{
|
||||
return QT_TRANSLATE_NOOP( "setupWidget", "PortAudio" );
|
||||
return QT_TRANSLATE_NOOP( "AudioDeviceSetupWidget", "PortAudio" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
|
||||
inline static QString name()
|
||||
{
|
||||
return QT_TRANSLATE_NOOP( "setupWidget", "PulseAudio" );
|
||||
return QT_TRANSLATE_NOOP( "AudioDeviceSetupWidget", "PulseAudio" );
|
||||
}
|
||||
|
||||
static QString probeDevice();
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
|
||||
inline static QString name()
|
||||
{
|
||||
return QT_TRANSLATE_NOOP( "setupWidget",
|
||||
return QT_TRANSLATE_NOOP( "AudioDeviceSetupWidget",
|
||||
"SDL (Simple DirectMedia Layer)" );
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
|
||||
inline static QString name( void )
|
||||
{
|
||||
return QT_TRANSLATE_NOOP( "setupWidget", "sndio" );
|
||||
return QT_TRANSLATE_NOOP( "AudioDeviceSetupWidget", "sndio" );
|
||||
}
|
||||
|
||||
class setupWidget : public AudioDeviceSetupWidget
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
|
||||
inline static QString name()
|
||||
{
|
||||
return QT_TRANSLATE_NOOP( "setupWidget", "soundio" );
|
||||
return QT_TRANSLATE_NOOP( "AudioDeviceSetupWidget", "soundio" );
|
||||
}
|
||||
|
||||
class setupWidget : public AudioDeviceSetupWidget
|
||||
@@ -110,6 +110,7 @@ private:
|
||||
fpp_t m_outBufFrameIndex;
|
||||
|
||||
bool m_stopped;
|
||||
bool m_outstreamStarted;
|
||||
|
||||
int m_disconnectErr;
|
||||
void onBackendDisconnect(int err);
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#include "JournallingObject.h"
|
||||
#include "Model.h"
|
||||
#include "MidiTime.h"
|
||||
#include "TimePos.h"
|
||||
#include "ValueBuffer.h"
|
||||
#include "Memory.h"
|
||||
#include "ModelVisitor.h"
|
||||
@@ -148,7 +148,7 @@ public:
|
||||
template<class T>
|
||||
inline T value( int frameOffset = 0 ) const
|
||||
{
|
||||
if( unlikely( hasLinkedModels() || m_controllerConnection != NULL ) )
|
||||
if( hasLinkedModels() || m_controllerConnection != NULL )
|
||||
{
|
||||
return castValue<T>( controllerValue( frameOffset ) );
|
||||
}
|
||||
@@ -281,7 +281,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
float globalAutomationValueAt( const MidiTime& time );
|
||||
float globalAutomationValueAt( const TimePos& time );
|
||||
|
||||
void setStrictStepSize( const bool b )
|
||||
{
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
}
|
||||
|
||||
void setModel( Model* model, bool isOldModelValid = true ) override;
|
||||
void unsetModel() override;
|
||||
|
||||
template<typename T>
|
||||
inline T value() const
|
||||
@@ -69,12 +70,16 @@ public:
|
||||
|
||||
void addDefaultActions( QMenu* menu );
|
||||
|
||||
void setConversionFactor( float factor );
|
||||
float getConversionFactor();
|
||||
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent( QMouseEvent* event );
|
||||
|
||||
QString m_description;
|
||||
QString m_unit;
|
||||
float m_conversionFactor; // Factor to be applied when the m_model->value is displayed
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "JournallingObject.h"
|
||||
#include "MidiTime.h"
|
||||
#include "TimePos.h"
|
||||
#include "AutomationPattern.h"
|
||||
#include "ComboBoxModel.h"
|
||||
#include "Knob.h"
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
|
||||
inline bool validPattern() const
|
||||
{
|
||||
return m_pattern != nullptr;
|
||||
return m_pattern != nullptr && m_pattern->hasAutomation();
|
||||
}
|
||||
|
||||
void saveSettings(QDomDocument & doc, QDomElement & parent) override;
|
||||
@@ -153,7 +153,7 @@ protected slots:
|
||||
void pasteValues();
|
||||
void deleteSelectedValues();
|
||||
|
||||
void updatePosition( const MidiTime & t );
|
||||
void updatePosition( const TimePos & t );
|
||||
|
||||
void zoomingXChanged();
|
||||
void zoomingYChanged();
|
||||
@@ -209,12 +209,13 @@ private:
|
||||
float m_bottomLevel;
|
||||
float m_topLevel;
|
||||
|
||||
void centerTopBottomScroll();
|
||||
void updateTopBottomLevels();
|
||||
|
||||
QScrollBar * m_leftRightScroll;
|
||||
QScrollBar * m_topBottomScroll;
|
||||
|
||||
MidiTime m_currentPosition;
|
||||
TimePos m_currentPosition;
|
||||
|
||||
Actions m_action;
|
||||
|
||||
@@ -264,7 +265,7 @@ private:
|
||||
|
||||
signals:
|
||||
void currentPatternChanged();
|
||||
void positionChanged( const MidiTime & );
|
||||
void positionChanged( const TimePos & );
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
#include "Track.h"
|
||||
#include "TrackContentObject.h"
|
||||
|
||||
|
||||
class AutomationTrack;
|
||||
class MidiTime;
|
||||
class TimePos;
|
||||
|
||||
|
||||
|
||||
@@ -74,19 +74,19 @@ public:
|
||||
}
|
||||
void setTension( QString _new_tension );
|
||||
|
||||
MidiTime timeMapLength() const;
|
||||
TimePos timeMapLength() const;
|
||||
void updateLength();
|
||||
|
||||
MidiTime putValue( const MidiTime & time,
|
||||
TimePos putValue( const TimePos & time,
|
||||
const float value,
|
||||
const bool quantPos = true,
|
||||
const bool ignoreSurroundingPoints = true );
|
||||
|
||||
void removeValue( const MidiTime & time );
|
||||
void removeValue( const TimePos & time );
|
||||
|
||||
void recordValue(MidiTime time, float value);
|
||||
void recordValue(TimePos time, float value);
|
||||
|
||||
MidiTime setDragValue( const MidiTime & time,
|
||||
TimePos setDragValue( const TimePos & time,
|
||||
const float value,
|
||||
const bool quantPos = true,
|
||||
const bool controlKey = false );
|
||||
@@ -134,8 +134,8 @@ public:
|
||||
return m_timeMap.isEmpty() == false;
|
||||
}
|
||||
|
||||
float valueAt( const MidiTime & _time ) const;
|
||||
float *valuesAfter( const MidiTime & _time ) const;
|
||||
float valueAt( const TimePos & _time ) const;
|
||||
float *valuesAfter( const TimePos & _time ) const;
|
||||
|
||||
const QString name() const;
|
||||
|
||||
|
||||
@@ -27,9 +27,10 @@
|
||||
|
||||
#include <QStaticText>
|
||||
|
||||
#include "Track.h"
|
||||
|
||||
class AutomationPattern;
|
||||
#include "AutomationPattern.h"
|
||||
#include "Song.h"
|
||||
#include "SongEditor.h"
|
||||
#include "TrackContentObjectView.h"
|
||||
|
||||
|
||||
class AutomationPatternView : public TrackContentObjectView
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define AUTOMATION_TRACK_H
|
||||
|
||||
#include "Track.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
|
||||
class LMMS_EXPORT AutomationTrack : public Track
|
||||
@@ -37,7 +38,7 @@ public:
|
||||
AutomationTrack( TrackContainer* tc, bool _hidden = false );
|
||||
virtual ~AutomationTrack() = default;
|
||||
|
||||
virtual bool play( const MidiTime & _start, const fpp_t _frames,
|
||||
virtual bool play( const TimePos & _start, const fpp_t _frames,
|
||||
const f_cnt_t _frame_base, int _tco_num = -1 ) override;
|
||||
|
||||
QString nodeName() const override
|
||||
@@ -46,7 +47,7 @@ public:
|
||||
}
|
||||
|
||||
TrackView * createView( TrackContainerView* ) override;
|
||||
TrackContentObject * createTCO( const MidiTime & _pos ) override;
|
||||
TrackContentObject* createTCO(const TimePos & pos) override;
|
||||
|
||||
virtual void saveTrackSpecificSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent ) override;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#ifndef BB_EDITOR_H
|
||||
#define BB_EDITOR_H
|
||||
|
||||
|
||||
#include "Editor.h"
|
||||
#include "TrackContainerView.h"
|
||||
|
||||
@@ -86,6 +87,7 @@ public slots:
|
||||
void removeSteps();
|
||||
void addSampleTrack();
|
||||
void addAutomationTrack();
|
||||
void clonePattern();
|
||||
|
||||
protected slots:
|
||||
void dropEvent(QDropEvent * de ) override;
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
#include <QStaticText>
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "TrackContentObjectView.h"
|
||||
#include "Track.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
class TrackLabelButton;
|
||||
class TrackContainer;
|
||||
@@ -51,33 +53,11 @@ public:
|
||||
return( "bbtco" );
|
||||
}
|
||||
|
||||
unsigned int color() const
|
||||
{
|
||||
return( m_color.rgb() );
|
||||
}
|
||||
|
||||
QColor colorObj() const
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void setColor( const QColor & c )
|
||||
{
|
||||
m_color = QColor( c );
|
||||
}
|
||||
|
||||
void setUseStyleColor( bool b )
|
||||
{
|
||||
m_useStyleColor = b;
|
||||
}
|
||||
|
||||
int bbTrackIndex();
|
||||
|
||||
TrackContentObjectView * createView( TrackView * _tv ) override;
|
||||
|
||||
private:
|
||||
QColor m_color;
|
||||
bool m_useStyleColor;
|
||||
|
||||
|
||||
friend class BBTCOView;
|
||||
@@ -93,11 +73,6 @@ public:
|
||||
BBTCOView( TrackContentObject * _tco, TrackView * _tv );
|
||||
virtual ~BBTCOView() = default;
|
||||
|
||||
QColor color() const
|
||||
{
|
||||
return( m_bbTCO->m_color );
|
||||
}
|
||||
void setColor( QColor _new_color );
|
||||
|
||||
public slots:
|
||||
void update() override;
|
||||
@@ -106,8 +81,6 @@ protected slots:
|
||||
void openInBBEditor();
|
||||
void resetName();
|
||||
void changeName();
|
||||
void changeColor();
|
||||
void resetColor();
|
||||
|
||||
|
||||
protected:
|
||||
@@ -133,10 +106,10 @@ public:
|
||||
BBTrack( TrackContainer* tc );
|
||||
virtual ~BBTrack();
|
||||
|
||||
virtual bool play( const MidiTime & _start, const fpp_t _frames,
|
||||
virtual bool play( const TimePos & _start, const fpp_t _frames,
|
||||
const f_cnt_t _frame_base, int _tco_num = -1 ) override;
|
||||
TrackView * createView( TrackContainerView* tcv ) override;
|
||||
TrackContentObject * createTCO( const MidiTime & _pos ) override;
|
||||
TrackContentObject* createTCO(const TimePos & pos) override;
|
||||
|
||||
virtual void saveTrackSpecificSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent ) override;
|
||||
@@ -163,27 +136,6 @@ public:
|
||||
m_disabledTracks.removeAll( _track );
|
||||
}
|
||||
|
||||
static void setLastTCOColor( const QColor & c )
|
||||
{
|
||||
if( ! s_lastTCOColor )
|
||||
{
|
||||
s_lastTCOColor = new QColor( c );
|
||||
}
|
||||
else
|
||||
{
|
||||
*s_lastTCOColor = QColor( c );
|
||||
}
|
||||
}
|
||||
|
||||
static void clearLastTCOColor()
|
||||
{
|
||||
if( s_lastTCOColor )
|
||||
{
|
||||
delete s_lastTCOColor;
|
||||
}
|
||||
s_lastTCOColor = NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
inline QString nodeName() const override
|
||||
{
|
||||
@@ -197,8 +149,6 @@ private:
|
||||
typedef QMap<BBTrack *, int> infoMap;
|
||||
static infoMap s_infoMap;
|
||||
|
||||
static QColor * s_lastTCOColor;
|
||||
|
||||
friend class BBTrackView;
|
||||
|
||||
} ;
|
||||
|
||||
@@ -38,8 +38,7 @@ public:
|
||||
BBTrackContainer();
|
||||
virtual ~BBTrackContainer();
|
||||
|
||||
virtual bool play( MidiTime _start, const fpp_t _frames,
|
||||
const f_cnt_t _frame_base, int _tco_num = -1 );
|
||||
virtual bool play(TimePos start, const fpp_t frames, const f_cnt_t frameBase, int tcoNum = -1);
|
||||
|
||||
void updateAfterTrackAdd() override;
|
||||
|
||||
@@ -48,21 +47,21 @@ public:
|
||||
return "bbtrackcontainer";
|
||||
}
|
||||
|
||||
bar_t lengthOfBB( int _bb ) const;
|
||||
bar_t lengthOfBB(int bb) const;
|
||||
inline bar_t lengthOfCurrentBB()
|
||||
{
|
||||
return lengthOfBB( currentBB() );
|
||||
return lengthOfBB(currentBB());
|
||||
}
|
||||
int numOfBBs() const;
|
||||
void removeBB( int _bb );
|
||||
void removeBB(int bb);
|
||||
|
||||
void swapBB( int _bb1, int _bb2 );
|
||||
void swapBB(int bb1, int bb2);
|
||||
|
||||
void updateBBTrack( TrackContentObject * _tco );
|
||||
void updateBBTrack(TrackContentObject * tco);
|
||||
void fixIncorrectPositions();
|
||||
void createTCOsForBB( int _bb );
|
||||
void createTCOsForBB(int bb);
|
||||
|
||||
AutomatedValueMap automatedValuesAt(MidiTime time, int tcoNum) const override;
|
||||
AutomatedValueMap automatedValuesAt(TimePos time, int tcoNum) const override;
|
||||
|
||||
public slots:
|
||||
void play();
|
||||
|
||||
@@ -29,25 +29,40 @@
|
||||
#include <QDomElement>
|
||||
|
||||
|
||||
class JournallingObject;
|
||||
|
||||
class Clipboard
|
||||
namespace Clipboard
|
||||
{
|
||||
public:
|
||||
typedef QMap<QString, QDomElement> Map;
|
||||
|
||||
static void copy( JournallingObject * _object );
|
||||
static const QDomElement * getContent( const QString & _node_name );
|
||||
|
||||
static const char * mimeType()
|
||||
enum class MimeType
|
||||
{
|
||||
return( "application/x-lmms-clipboard" );
|
||||
StringPair,
|
||||
Default
|
||||
};
|
||||
|
||||
// Convenience Methods
|
||||
const QMimeData * getMimeData();
|
||||
bool hasFormat( MimeType mT );
|
||||
|
||||
// Helper methods for String data
|
||||
void copyString( const QString & str, MimeType mT );
|
||||
QString getString( MimeType mT );
|
||||
|
||||
// Helper methods for String Pair data
|
||||
void copyStringPair( const QString & key, const QString & value );
|
||||
QString decodeKey( const QMimeData * mimeData );
|
||||
QString decodeValue( const QMimeData * mimeData );
|
||||
|
||||
inline const char * mimeType( MimeType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case MimeType::StringPair:
|
||||
return "application/x-lmms-stringpair";
|
||||
break;
|
||||
case MimeType::Default:
|
||||
default:
|
||||
return "application/x-lmms-clipboard";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static Map content;
|
||||
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,21 +21,39 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QColorDialog>
|
||||
#include <QApplication>
|
||||
#include <QColor>
|
||||
#include <QColorDialog>
|
||||
#include <QKeyEvent>
|
||||
#include <QVector>
|
||||
|
||||
class ColorChooser: public QColorDialog
|
||||
{
|
||||
public:
|
||||
ColorChooser(const QColor &initial, QWidget *parent): QColorDialog(initial, parent) {};
|
||||
ColorChooser(QWidget *parent): QColorDialog(parent) {};
|
||||
//! For getting a color without having to initialise a color dialog
|
||||
ColorChooser() {};
|
||||
enum class Palette {Default, Track, Mixer};
|
||||
//! Set global palette via array, checking bounds
|
||||
void setPalette (QVector<QColor>);
|
||||
//! Set global paletter via enum
|
||||
void setPalette (Palette);
|
||||
//! Set palette via enum, return self pointer for chaining
|
||||
ColorChooser* withPalette (Palette);
|
||||
//! Return a certain palette
|
||||
static QVector<QColor> getPalette (Palette);
|
||||
|
||||
protected:
|
||||
// Forward key events to the parent to prevent stuck notes when the dialog gets focus
|
||||
//! Forward key events to the parent to prevent stuck notes when the dialog gets focus
|
||||
void keyReleaseEvent(QKeyEvent *event) override
|
||||
{
|
||||
QKeyEvent ke(*event);
|
||||
QApplication::sendEvent(parentWidget(), &ke);
|
||||
}
|
||||
private:
|
||||
//! Copy the current QColorDialog palette into an array
|
||||
static QVector<QColor> defaultPalette();
|
||||
//! Generate a nice palette, with adjustable value
|
||||
static QVector<QColor> nicePalette (int);
|
||||
};
|
||||
|
||||
@@ -32,8 +32,6 @@
|
||||
#include "ComboBoxModel.h"
|
||||
#include "AutomatableModelView.h"
|
||||
|
||||
|
||||
|
||||
class LMMS_EXPORT ComboBox : public QWidget, public IntModelView
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -51,6 +49,8 @@ public:
|
||||
return castModel<ComboBoxModel>();
|
||||
}
|
||||
|
||||
static constexpr int DEFAULT_HEIGHT = 22;
|
||||
|
||||
public slots:
|
||||
void selectNext();
|
||||
void selectPrevious();
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
|
||||
class LmmsCore;
|
||||
|
||||
|
||||
const QString PROJECTS_PATH = "projects/";
|
||||
const QString TEMPLATE_PATH = "templates/";
|
||||
const QString PRESETS_PATH = "presets/";
|
||||
@@ -50,11 +49,14 @@ const QString LADSPA_PATH ="plugins/ladspa/";
|
||||
const QString DEFAULT_THEME_PATH = "themes/default/";
|
||||
const QString TRACK_ICON_PATH = "track_icons/";
|
||||
const QString LOCALE_PATH = "locale/";
|
||||
|
||||
const QString PORTABLE_MODE_FILE = "/portable_mode.txt";
|
||||
|
||||
class LMMS_EXPORT ConfigManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using UpgradeMethod = void(ConfigManager::*)();
|
||||
|
||||
public:
|
||||
static inline ConfigManager * inst()
|
||||
{
|
||||
@@ -71,6 +73,12 @@ public:
|
||||
return m_workingDir;
|
||||
}
|
||||
|
||||
void initPortableWorkingDir();
|
||||
|
||||
void initInstalledWorkingDir();
|
||||
|
||||
void initDevelopmentWorkingDir();
|
||||
|
||||
const QString & dataDir() const
|
||||
{
|
||||
return m_dataDir;
|
||||
@@ -213,10 +221,14 @@ public:
|
||||
return m_version;
|
||||
}
|
||||
|
||||
// Used when the configversion attribute is not present in a configuration file.
|
||||
// Returns the appropriate config file version based on the LMMS version.
|
||||
unsigned int legacyConfigVersion();
|
||||
|
||||
QString defaultVersion() const;
|
||||
|
||||
|
||||
static QStringList availabeVstEmbedMethods();
|
||||
static QStringList availableVstEmbedMethods();
|
||||
QString vstEmbedMethod() const;
|
||||
|
||||
// Returns true if the working dir (e.g. ~/lmms) exists on disk.
|
||||
@@ -264,6 +276,9 @@ private:
|
||||
void upgrade_1_1_91();
|
||||
void upgrade();
|
||||
|
||||
// List of all upgrade methods
|
||||
static const std::vector<UpgradeMethod> UPGRADE_METHODS;
|
||||
|
||||
QString m_workingDir;
|
||||
QString m_dataDir;
|
||||
QString m_vstDir;
|
||||
@@ -280,6 +295,7 @@ private:
|
||||
QString m_backgroundPicFile;
|
||||
QString m_lmmsRcFile;
|
||||
QString m_version;
|
||||
unsigned int m_configVersion;
|
||||
QStringList m_recentlyOpenedProjects;
|
||||
|
||||
typedef QVector<QPair<QString, QString> > stringPairVector;
|
||||
|
||||
@@ -110,6 +110,9 @@ public:
|
||||
void setGeometry(const QRect &rect) override;
|
||||
QSize sizeHint() const override;
|
||||
QLayoutItem *takeAt(int index) override;
|
||||
//! remove focus from QLineEdit search bar
|
||||
//! this may be useful if the mouse is outside the layout
|
||||
void removeFocusFromSearchBar();
|
||||
|
||||
private slots:
|
||||
void onTextChanged(const QString&);
|
||||
|
||||
30
include/CustomTextKnob.h
Normal file
30
include/CustomTextKnob.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* Text customizable knob */
|
||||
#ifndef CUSTOM_TEXT_KNOB_H
|
||||
#define CUSTOM_TEXT_KNOB_H
|
||||
|
||||
#include "Knob.h"
|
||||
|
||||
class LMMS_EXPORT CustomTextKnob : public Knob
|
||||
{
|
||||
protected:
|
||||
inline void setHintText( const QString & _txt_before, const QString & _txt_after ) {} // inaccessible
|
||||
public:
|
||||
CustomTextKnob( knobTypes _knob_num, QWidget * _parent = NULL, const QString & _name = QString(), const QString & _value_text = QString() );
|
||||
|
||||
CustomTextKnob( QWidget * _parent = NULL, const QString & _name = QString(), const QString & _value_text = QString() ); //!< default ctor
|
||||
|
||||
CustomTextKnob( const Knob& other ) = delete;
|
||||
|
||||
inline void setValueText(const QString & _value_text)
|
||||
{
|
||||
m_value_text = _value_text;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual QString displayValue() const;
|
||||
|
||||
protected:
|
||||
QString m_value_text;
|
||||
} ;
|
||||
|
||||
#endif
|
||||
@@ -31,12 +31,16 @@
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "Memory.h"
|
||||
#include "ProjectVersion.h"
|
||||
|
||||
class QTextStream;
|
||||
|
||||
class LMMS_EXPORT DataFile : public QDomDocument
|
||||
{
|
||||
MM_OPERATORS
|
||||
|
||||
using UpgradeMethod = void(DataFile::*)();
|
||||
|
||||
public:
|
||||
enum Types
|
||||
{
|
||||
@@ -84,6 +88,8 @@ public:
|
||||
return m_type;
|
||||
}
|
||||
|
||||
unsigned int legacyFileVersion();
|
||||
|
||||
private:
|
||||
static Type type( const QString& typeName );
|
||||
static QString typeName( Type type );
|
||||
@@ -107,8 +113,13 @@ private:
|
||||
void upgrade_1_1_0();
|
||||
void upgrade_1_1_91();
|
||||
void upgrade_1_2_0_rc3();
|
||||
void upgrade_1_2_0_rc2_42();
|
||||
void upgrade_1_3_0();
|
||||
void upgrade_noHiddenClipNames();
|
||||
|
||||
// List of all upgrade methods
|
||||
static const std::vector<UpgradeMethod> UPGRADE_METHODS;
|
||||
// List of ProjectVersions for the legacyFileVersion method
|
||||
static const std::vector<ProjectVersion> UPGRADE_VERSIONS;
|
||||
|
||||
void upgrade();
|
||||
|
||||
@@ -125,14 +136,9 @@ private:
|
||||
QDomElement m_content;
|
||||
QDomElement m_head;
|
||||
Type m_type;
|
||||
unsigned int m_fileVersion;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
const int LDF_MAJOR_VERSION = 1;
|
||||
const int LDF_MINOR_VERSION = 0;
|
||||
const QString LDF_VERSION_STRING = QString::number( LDF_MAJOR_VERSION ) + "." + QString::number( LDF_MINOR_VERSION );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
63
include/DeprecationHelper.h
Normal file
63
include/DeprecationHelper.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* DeprecationHelper.h - This file contains the declarations of helper functions
|
||||
* which helps centralize the #ifdefs preprocessors regarding deprecation based on Qt versions.
|
||||
* The functions are defined differently based on the callers' Qt versions.
|
||||
*
|
||||
* Copyright (c) 2020 Tien Dat Nguyen <ntd.bk.k56/at/gmail.com>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 DEPRECATIONHELPER_H
|
||||
#define DEPRECATIONHELPER_H
|
||||
|
||||
#include <QFontMetrics>
|
||||
#include <QWheelEvent>
|
||||
|
||||
/**
|
||||
* @brief horizontalAdvance is a backwards-compatible adapter for
|
||||
* QFontMetrics::horizontalAdvance and width functions.
|
||||
* @param metrics
|
||||
* @param text
|
||||
* @return text's horizontal advance based on metrics.
|
||||
*/
|
||||
inline int horizontalAdvance(const QFontMetrics& metrics, const QString& text)
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
||||
return metrics.horizontalAdvance(text);
|
||||
#else
|
||||
return metrics.width(text);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief position is a backwards-compatible adapter for
|
||||
* QWheelEvent::position and pos functions.
|
||||
* @param wheelEvent
|
||||
* @return the position of wheelEvent
|
||||
*/
|
||||
inline QPoint position(QWheelEvent *wheelEvent)
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||
return wheelEvent->position().toPoint();
|
||||
#else
|
||||
return wheelEvent->pos();
|
||||
#endif
|
||||
}
|
||||
#endif // DEPRECATIONHELPER_H
|
||||
@@ -28,6 +28,12 @@
|
||||
#include <QMainWindow>
|
||||
#include <QToolBar>
|
||||
|
||||
static const int Quantizations[] = {
|
||||
1, 2, 4, 8, 16, 32, 64,
|
||||
3, 6, 12, 24, 48, 96, 192
|
||||
};
|
||||
|
||||
|
||||
class QAction;
|
||||
|
||||
class DropToolBar;
|
||||
@@ -58,6 +64,11 @@ protected slots:
|
||||
private slots:
|
||||
/// Called by pressing the space key. Plays or stops.
|
||||
void togglePlayStop();
|
||||
|
||||
/// Called by pressing shift+space. Toggles pause state.
|
||||
void togglePause();
|
||||
|
||||
void toggleMaximize();
|
||||
|
||||
signals:
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
EffectRackView( EffectChain* model, QWidget* parent = NULL );
|
||||
virtual ~EffectRackView();
|
||||
|
||||
static constexpr int DEFAULT_WIDTH = 245;
|
||||
|
||||
public slots:
|
||||
void clearViews();
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
return castModel<Effect>();
|
||||
}
|
||||
|
||||
static constexpr int DEFAULT_WIDTH = 215;
|
||||
|
||||
public slots:
|
||||
void editControls();
|
||||
|
||||
@@ -30,11 +30,11 @@
|
||||
#include <QtCore/QObject>
|
||||
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
#include "lmms_export.h"
|
||||
#include "lmms_basics.h"
|
||||
|
||||
class BBTrackContainer;
|
||||
class DummyTrackContainer;
|
||||
class FxMixer;
|
||||
class ProjectJournal;
|
||||
class Mixer;
|
||||
@@ -87,16 +87,20 @@ public:
|
||||
return s_projectJournal;
|
||||
}
|
||||
|
||||
static bool ignorePluginBlacklist();
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
static class Lv2Manager * getLv2Manager()
|
||||
{
|
||||
return s_lv2Manager;
|
||||
}
|
||||
#endif
|
||||
|
||||
static Ladspa2LMMS * getLADSPAManager()
|
||||
{
|
||||
return s_ladspaManager;
|
||||
}
|
||||
|
||||
static DummyTrackContainer * dummyTrackContainer()
|
||||
{
|
||||
return s_dummyTC;
|
||||
}
|
||||
|
||||
static float framesPerTick()
|
||||
{
|
||||
return s_framesPerTick;
|
||||
@@ -141,8 +145,10 @@ private:
|
||||
static Song * s_song;
|
||||
static BBTrackContainer * s_bbTrackContainer;
|
||||
static ProjectJournal * s_projectJournal;
|
||||
static DummyTrackContainer * s_dummyTC;
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
static class Lv2Manager* s_lv2Manager;
|
||||
#endif
|
||||
static Ladspa2LMMS * s_ladspaManager;
|
||||
static void* s_dndPluginKey;
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#ifndef FADE_BUTTON_H
|
||||
#define FADE_BUTTON_H
|
||||
|
||||
#include <QtCore/QTime>
|
||||
#include <QAbstractButton>
|
||||
#include <QColor>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
|
||||
class FadeButton : public QAbstractButton
|
||||
@@ -55,8 +55,8 @@ protected:
|
||||
|
||||
|
||||
private:
|
||||
QTime m_stateTimer;
|
||||
QTime m_releaseTimer;
|
||||
QElapsedTimer m_stateTimer;
|
||||
QElapsedTimer m_releaseTimer;
|
||||
|
||||
// the default color of the widget
|
||||
QColor m_normalColor;
|
||||
@@ -66,7 +66,7 @@ private:
|
||||
QColor m_holdColor;
|
||||
int activeNotes;
|
||||
|
||||
QColor fadeToColor(QColor, QColor, QTime, float);
|
||||
QColor fadeToColor(QColor, QColor, QElapsedTimer, float);
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -48,9 +48,10 @@
|
||||
#ifndef FADER_H
|
||||
#define FADER_H
|
||||
|
||||
#include <QtCore/QTime>
|
||||
#include <QWidget>
|
||||
#include <QElapsedTimer>
|
||||
#include <QPixmap>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
#include "AutomatableModelView.h"
|
||||
|
||||
@@ -98,7 +99,7 @@ public:
|
||||
|
||||
void setDisplayConversion( bool b )
|
||||
{
|
||||
m_displayConversion = b;
|
||||
m_conversionFactor = b ? 100.0 : 1.0;
|
||||
}
|
||||
|
||||
inline void setHintText( const QString & _txt_before,
|
||||
@@ -130,7 +131,7 @@ private:
|
||||
return height() - ( ( height() - m_knob->height() ) * ( realVal / fRange ) );
|
||||
}
|
||||
|
||||
void setPeak( float fPeak, float &targetPeak, float &persistentPeak, QTime &lastPeakTime );
|
||||
void setPeak( float fPeak, float &targetPeak, float &persistentPeak, QElapsedTimer &lastPeakTimer );
|
||||
int calculateDisplayPeak( float fPeak );
|
||||
|
||||
void updateTextFloat();
|
||||
@@ -144,8 +145,8 @@ private:
|
||||
float m_fMinPeak;
|
||||
float m_fMaxPeak;
|
||||
|
||||
QTime m_lastPeakTime_L;
|
||||
QTime m_lastPeakTime_R;
|
||||
QElapsedTimer m_lastPeakTimer_L;
|
||||
QElapsedTimer m_lastPeakTimer_R;
|
||||
|
||||
static QPixmap * s_back;
|
||||
static QPixmap * s_leds;
|
||||
@@ -154,8 +155,7 @@ private:
|
||||
QPixmap * m_back;
|
||||
QPixmap * m_leds;
|
||||
QPixmap * m_knob;
|
||||
|
||||
bool m_displayConversion;
|
||||
|
||||
bool m_levelsDisplayedInDBFS;
|
||||
|
||||
int m_moveStartPoint;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#ifndef FILE_BROWSER_H
|
||||
#define FILE_BROWSER_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QMutex>
|
||||
#include <QTreeWidget>
|
||||
@@ -58,14 +59,17 @@ public:
|
||||
*/
|
||||
FileBrowser( const QString & directories, const QString & filter,
|
||||
const QString & title, const QPixmap & pm,
|
||||
QWidget * parent, bool dirs_as_items = false, bool recurse = false );
|
||||
QWidget * parent, bool dirs_as_items = false, bool recurse = false,
|
||||
const QString& userDir = "",
|
||||
const QString& factoryDir = "");
|
||||
|
||||
virtual ~FileBrowser() = default;
|
||||
|
||||
private slots:
|
||||
void reloadTree( void );
|
||||
void expandItems( QTreeWidgetItem * item=NULL, QList<QString> expandedDirs = QList<QString>() );
|
||||
void expandItems( QTreeWidgetItem * item=nullptr, QList<QString> expandedDirs = QList<QString>() );
|
||||
// call with item=NULL to filter the entire tree
|
||||
bool filterItems( const QString & filter, QTreeWidgetItem * item=NULL );
|
||||
bool filterItems( const QString & filter, QTreeWidgetItem * item=nullptr );
|
||||
void giveFocusToFilter();
|
||||
|
||||
private:
|
||||
@@ -83,6 +87,11 @@ private:
|
||||
bool m_dirsAsItems;
|
||||
bool m_recurse;
|
||||
|
||||
void addContentCheckBox();
|
||||
QCheckBox* m_showUserContent = nullptr;
|
||||
QCheckBox* m_showFactoryContent = nullptr;
|
||||
QString m_userDir;
|
||||
QString m_factoryDir;
|
||||
} ;
|
||||
|
||||
|
||||
@@ -105,29 +114,39 @@ protected:
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void mouseMoveEvent( QMouseEvent * me ) override;
|
||||
void mouseReleaseEvent( QMouseEvent * me ) override;
|
||||
void keyPressEvent( QKeyEvent * ke ) override;
|
||||
void keyReleaseEvent( QKeyEvent * ke ) override;
|
||||
void hideEvent( QHideEvent * he ) override;
|
||||
void focusOutEvent( QFocusEvent * fe ) override;
|
||||
|
||||
|
||||
private:
|
||||
//! Start a preview of a file item
|
||||
void previewFileItem(FileItem* file);
|
||||
//! If a preview is playing, stop it.
|
||||
void stopPreview();
|
||||
|
||||
void handleFile( FileItem * fi, InstrumentTrack * it );
|
||||
void openInNewInstrumentTrack( TrackContainer* tc );
|
||||
void openInNewInstrumentTrack( TrackContainer* tc, FileItem* item );
|
||||
|
||||
|
||||
bool m_mousePressed;
|
||||
QPoint m_pressPos;
|
||||
|
||||
//! This should only be accessed or modified when m_pphMutex is held
|
||||
PlayHandle* m_previewPlayHandle;
|
||||
QMutex m_pphMutex;
|
||||
|
||||
FileItem * m_contextMenuItem;
|
||||
QList<QAction*> getContextActions(FileItem* item, bool songEditor);
|
||||
|
||||
|
||||
private slots:
|
||||
void activateListItem( QTreeWidgetItem * item, int column );
|
||||
void openInNewInstrumentTrackBBE( void );
|
||||
void openInNewInstrumentTrackSE( void );
|
||||
void sendToActiveInstrumentTrack( void );
|
||||
void openInNewInstrumentTrack( FileItem* item, bool songEditor );
|
||||
bool openInNewSampleTrack( FileItem* item );
|
||||
void sendToActiveInstrumentTrack( FileItem* item );
|
||||
void updateDirectory( QTreeWidgetItem * item );
|
||||
void openContainingFolder();
|
||||
void openContainingFolder( FileItem* item );
|
||||
|
||||
} ;
|
||||
|
||||
@@ -234,6 +253,11 @@ public:
|
||||
return( m_handling );
|
||||
}
|
||||
|
||||
inline bool isTrack( void ) const
|
||||
{
|
||||
return m_handling == LoadAsPreset || m_handling == LoadByPlugin;
|
||||
}
|
||||
|
||||
QString extension( void );
|
||||
static QString extension( const QString & file );
|
||||
|
||||
|
||||
@@ -46,8 +46,7 @@ public:
|
||||
const QString &caption = QString(),
|
||||
const QString &directory = QString(),
|
||||
const QString &filter = QString(),
|
||||
QString *selectedFilter = 0,
|
||||
QFileDialog::Options options = 0);
|
||||
QString *selectedFilter = 0);
|
||||
void clearSelection();
|
||||
};
|
||||
|
||||
|
||||
@@ -26,10 +26,12 @@
|
||||
#ifndef FX_LINE_H
|
||||
#define FX_LINE_H
|
||||
|
||||
#include <QColorDialog>
|
||||
#include <QGraphicsView>
|
||||
#include <QLineEdit>
|
||||
#include <QWidget>
|
||||
|
||||
#include "ColorChooser.h"
|
||||
#include "Knob.h"
|
||||
#include "LcdWidget.h"
|
||||
#include "SendButtonIndicator.h"
|
||||
@@ -101,6 +103,9 @@ private:
|
||||
|
||||
public slots:
|
||||
void renameChannel();
|
||||
void resetColor();
|
||||
void changeColor();
|
||||
void randomColor();
|
||||
|
||||
private slots:
|
||||
void renameFinished();
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <QColor>
|
||||
|
||||
class FxRoute;
|
||||
typedef QVector<FxRoute *> FxRouteVector;
|
||||
|
||||
@@ -70,6 +72,17 @@ class FxChannel : public ThreadableJob
|
||||
bool requiresProcessing() const override { return true; }
|
||||
void unmuteForSolo();
|
||||
|
||||
|
||||
void setColor (QColor newColor)
|
||||
{
|
||||
m_color = newColor;
|
||||
m_hasColor = true;
|
||||
}
|
||||
|
||||
// TODO C++17 and above: use std::optional instead
|
||||
QColor m_color;
|
||||
bool m_hasColor;
|
||||
|
||||
|
||||
std::atomic_int m_dependenciesMet;
|
||||
void incrementDeps();
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
class QLabel;
|
||||
|
||||
@@ -48,6 +49,9 @@ public:
|
||||
~GuiApplication();
|
||||
|
||||
static GuiApplication* instance();
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
static QFont getWin32SystemFont();
|
||||
#endif
|
||||
|
||||
MainWindow* mainWindow() { return m_mainWindow; }
|
||||
FxMixerView* fxMixerView() { return m_fxMixerView; }
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
#include "lmms_export.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "Memory.h"
|
||||
#include "MidiTime.h"
|
||||
#include "Plugin.h"
|
||||
#include "TimePos.h"
|
||||
|
||||
|
||||
// forward-declarations
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
|
||||
// sub-classes can re-implement this for receiving all incoming
|
||||
// MIDI-events
|
||||
inline virtual bool handleMidiEvent( const MidiEvent&, const MidiTime& = MidiTime(), f_cnt_t offset = 0 )
|
||||
inline virtual bool handleMidiEvent( const MidiEvent&, const TimePos& = TimePos(), f_cnt_t offset = 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -132,6 +132,9 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
// fade in to prevent clicks
|
||||
void applyFadeIn(sampleFrame * buf, NotePlayHandle * n);
|
||||
|
||||
// instruments may use this to apply a soft fade out at the end of
|
||||
// notes - method does this only if really less or equal
|
||||
// desiredReleaseFrames() frames are left
|
||||
|
||||
@@ -74,7 +74,7 @@ private:
|
||||
FloatModel m_filterCutModel;
|
||||
FloatModel m_filterResModel;
|
||||
|
||||
static const QString targetNames[InstrumentSoundShaping::NumTargets][3];
|
||||
static const char *const targetNames[InstrumentSoundShaping::NumTargets][3];
|
||||
|
||||
|
||||
friend class InstrumentSoundShapingView;
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "GroupBox.h"
|
||||
#include "InstrumentFunctions.h"
|
||||
#include "InstrumentSoundShaping.h"
|
||||
#include "Midi.h"
|
||||
#include "MidiCCRackView.h"
|
||||
#include "MidiEventProcessor.h"
|
||||
#include "MidiPort.h"
|
||||
#include "NotePlayHandle.h"
|
||||
@@ -38,11 +40,11 @@
|
||||
#include "Pitch.h"
|
||||
#include "Plugin.h"
|
||||
#include "Track.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
|
||||
|
||||
class QLineEdit;
|
||||
template<class T> class QQueue;
|
||||
class InstrumentFunctionArpeggioView;
|
||||
class InstrumentFunctionNoteStackingView;
|
||||
class EffectRackView;
|
||||
@@ -80,8 +82,8 @@ public:
|
||||
|
||||
MidiEvent applyMasterKey( const MidiEvent& event );
|
||||
|
||||
void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ) override;
|
||||
void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ) override;
|
||||
void processInEvent( const MidiEvent& event, const TimePos& time = TimePos(), f_cnt_t offset = 0 ) override;
|
||||
void processOutEvent( const MidiEvent& event, const TimePos& time = TimePos(), f_cnt_t offset = 0 ) override;
|
||||
// silence all running notes played by this track
|
||||
void silenceAllNotes( bool removeIPH = false );
|
||||
|
||||
@@ -130,13 +132,13 @@ public:
|
||||
}
|
||||
|
||||
// play everything in given frame-range - creates note-play-handles
|
||||
virtual bool play( const MidiTime & _start, const fpp_t _frames,
|
||||
virtual bool play( const TimePos & _start, const fpp_t _frames,
|
||||
const f_cnt_t _frame_base, int _tco_num = -1 ) override;
|
||||
// create new view for me
|
||||
TrackView * createView( TrackContainerView* tcv ) override;
|
||||
|
||||
// create new track-content-object = pattern
|
||||
TrackContentObject * createTCO( const MidiTime & _pos ) override;
|
||||
TrackContentObject* createTCO(const TimePos & pos) override;
|
||||
|
||||
|
||||
// called by track
|
||||
@@ -219,6 +221,8 @@ public:
|
||||
return m_previewMode;
|
||||
}
|
||||
|
||||
void autoAssignMidiDevice( bool );
|
||||
|
||||
signals:
|
||||
void instrumentChanged();
|
||||
void midiNoteOn( const Note& );
|
||||
@@ -227,7 +231,6 @@ signals:
|
||||
void newNote();
|
||||
void endNote();
|
||||
|
||||
|
||||
protected:
|
||||
QString nodeName() const override
|
||||
{
|
||||
@@ -246,6 +249,8 @@ protected slots:
|
||||
|
||||
|
||||
private:
|
||||
void processCCEvent(int controller);
|
||||
|
||||
MidiPort m_midiPort;
|
||||
|
||||
NotePlayHandle* m_notes[NumKeys];
|
||||
@@ -260,6 +265,9 @@ private:
|
||||
|
||||
bool m_previewMode;
|
||||
|
||||
bool m_hasAutoMidiDev;
|
||||
static InstrumentTrack *s_autoAssignedTrack;
|
||||
|
||||
IntModel m_baseNoteModel;
|
||||
|
||||
NotePlayHandleList m_processHandles;
|
||||
@@ -282,11 +290,14 @@ private:
|
||||
|
||||
Piano m_piano;
|
||||
|
||||
std::unique_ptr<BoolModel> m_midiCCEnable;
|
||||
std::unique_ptr<FloatModel> m_midiCCModel[MidiControllerCount];
|
||||
|
||||
friend class InstrumentTrackView;
|
||||
friend class InstrumentTrackWindow;
|
||||
friend class NotePlayHandle;
|
||||
friend class InstrumentMiscView;
|
||||
friend class MidiCCRackView;
|
||||
|
||||
} ;
|
||||
|
||||
@@ -319,10 +330,6 @@ public:
|
||||
return m_midiMenu;
|
||||
}
|
||||
|
||||
void freeInstrumentTrackWindow();
|
||||
|
||||
static void cleanupWindowCache();
|
||||
|
||||
// Create a menu for assigning/creating channels for this track
|
||||
QMenu * createFxMenu( QString title, QString newFxLabel ) override;
|
||||
|
||||
@@ -334,6 +341,7 @@ protected:
|
||||
|
||||
private slots:
|
||||
void toggleInstrumentWindow( bool _on );
|
||||
void toggleMidiCCRack();
|
||||
void activityIndicatorPressed();
|
||||
void activityIndicatorReleased();
|
||||
|
||||
@@ -344,12 +352,12 @@ private slots:
|
||||
void assignFxLine( int channelIndex );
|
||||
void createFxLine();
|
||||
|
||||
void handleConfigChange(QString cls, QString attr, QString value);
|
||||
|
||||
|
||||
private:
|
||||
InstrumentTrackWindow * m_window;
|
||||
|
||||
static QQueue<InstrumentTrackWindow *> s_windowCache;
|
||||
|
||||
// widgets in track-settings-widget
|
||||
TrackLabelButton * m_tlb;
|
||||
Knob * m_volumeKnob;
|
||||
@@ -361,9 +369,11 @@ private:
|
||||
QAction * m_midiInputAction;
|
||||
QAction * m_midiOutputAction;
|
||||
|
||||
std::unique_ptr<MidiCCRackView> m_midiCCRackView;
|
||||
|
||||
QPoint m_lastPos;
|
||||
|
||||
FadeButton * getActivityIndicator()
|
||||
FadeButton * getActivityIndicator() override
|
||||
{
|
||||
return m_activityIndicator;
|
||||
}
|
||||
@@ -477,6 +487,7 @@ private:
|
||||
PianoView * m_pianoView;
|
||||
|
||||
friend class InstrumentView;
|
||||
friend class InstrumentTrackView;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#ifndef KNOB_H
|
||||
#define KNOB_H
|
||||
|
||||
#include <memory>
|
||||
#include <QPixmap>
|
||||
#include <QWidget>
|
||||
#include <QtCore/QPoint>
|
||||
|
||||
@@ -41,6 +43,7 @@ enum knobTypes
|
||||
} ;
|
||||
|
||||
|
||||
void convertPixmapToGrayScale(QPixmap &pixMap);
|
||||
|
||||
class LMMS_EXPORT Knob : public QWidget, public FloatModelView
|
||||
{
|
||||
@@ -58,8 +61,12 @@ class LMMS_EXPORT Knob : public QWidget, public FloatModelView
|
||||
// Unfortunately, the gradient syntax doesn't create our gradient
|
||||
// correctly so we need to do this:
|
||||
Q_PROPERTY(QColor outerColor READ outerColor WRITE setOuterColor)
|
||||
Q_PROPERTY(QColor lineColor READ lineColor WRITE setlineColor)
|
||||
Q_PROPERTY(QColor arcColor READ arcColor WRITE setarcColor)
|
||||
|
||||
Q_PROPERTY(QColor lineActiveColor MEMBER m_lineActiveColor)
|
||||
Q_PROPERTY(QColor lineInactiveColor MEMBER m_lineInactiveColor)
|
||||
Q_PROPERTY(QColor arcActiveColor MEMBER m_arcActiveColor)
|
||||
Q_PROPERTY(QColor arcInactiveColor MEMBER m_arcInactiveColor)
|
||||
|
||||
mapPropertyFromModel(bool,isVolumeKnob,setVolumeKnob,m_volumeKnob);
|
||||
mapPropertyFromModel(float,volumeRatio,setVolumeRatio,m_volumeRatio);
|
||||
|
||||
@@ -74,7 +81,6 @@ public:
|
||||
Knob( knobTypes _knob_num, QWidget * _parent = NULL, const QString & _name = QString() );
|
||||
Knob( QWidget * _parent = NULL, const QString & _name = QString() ); //!< default ctor
|
||||
Knob( const Knob& other ) = delete;
|
||||
virtual ~Knob();
|
||||
|
||||
// TODO: remove
|
||||
inline void setHintText( const QString & _txt_before,
|
||||
@@ -108,10 +114,6 @@ public:
|
||||
|
||||
QColor outerColor() const;
|
||||
void setOuterColor( const QColor & c );
|
||||
QColor lineColor() const;
|
||||
void setlineColor( const QColor & c );
|
||||
QColor arcColor() const;
|
||||
void setarcColor( const QColor & c );
|
||||
|
||||
QColor textColor() const;
|
||||
void setTextColor( const QColor & c );
|
||||
@@ -134,6 +136,7 @@ protected:
|
||||
void mouseDoubleClickEvent( QMouseEvent * _me ) override;
|
||||
void paintEvent( QPaintEvent * _me ) override;
|
||||
void wheelEvent( QWheelEvent * _me ) override;
|
||||
void changeEvent(QEvent * ev) override;
|
||||
|
||||
virtual float getValue( const QPoint & _p );
|
||||
|
||||
@@ -143,7 +146,7 @@ private slots:
|
||||
void toggleScale();
|
||||
|
||||
private:
|
||||
QString displayValue() const;
|
||||
virtual QString displayValue() const;
|
||||
|
||||
void doConnections() override;
|
||||
|
||||
@@ -169,12 +172,11 @@ private:
|
||||
|
||||
QString m_label;
|
||||
|
||||
QPixmap * m_knobPixmap;
|
||||
std::unique_ptr<QPixmap> m_knobPixmap;
|
||||
BoolModel m_volumeKnob;
|
||||
FloatModel m_volumeRatio;
|
||||
|
||||
QPoint m_mouseOffset;
|
||||
QPoint m_origMousePos;
|
||||
QPoint m_lastMousePos; //!< mouse position in last mouseMoveEvent
|
||||
float m_leftOver;
|
||||
bool m_buttonPressed;
|
||||
|
||||
@@ -188,8 +190,11 @@ private:
|
||||
float m_outerRadius;
|
||||
float m_lineWidth;
|
||||
QColor m_outerColor;
|
||||
QColor m_lineColor; //!< unused yet
|
||||
QColor m_arcColor; //!< unused yet
|
||||
|
||||
QColor m_lineActiveColor;
|
||||
QColor m_lineInactiveColor;
|
||||
QColor m_arcActiveColor;
|
||||
QColor m_arcInactiveColor;
|
||||
|
||||
QColor m_textColor;
|
||||
|
||||
|
||||
@@ -73,8 +73,9 @@ protected:
|
||||
void mouseDoubleClickEvent( QMouseEvent * _me ) override;
|
||||
|
||||
private:
|
||||
float m_remainder; //!< floating offset of spinbox in [-0.5, 0.5]
|
||||
bool m_mouseMoving;
|
||||
QPoint m_origMousePos;
|
||||
QPoint m_lastMousePos; //!< mouse position in last mouseMoveEvent
|
||||
int m_displayOffset;
|
||||
void enterValue();
|
||||
|
||||
|
||||
@@ -71,6 +71,8 @@ protected:
|
||||
|
||||
void removeControl(const QString &key);
|
||||
|
||||
void removeFocusFromSearchBar();
|
||||
|
||||
private:
|
||||
class LinkedModelGroup* m_model;
|
||||
|
||||
@@ -96,7 +98,7 @@ protected:
|
||||
void modelChanged(class LinkedModelGroups* ctrlBase);
|
||||
|
||||
private:
|
||||
//! The base class must return the adressed group view,
|
||||
//! The base class must return the addressed group view,
|
||||
//! which has the same value as "this"
|
||||
virtual LinkedModelGroupView* getGroupView() = 0;
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
/**
|
||||
Base class for a group of linked models
|
||||
|
||||
See the LinkedModelGroup class for explenations
|
||||
See the LinkedModelGroup class for explanations
|
||||
|
||||
Features:
|
||||
* Models are stored by their QObject::objectName
|
||||
|
||||
@@ -28,27 +28,32 @@
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "lmms_export.h"
|
||||
#include "../src/3rdparty/ringbuffer/include/ringbuffer/ringbuffer.h"
|
||||
|
||||
|
||||
//! A convenience layer for a realtime-safe and thread-safe multi-reader ring buffer library.
|
||||
//! A convenience layer for a realtime-safe and thread-safe multi-reader ringbuffer
|
||||
template <class T>
|
||||
class LocklessRingBufferBase
|
||||
class LocklessRingBuffer
|
||||
{
|
||||
template<class _T>
|
||||
friend class LocklessRingBufferReader;
|
||||
public:
|
||||
LocklessRingBufferBase(std::size_t sz) : m_buffer(sz)
|
||||
LocklessRingBuffer(std::size_t sz) : m_buffer(sz)
|
||||
{
|
||||
m_buffer.touch(); // reserve storage space before realtime operation starts
|
||||
}
|
||||
~LocklessRingBufferBase() {};
|
||||
~LocklessRingBuffer() {};
|
||||
|
||||
std::size_t capacity() const {return m_buffer.maximum_eventual_write_space();}
|
||||
std::size_t free() const {return m_buffer.write_space();}
|
||||
void wakeAll() {m_notifier.wakeAll();}
|
||||
std::size_t write(const sampleFrame *src, std::size_t cnt, bool notify = false)
|
||||
{
|
||||
std::size_t written = LocklessRingBuffer<T>::m_buffer.write(src, cnt);
|
||||
// Let all waiting readers know new data are available.
|
||||
if (notify) {LocklessRingBuffer<T>::m_notifier.wakeAll();}
|
||||
return written;
|
||||
}
|
||||
|
||||
protected:
|
||||
ringbuffer_t<T> m_buffer;
|
||||
@@ -56,59 +61,6 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
// The SampleFrameCopier is required because sampleFrame is just a two-element
|
||||
// array and therefore does not have a copy constructor needed by std::copy.
|
||||
class SampleFrameCopier
|
||||
{
|
||||
const sampleFrame* m_src;
|
||||
public:
|
||||
SampleFrameCopier(const sampleFrame* src) : m_src(src) {}
|
||||
void operator()(std::size_t src_offset, std::size_t count, sampleFrame* dest)
|
||||
{
|
||||
for (std::size_t i = src_offset; i < src_offset + count; i++, dest++)
|
||||
{
|
||||
(*dest)[0] = m_src[i][0];
|
||||
(*dest)[1] = m_src[i][1];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! Standard ring buffer template for data types with copy constructor.
|
||||
template <class T>
|
||||
class LocklessRingBuffer : public LocklessRingBufferBase<T>
|
||||
{
|
||||
public:
|
||||
LocklessRingBuffer(std::size_t sz) : LocklessRingBufferBase<T>(sz) {};
|
||||
|
||||
std::size_t write(const sampleFrame *src, std::size_t cnt, bool notify = false)
|
||||
{
|
||||
std::size_t written = LocklessRingBufferBase<T>::m_buffer.write(src, cnt);
|
||||
// Let all waiting readers know new data are available.
|
||||
if (notify) {LocklessRingBufferBase<T>::m_notifier.wakeAll();}
|
||||
return written;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! Specialized ring buffer template with write function modified to support sampleFrame.
|
||||
template <>
|
||||
class LocklessRingBuffer<sampleFrame> : public LocklessRingBufferBase<sampleFrame>
|
||||
{
|
||||
public:
|
||||
LocklessRingBuffer(std::size_t sz) : LocklessRingBufferBase<sampleFrame>(sz) {};
|
||||
|
||||
std::size_t write(const sampleFrame *src, std::size_t cnt, bool notify = false)
|
||||
{
|
||||
SampleFrameCopier copier(src);
|
||||
std::size_t written = LocklessRingBufferBase<sampleFrame>::m_buffer.write_func<SampleFrameCopier>(copier, cnt);
|
||||
// Let all waiting readers know new data are available.
|
||||
if (notify) {LocklessRingBufferBase<sampleFrame>::m_notifier.wakeAll();}
|
||||
return written;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! Wrapper for lockless ringbuffer reader
|
||||
template <class T>
|
||||
class LocklessRingBufferReader : public ringbuffer_reader_t<T>
|
||||
|
||||
67
include/Lv2Basics.h
Normal file
67
include/Lv2Basics.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Lv2Basics.h - basic Lv2 utils
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 LV2BASICS_H
|
||||
#define LV2BASICS_H
|
||||
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
#include <lilv/lilv.h>
|
||||
#include <memory>
|
||||
#include <QString>
|
||||
#include <string>
|
||||
|
||||
struct LilvNodeDeleter
|
||||
{
|
||||
void operator()(LilvNode* n) { lilv_node_free(n); }
|
||||
};
|
||||
|
||||
struct LilvNodesDeleter
|
||||
{
|
||||
void operator()(LilvNodes* n) { lilv_nodes_free(n); }
|
||||
};
|
||||
|
||||
using AutoLilvNode = std::unique_ptr<LilvNode, LilvNodeDeleter>;
|
||||
using AutoLilvNodes = std::unique_ptr<LilvNodes, LilvNodesDeleter>;
|
||||
|
||||
/**
|
||||
Return QString from a plugin's node, everything will be freed automatically
|
||||
@param plug The plugin where the node is
|
||||
@param getFunc The function to return the node from the plugin
|
||||
*/
|
||||
QString qStringFromPluginNode(const LilvPlugin* plug,
|
||||
LilvNode * (*getFunc)(const LilvPlugin*));
|
||||
|
||||
//! Return port name as QString, everything will be freed automatically
|
||||
QString qStringFromPortName(const LilvPlugin* plug, const LilvPort* port);
|
||||
|
||||
//! Return port name as std::string, everything will be freed automatically
|
||||
std::string stdStringFromPortName(const LilvPlugin* plug, const LilvPort* port);
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
#endif // LV2BASICS_H
|
||||
158
include/Lv2ControlBase.h
Normal file
158
include/Lv2ControlBase.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Lv2ControlBase.h - Lv2 control base class
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 LV2_CONTROL_BASE_H
|
||||
#define LV2_CONTROL_BASE_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
#include <lilv/lilv.h>
|
||||
|
||||
#include "DataFile.h"
|
||||
#include "LinkedModelGroups.h"
|
||||
#include "lmms_export.h"
|
||||
#include "Plugin.h"
|
||||
|
||||
class Lv2Proc;
|
||||
class PluginIssue;
|
||||
|
||||
/**
|
||||
Common base class for Lv2 plugins
|
||||
|
||||
This class contains a vector of Lv2Proc, usually 1 (for stereo plugins) or
|
||||
2 (for mono plugins). Most of the logic is done there, this class primarily
|
||||
forwards work to the Lv2Proc and collects the results.
|
||||
|
||||
This class provides everything Lv2 plugins have in common. It's not
|
||||
named Lv2Plugin, because
|
||||
* it does not inherit Instrument
|
||||
* the Plugin subclass Effect does not inherit this class
|
||||
|
||||
This class would usually be a Model subclass. However, Qt doesn't allow
|
||||
this:
|
||||
* inheriting only from Model will cause diamond inheritance for QObject,
|
||||
which will cause errors with Q_OBJECT
|
||||
* making this a direct subclass of Instrument resp. EffectControls would
|
||||
require CRTP, which would make this class a template class, which would
|
||||
conflict with Q_OBJECT
|
||||
|
||||
The consequence is that this class can neither inherit QObject or Model, nor
|
||||
Instrument or EffectControls, which means in fact:
|
||||
* this class contains no signals or slots, but it offers stubs for slots
|
||||
that shall be called by child classes
|
||||
* this class can not override virtuals of Instrument or EffectControls, so
|
||||
it will offer functions that must be called by virtuals in its child class
|
||||
*/
|
||||
class LMMS_EXPORT Lv2ControlBase : public LinkedModelGroups
|
||||
{
|
||||
public:
|
||||
static Plugin::PluginTypes check(const LilvPlugin* m_plugin,
|
||||
std::vector<PluginIssue> &issues);
|
||||
|
||||
const LilvPlugin* getPlugin() const { return m_plugin; }
|
||||
|
||||
Lv2Proc *control(std::size_t idx) { return m_procs[idx].get(); }
|
||||
const Lv2Proc *control(std::size_t idx) const { return m_procs[idx].get(); }
|
||||
|
||||
bool hasGui() const { return m_hasGUI; }
|
||||
void setHasGui(bool val) { m_hasGUI = val; }
|
||||
|
||||
protected:
|
||||
/*
|
||||
ctor/dtor
|
||||
*/
|
||||
//! @param that the class inheriting this class and inheriting Model;
|
||||
//! this is the same pointer as this, but a different type
|
||||
//! @param uri the Lv2 URI telling this class what plugin to construct
|
||||
Lv2ControlBase(class Model *that, const QString& uri);
|
||||
Lv2ControlBase(const Lv2ControlBase&) = delete;
|
||||
~Lv2ControlBase() override;
|
||||
|
||||
Lv2ControlBase& operator=(const Lv2ControlBase&) = delete;
|
||||
|
||||
//! Must be checked after ctor or reload
|
||||
bool isValid() const { return m_valid; }
|
||||
|
||||
/*
|
||||
overrides
|
||||
*/
|
||||
LinkedModelGroup* getGroup(std::size_t idx) override;
|
||||
const LinkedModelGroup* getGroup(std::size_t idx) const override;
|
||||
|
||||
/*
|
||||
utils for the run thread
|
||||
*/
|
||||
//! Copy values from the LMMS core (connected models, MIDI events, ...) into
|
||||
//! the respective ports
|
||||
void copyModelsFromLmms();
|
||||
//! Bring values from all ports to the LMMS core
|
||||
void copyModelsToLmms() const;
|
||||
|
||||
//! Copy buffer passed by LMMS into our ports
|
||||
void copyBuffersFromLmms(const sampleFrame *buf, fpp_t frames);
|
||||
//! Copy our ports into buffers passed by LMMS
|
||||
void copyBuffersToLmms(sampleFrame *buf, fpp_t frames) const;
|
||||
//! Run the Lv2 plugin instance for @param frames frames
|
||||
void run(fpp_t frames);
|
||||
|
||||
/*
|
||||
load/save, must be called from virtuals
|
||||
*/
|
||||
void saveSettings(QDomDocument &doc, QDomElement &that);
|
||||
void loadSettings(const QDomElement &that);
|
||||
void loadFile(const QString &file);
|
||||
//! TODO: not implemented
|
||||
void reloadPlugin();
|
||||
|
||||
/*
|
||||
more functions that must be called from virtuals
|
||||
*/
|
||||
std::size_t controlCount() const;
|
||||
QString nodeName() const { return "lv2controls"; }
|
||||
bool hasNoteInput() const;
|
||||
void handleMidiInputEvent(const class MidiEvent &event,
|
||||
const class TimePos &time, f_cnt_t offset);
|
||||
|
||||
private:
|
||||
//! Return the DataFile settings type
|
||||
virtual DataFile::Types settingsType() = 0;
|
||||
//! Inform the plugin about a file name change
|
||||
virtual void setNameFromFile(const QString &fname) = 0;
|
||||
|
||||
//! Independent processors
|
||||
//! If this is a mono effect, the vector will have size 2 in order to
|
||||
//! fulfill LMMS' requirement of having stereo input and output
|
||||
std::vector<std::unique_ptr<Lv2Proc>> m_procs;
|
||||
|
||||
bool m_valid = true;
|
||||
bool m_hasGUI = false;
|
||||
unsigned m_channelsPerProc;
|
||||
|
||||
const LilvPlugin* m_plugin;
|
||||
};
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
#endif // LV2_CONTROL_BASE_H
|
||||
149
include/Lv2Evbuf.h
Normal file
149
include/Lv2Evbuf.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* lv2_evbuf.h - Lv2 event buffer definitions
|
||||
*
|
||||
* Copyright (c) 2019-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The original code was written by David Robillard <http://drobilla.net>
|
||||
* Original version: 6f22ee0 from https://github.com/drobilla/jalv.git
|
||||
* Minor changes have been done, but no functional changes.
|
||||
* Considering this as an "external library", the identifiers do not need to
|
||||
* match the LMMS coding conventions.
|
||||
*/
|
||||
|
||||
#ifndef LV2_EVBUF_H
|
||||
#define LV2_EVBUF_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
An abstract/opaque LV2 event buffer.
|
||||
*/
|
||||
typedef struct LV2_Evbuf_Impl LV2_Evbuf;
|
||||
|
||||
/**
|
||||
An iterator over an LV2_Evbuf.
|
||||
*/
|
||||
typedef struct {
|
||||
LV2_Evbuf* evbuf;
|
||||
uint32_t offset;
|
||||
} LV2_Evbuf_Iterator;
|
||||
|
||||
/**
|
||||
Allocate a new, empty event buffer.
|
||||
URIDs for atom:Chunk and atom:Sequence must be passed for LV2_EVBUF_ATOM.
|
||||
*/
|
||||
LV2_Evbuf*
|
||||
lv2_evbuf_new(uint32_t capacity, uint32_t atom_Chunk, uint32_t atom_Sequence);
|
||||
|
||||
/**
|
||||
Free an event buffer allocated with lv2_evbuf_new.
|
||||
*/
|
||||
void
|
||||
lv2_evbuf_free(LV2_Evbuf* evbuf);
|
||||
|
||||
/**
|
||||
Clear and initialize an existing event buffer.
|
||||
The contents of buf are ignored entirely and overwritten, except capacity
|
||||
which is unmodified.
|
||||
If input is false and this is an atom buffer, the buffer will be prepared
|
||||
for writing by the plugin. This MUST be called before every run cycle.
|
||||
*/
|
||||
void
|
||||
lv2_evbuf_reset(LV2_Evbuf* evbuf, bool input);
|
||||
|
||||
/**
|
||||
Return the total padded size of the events stored in the buffer.
|
||||
*/
|
||||
uint32_t
|
||||
lv2_evbuf_get_size(LV2_Evbuf* evbuf);
|
||||
|
||||
/**
|
||||
Return the actual buffer implementation.
|
||||
The format of the buffer returned depends on the buffer type.
|
||||
*/
|
||||
void*
|
||||
lv2_evbuf_get_buffer(LV2_Evbuf* evbuf);
|
||||
|
||||
/**
|
||||
Return an iterator to the start of `evbuf`.
|
||||
*/
|
||||
LV2_Evbuf_Iterator
|
||||
lv2_evbuf_begin(LV2_Evbuf* evbuf);
|
||||
|
||||
/**
|
||||
Return an iterator to the end of `evbuf`.
|
||||
*/
|
||||
LV2_Evbuf_Iterator
|
||||
lv2_evbuf_end(LV2_Evbuf* evbuf);
|
||||
|
||||
/**
|
||||
Check if `iter` is valid.
|
||||
@return True if `iter` is valid, otherwise false (past end of buffer)
|
||||
*/
|
||||
bool
|
||||
lv2_evbuf_is_valid(LV2_Evbuf_Iterator iter);
|
||||
|
||||
/**
|
||||
Advance `iter` forward one event.
|
||||
`iter` must be valid.
|
||||
@return True if `iter` is valid, otherwise false (reached end of buffer)
|
||||
*/
|
||||
LV2_Evbuf_Iterator
|
||||
lv2_evbuf_next(LV2_Evbuf_Iterator iter);
|
||||
|
||||
/**
|
||||
Dereference an event iterator (i.e. get the event currently pointed to).
|
||||
`iter` must be valid.
|
||||
`type` Set to the type of the event.
|
||||
`size` Set to the size of the event.
|
||||
`data` Set to the contents of the event.
|
||||
@return True on success.
|
||||
*/
|
||||
bool
|
||||
lv2_evbuf_get( LV2_Evbuf_Iterator iter,
|
||||
uint32_t* frames,
|
||||
uint32_t* type,
|
||||
uint32_t* size,
|
||||
uint8_t** data);
|
||||
|
||||
/**
|
||||
Write an event at `iter`.
|
||||
The event (if any) pointed to by `iter` will be overwritten, and `iter`
|
||||
incremented to point to the following event (i.e. several calls to this
|
||||
function can be done in sequence without twiddling iter in-between).
|
||||
@return True if event was written, otherwise false (buffer is full).
|
||||
*/
|
||||
bool
|
||||
lv2_evbuf_write( LV2_Evbuf_Iterator* iter,
|
||||
uint32_t frames,
|
||||
uint32_t type,
|
||||
uint32_t size,
|
||||
const uint8_t* data);
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
|
||||
#endif // LV2_EVBUF_H
|
||||
81
include/Lv2Features.h
Normal file
81
include/Lv2Features.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Lv2Features.h - Lv2Features class
|
||||
*
|
||||
* Copyright (c) 2020-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 LV2FEATURES_H
|
||||
#define LV2FEATURES_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
#include <lv2.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "Lv2Manager.h"
|
||||
|
||||
/**
|
||||
Feature container
|
||||
|
||||
References all available features for a plugin and maps them to their URIs.
|
||||
|
||||
The public member functions should be called in descending order:
|
||||
|
||||
1. initCommon: map plugin-common features
|
||||
2. operator[]: map plugin-specific features
|
||||
3. createFeatureVectors: create the feature vectors required for
|
||||
lilv_plugin_instantiate
|
||||
4. access the latter
|
||||
*/
|
||||
class Lv2Features
|
||||
{
|
||||
public:
|
||||
//! Return if a feature is supported by LMMS
|
||||
static bool isFeatureSupported(const char *featName);
|
||||
|
||||
Lv2Features();
|
||||
|
||||
//! Register only plugin-common features
|
||||
void initCommon();
|
||||
//! Return reference to feature data with given URI featName
|
||||
void*& operator[](const char* featName);
|
||||
//! Fill m_features and m_featurePointers with all features
|
||||
void createFeatureVectors();
|
||||
//! Return LV2_Feature pointer vector, suited for lilv_plugin_instantiate
|
||||
const LV2_Feature* const* featurePointers() const
|
||||
{
|
||||
return m_featurePointers.data();
|
||||
}
|
||||
|
||||
private:
|
||||
//! feature storage
|
||||
std::vector<LV2_Feature> m_features;
|
||||
//! pointers to m_features, required for lilv_plugin_instantiate
|
||||
std::vector<const LV2_Feature*> m_featurePointers;
|
||||
//! features + data, ordered by URI
|
||||
std::map<const char*, void*, Lv2Manager::CmpStr> m_featureByUri;
|
||||
};
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
|
||||
#endif // LV2FEATURES_H
|
||||
163
include/Lv2Manager.h
Normal file
163
include/Lv2Manager.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Lv2Manager.h - Implementation of Lv2Manager class
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 LV2MANAGER_H
|
||||
#define LV2MANAGER_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <lilv/lilv.h>
|
||||
|
||||
#include "Lv2Basics.h"
|
||||
#include "Lv2UridCache.h"
|
||||
#include "Lv2UridMap.h"
|
||||
#include "Plugin.h"
|
||||
|
||||
|
||||
/*
|
||||
all Lv2 classes in relation (use our "4 spaces per tab rule" to view):
|
||||
|
||||
explanation:
|
||||
"x = {y z}" means class "x" consists of classes "y" and "z"
|
||||
(and probably other classes not mentioned)
|
||||
"x = {y*}" means class "x" references/uses class "y"
|
||||
|
||||
core:
|
||||
Lv2Proc = {LilvInstance}
|
||||
Lv2ControlBase = {Lv2Proc, Lv2Proc... (2 for mono, 1 for stereo)}
|
||||
Lv2Manager = {LilvPlugin*, LilvPlugin* ...}
|
||||
(creates Lv2ControlBase, Lv2ControlBase...)
|
||||
|
||||
Lv2FxControls = {Lv2ControlBase}
|
||||
Lv2Effect = {Effect + Lv2FxControls}
|
||||
(takes Lv2SubPluginFeatures in ctor)
|
||||
Lv2Instrument = {Instrument + Lv2ControlBase}
|
||||
(takes Lv2SubPluginFeatures in ctor)
|
||||
|
||||
gui:
|
||||
Lv2ViewProc = {Lv2Proc*}
|
||||
Lv2ViewBase = {Lv2ViewProc, Lv2ViewProc...
|
||||
(2 for mono, 1 for stereo)}
|
||||
Lv2FxControlDialog = {EffectControlDialog + Lv2ViewBase}
|
||||
Lv2InsView = {InstrumentView + Lv2ViewBase}
|
||||
|
||||
Lv2SubPluginFeatures:
|
||||
Lv2SubPluginFeatures = {Lv2Manager*}
|
||||
Lv2Effect::Descriptor = {Lv2SubPluginFeatures}
|
||||
Lv2Instrument::Descriptor = {Lv2SubPluginFeatures}
|
||||
*/
|
||||
|
||||
|
||||
//! Class to keep track of all LV2 plugins
|
||||
class Lv2Manager
|
||||
{
|
||||
public:
|
||||
void initPlugins();
|
||||
|
||||
Lv2Manager();
|
||||
~Lv2Manager();
|
||||
|
||||
|
||||
AutoLilvNode uri(const char* uriStr);
|
||||
|
||||
//! Class representing info for one plugin
|
||||
struct Lv2Info
|
||||
{
|
||||
public:
|
||||
//! use only for std::map internals
|
||||
Lv2Info() : m_plugin(nullptr) {}
|
||||
//! ctor used inside Lv2Manager
|
||||
Lv2Info(const LilvPlugin* plug, Plugin::PluginTypes type, bool valid) :
|
||||
m_plugin(plug), m_type(type), m_valid(valid) {}
|
||||
Lv2Info(Lv2Info&& other) = default;
|
||||
Lv2Info& operator=(Lv2Info&& other) = default;
|
||||
|
||||
const LilvPlugin* plugin() const { return m_plugin; }
|
||||
Plugin::PluginTypes type() const { return m_type; }
|
||||
bool isValid() const { return m_valid; }
|
||||
|
||||
private:
|
||||
const LilvPlugin* m_plugin;
|
||||
Plugin::PluginTypes m_type;
|
||||
bool m_valid = false;
|
||||
};
|
||||
|
||||
//! Return descriptor with URI @p uri or nullptr if none exists
|
||||
const LilvPlugin *getPlugin(const std::string &uri);
|
||||
//! Return descriptor with URI @p uri or nullptr if none exists
|
||||
const LilvPlugin *getPlugin(const QString& uri);
|
||||
|
||||
using Lv2InfoMap = std::map<std::string, Lv2Info>;
|
||||
using Iterator = Lv2InfoMap::iterator;
|
||||
Iterator begin() { return m_lv2InfoMap.begin(); }
|
||||
Iterator end() { return m_lv2InfoMap.end(); }
|
||||
|
||||
//! strcmp based key comparator for std::set and std::map
|
||||
struct CmpStr
|
||||
{
|
||||
bool operator()(char const *a, char const *b) const;
|
||||
};
|
||||
|
||||
UridMap& uridMap() { return m_uridMap; }
|
||||
const Lv2UridCache& uridCache() const { return m_uridCache; }
|
||||
const std::set<const char*, CmpStr>& supportedFeatureURIs() const
|
||||
{
|
||||
return m_supportedFeatureURIs;
|
||||
}
|
||||
bool isFeatureSupported(const char* featName) const;
|
||||
AutoLilvNodes findNodes(const LilvNode *subject,
|
||||
const LilvNode *predicate, const LilvNode *object);
|
||||
|
||||
static const std::set<const char*, Lv2Manager::CmpStr>& getPluginBlacklist()
|
||||
{
|
||||
return pluginBlacklist;
|
||||
}
|
||||
|
||||
private:
|
||||
// general data
|
||||
bool m_debug; //!< if set, debug output will be printed
|
||||
LilvWorld* m_world;
|
||||
Lv2InfoMap m_lv2InfoMap;
|
||||
std::set<const char*, CmpStr> m_supportedFeatureURIs;
|
||||
|
||||
// feature data that are common for all Lv2Proc
|
||||
UridMap m_uridMap;
|
||||
|
||||
// URID cache for fast URID access
|
||||
Lv2UridCache m_uridCache;
|
||||
|
||||
// static
|
||||
static const std::set<const char*, Lv2Manager::CmpStr> pluginBlacklist;
|
||||
|
||||
// functions
|
||||
bool isSubclassOf(const LilvPluginClass *clvss, const char *uriStr);
|
||||
};
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
|
||||
#endif // LV2MANAGER_H
|
||||
104
include/Lv2Options.h
Normal file
104
include/Lv2Options.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Lv2Options.h - Lv2Options class
|
||||
*
|
||||
* Copyright (c) 2020-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 LV2OPTIONS_H
|
||||
#define LV2OPTIONS_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
#include <cstdint>
|
||||
#include <lv2/lv2plug.in/ns/ext/options/options.h>
|
||||
#include <lv2/lv2plug.in/ns/ext/urid/urid.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "Engine.h"
|
||||
#include "Lv2Manager.h"
|
||||
#include "Lv2UridCache.h"
|
||||
|
||||
/**
|
||||
Option container
|
||||
|
||||
References all available options for a plugin and maps them to their URIDs.
|
||||
This class is used per Lv2 processor (justification in Lv2Proc::initMOptions())
|
||||
|
||||
The public member functions should be called in descending order:
|
||||
|
||||
1. supportOption: set all supported option URIDs
|
||||
2. initOption: initialize options with values
|
||||
3. createOptionVectors: create the option vectors required for
|
||||
the feature
|
||||
4. access the latter using feature()
|
||||
*/
|
||||
class Lv2Options
|
||||
{
|
||||
public:
|
||||
//! Return if an option is supported by LMMS
|
||||
static bool isOptionSupported(LV2_URID key);
|
||||
//! Mark option as supported
|
||||
static void supportOption(LV2_URID key);
|
||||
|
||||
//! Initialize an option
|
||||
template<typename Opt, typename Arg>
|
||||
void initOption(Lv2UridCache::Id key, Arg&& value,
|
||||
LV2_Options_Context context = LV2_OPTIONS_INSTANCE,
|
||||
std::uint32_t subject = 0)
|
||||
{
|
||||
const Lv2UridCache& cache = Engine::getLv2Manager()->uridCache();
|
||||
initOption(cache[key], sizeof(Opt), cache[Lv2UridCache::IdForType<Opt>::value],
|
||||
std::make_shared<Opt>(std::forward<Arg>(value)), context, subject);
|
||||
}
|
||||
//! Fill m_options and m_optionPointers with all options
|
||||
void createOptionVectors();
|
||||
//! Return the feature
|
||||
const LV2_Options_Option* feature() const
|
||||
{
|
||||
return m_options.data();
|
||||
}
|
||||
|
||||
private:
|
||||
//! Initialize an option internally
|
||||
void initOption(LV2_URID key,
|
||||
uint32_t size,
|
||||
LV2_URID type,
|
||||
std::shared_ptr<void> value,
|
||||
LV2_Options_Context context = LV2_OPTIONS_INSTANCE,
|
||||
uint32_t subject = 0);
|
||||
//! options that are supported by every processor
|
||||
static std::set<LV2_URID> s_supportedOptions;
|
||||
//! options + data, ordered by URID
|
||||
std::map<LV2_URID, LV2_Options_Option> m_optionByUrid;
|
||||
//! option storage
|
||||
std::vector<LV2_Options_Option> m_options;
|
||||
//! option value storage
|
||||
std::map<LV2_URID, std::shared_ptr<void>> m_optionValues;
|
||||
};
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
|
||||
#endif // LV2OPTIONS_H
|
||||
265
include/Lv2Ports.h
Normal file
265
include/Lv2Ports.h
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Lv2Ports.h - Lv2 port classes definitions
|
||||
*
|
||||
* Copyright (c) 2019-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 LV2PORTS_H
|
||||
#define LV2PORTS_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
#include <lilv/lilv.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "PluginIssue.h"
|
||||
|
||||
struct ConnectPortVisitor;
|
||||
typedef struct LV2_Evbuf_Impl LV2_Evbuf;
|
||||
|
||||
namespace Lv2Ports {
|
||||
|
||||
/*
|
||||
port structs
|
||||
*/
|
||||
enum class Flow {
|
||||
Unknown,
|
||||
Input,
|
||||
Output
|
||||
};
|
||||
|
||||
enum class Type {
|
||||
Unknown,
|
||||
Control,
|
||||
Audio,
|
||||
AtomSeq,
|
||||
Cv //!< TODO: unused, describe
|
||||
};
|
||||
|
||||
//! Port visualization
|
||||
//! @note All Lv2 audio ports are float, this is only the visualisation
|
||||
enum class Vis {
|
||||
Generic, //!< nothing specific, a generic knob or slider shall be used
|
||||
Integer, //!< counter
|
||||
Enumeration, //!< selection from enumerated values
|
||||
Toggled //!< boolean widget
|
||||
};
|
||||
|
||||
const char* toStr(Lv2Ports::Flow pf);
|
||||
const char* toStr(Lv2Ports::Type pt);
|
||||
const char* toStr(Lv2Ports::Vis pv);
|
||||
|
||||
struct ControlPortBase;
|
||||
struct Control;
|
||||
struct Audio;
|
||||
struct Cv;
|
||||
struct AtomSeq;
|
||||
struct Unknown;
|
||||
|
||||
struct ConstVisitor
|
||||
{
|
||||
virtual void visit(const Lv2Ports::ControlPortBase& ) {}
|
||||
virtual void visit(const Lv2Ports::Control& ) {}
|
||||
virtual void visit(const Lv2Ports::Audio& ) {}
|
||||
virtual void visit(const Lv2Ports::Cv& ) {}
|
||||
virtual void visit(const Lv2Ports::AtomSeq& ) {}
|
||||
virtual void visit(const Lv2Ports::Unknown& ) {}
|
||||
|
||||
virtual ~ConstVisitor();
|
||||
};
|
||||
|
||||
struct Visitor
|
||||
{
|
||||
virtual void visit(Lv2Ports::ControlPortBase& ) {}
|
||||
virtual void visit(Lv2Ports::Control& ) {}
|
||||
virtual void visit(Lv2Ports::Audio& ) {}
|
||||
virtual void visit(Lv2Ports::Cv& ) {}
|
||||
virtual void visit(Lv2Ports::AtomSeq& ) {}
|
||||
virtual void visit(Lv2Ports::Unknown& ) {}
|
||||
|
||||
virtual ~Visitor();
|
||||
};
|
||||
|
||||
struct Meta
|
||||
{
|
||||
Type m_type = Type::Unknown;
|
||||
Flow m_flow = Flow::Unknown;
|
||||
Vis m_vis = Vis::Generic;
|
||||
|
||||
bool m_logarithmic = false;
|
||||
|
||||
bool m_optional = false;
|
||||
bool m_used = true;
|
||||
|
||||
std::vector<PluginIssue> get(const LilvPlugin* plugin, std::size_t portNum);
|
||||
|
||||
float def() const { return m_def; }
|
||||
float min(sample_rate_t sr) const { return m_sampleRate ? sr * m_min : m_min; }
|
||||
float max(sample_rate_t sr) const { return m_sampleRate ? sr * m_max : m_max; }
|
||||
private:
|
||||
float m_def = .0f, m_min = .0f, m_max = .0f;
|
||||
bool m_sampleRate = false;
|
||||
};
|
||||
|
||||
struct PortBase : public Meta
|
||||
{
|
||||
const LilvPort* m_port = nullptr;
|
||||
const LilvPlugin* m_plugin = nullptr;
|
||||
|
||||
virtual void accept(Visitor& v) = 0;
|
||||
virtual void accept(ConstVisitor& v) const = 0;
|
||||
|
||||
QString name() const;
|
||||
QString uri() const;
|
||||
|
||||
virtual ~PortBase();
|
||||
};
|
||||
|
||||
template<typename Derived, typename Base>
|
||||
struct VisitablePort : public Base
|
||||
{
|
||||
void accept(Visitor& v) override { v.visit(static_cast<Derived&>(*this)); }
|
||||
void accept(ConstVisitor& v) const override { v.visit(static_cast<const Derived&>(*this)); }
|
||||
};
|
||||
|
||||
struct ControlPortBase : public VisitablePort<ControlPortBase, PortBase>
|
||||
{
|
||||
//! LMMS models
|
||||
//! Always up-to-date, except during runs
|
||||
std::unique_ptr<class AutomatableModel> m_connectedModel;
|
||||
|
||||
//! Enumerate float values
|
||||
//! lv2 defines scale points as
|
||||
//! "single float Points (for control inputs)"
|
||||
std::vector<float> m_scalePointMap;
|
||||
};
|
||||
|
||||
struct Control : public VisitablePort<Control, ControlPortBase>
|
||||
{
|
||||
//! Data location which Lv2 plugins see
|
||||
//! Model values are being copied here every run
|
||||
//! Between runs, this data is not up-to-date
|
||||
float m_val;
|
||||
};
|
||||
|
||||
struct Cv : public VisitablePort<Cv, ControlPortBase>
|
||||
{
|
||||
//! Data location which Lv2 plugins see
|
||||
//! Model values are being copied here every run
|
||||
//! Between runs, this data is not up-to-date
|
||||
std::vector<float> m_buffer;
|
||||
};
|
||||
|
||||
struct Audio : public VisitablePort<Audio, PortBase>
|
||||
{
|
||||
Audio(std::size_t bufferSize, bool isSidechain);
|
||||
|
||||
//! Copy buffer passed by LMMS into our ports
|
||||
//! @param channel channel index into each sample frame
|
||||
void copyBuffersFromCore(const sampleFrame *lmmsBuf,
|
||||
unsigned channel, fpp_t frames);
|
||||
//! Add buffer passed by LMMS into our ports, and halve the result
|
||||
//! @param channel channel index into each sample frame
|
||||
void averageWithBuffersFromCore(const sampleFrame *lmmsBuf,
|
||||
unsigned channel, fpp_t frames);
|
||||
//! Copy our ports into buffers passed by LMMS
|
||||
//! @param channel channel index into each sample frame
|
||||
void copyBuffersToCore(sampleFrame *lmmsBuf,
|
||||
unsigned channel, fpp_t frames) const;
|
||||
|
||||
bool isSideChain() const { return m_sidechain; }
|
||||
bool isOptional() const { return m_optional; }
|
||||
bool mustBeUsed() const { return !isSideChain() && !isOptional(); }
|
||||
std::size_t bufferSize() const { return m_buffer.size(); }
|
||||
|
||||
private:
|
||||
//! the buffer where Lv2 reads/writes the data from/to
|
||||
std::vector<float> m_buffer;
|
||||
bool m_sidechain;
|
||||
|
||||
// the only case when data of m_buffer may be referenced:
|
||||
friend struct ::ConnectPortVisitor;
|
||||
};
|
||||
|
||||
struct AtomSeq : public VisitablePort<AtomSeq, PortBase>
|
||||
{
|
||||
enum FlagType
|
||||
{
|
||||
None = 0,
|
||||
Midi = 1
|
||||
};
|
||||
unsigned flags = FlagType::None;
|
||||
|
||||
struct Lv2EvbufDeleter
|
||||
{
|
||||
void operator()(LV2_Evbuf* n);
|
||||
};
|
||||
using AutoLv2Evbuf = std::unique_ptr<LV2_Evbuf, Lv2EvbufDeleter>;
|
||||
AutoLv2Evbuf m_buf;
|
||||
};
|
||||
|
||||
struct Unknown : public VisitablePort<Unknown, PortBase>
|
||||
{
|
||||
};
|
||||
|
||||
/*
|
||||
port casts
|
||||
*/
|
||||
template<class Target>
|
||||
struct DCastVisitor : public Visitor
|
||||
{
|
||||
Target* m_result = nullptr;
|
||||
void visit(Target& tar) { m_result = &tar; }
|
||||
};
|
||||
|
||||
template<class Target>
|
||||
struct ConstDCastVisitor : public ConstVisitor
|
||||
{
|
||||
const Target* m_result = nullptr;
|
||||
void visit(const Target& tar) { m_result = &tar; }
|
||||
};
|
||||
|
||||
//! If you don't want to use a whole visitor, you can use dcast
|
||||
template<class Target>
|
||||
Target* dcast(PortBase* base)
|
||||
{
|
||||
DCastVisitor<Target> vis;
|
||||
base->accept(vis);
|
||||
return vis.m_result;
|
||||
}
|
||||
|
||||
//! const overload
|
||||
template<class Target>
|
||||
const Target* dcast(const PortBase* base)
|
||||
{
|
||||
ConstDCastVisitor<Target> vis;
|
||||
base->accept(vis);
|
||||
return vis.m_result;
|
||||
}
|
||||
|
||||
} // namespace Lv2Ports
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
#endif // LV2PORTS_H
|
||||
217
include/Lv2Proc.h
Normal file
217
include/Lv2Proc.h
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Lv2Proc.h - Lv2 processor class
|
||||
*
|
||||
* Copyright (c) 2019-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 LV2PROC_H
|
||||
#define LV2PROC_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
#include <lilv/lilv.h>
|
||||
#include <memory>
|
||||
#include <QObject>
|
||||
|
||||
#include "Lv2Basics.h"
|
||||
#include "Lv2Features.h"
|
||||
#include "Lv2Options.h"
|
||||
#include "LinkedModelGroups.h"
|
||||
#include "MidiEvent.h"
|
||||
#include "Plugin.h"
|
||||
#include "PluginIssue.h"
|
||||
#include "../src/3rdparty/ringbuffer/include/ringbuffer/ringbuffer.h"
|
||||
#include "TimePos.h"
|
||||
|
||||
// forward declare port structs/enums
|
||||
namespace Lv2Ports
|
||||
{
|
||||
struct Audio;
|
||||
struct PortBase;
|
||||
struct AtomSeq;
|
||||
|
||||
enum class Type;
|
||||
enum class Flow;
|
||||
enum class Vis;
|
||||
}
|
||||
|
||||
|
||||
//! Class representing one Lv2 processor, i.e. one Lv2 handle
|
||||
//! For Mono effects, 1 Lv2ControlBase references 2 Lv2Proc
|
||||
class Lv2Proc : public LinkedModelGroup
|
||||
{
|
||||
public:
|
||||
static Plugin::PluginTypes check(const LilvPlugin* plugin,
|
||||
std::vector<PluginIssue> &issues);
|
||||
|
||||
/*
|
||||
ctor/dtor
|
||||
*/
|
||||
Lv2Proc(const LilvPlugin* plugin, Model *parent);
|
||||
~Lv2Proc() override;
|
||||
//! Must be checked after ctor or reload
|
||||
bool isValid() const { return m_valid; }
|
||||
|
||||
/*
|
||||
port access
|
||||
*/
|
||||
struct StereoPortRef
|
||||
{
|
||||
//! mono port or left port in case of stereo
|
||||
Lv2Ports::Audio* m_left = nullptr;
|
||||
//! unused, or right port in case of stereo
|
||||
Lv2Ports::Audio* m_right = nullptr;
|
||||
};
|
||||
|
||||
StereoPortRef& inPorts() { return m_inPorts; }
|
||||
const StereoPortRef& inPorts() const { return m_inPorts; }
|
||||
StereoPortRef& outPorts() { return m_outPorts; }
|
||||
const StereoPortRef& outPorts() const { return m_outPorts; }
|
||||
template<class Functor>
|
||||
void foreach_port(const Functor& ftor)
|
||||
{
|
||||
for (std::unique_ptr<Lv2Ports::PortBase>& port : m_ports)
|
||||
{
|
||||
ftor(port.get());
|
||||
}
|
||||
}
|
||||
template<class Functor>
|
||||
void foreach_port(const Functor& ftor) const
|
||||
{
|
||||
for (const std::unique_ptr<Lv2Ports::PortBase>& port : m_ports)
|
||||
{
|
||||
ftor(port.get());
|
||||
}
|
||||
}
|
||||
|
||||
//! Debug function to print ports to stdout
|
||||
void dumpPorts();
|
||||
|
||||
/*
|
||||
utils for the run thread
|
||||
*/
|
||||
//! Copy values from the LMMS core (connected models, MIDI events, ...) into
|
||||
//! the respective ports
|
||||
void copyModelsFromCore();
|
||||
//! Bring values from all ports to the LMMS core
|
||||
void copyModelsToCore();
|
||||
/**
|
||||
* Copy buffer passed by the core into our ports
|
||||
* @param buf buffer of sample frames, each sample frame is something like
|
||||
* a `float[<number-of-procs> * <channels per proc>]` array.
|
||||
* @param firstChan The offset for @p buf where we have to read our
|
||||
* first channel.
|
||||
* This marks the first sample in each sample frame where we read from.
|
||||
* If we are the 2nd of 2 mono procs, this can be greater than 0.
|
||||
* @param num Number of channels we must read from @param buf (starting at
|
||||
* @p offset)
|
||||
*/
|
||||
void copyBuffersFromCore(const sampleFrame *buf,
|
||||
unsigned firstChan, unsigned num, fpp_t frames);
|
||||
/**
|
||||
* Copy our ports into buffers passed by the core
|
||||
* @param buf buffer of sample frames, each sample frame is something like
|
||||
* a `float[<number-of-procs> * <channels per proc>]` array.
|
||||
* @param firstChan The offset for @p buf where we have to write our
|
||||
* first channel.
|
||||
* This marks the first sample in each sample frame where we write to.
|
||||
* If we are the 2nd of 2 mono procs, this can be greater than 0.
|
||||
* @param num Number of channels we must write to @param buf (starting at
|
||||
* @p offset)
|
||||
*/
|
||||
void copyBuffersToCore(sampleFrame *buf, unsigned firstChan, unsigned num,
|
||||
fpp_t frames) const;
|
||||
//! Run the Lv2 plugin instance for @param frames frames
|
||||
void run(fpp_t frames);
|
||||
|
||||
void handleMidiInputEvent(const class MidiEvent &event,
|
||||
const TimePos &time, f_cnt_t offset);
|
||||
|
||||
/*
|
||||
misc
|
||||
*/
|
||||
class AutomatableModel *modelAtPort(const QString &uri); // unused currently
|
||||
std::size_t controlCount() const { return LinkedModelGroup::modelNum(); }
|
||||
bool hasNoteInput() const;
|
||||
|
||||
protected:
|
||||
/*
|
||||
load and save
|
||||
*/
|
||||
//! Create ports and instance, connect ports, activate plugin
|
||||
void initPlugin();
|
||||
//! Deactivate instance
|
||||
void shutdownPlugin();
|
||||
|
||||
private:
|
||||
bool m_valid = true;
|
||||
|
||||
const LilvPlugin* m_plugin;
|
||||
LilvInstance* m_instance;
|
||||
Lv2Features m_features;
|
||||
Lv2Options m_options;
|
||||
|
||||
// full list of ports
|
||||
std::vector<std::unique_ptr<Lv2Ports::PortBase>> m_ports;
|
||||
// quick reference to specific, unique ports
|
||||
StereoPortRef m_inPorts, m_outPorts;
|
||||
Lv2Ports::AtomSeq *m_midiIn = nullptr, *m_midiOut = nullptr;
|
||||
|
||||
// MIDI
|
||||
// many things here may be moved into the `Instrument` class
|
||||
constexpr const static std::size_t m_maxMidiInputEvents = 1024;
|
||||
//! spinlock for the MIDI ringbuffer (for MIDI events going to the plugin)
|
||||
std::atomic_flag m_ringLock = ATOMIC_FLAG_INIT;
|
||||
|
||||
//! MIDI ringbuffer (for MIDI events going to the plugin)
|
||||
ringbuffer_t<struct MidiInputEvent> m_midiInputBuf;
|
||||
//! MIDI ringbuffer reader
|
||||
ringbuffer_reader_t<struct MidiInputEvent> m_midiInputReader;
|
||||
|
||||
// other
|
||||
static int32_t defaultEvbufSize() { return 1 << 15; /* ardour uses this*/ }
|
||||
|
||||
//! models for the controls, sorted by port symbols
|
||||
std::map<std::string, AutomatableModel *> m_connectedModels;
|
||||
|
||||
void initMOptions(); //!< initialize m_options
|
||||
void initPluginSpecificFeatures();
|
||||
|
||||
//! load a file in the plugin, but don't do anything in LMMS
|
||||
void loadFileInternal(const QString &file);
|
||||
//! allocate m_ports, fill all with metadata, and assign meaning of ports
|
||||
void createPorts();
|
||||
//! fill m_ports[portNum] with metadata
|
||||
void createPort(std::size_t portNum);
|
||||
//! connect m_ports[portNum] with Lv2
|
||||
void connectPort(std::size_t num);
|
||||
|
||||
void dumpPort(std::size_t num);
|
||||
|
||||
static bool portIsSideChain(const LilvPlugin* plugin, const LilvPort *port);
|
||||
static bool portIsOptional(const LilvPlugin* plugin, const LilvPort *port);
|
||||
static AutoLilvNode uri(const char* uriStr);
|
||||
};
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
#endif // LV2PROC_H
|
||||
62
include/Lv2SubPluginFeatures.h
Normal file
62
include/Lv2SubPluginFeatures.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Lv2SubPluginFeatures.h - derivation from
|
||||
* Plugin::Descriptor::SubPluginFeatures for
|
||||
* hosting LV2 plugins
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 LV2_SUBPLUGIN_FEATURES_H
|
||||
#define LV2_SUBPLUGIN_FEATURES_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
#include <lilv/lilv.h>
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "Plugin.h"
|
||||
|
||||
class LMMS_EXPORT Lv2SubPluginFeatures : public Plugin::Descriptor::SubPluginFeatures
|
||||
{
|
||||
private:
|
||||
static const LilvPlugin *getPlugin(const Key &k);
|
||||
static QString pluginName(const LilvPlugin *plug);
|
||||
|
||||
public:
|
||||
Lv2SubPluginFeatures(Plugin::PluginTypes type);
|
||||
|
||||
void fillDescriptionWidget(
|
||||
QWidget *parent, const Key *k) const override;
|
||||
|
||||
QString additionalFileExtensions(const Key &k) const override;
|
||||
QString displayName(const Key &k) const override;
|
||||
QString description(const Key &k) const override;
|
||||
const PixmapLoader *logo(const Key &k) const override;
|
||||
|
||||
void listSubPluginKeys(
|
||||
const Plugin::Descriptor *desc, KeyList &kl) const override;
|
||||
};
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
|
||||
#endif
|
||||
70
include/Lv2UridCache.h
Normal file
70
include/Lv2UridCache.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Lv2UridCache.h - Lv2UridCache definition
|
||||
*
|
||||
* Copyright (c) 2020-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 LV2URIDCACHE_H
|
||||
#define LV2URIDCACHE_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <cstdint>
|
||||
|
||||
//! Cached URIDs for fast access (for use in real-time code)
|
||||
class Lv2UridCache
|
||||
{
|
||||
public:
|
||||
enum class Id //!< ID for m_uridCache array
|
||||
{
|
||||
// keep it alphabetically (except "size" at the end)
|
||||
atom_Float,
|
||||
atom_Int,
|
||||
bufsz_minBlockLength,
|
||||
bufsz_maxBlockLength,
|
||||
bufsz_nominalBlockLength,
|
||||
bufsz_sequenceSize,
|
||||
midi_MidiEvent,
|
||||
param_sampleRate,
|
||||
// exception to alphabetic ordering - keep at the end:
|
||||
size
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct IdForType;
|
||||
|
||||
//! Return URID for a cache ID
|
||||
uint32_t operator[](Id id) const;
|
||||
|
||||
Lv2UridCache(class UridMap& mapper);
|
||||
|
||||
private:
|
||||
uint32_t m_cache[static_cast<int>(Id::size)];
|
||||
};
|
||||
|
||||
template<> struct Lv2UridCache::IdForType<float> { static constexpr auto value = Id::atom_Float; };
|
||||
template<> struct Lv2UridCache::IdForType<std::int32_t> { static constexpr auto value = Id::atom_Int; };
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
#endif // LV2URIDCACHE_H
|
||||
70
include/Lv2UridMap.h
Normal file
70
include/Lv2UridMap.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Lv2UridMap.cpp - Lv2UridMap class
|
||||
*
|
||||
* Copyright (c) 2019 Johannes Lorenz <j.git$$$lorenz-ho.me, $$$=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 LV2URIDMAP_H
|
||||
#define LV2URIDMAP_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
#include <lv2/lv2plug.in/ns/ext/urid/urid.h>
|
||||
#include <mutex> // TODO: use semaphore, even though this is not realtime critical
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Complete implementation of the Lv2 Urid Map extension
|
||||
*/
|
||||
class UridMap
|
||||
{
|
||||
std::unordered_map<std::string, LV2_URID> m_map;
|
||||
std::vector<const char*> m_unMap;
|
||||
|
||||
//! mutex for both m_map and m_unMap
|
||||
//! the URID map is global, which is why a mutex is required here
|
||||
std::mutex m_MapMutex;
|
||||
|
||||
LV2_URID_Map m_mapFeature;
|
||||
LV2_URID_Unmap m_unmapFeature;
|
||||
|
||||
LV2_URID m_lastUrid = 0;
|
||||
|
||||
public:
|
||||
//! constructor; will set up the features
|
||||
UridMap();
|
||||
|
||||
//! map feature function
|
||||
LV2_URID map(const char* uri);
|
||||
//! unmap feature function
|
||||
const char* unmap(LV2_URID urid);
|
||||
|
||||
// access the features
|
||||
LV2_URID_Map* mapFeature() { return &m_mapFeature; }
|
||||
LV2_URID_Unmap* unmapFeature() { return &m_unmapFeature; }
|
||||
};
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
#endif // LV2URIDMAP_H
|
||||
98
include/Lv2ViewBase.h
Normal file
98
include/Lv2ViewBase.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Lv2ViewBase.h - base class for Lv2 plugin views
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 LV2VIEWBASE_H
|
||||
#define LV2VIEWBASE_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_LV2
|
||||
|
||||
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
#include "LinkedModelGroupViews.h"
|
||||
#include "lmms_export.h"
|
||||
#include "Lv2Basics.h"
|
||||
|
||||
class Lv2Proc;
|
||||
class Lv2ControlBase;
|
||||
|
||||
|
||||
//! View for one processor, Lv2ViewBase contains 2 of those for mono plugins
|
||||
class Lv2ViewProc : public LinkedModelGroupView
|
||||
{
|
||||
public:
|
||||
//! @param colNum numbers of columns for the controls
|
||||
Lv2ViewProc(QWidget *parent, Lv2Proc *ctrlBase, int colNum);
|
||||
~Lv2ViewProc();
|
||||
|
||||
private:
|
||||
static AutoLilvNode uri(const char *uriStr);
|
||||
};
|
||||
|
||||
|
||||
//! Base class for view for one Lv2 plugin
|
||||
class LMMS_EXPORT Lv2ViewBase : public LinkedModelGroupsView
|
||||
{
|
||||
protected:
|
||||
//! @param pluginWidget A child class which inherits QWidget
|
||||
Lv2ViewBase(class QWidget *pluginWidget, Lv2ControlBase *ctrlBase);
|
||||
~Lv2ViewBase();
|
||||
|
||||
// these widgets must be connected by child widgets
|
||||
class QPushButton *m_reloadPluginButton = nullptr;
|
||||
class QPushButton *m_toggleUIButton = nullptr;
|
||||
class QPushButton *m_helpButton = nullptr;
|
||||
|
||||
void toggleUI();
|
||||
void toggleHelp(bool visible);
|
||||
|
||||
// to be called by child virtuals
|
||||
//! Reconnect models if model changed
|
||||
void modelChanged(Lv2ControlBase* ctrlBase);
|
||||
|
||||
private:
|
||||
enum Rows
|
||||
{
|
||||
ButtonRow,
|
||||
ProcRow,
|
||||
LinkChannelsRow
|
||||
};
|
||||
|
||||
static AutoLilvNode uri(const char *uriStr);
|
||||
LinkedModelGroupView* getGroupView() override { return m_procView; }
|
||||
|
||||
Lv2ViewProc* m_procView;
|
||||
|
||||
//! Numbers of controls per row; must be multiple of 2 for mono effects
|
||||
const int m_colNum = 6;
|
||||
class QMdiSubWindow* m_helpWindow = nullptr;
|
||||
class LedCheckBox *m_multiChannelLink;
|
||||
};
|
||||
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
#endif // LV2VIEWBASE_H
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
void addSpacingToToolBar( int _size );
|
||||
|
||||
// wrap the widget with a window decoration and add it to the workspace
|
||||
SubWindow* addWindowedWidget(QWidget *w, Qt::WindowFlags windowFlags=0);
|
||||
SubWindow* addWindowedWidget(QWidget *w, Qt::WindowFlags windowFlags = QFlag(0));
|
||||
|
||||
|
||||
///
|
||||
@@ -157,6 +157,7 @@ public slots:
|
||||
void toggleFxMixerWin();
|
||||
void togglePianoRollWin();
|
||||
void toggleControllerRack();
|
||||
void toggleFullscreen();
|
||||
|
||||
void updatePlayPauseIcons();
|
||||
|
||||
@@ -226,6 +227,8 @@ private:
|
||||
ToolButton * m_metronomeToggle;
|
||||
|
||||
SessionState m_session;
|
||||
|
||||
bool maximized;
|
||||
|
||||
private slots:
|
||||
void browseHelp();
|
||||
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
|
||||
|
||||
virtual void processOutEvent( const MidiEvent & _me,
|
||||
const MidiTime & _time,
|
||||
const TimePos & _time,
|
||||
const MidiPort * _port ) override;
|
||||
|
||||
void applyPortMode( MidiPort * _port ) override;
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void processOutEvent( const MidiEvent & _me,
|
||||
const MidiTime & _time,
|
||||
const TimePos & _time,
|
||||
const MidiPort * _port );
|
||||
|
||||
virtual void applyPortMode( MidiPort * _port );
|
||||
|
||||
40
include/MidiCCRackView.h
Normal file
40
include/MidiCCRackView.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef MIDI_CC_RACK_VIEW_H
|
||||
#define MIDI_CC_RACK_VIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "GroupBox.h"
|
||||
#include "Knob.h"
|
||||
#include "Midi.h"
|
||||
#include "SerializingObject.h"
|
||||
|
||||
class InstrumentTrack;
|
||||
|
||||
class MidiCCRackView : public QWidget, public SerializingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MidiCCRackView(InstrumentTrack * track);
|
||||
~MidiCCRackView() override;
|
||||
|
||||
void saveSettings(QDomDocument & doc, QDomElement & parent) override;
|
||||
void loadSettings(const QDomElement &) override;
|
||||
|
||||
inline QString nodeName() const override
|
||||
{
|
||||
return "MidiCCRackView";
|
||||
}
|
||||
|
||||
private slots:
|
||||
void renameWindow();
|
||||
|
||||
private:
|
||||
InstrumentTrack *m_track;
|
||||
|
||||
GroupBox *m_midiCCGroupBox; // MIDI CC GroupBox (used to enable disable MIDI CC)
|
||||
|
||||
Knob *m_controllerKnob[MidiControllerCount]; // Holds the knob widgets for each controller
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
|
||||
// to be implemented by sub-classes
|
||||
virtual void processOutEvent( const MidiEvent & _me,
|
||||
const MidiTime & _time,
|
||||
const TimePos & _time,
|
||||
const MidiPort * _port ) = 0;
|
||||
|
||||
// inheriting classes can re-implement this for being able to update
|
||||
@@ -141,7 +141,7 @@ protected:
|
||||
private:
|
||||
// this does MIDI-event-process
|
||||
void processParsedEvent();
|
||||
void processOutEvent( const MidiEvent& event, const MidiTime& time, const MidiPort* port ) override;
|
||||
void processOutEvent( const MidiEvent& event, const TimePos& time, const MidiPort* port ) override;
|
||||
|
||||
// small helper function returning length of a certain event - this
|
||||
// is necessary for parsing raw-MIDI-data
|
||||
|
||||
@@ -44,10 +44,10 @@ public:
|
||||
virtual ~MidiController();
|
||||
|
||||
virtual void processInEvent( const MidiEvent & _me,
|
||||
const MidiTime & _time, f_cnt_t offset = 0 ) override;
|
||||
const TimePos & _time, f_cnt_t offset = 0 ) override;
|
||||
|
||||
virtual void processOutEvent( const MidiEvent& _me,
|
||||
const MidiTime & _time, f_cnt_t offset = 0 ) override
|
||||
const TimePos & _time, f_cnt_t offset = 0 ) override
|
||||
{
|
||||
// No output yet
|
||||
}
|
||||
|
||||
@@ -33,27 +33,32 @@
|
||||
class MidiEvent
|
||||
{
|
||||
public:
|
||||
MidiEvent( MidiEventTypes type = MidiActiveSensing,
|
||||
enum class Source { Internal, External };
|
||||
|
||||
MidiEvent(MidiEventTypes type = MidiActiveSensing,
|
||||
int8_t channel = 0,
|
||||
int16_t param1 = 0,
|
||||
int16_t param2 = 0,
|
||||
const void* sourcePort = NULL ) :
|
||||
const void* sourcePort = nullptr,
|
||||
Source source = Source::External) :
|
||||
m_type( type ),
|
||||
m_metaEvent( MidiMetaInvalid ),
|
||||
m_channel( channel ),
|
||||
m_sysExData( NULL ),
|
||||
m_sourcePort( sourcePort )
|
||||
m_sourcePort(sourcePort),
|
||||
m_source(source)
|
||||
{
|
||||
m_data.m_param[0] = param1;
|
||||
m_data.m_param[1] = param2;
|
||||
}
|
||||
|
||||
MidiEvent( MidiEventTypes type, const char* sysExData, int dataLen ) :
|
||||
MidiEvent(MidiEventTypes type, const char* sysExData, std::size_t dataLen, Source source = Source::External) :
|
||||
m_type( type ),
|
||||
m_metaEvent( MidiMetaInvalid ),
|
||||
m_channel( 0 ),
|
||||
m_sysExData( sysExData ),
|
||||
m_sourcePort( NULL )
|
||||
m_sourcePort(nullptr),
|
||||
m_source(source)
|
||||
{
|
||||
m_data.m_sysExDataLen = dataLen;
|
||||
}
|
||||
@@ -64,7 +69,8 @@ public:
|
||||
m_channel( other.m_channel ),
|
||||
m_data( other.m_data ),
|
||||
m_sysExData( other.m_sysExData ),
|
||||
m_sourcePort( other.m_sourcePort )
|
||||
m_sourcePort(other.m_sourcePort),
|
||||
m_source(other.m_source)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -190,6 +196,16 @@ public:
|
||||
setParam( 0, pitchBend );
|
||||
}
|
||||
|
||||
Source source() const
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
void setSource(Source value)
|
||||
{
|
||||
m_source = value;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
MidiEventTypes m_type; // MIDI event type
|
||||
@@ -198,13 +214,15 @@ private:
|
||||
union
|
||||
{
|
||||
int16_t m_param[2]; // first/second parameter (key/velocity)
|
||||
uint8_t m_bytes[4]; // raw bytes
|
||||
uint8_t m_bytes[4]; // raw bytes
|
||||
int32_t m_sysExDataLen; // len of m_sysExData
|
||||
} m_data;
|
||||
|
||||
const char* m_sysExData;
|
||||
const void* m_sourcePort;
|
||||
|
||||
// Stores the source of the MidiEvent: Internal or External (hardware controllers).
|
||||
Source m_source;
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
#define MIDI_EVENT_PROCESSOR_H
|
||||
|
||||
#include "MidiEvent.h"
|
||||
#include "MidiTime.h"
|
||||
#include "Memory.h"
|
||||
#include "TimePos.h"
|
||||
|
||||
// all classes being able to process MIDI-events should inherit from this
|
||||
class MidiEventProcessor
|
||||
@@ -43,8 +43,8 @@ public:
|
||||
}
|
||||
|
||||
// to be implemented by inheriting classes
|
||||
virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ) = 0;
|
||||
virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ) = 0;
|
||||
virtual void processInEvent( const MidiEvent& event, const TimePos& time = TimePos(), f_cnt_t offset = 0 ) = 0;
|
||||
virtual void processOutEvent( const MidiEvent& event, const TimePos& time = TimePos(), f_cnt_t offset = 0 ) = 0;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
47
include/MidiEventToByteSeq.h
Normal file
47
include/MidiEventToByteSeq.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* MidiEventToByteSeq.h - writeToByteSeq declaration
|
||||
*
|
||||
* Copyright (c) 2020-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 MIDIEVENTTOBYTESEQ_H
|
||||
#define MIDIEVENTTOBYTESEQ_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "lmms_export.h"
|
||||
|
||||
/**
|
||||
Write MIDI event into byte sequence.
|
||||
|
||||
Conforming to http://lv2plug.in/ns/ext/midi#MidiEvent
|
||||
|
||||
@param data Pointer to the target buffer for the byte sequence. Must
|
||||
point to existing memory with at least 3 bytes size.
|
||||
@param bufsize Available size of the target buffer.
|
||||
@return Used size of the target buffer, or 0 if the MidiEvent could not
|
||||
be converted.
|
||||
*/
|
||||
std::size_t LMMS_EXPORT writeToByteSeq( const class MidiEvent& ev,
|
||||
uint8_t* data, std::size_t bufsize );
|
||||
|
||||
#endif // MIDIEVENTTOBYTESEQ_H
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <QtCore/QMap>
|
||||
|
||||
#include "Midi.h"
|
||||
#include "MidiTime.h"
|
||||
#include "TimePos.h"
|
||||
#include "AutomatableModel.h"
|
||||
|
||||
|
||||
@@ -96,11 +96,14 @@ public:
|
||||
|
||||
int realOutputChannel() const
|
||||
{
|
||||
return outputChannel() - 1;
|
||||
// There's a possibility of outputChannel being 0 ("--"), which is used to keep all
|
||||
// midi channels when forwarding. In that case, realOutputChannel will return the
|
||||
// default channel 1 (whose value is 0).
|
||||
return outputChannel() ? outputChannel() - 1 : 0;
|
||||
}
|
||||
|
||||
void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime() );
|
||||
void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime() );
|
||||
void processInEvent( const MidiEvent& event, const TimePos& time = TimePos() );
|
||||
void processOutEvent( const MidiEvent& event, const TimePos& time = TimePos() );
|
||||
|
||||
|
||||
void saveSettings( QDomDocument& doc, QDomElement& thisElement ) override;
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
|
||||
|
||||
virtual void processOutEvent( const MidiEvent & _me,
|
||||
const MidiTime & _time,
|
||||
const TimePos & _time,
|
||||
const MidiPort * _port );
|
||||
|
||||
virtual void applyPortMode( MidiPort * _port );
|
||||
|
||||
@@ -98,9 +98,9 @@ public:
|
||||
Interpolation interpolation;
|
||||
Oversampling oversampling;
|
||||
|
||||
qualitySettings( Mode _m )
|
||||
qualitySettings(Mode m)
|
||||
{
|
||||
switch( _m )
|
||||
switch (m)
|
||||
{
|
||||
case Mode_Draft:
|
||||
interpolation = Interpolation_Linear;
|
||||
@@ -118,9 +118,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
qualitySettings( Interpolation _i, Oversampling _o ) :
|
||||
interpolation( _i ),
|
||||
oversampling( _o )
|
||||
qualitySettings(Interpolation i, Oversampling o) :
|
||||
interpolation(i),
|
||||
oversampling(o)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -173,8 +173,6 @@ public:
|
||||
|
||||
//! Set new audio device. Old device will be deleted,
|
||||
//! unless it's stored using storeAudioDevice
|
||||
void setAudioDevice( AudioDevice * _dev , bool startNow );
|
||||
//! See overloaded function
|
||||
void setAudioDevice( AudioDevice * _dev,
|
||||
const struct qualitySettings & _qs,
|
||||
bool _needs_fifo,
|
||||
@@ -188,14 +186,14 @@ public:
|
||||
|
||||
|
||||
// audio-port-stuff
|
||||
inline void addAudioPort( AudioPort * _port )
|
||||
inline void addAudioPort(AudioPort * port)
|
||||
{
|
||||
requestChangeInModel();
|
||||
m_audioPorts.push_back( _port );
|
||||
m_audioPorts.push_back(port);
|
||||
doneChangeInModel();
|
||||
}
|
||||
|
||||
void removeAudioPort( AudioPort * _port );
|
||||
void removeAudioPort(AudioPort * port);
|
||||
|
||||
|
||||
// MIDI-client-stuff
|
||||
@@ -220,7 +218,7 @@ public:
|
||||
return m_playHandles;
|
||||
}
|
||||
|
||||
void removePlayHandlesOfTypes( Track * _track, const quint8 types );
|
||||
void removePlayHandlesOfTypes(Track * track, const quint8 types);
|
||||
|
||||
|
||||
// methods providing information for other classes
|
||||
@@ -257,23 +255,23 @@ public:
|
||||
return m_masterGain;
|
||||
}
|
||||
|
||||
inline void setMasterGain( const float _mo )
|
||||
inline void setMasterGain(const float mo)
|
||||
{
|
||||
m_masterGain = _mo;
|
||||
m_masterGain = mo;
|
||||
}
|
||||
|
||||
|
||||
static inline sample_t clip( const sample_t _s )
|
||||
static inline sample_t clip(const sample_t s)
|
||||
{
|
||||
if( _s > 1.0f )
|
||||
if (s > 1.0f)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
else if( _s < -1.0f )
|
||||
else if (s < -1.0f)
|
||||
{
|
||||
return -1.0f;
|
||||
}
|
||||
return _s;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -283,7 +281,7 @@ public:
|
||||
sample_t left;
|
||||
sample_t right;
|
||||
};
|
||||
StereoSample getPeakValues(sampleFrame * _ab, const f_cnt_t _frames) const;
|
||||
StereoSample getPeakValues(sampleFrame * ab, const f_cnt_t _frames) const;
|
||||
|
||||
|
||||
bool criticalXRuns() const;
|
||||
@@ -310,7 +308,7 @@ public:
|
||||
return hasFifoWriter() ? m_fifo->read() : renderNextBuffer();
|
||||
}
|
||||
|
||||
void changeQuality( const struct qualitySettings & _qs );
|
||||
void changeQuality(const struct qualitySettings & qs);
|
||||
|
||||
inline bool isMetronomeActive() const { return m_metronomeActive; }
|
||||
inline void setMetronomeActive(bool value = true) { m_metronomeActive = value; }
|
||||
@@ -335,7 +333,7 @@ private:
|
||||
class fifoWriter : public QThread
|
||||
{
|
||||
public:
|
||||
fifoWriter( Mixer * _mixer, fifo * _fifo );
|
||||
fifoWriter(Mixer * mixer, fifo * _fifo);
|
||||
|
||||
void finish();
|
||||
|
||||
@@ -355,7 +353,7 @@ private:
|
||||
Mixer( bool renderOnly );
|
||||
virtual ~Mixer();
|
||||
|
||||
void startProcessing( bool _needs_fifo = true );
|
||||
void startProcessing(bool needsFifo = true);
|
||||
void stopProcessing();
|
||||
|
||||
|
||||
@@ -365,6 +363,10 @@ private:
|
||||
|
||||
const surroundSampleFrame * renderNextBuffer();
|
||||
|
||||
void swapBuffers();
|
||||
|
||||
void handleMetronome();
|
||||
|
||||
void clearInternal();
|
||||
|
||||
//! Called by the audio thread to give control to other threads,
|
||||
@@ -383,13 +385,8 @@ private:
|
||||
int m_inputBufferRead;
|
||||
int m_inputBufferWrite;
|
||||
|
||||
surroundSampleFrame * m_readBuf;
|
||||
surroundSampleFrame * m_writeBuf;
|
||||
|
||||
QVector<surroundSampleFrame *> m_bufferPool;
|
||||
int m_readBuffer;
|
||||
int m_writeBuffer;
|
||||
int m_poolDepth;
|
||||
surroundSampleFrame * m_outputBufferRead;
|
||||
surroundSampleFrame * m_outputBufferWrite;
|
||||
|
||||
// worker thread stuff
|
||||
QVector<MixerWorkerThread *> m_workers;
|
||||
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
virtual ~ModelView();
|
||||
|
||||
virtual void setModel( Model* model, bool isOldModelValid = true );
|
||||
virtual void unsetModel();
|
||||
|
||||
Model* model()
|
||||
{
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
|
||||
#include "volume.h"
|
||||
#include "panning.h"
|
||||
#include "MidiTime.h"
|
||||
#include "SerializingObject.h"
|
||||
#include "TimePos.h"
|
||||
|
||||
class DetuningHelper;
|
||||
|
||||
@@ -81,8 +81,8 @@ const float MaxDetuning = 4 * 12.0f;
|
||||
class LMMS_EXPORT Note : public SerializingObject
|
||||
{
|
||||
public:
|
||||
Note( const MidiTime & length = MidiTime( 0 ),
|
||||
const MidiTime & pos = MidiTime( 0 ),
|
||||
Note( const TimePos & length = TimePos( 0 ),
|
||||
const TimePos & pos = TimePos( 0 ),
|
||||
int key = DefaultKey,
|
||||
volume_t volume = DefaultVolume,
|
||||
panning_t panning = DefaultPanning,
|
||||
@@ -93,9 +93,9 @@ public:
|
||||
// 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 setOldPos( const TimePos & oldPos ) { m_oldPos = oldPos; }
|
||||
|
||||
inline void setOldLength( const MidiTime & oldLength )
|
||||
inline void setOldLength( const TimePos & oldLength )
|
||||
{
|
||||
m_oldLength = oldLength;
|
||||
}
|
||||
@@ -105,8 +105,8 @@ public:
|
||||
}
|
||||
|
||||
|
||||
void setLength( const MidiTime & length );
|
||||
void setPos( const MidiTime & pos );
|
||||
void setLength( const TimePos & length );
|
||||
void setPos( const TimePos & pos );
|
||||
void setKey( const int key );
|
||||
virtual void setVolume( volume_t volume );
|
||||
virtual void setPanning( panning_t panning );
|
||||
@@ -138,12 +138,12 @@ public:
|
||||
return m_oldKey;
|
||||
}
|
||||
|
||||
inline MidiTime oldPos() const
|
||||
inline TimePos oldPos() const
|
||||
{
|
||||
return m_oldPos;
|
||||
}
|
||||
|
||||
inline MidiTime oldLength() const
|
||||
inline TimePos oldLength() const
|
||||
{
|
||||
return m_oldLength;
|
||||
}
|
||||
@@ -153,23 +153,23 @@ public:
|
||||
return m_isPlaying;
|
||||
}
|
||||
|
||||
inline MidiTime endPos() const
|
||||
inline TimePos endPos() const
|
||||
{
|
||||
const int l = length();
|
||||
return pos() + l;
|
||||
}
|
||||
|
||||
inline const MidiTime & length() const
|
||||
inline const TimePos & length() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
inline const MidiTime & pos() const
|
||||
inline const TimePos & pos() const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
inline MidiTime pos( MidiTime basePos ) const
|
||||
inline TimePos pos( TimePos basePos ) const
|
||||
{
|
||||
const int bp = basePos;
|
||||
return m_pos - bp;
|
||||
@@ -205,7 +205,7 @@ public:
|
||||
return classNodeName();
|
||||
}
|
||||
|
||||
static MidiTime quantized( const MidiTime & m, const int qGrid );
|
||||
static TimePos quantized( const TimePos & m, const int qGrid );
|
||||
|
||||
DetuningHelper * detuning() const
|
||||
{
|
||||
@@ -226,15 +226,15 @@ private:
|
||||
// for piano roll editing
|
||||
bool m_selected;
|
||||
int m_oldKey;
|
||||
MidiTime m_oldPos;
|
||||
MidiTime m_oldLength;
|
||||
TimePos m_oldPos;
|
||||
TimePos m_oldLength;
|
||||
bool m_isPlaying;
|
||||
|
||||
int m_key;
|
||||
volume_t m_volume;
|
||||
panning_t m_panning;
|
||||
MidiTime m_length;
|
||||
MidiTime m_pos;
|
||||
TimePos m_length;
|
||||
TimePos m_pos;
|
||||
DetuningHelper * m_detuning;
|
||||
};
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@ public:
|
||||
void * m_pluginData;
|
||||
std::unique_ptr<BasicFilters<>> m_filter;
|
||||
|
||||
// length of the declicking fade in
|
||||
fpp_t m_fadeInLength;
|
||||
|
||||
// specifies origin of NotePlayHandle
|
||||
enum Origins
|
||||
{
|
||||
@@ -240,19 +243,19 @@ public:
|
||||
}
|
||||
|
||||
/*! Process note detuning automation */
|
||||
void processMidiTime( const MidiTime& time );
|
||||
void processTimePos( const TimePos& time );
|
||||
|
||||
/*! Updates total length (m_frames) depending on a new tempo */
|
||||
void resize( const bpm_t newTempo );
|
||||
|
||||
/*! Set song-global offset (relative to containing pattern) in order to properly perform the note detuning */
|
||||
void setSongGlobalParentOffset( const MidiTime& offset )
|
||||
void setSongGlobalParentOffset( const TimePos& offset )
|
||||
{
|
||||
m_songGlobalParentOffset = offset;
|
||||
}
|
||||
|
||||
/*! Returns song-global offset */
|
||||
const MidiTime& songGlobalParentOffset() const
|
||||
const TimePos& songGlobalParentOffset() const
|
||||
{
|
||||
return m_songGlobalParentOffset;
|
||||
}
|
||||
@@ -319,7 +322,7 @@ private:
|
||||
float m_unpitchedFrequency;
|
||||
|
||||
BaseDetuning* m_baseDetuning;
|
||||
MidiTime m_songGlobalParentOffset;
|
||||
TimePos m_songGlobalParentOffset;
|
||||
|
||||
int m_midiChannel;
|
||||
Origin m_origin;
|
||||
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
|
||||
static inline sample_t triangleSample( const float _sample )
|
||||
{
|
||||
const float ph = fraction( _sample );
|
||||
const float ph = absFraction( _sample );
|
||||
if( ph <= 0.25f )
|
||||
{
|
||||
return ph * 4.0f;
|
||||
@@ -111,17 +111,17 @@ public:
|
||||
|
||||
static inline sample_t sawSample( const float _sample )
|
||||
{
|
||||
return -1.0f + fraction( _sample ) * 2.0f;
|
||||
return -1.0f + absFraction( _sample ) * 2.0f;
|
||||
}
|
||||
|
||||
static inline sample_t squareSample( const float _sample )
|
||||
{
|
||||
return ( fraction( _sample ) > 0.5f ) ? -1.0f : 1.0f;
|
||||
return ( absFraction( _sample ) > 0.5f ) ? -1.0f : 1.0f;
|
||||
}
|
||||
|
||||
static inline sample_t moogSawSample( const float _sample )
|
||||
{
|
||||
const float ph = fraction( _sample );
|
||||
const float ph = absFraction( _sample );
|
||||
if( ph < 0.5f )
|
||||
{
|
||||
return -1.0f + ph * 4.0f;
|
||||
@@ -131,7 +131,7 @@ public:
|
||||
|
||||
static inline sample_t expSample( const float _sample )
|
||||
{
|
||||
float ph = fraction( _sample );
|
||||
float ph = absFraction( _sample );
|
||||
if( ph > 0.5f )
|
||||
{
|
||||
ph = 1.0f - ph;
|
||||
|
||||
@@ -37,7 +37,6 @@ class Oscilloscope : public QWidget
|
||||
Q_OBJECT
|
||||
public:
|
||||
Q_PROPERTY( QColor normalColor READ normalColor WRITE setNormalColor )
|
||||
Q_PROPERTY( QColor warningColor READ warningColor WRITE setWarningColor )
|
||||
Q_PROPERTY( QColor clippingColor READ clippingColor WRITE setClippingColor )
|
||||
|
||||
Oscilloscope( QWidget * _parent );
|
||||
@@ -48,9 +47,6 @@ public:
|
||||
QColor const & normalColor() const;
|
||||
void setNormalColor(QColor const & normalColor);
|
||||
|
||||
QColor const & warningColor() const;
|
||||
void setWarningColor(QColor const & warningColor);
|
||||
|
||||
QColor const & clippingColor() const;
|
||||
void setClippingColor(QColor const & clippingColor);
|
||||
|
||||
@@ -74,7 +70,6 @@ private:
|
||||
bool m_active;
|
||||
|
||||
QColor m_normalColor;
|
||||
QColor m_warningColor;
|
||||
QColor m_clippingColor;
|
||||
} ;
|
||||
|
||||
|
||||
41
include/PathUtil.h
Normal file
41
include/PathUtil.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef PATHUTIL_H
|
||||
#define PATHUTIL_H
|
||||
|
||||
#include "lmms_export.h"
|
||||
|
||||
#include <QDir>
|
||||
|
||||
namespace PathUtil
|
||||
{
|
||||
enum class Base { Absolute, ProjectDir, FactorySample, UserSample, UserVST, Preset,
|
||||
UserLADSPA, DefaultLADSPA, UserSoundfont, DefaultSoundfont, UserGIG, DefaultGIG };
|
||||
|
||||
//! Return the directory associated with a given base as a QString
|
||||
QString LMMS_EXPORT baseLocation(const Base base);
|
||||
//! Return the directory associated with a given base as a QDir
|
||||
QDir LMMS_EXPORT baseQDir (const Base base);
|
||||
//! Return the prefix used to denote this base in path strings
|
||||
QString LMMS_EXPORT basePrefix(const Base base);
|
||||
//! Check the prefix of a path and return the base it corresponds to
|
||||
//! Defaults to Base::Absolute
|
||||
Base LMMS_EXPORT baseLookup(const QString & path);
|
||||
|
||||
//! Remove the prefix from a path, iff there is one
|
||||
QString LMMS_EXPORT stripPrefix(const QString & path);
|
||||
//! Get the filename for a path, handling prefixed paths correctly
|
||||
QString LMMS_EXPORT cleanName(const QString & path);
|
||||
|
||||
//! Upgrade prefix-less relative paths to the new format
|
||||
QString LMMS_EXPORT oldRelativeUpgrade(const QString & input);
|
||||
|
||||
//! Make this path absolute
|
||||
QString LMMS_EXPORT toAbsolute(const QString & input);
|
||||
//! Make this path relative to a given base, return an absolute path if that fails
|
||||
QString LMMS_EXPORT relativeOrAbsolute(const QString & input, const Base base);
|
||||
//! Make this path relative to any base, choosing the shortest if there are
|
||||
//! multiple options. Defaults to an absolute path if all bases fail.
|
||||
QString LMMS_EXPORT toShortestRelative(const QString & input);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -34,16 +34,10 @@
|
||||
|
||||
|
||||
#include "Note.h"
|
||||
#include "Track.h"
|
||||
#include "TrackContentObjectView.h"
|
||||
|
||||
|
||||
class QAction;
|
||||
class QProgressBar;
|
||||
class QPushButton;
|
||||
|
||||
class InstrumentTrack;
|
||||
class SampleBuffer;
|
||||
|
||||
|
||||
|
||||
class LMMS_EXPORT Pattern : public TrackContentObject
|
||||
@@ -128,7 +122,7 @@ protected slots:
|
||||
|
||||
|
||||
private:
|
||||
MidiTime beatPatternLength() const;
|
||||
TimePos beatPatternLength() const;
|
||||
|
||||
void setType( PatternTypes _new_pattern_type );
|
||||
void checkType();
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "ToolTip.h"
|
||||
#include "StepRecorder.h"
|
||||
#include "StepRecorderWidget.h"
|
||||
#include "PositionLine.h"
|
||||
|
||||
class QPainter;
|
||||
class QPixmap;
|
||||
@@ -55,25 +56,38 @@ class TimeLineWidget;
|
||||
class PianoRoll : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY( QColor barLineColor READ barLineColor WRITE setBarLineColor )
|
||||
Q_PROPERTY( QColor beatLineColor READ beatLineColor WRITE setBeatLineColor )
|
||||
Q_PROPERTY( QColor lineColor READ lineColor WRITE setLineColor )
|
||||
Q_PROPERTY( QColor noteModeColor READ noteModeColor WRITE setNoteModeColor )
|
||||
Q_PROPERTY( QColor noteColor READ noteColor WRITE setNoteColor )
|
||||
Q_PROPERTY( QColor ghostNoteColor READ ghostNoteColor WRITE setGhostNoteColor )
|
||||
Q_PROPERTY( QColor noteTextColor READ noteTextColor WRITE setNoteTextColor )
|
||||
Q_PROPERTY( QColor ghostNoteTextColor READ ghostNoteTextColor WRITE setGhostNoteTextColor )
|
||||
Q_PROPERTY( QColor barColor READ barColor WRITE setBarColor )
|
||||
Q_PROPERTY( QColor selectedNoteColor READ selectedNoteColor WRITE setSelectedNoteColor )
|
||||
Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor )
|
||||
Q_PROPERTY( QColor textColorLight READ textColorLight WRITE setTextColorLight )
|
||||
Q_PROPERTY( QColor textShadow READ textShadow WRITE setTextShadow )
|
||||
Q_PROPERTY( QColor markedSemitoneColor READ markedSemitoneColor WRITE setMarkedSemitoneColor )
|
||||
Q_PROPERTY( int noteOpacity READ noteOpacity WRITE setNoteOpacity )
|
||||
Q_PROPERTY( bool noteBorders READ noteBorders WRITE setNoteBorders )
|
||||
Q_PROPERTY( int ghostNoteOpacity READ ghostNoteOpacity WRITE setGhostNoteOpacity )
|
||||
Q_PROPERTY( bool ghostNoteBorders READ ghostNoteBorders WRITE setGhostNoteBorders )
|
||||
Q_PROPERTY( QColor backgroundShade READ backgroundShade WRITE setBackgroundShade )
|
||||
Q_PROPERTY(QColor barLineColor MEMBER m_barLineColor)
|
||||
Q_PROPERTY(QColor beatLineColor MEMBER m_beatLineColor)
|
||||
Q_PROPERTY(QColor lineColor MEMBER m_lineColor)
|
||||
Q_PROPERTY(QColor noteModeColor MEMBER m_noteModeColor)
|
||||
Q_PROPERTY(QColor noteColor MEMBER m_noteColor)
|
||||
Q_PROPERTY(QColor ghostNoteColor MEMBER m_ghostNoteColor)
|
||||
Q_PROPERTY(QColor noteTextColor MEMBER m_noteTextColor)
|
||||
Q_PROPERTY(QColor ghostNoteTextColor MEMBER m_ghostNoteTextColor)
|
||||
Q_PROPERTY(QColor barColor MEMBER m_barColor)
|
||||
Q_PROPERTY(QColor selectedNoteColor MEMBER m_selectedNoteColor)
|
||||
Q_PROPERTY(QColor textColor MEMBER m_textColor)
|
||||
Q_PROPERTY(QColor textColorLight MEMBER m_textColorLight)
|
||||
Q_PROPERTY(QColor textShadow MEMBER m_textShadow)
|
||||
Q_PROPERTY(QColor markedSemitoneColor MEMBER m_markedSemitoneColor)
|
||||
Q_PROPERTY(int noteOpacity MEMBER m_noteOpacity)
|
||||
Q_PROPERTY(bool noteBorders MEMBER m_noteBorders)
|
||||
Q_PROPERTY(int ghostNoteOpacity MEMBER m_ghostNoteOpacity)
|
||||
Q_PROPERTY(bool ghostNoteBorders MEMBER m_ghostNoteBorders)
|
||||
Q_PROPERTY(QColor backgroundShade MEMBER m_backgroundShade)
|
||||
|
||||
/* white key properties */
|
||||
Q_PROPERTY(int whiteKeyWidth MEMBER m_whiteKeyWidth)
|
||||
Q_PROPERTY(QColor whiteKeyInactiveTextColor MEMBER m_whiteKeyInactiveTextColor)
|
||||
Q_PROPERTY(QColor whiteKeyInactiveTextShadow MEMBER m_whiteKeyInactiveTextShadow)
|
||||
Q_PROPERTY(QBrush whiteKeyInactiveBackground MEMBER m_whiteKeyInactiveBackground)
|
||||
Q_PROPERTY(QColor whiteKeyActiveTextColor MEMBER m_whiteKeyActiveTextColor)
|
||||
Q_PROPERTY(QColor whiteKeyActiveTextShadow MEMBER m_whiteKeyActiveTextShadow)
|
||||
Q_PROPERTY(QBrush whiteKeyActiveBackground MEMBER m_whiteKeyActiveBackground)
|
||||
/* black key properties */
|
||||
Q_PROPERTY(int blackKeyWidth MEMBER m_blackKeyWidth)
|
||||
Q_PROPERTY(QBrush blackKeyInactiveBackground MEMBER m_blackKeyInactiveBackground)
|
||||
Q_PROPERTY(QBrush blackKeyActiveBackground MEMBER m_blackKeyActiveBackground)
|
||||
public:
|
||||
enum EditModes
|
||||
{
|
||||
@@ -125,47 +139,6 @@ public:
|
||||
|
||||
int quantization() const;
|
||||
|
||||
// qproperty access functions
|
||||
QColor barLineColor() const;
|
||||
void setBarLineColor( const QColor & c );
|
||||
QColor beatLineColor() const;
|
||||
void setBeatLineColor( const QColor & c );
|
||||
QColor lineColor() const;
|
||||
void setLineColor( const QColor & c );
|
||||
QColor noteModeColor() const;
|
||||
void setNoteModeColor( const QColor & c );
|
||||
QColor noteColor() const;
|
||||
void setNoteColor( const QColor & c );
|
||||
QColor noteTextColor() const;
|
||||
void setNoteTextColor( const QColor & c );
|
||||
QColor barColor() const;
|
||||
void setBarColor( const QColor & c );
|
||||
QColor selectedNoteColor() const;
|
||||
void setSelectedNoteColor( const QColor & c );
|
||||
QColor textColor() const;
|
||||
void setTextColor( const QColor & c );
|
||||
QColor textColorLight() const;
|
||||
void setTextColorLight( const QColor & c );
|
||||
QColor textShadow() const;
|
||||
void setTextShadow( const QColor & c );
|
||||
QColor markedSemitoneColor() const;
|
||||
void setMarkedSemitoneColor( const QColor & c );
|
||||
int noteOpacity() const;
|
||||
void setNoteOpacity( const int i );
|
||||
bool noteBorders() const;
|
||||
void setNoteBorders( const bool b );
|
||||
QColor ghostNoteColor() const;
|
||||
void setGhostNoteColor( const QColor & c );
|
||||
QColor ghostNoteTextColor() const;
|
||||
void setGhostNoteTextColor( const QColor & c );
|
||||
int ghostNoteOpacity() const;
|
||||
void setGhostNoteOpacity( const int i );
|
||||
bool ghostNoteBorders() const;
|
||||
void setGhostNoteBorders( const bool b );
|
||||
QColor backgroundShade() const;
|
||||
void setBackgroundShade( const QColor & c );
|
||||
|
||||
|
||||
protected:
|
||||
void keyPressEvent( QKeyEvent * ke ) override;
|
||||
void keyReleaseEvent( QKeyEvent * ke ) override;
|
||||
@@ -178,6 +151,7 @@ protected:
|
||||
void resizeEvent( QResizeEvent * re ) override;
|
||||
void wheelEvent( QWheelEvent * we ) override;
|
||||
void focusOutEvent( QFocusEvent * ) override;
|
||||
void focusInEvent( QFocusEvent * ) override;
|
||||
|
||||
int getKey( int y ) const;
|
||||
void drawNoteRect( QPainter & p, int x, int y,
|
||||
@@ -185,9 +159,8 @@ protected:
|
||||
const QColor & selCol, const int noteOpc, const bool borderless, bool drawNoteName );
|
||||
void removeSelection();
|
||||
void selectAll();
|
||||
NoteVector getSelectedNotes();
|
||||
NoteVector getSelectedNotes() const;
|
||||
void selectNotesOnKey();
|
||||
int xCoordOfTick( int tick );
|
||||
|
||||
// for entering values with dblclick in the vol/pan bars
|
||||
void enterValue( NoteVector* nv );
|
||||
@@ -212,28 +185,30 @@ protected slots:
|
||||
void copySelectedNotes();
|
||||
void cutSelectedNotes();
|
||||
void pasteNotes();
|
||||
void deleteSelectedNotes();
|
||||
bool deleteSelectedNotes();
|
||||
|
||||
void updatePosition(const MidiTime & t );
|
||||
void updatePositionAccompany(const MidiTime & t );
|
||||
void updatePositionStepRecording(const MidiTime & t );
|
||||
void updatePosition(const TimePos & t );
|
||||
void updatePositionAccompany(const TimePos & t );
|
||||
void updatePositionStepRecording(const TimePos & t );
|
||||
|
||||
void zoomingChanged();
|
||||
void zoomingYChanged();
|
||||
void quantizeChanged();
|
||||
void noteLengthChanged();
|
||||
void keyChanged();
|
||||
void quantizeNotes();
|
||||
|
||||
void updateSemiToneMarkerMenu();
|
||||
|
||||
void changeNoteEditMode( int i );
|
||||
void markSemiTone( int i );
|
||||
void markSemiTone(int i, bool fromMenu = true);
|
||||
|
||||
void hidePattern( Pattern* pattern );
|
||||
|
||||
void selectRegionFromPixels( int xStart, int xEnd );
|
||||
|
||||
void clearGhostPattern();
|
||||
void glueNotes();
|
||||
|
||||
|
||||
signals:
|
||||
@@ -278,6 +253,8 @@ private:
|
||||
PR_BLACK_KEY
|
||||
};
|
||||
|
||||
PositionLine * m_positionLine;
|
||||
|
||||
QVector<QString> m_nemStr; // gui names of each edit mode
|
||||
QMenu * m_noteEditMenu; // when you right click below the key area
|
||||
|
||||
@@ -289,12 +266,14 @@ private:
|
||||
PianoRoll( const PianoRoll & );
|
||||
virtual ~PianoRoll();
|
||||
|
||||
void autoScroll(const MidiTime & t );
|
||||
void autoScroll(const TimePos & t );
|
||||
|
||||
MidiTime newNoteLen() const;
|
||||
TimePos newNoteLen() const;
|
||||
|
||||
void shiftPos(int amount);
|
||||
void shiftPos(NoteVector notes, int amount);
|
||||
void shiftSemiTone(int amount);
|
||||
void shiftSemiTone(NoteVector notes, int amount);
|
||||
bool isSelection() const;
|
||||
int selectionCount() const;
|
||||
void testPlayNote( Note * n );
|
||||
@@ -303,6 +282,9 @@ private:
|
||||
void playChordNotes(int key, int velocity=-1);
|
||||
void pauseChordNotes(int key);
|
||||
|
||||
void updateScrollbars();
|
||||
void updatePositionLineHeight();
|
||||
|
||||
QList<int> getAllOctavesForKey( int keyToMirror ) const;
|
||||
|
||||
int noteEditTop() const;
|
||||
@@ -317,12 +299,6 @@ private:
|
||||
static const int cm_scrollAmtHoriz = 10;
|
||||
static const int cm_scrollAmtVert = 1;
|
||||
|
||||
static QPixmap * s_whiteKeyBigPm;
|
||||
static QPixmap * s_whiteKeyBigPressedPm;
|
||||
static QPixmap * s_whiteKeySmallPm;
|
||||
static QPixmap * s_whiteKeySmallPressedPm;
|
||||
static QPixmap * s_blackKeyPm;
|
||||
static QPixmap * s_blackKeyPressedPm;
|
||||
static QPixmap * s_toolDraw;
|
||||
static QPixmap * s_toolErase;
|
||||
static QPixmap * s_toolSelect;
|
||||
@@ -337,6 +313,7 @@ private:
|
||||
ComboBoxModel m_zoomingYModel;
|
||||
ComboBoxModel m_quantizeModel;
|
||||
ComboBoxModel m_noteLenModel;
|
||||
ComboBoxModel m_keyModel;
|
||||
ComboBoxModel m_scaleModel;
|
||||
ComboBoxModel m_chordModel;
|
||||
|
||||
@@ -354,7 +331,7 @@ private:
|
||||
QScrollBar * m_leftRightScroll;
|
||||
QScrollBar * m_topBottomScroll;
|
||||
|
||||
MidiTime m_currentPosition;
|
||||
TimePos m_currentPosition;
|
||||
bool m_recording;
|
||||
QList<Note> m_recordingNotes;
|
||||
|
||||
@@ -386,10 +363,11 @@ private:
|
||||
int m_moveStartX;
|
||||
int m_moveStartY;
|
||||
|
||||
int m_oldNotesEditHeight;
|
||||
int m_notesEditHeight;
|
||||
int m_userSetNotesEditHeight;
|
||||
int m_ppb; // pixels per bar
|
||||
int m_totalKeysToScroll;
|
||||
int m_pianoKeysVisible;
|
||||
|
||||
int m_keyLineHeight;
|
||||
int m_octaveHeight;
|
||||
@@ -399,10 +377,13 @@ private:
|
||||
|
||||
// remember these values to use them
|
||||
// for the next note that is set
|
||||
MidiTime m_lenOfNewNotes;
|
||||
TimePos m_lenOfNewNotes;
|
||||
volume_t m_lastNoteVolume;
|
||||
panning_t m_lastNotePanning;
|
||||
|
||||
//When resizing several notes, we want to calculate a common minimum length
|
||||
TimePos m_minResizeLen;
|
||||
|
||||
int m_startKey; // first key when drawing
|
||||
int m_lastKey;
|
||||
|
||||
@@ -452,9 +433,21 @@ private:
|
||||
bool m_noteBorders;
|
||||
bool m_ghostNoteBorders;
|
||||
QColor m_backgroundShade;
|
||||
/* white key properties */
|
||||
int m_whiteKeyWidth;
|
||||
QColor m_whiteKeyActiveTextColor;
|
||||
QColor m_whiteKeyActiveTextShadow;
|
||||
QBrush m_whiteKeyActiveBackground;
|
||||
QColor m_whiteKeyInactiveTextColor;
|
||||
QColor m_whiteKeyInactiveTextShadow;
|
||||
QBrush m_whiteKeyInactiveBackground;
|
||||
/* black key properties */
|
||||
int m_blackKeyWidth;
|
||||
QBrush m_blackKeyActiveBackground;
|
||||
QBrush m_blackKeyInactiveBackground;
|
||||
|
||||
signals:
|
||||
void positionChanged( const MidiTime & );
|
||||
void positionChanged( const TimePos & );
|
||||
} ;
|
||||
|
||||
|
||||
@@ -495,6 +488,7 @@ public:
|
||||
}
|
||||
|
||||
QSize sizeHint() const override;
|
||||
bool hasFocus() const;
|
||||
|
||||
signals:
|
||||
void currentPatternChanged();
|
||||
@@ -516,6 +510,7 @@ private:
|
||||
ComboBox * m_zoomingYComboBox;
|
||||
ComboBox * m_quantizeComboBox;
|
||||
ComboBox * m_noteLenComboBox;
|
||||
ComboBox * m_keyComboBox;
|
||||
ComboBox * m_scaleComboBox;
|
||||
ComboBox * m_chordComboBox;
|
||||
QPushButton * m_clearGhostButton;
|
||||
|
||||
@@ -56,6 +56,7 @@ protected:
|
||||
void mouseReleaseEvent( QMouseEvent * me ) override;
|
||||
void mouseMoveEvent( QMouseEvent * me ) override;
|
||||
void focusOutEvent( QFocusEvent * _fe ) override;
|
||||
void focusInEvent( QFocusEvent * fe ) override;
|
||||
void resizeEvent( QResizeEvent * _event ) override;
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
|
||||
class QLineEdit;
|
||||
class QTreeWidget;
|
||||
class QTreeWidgetItem;
|
||||
|
||||
|
||||
class PluginBrowser : public SideBarWidget
|
||||
@@ -53,8 +52,6 @@ private:
|
||||
|
||||
QWidget * m_view;
|
||||
QTreeWidget * m_descTree;
|
||||
QTreeWidgetItem * m_lmmsRoot;
|
||||
QTreeWidgetItem * m_lv2Root;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -32,16 +32,29 @@
|
||||
//! LMMS Plugins should use this to indicate errors
|
||||
enum PluginIssueType
|
||||
{
|
||||
// port flow & type
|
||||
unknownPortFlow,
|
||||
unknownPortType,
|
||||
// channel count
|
||||
tooManyInputChannels,
|
||||
tooManyOutputChannels,
|
||||
tooManyMidiInputChannels,
|
||||
tooManyMidiOutputChannels,
|
||||
noOutputChannel,
|
||||
// port metadata
|
||||
portHasNoDef,
|
||||
portHasNoMin,
|
||||
portHasNoMax,
|
||||
minGreaterMax,
|
||||
defaultValueNotInRange,
|
||||
logScaleMinMissing,
|
||||
logScaleMaxMissing,
|
||||
logScaleMinMaxDifferentSigns,
|
||||
// features
|
||||
featureNotSupported, //!< plugin requires functionality LMMS can't offer
|
||||
// misc
|
||||
badPortType, //!< port type not supported
|
||||
blacklisted,
|
||||
noIssue
|
||||
};
|
||||
|
||||
@@ -58,6 +71,9 @@ public:
|
||||
: m_issueType(it), m_info(msg)
|
||||
{
|
||||
}
|
||||
PluginIssueType type() const { return m_issueType; }
|
||||
bool operator==(const PluginIssue& other) const;
|
||||
bool operator<(const PluginIssue& other) const;
|
||||
friend QDebug operator<<(QDebug stream, const PluginIssue& iss);
|
||||
};
|
||||
|
||||
|
||||
49
include/PositionLine.h
Normal file
49
include/PositionLine.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* PositionLine.h - declaration of class PositionLine, a simple widget that
|
||||
* draws a line, mainly works with TimeLineWidget
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 POSITION_LINE_H
|
||||
#define POSITION_LINE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class PositionLine : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool tailGradient MEMBER m_hasTailGradient)
|
||||
Q_PROPERTY(QColor lineColor MEMBER m_lineColor)
|
||||
public:
|
||||
PositionLine(QWidget* parent);
|
||||
|
||||
public slots:
|
||||
void zoomChange(double zoom);
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent* pe) override;
|
||||
|
||||
bool m_hasTailGradient;
|
||||
QColor m_lineColor;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "NotePlayHandle.h"
|
||||
|
||||
|
||||
class DataFile;
|
||||
class InstrumentTrack;
|
||||
class PreviewTrackContainer;
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#define PROJECT_VERSION_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#include <limits>
|
||||
#include "lmms_export.h"
|
||||
|
||||
/*! \brief Version number parsing and comparison
|
||||
@@ -37,16 +40,17 @@
|
||||
class LMMS_EXPORT ProjectVersion
|
||||
{
|
||||
public:
|
||||
enum CompareType { Major, Minor, Release, Stage, Build };
|
||||
enum CompareType : int { None = 0, Major=1, Minor=2, Release=3, Stage=4, Build=5, All = std::numeric_limits<int>::max() };
|
||||
|
||||
ProjectVersion(QString version, CompareType c = Build);
|
||||
ProjectVersion(const char * version, CompareType c = Build);
|
||||
|
||||
ProjectVersion(QString version, CompareType c = All);
|
||||
ProjectVersion(const char * version, CompareType c = All);
|
||||
|
||||
const QString& getVersion() const { return m_version; }
|
||||
int getMajor() const { return m_major; }
|
||||
int getMinor() const { return m_minor; }
|
||||
int getRelease() const { return m_release; }
|
||||
QString getStage() const { return m_stage; }
|
||||
int getBuild() const { return m_build; }
|
||||
int getPatch() const { return m_patch; }
|
||||
const QStringList& getLabels() const { return m_labels; }
|
||||
CompareType getCompareType() const { return m_compareType; }
|
||||
ProjectVersion setCompareType(CompareType compareType) { m_compareType = compareType; return * this; }
|
||||
|
||||
@@ -55,11 +59,10 @@ public:
|
||||
|
||||
private:
|
||||
QString m_version;
|
||||
int m_major;
|
||||
int m_minor;
|
||||
int m_release;
|
||||
QString m_stage;
|
||||
int m_build;
|
||||
int m_major = 0;
|
||||
int m_minor = 0;
|
||||
int m_patch = 0;
|
||||
QStringList m_labels;
|
||||
CompareType m_compareType;
|
||||
} ;
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
{
|
||||
MM_OPERATORS
|
||||
public:
|
||||
handleState( bool _varying_pitch = false, int interpolation_mode = SRC_LINEAR );
|
||||
handleState(bool varyingPitch = false, int interpolationMode = SRC_LINEAR);
|
||||
virtual ~handleState();
|
||||
|
||||
const f_cnt_t frameIndex() const
|
||||
@@ -70,9 +70,9 @@ public:
|
||||
return m_frameIndex;
|
||||
}
|
||||
|
||||
void setFrameIndex( f_cnt_t _index )
|
||||
void setFrameIndex(f_cnt_t index)
|
||||
{
|
||||
m_frameIndex = _index;
|
||||
m_frameIndex = index;
|
||||
}
|
||||
|
||||
bool isBackwards() const
|
||||
@@ -80,11 +80,11 @@ public:
|
||||
return m_isBackwards;
|
||||
}
|
||||
|
||||
void setBackwards( bool _backwards )
|
||||
void setBackwards(bool backwards)
|
||||
{
|
||||
m_isBackwards = _backwards;
|
||||
m_isBackwards = backwards;
|
||||
}
|
||||
|
||||
|
||||
int interpolationMode() const
|
||||
{
|
||||
return m_interpolationMode;
|
||||
@@ -106,21 +106,35 @@ public:
|
||||
SampleBuffer();
|
||||
// constructor which either loads sample _audio_file or decodes
|
||||
// base64-data out of string
|
||||
SampleBuffer( const QString & _audio_file, bool _is_base64_data = false );
|
||||
SampleBuffer( const sampleFrame * _data, const f_cnt_t _frames );
|
||||
explicit SampleBuffer( const f_cnt_t _frames );
|
||||
SampleBuffer(const QString & audioFile, bool isBase64Data = false);
|
||||
SampleBuffer(const sampleFrame * data, const f_cnt_t frames);
|
||||
explicit SampleBuffer(const f_cnt_t frames);
|
||||
|
||||
virtual ~SampleBuffer();
|
||||
|
||||
bool play( sampleFrame * _ab, handleState * _state,
|
||||
const fpp_t _frames,
|
||||
const float _freq,
|
||||
const LoopMode _loopmode = LoopOff );
|
||||
bool play(
|
||||
sampleFrame * ab,
|
||||
handleState * state,
|
||||
const fpp_t frames,
|
||||
const float freq,
|
||||
const LoopMode loopMode = LoopOff
|
||||
);
|
||||
|
||||
void visualize( QPainter & _p, const QRect & _dr, const QRect & _clip, f_cnt_t _from_frame = 0, f_cnt_t _to_frame = 0 );
|
||||
inline void visualize( QPainter & _p, const QRect & _dr, f_cnt_t _from_frame = 0, f_cnt_t _to_frame = 0 )
|
||||
void visualize(
|
||||
QPainter & p,
|
||||
const QRect & dr,
|
||||
const QRect & clip,
|
||||
f_cnt_t fromFrame = 0,
|
||||
f_cnt_t toFrame = 0
|
||||
);
|
||||
inline void visualize(
|
||||
QPainter & p,
|
||||
const QRect & dr,
|
||||
f_cnt_t fromFrame = 0,
|
||||
f_cnt_t toFrame = 0
|
||||
)
|
||||
{
|
||||
visualize( _p, _dr, _dr, _from_frame, _to_frame );
|
||||
visualize(p, dr, dr, fromFrame, toFrame);
|
||||
}
|
||||
|
||||
inline const QString & audioFile() const
|
||||
@@ -148,22 +162,27 @@ public:
|
||||
return m_loopEndFrame;
|
||||
}
|
||||
|
||||
void setLoopStartFrame( f_cnt_t _start )
|
||||
void setLoopStartFrame(f_cnt_t start)
|
||||
{
|
||||
m_loopStartFrame = _start;
|
||||
m_loopStartFrame = start;
|
||||
}
|
||||
|
||||
void setLoopEndFrame( f_cnt_t _end )
|
||||
void setLoopEndFrame(f_cnt_t end)
|
||||
{
|
||||
m_loopEndFrame = _end;
|
||||
m_loopEndFrame = end;
|
||||
}
|
||||
|
||||
void setAllPointFrames( f_cnt_t _start, f_cnt_t _end, f_cnt_t _loopstart, f_cnt_t _loopend )
|
||||
void setAllPointFrames(
|
||||
f_cnt_t start,
|
||||
f_cnt_t end,
|
||||
f_cnt_t loopStart,
|
||||
f_cnt_t loopEnd
|
||||
)
|
||||
{
|
||||
m_startFrame = _start;
|
||||
m_endFrame = _end;
|
||||
m_loopStartFrame = _loopstart;
|
||||
m_loopEndFrame = _loopend;
|
||||
m_startFrame = start;
|
||||
m_endFrame = end;
|
||||
m_loopStartFrame = loopStart;
|
||||
m_loopEndFrame = loopEnd;
|
||||
}
|
||||
|
||||
inline f_cnt_t frames() const
|
||||
@@ -193,17 +212,17 @@ public:
|
||||
|
||||
int sampleLength() const
|
||||
{
|
||||
return double( m_endFrame - m_startFrame ) / m_sampleRate * 1000;
|
||||
return double(m_endFrame - m_startFrame) / m_sampleRate * 1000;
|
||||
}
|
||||
|
||||
inline void setFrequency( float _freq )
|
||||
inline void setFrequency(float freq)
|
||||
{
|
||||
m_frequency = _freq;
|
||||
m_frequency = freq;
|
||||
}
|
||||
|
||||
inline void setSampleRate( sample_rate_t _rate )
|
||||
inline void setSampleRate(sample_rate_t rate)
|
||||
{
|
||||
m_sampleRate = _rate;
|
||||
m_sampleRate = rate;
|
||||
}
|
||||
|
||||
inline const sampleFrame * data() const
|
||||
@@ -215,30 +234,28 @@ public:
|
||||
QString openAndSetAudioFile();
|
||||
QString openAndSetWaveformFile();
|
||||
|
||||
QString & toBase64( QString & _dst ) const;
|
||||
QString & toBase64(QString & dst) const;
|
||||
|
||||
|
||||
// protect calls from the GUI to this function with dataReadLock() and
|
||||
// dataUnlock()
|
||||
SampleBuffer * resample( const sample_rate_t _src_sr,
|
||||
const sample_rate_t _dst_sr );
|
||||
SampleBuffer * resample(const sample_rate_t srcSR, const sample_rate_t dstSR);
|
||||
|
||||
void normalizeSampleRate( const sample_rate_t _src_sr,
|
||||
bool _keep_settings = false );
|
||||
void normalizeSampleRate(const sample_rate_t srcSR, bool keepSettings = false);
|
||||
|
||||
// protect calls from the GUI to this function with dataReadLock() and
|
||||
// dataUnlock(), out of loops for efficiency
|
||||
inline sample_t userWaveSample( const float _sample ) const
|
||||
inline sample_t userWaveSample(const float sample) const
|
||||
{
|
||||
f_cnt_t frames = m_frames;
|
||||
sampleFrame * data = m_data;
|
||||
const float frame = _sample * frames;
|
||||
f_cnt_t f1 = static_cast<f_cnt_t>( frame ) % frames;
|
||||
if( f1 < 0 )
|
||||
const float frame = sample * frames;
|
||||
f_cnt_t f1 = static_cast<f_cnt_t>(frame) % frames;
|
||||
if (f1 < 0)
|
||||
{
|
||||
f1 += frames;
|
||||
}
|
||||
return linearInterpolate( data[f1][0], data[ (f1 + 1) % frames ][0], fraction( frame ) );
|
||||
return linearInterpolate(data[f1][0], data[(f1 + 1) % frames][0], fraction(frame));
|
||||
}
|
||||
|
||||
void dataReadLock()
|
||||
@@ -251,38 +268,44 @@ public:
|
||||
m_varLock.unlock();
|
||||
}
|
||||
|
||||
static QString tryToMakeRelative( const QString & _file );
|
||||
static QString tryToMakeAbsolute(const QString & file);
|
||||
|
||||
|
||||
public slots:
|
||||
void setAudioFile( const QString & _audio_file );
|
||||
void loadFromBase64( const QString & _data );
|
||||
void setStartFrame( const f_cnt_t _s );
|
||||
void setEndFrame( const f_cnt_t _e );
|
||||
void setAmplification( float _a );
|
||||
void setReversed( bool _on );
|
||||
void setAudioFile(const QString & audioFile);
|
||||
void loadFromBase64(const QString & data);
|
||||
void setStartFrame(const f_cnt_t s);
|
||||
void setEndFrame(const f_cnt_t e);
|
||||
void setAmplification(float a);
|
||||
void setReversed(bool on);
|
||||
void sampleRateChanged();
|
||||
|
||||
private:
|
||||
static sample_rate_t mixerSampleRate();
|
||||
|
||||
void update( bool _keep_settings = false );
|
||||
void update(bool keepSettings = false);
|
||||
|
||||
void convertIntToFloat ( int_sample_t * & _ibuf, f_cnt_t _frames, int _channels);
|
||||
void directFloatWrite ( sample_t * & _fbuf, f_cnt_t _frames, int _channels);
|
||||
void convertIntToFloat(int_sample_t * & ibuf, f_cnt_t frames, int channels);
|
||||
void directFloatWrite(sample_t * & fbuf, f_cnt_t frames, int channels);
|
||||
|
||||
f_cnt_t decodeSampleSF( QString _f, sample_t * & _buf,
|
||||
ch_cnt_t & _channels,
|
||||
sample_rate_t & _sample_rate );
|
||||
f_cnt_t decodeSampleSF(
|
||||
QString fileName,
|
||||
sample_t * & buf,
|
||||
ch_cnt_t & channels,
|
||||
sample_rate_t & samplerate
|
||||
);
|
||||
#ifdef LMMS_HAVE_OGGVORBIS
|
||||
f_cnt_t decodeSampleOGGVorbis( QString _f, int_sample_t * & _buf,
|
||||
ch_cnt_t & _channels,
|
||||
sample_rate_t & _sample_rate );
|
||||
f_cnt_t decodeSampleOGGVorbis(
|
||||
QString fileName,
|
||||
int_sample_t * & buf,
|
||||
ch_cnt_t & channels,
|
||||
sample_rate_t & samplerate
|
||||
);
|
||||
#endif
|
||||
f_cnt_t decodeSampleDS( QString _f, int_sample_t * & _buf,
|
||||
ch_cnt_t & _channels,
|
||||
sample_rate_t & _sample_rate );
|
||||
f_cnt_t decodeSampleDS(
|
||||
QString fileName,
|
||||
int_sample_t * & buf,
|
||||
ch_cnt_t & channels,
|
||||
sample_rate_t & samplerate
|
||||
);
|
||||
|
||||
QString m_audioFile;
|
||||
sampleFrame * m_origData;
|
||||
@@ -299,13 +322,19 @@ private:
|
||||
float m_frequency;
|
||||
sample_rate_t m_sampleRate;
|
||||
|
||||
sampleFrame * getSampleFragment( f_cnt_t _index, f_cnt_t _frames,
|
||||
LoopMode _loopmode,
|
||||
sampleFrame * * _tmp,
|
||||
bool * _backwards, f_cnt_t _loopstart, f_cnt_t _loopend,
|
||||
f_cnt_t _end ) const;
|
||||
f_cnt_t getLoopedIndex( f_cnt_t _index, f_cnt_t _startf, f_cnt_t _endf ) const;
|
||||
f_cnt_t getPingPongIndex( f_cnt_t _index, f_cnt_t _startf, f_cnt_t _endf ) const;
|
||||
sampleFrame * getSampleFragment(
|
||||
f_cnt_t index,
|
||||
f_cnt_t frames,
|
||||
LoopMode loopMode,
|
||||
sampleFrame * * tmp,
|
||||
bool * backwards,
|
||||
f_cnt_t loopStart,
|
||||
f_cnt_t loopEnd,
|
||||
f_cnt_t end
|
||||
) const;
|
||||
|
||||
f_cnt_t getLoopedIndex(f_cnt_t index, f_cnt_t startf, f_cnt_t endf) const;
|
||||
f_cnt_t getPingPongIndex(f_cnt_t index, f_cnt_t startf, f_cnt_t endf) const;
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QPair>
|
||||
|
||||
#include "MidiTime.h"
|
||||
#include "PlayHandle.h"
|
||||
#include "TimePos.h"
|
||||
|
||||
class BBTrack;
|
||||
class SampleBuffer;
|
||||
@@ -60,7 +60,7 @@ private:
|
||||
typedef QList<QPair<sampleFrame *, f_cnt_t> > bufferList;
|
||||
bufferList m_buffers;
|
||||
f_cnt_t m_framesRecorded;
|
||||
MidiTime m_minLength;
|
||||
TimePos m_minLength;
|
||||
|
||||
Track * m_track;
|
||||
BBTrack * m_bbTrack;
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "FxMixer.h"
|
||||
#include "FxLineLcdSpinBox.h"
|
||||
#include "Track.h"
|
||||
#include "TrackContentObjectView.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
class EffectRackView;
|
||||
class Knob;
|
||||
@@ -50,7 +52,7 @@ public:
|
||||
SampleTCO( Track * _track );
|
||||
virtual ~SampleTCO();
|
||||
|
||||
void changeLength( const MidiTime & _length ) override;
|
||||
void changeLength( const TimePos & _length ) override;
|
||||
const QString & sampleFile() const;
|
||||
|
||||
void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
|
||||
@@ -65,7 +67,7 @@ public:
|
||||
return m_sampleBuffer;
|
||||
}
|
||||
|
||||
MidiTime sampleLength() const;
|
||||
TimePos sampleLength() const;
|
||||
void setSampleStartFrame( f_cnt_t startFrame );
|
||||
void setSamplePlayLength( f_cnt_t length );
|
||||
TrackContentObjectView * createView( TrackView * _tv ) override;
|
||||
@@ -94,6 +96,7 @@ private:
|
||||
|
||||
signals:
|
||||
void sampleChanged();
|
||||
void wasReversed();
|
||||
|
||||
} ;
|
||||
|
||||
@@ -109,6 +112,7 @@ public:
|
||||
|
||||
public slots:
|
||||
void updateSample();
|
||||
void reverseSample();
|
||||
|
||||
|
||||
|
||||
@@ -137,10 +141,10 @@ public:
|
||||
SampleTrack( TrackContainer* tc );
|
||||
virtual ~SampleTrack();
|
||||
|
||||
virtual bool play( const MidiTime & _start, const fpp_t _frames,
|
||||
virtual bool play( const TimePos & _start, const fpp_t _frames,
|
||||
const f_cnt_t _frame_base, int _tco_num = -1 ) override;
|
||||
TrackView * createView( TrackContainerView* tcv ) override;
|
||||
TrackContentObject * createTCO( const MidiTime & _pos ) override;
|
||||
TrackContentObject* createTCO(const TimePos & pos) override;
|
||||
|
||||
|
||||
virtual void saveTrackSpecificSettings( QDomDocument & _doc,
|
||||
@@ -251,7 +255,7 @@ private:
|
||||
|
||||
TrackLabelButton * m_tlb;
|
||||
|
||||
FadeButton * getActivityIndicator()
|
||||
FadeButton * getActivityIndicator() override
|
||||
{
|
||||
return m_activityIndicator;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,8 @@ private slots:
|
||||
void toggleCompactTrackButtons(bool enabled);
|
||||
void toggleOneInstrumentTrackWindow(bool enabled);
|
||||
void toggleSideBarOnRight(bool enabled);
|
||||
void toggleLetPreviewsFinish(bool enabled);
|
||||
void toggleSoloLegacyBehavior(bool enabled);
|
||||
void toggleMMPZ(bool enabled);
|
||||
void toggleDisableBackup(bool enabled);
|
||||
void toggleOpenLastProject(bool enabled);
|
||||
@@ -132,6 +134,8 @@ private:
|
||||
bool m_compactTrackButtons;
|
||||
bool m_oneInstrumentTrackWindow;
|
||||
bool m_sideBarOnRight;
|
||||
bool m_letPreviewsFinish;
|
||||
bool m_soloLegacyBehavior;
|
||||
bool m_MMPZ;
|
||||
bool m_disableBackup;
|
||||
bool m_openLastProject;
|
||||
@@ -175,6 +179,7 @@ private:
|
||||
QComboBox * m_midiInterfaces;
|
||||
MswMap m_midiIfaceSetupWidgets;
|
||||
trMap m_midiIfaceNames;
|
||||
QComboBox * m_assignableMidiDevices;
|
||||
|
||||
// Paths settings widgets.
|
||||
QString m_workingDir;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <QtCore/QSharedMemory>
|
||||
#include <QtCore/QVector>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
|
||||
#include "TrackContainer.h"
|
||||
#include "Controller.h"
|
||||
@@ -81,11 +83,11 @@ public:
|
||||
bool hasErrors();
|
||||
QString errorSummary();
|
||||
|
||||
class PlayPos : public MidiTime
|
||||
class PlayPos : public TimePos
|
||||
{
|
||||
public:
|
||||
PlayPos( const int abs = 0 ) :
|
||||
MidiTime( abs ),
|
||||
TimePos( abs ),
|
||||
m_timeLine( NULL ),
|
||||
m_currentFrame( 0.0f )
|
||||
{
|
||||
@@ -131,27 +133,27 @@ public:
|
||||
return m_elapsedMilliSeconds[playMode];
|
||||
}
|
||||
|
||||
inline void setToTime(MidiTime const & midiTime)
|
||||
inline void setToTime(TimePos const & pos)
|
||||
{
|
||||
m_elapsedMilliSeconds[m_playMode] = midiTime.getTimeInMilliseconds(getTempo());
|
||||
m_playPos[m_playMode].setTicks(midiTime.getTicks());
|
||||
m_elapsedMilliSeconds[m_playMode] = pos.getTimeInMilliseconds(getTempo());
|
||||
m_playPos[m_playMode].setTicks(pos.getTicks());
|
||||
}
|
||||
|
||||
inline void setToTime(MidiTime const & midiTime, PlayModes playMode)
|
||||
inline void setToTime(TimePos const & pos, PlayModes playMode)
|
||||
{
|
||||
m_elapsedMilliSeconds[playMode] = midiTime.getTimeInMilliseconds(getTempo());
|
||||
m_playPos[playMode].setTicks(midiTime.getTicks());
|
||||
m_elapsedMilliSeconds[playMode] = pos.getTimeInMilliseconds(getTempo());
|
||||
m_playPos[playMode].setTicks(pos.getTicks());
|
||||
}
|
||||
|
||||
inline void setToTimeByTicks(tick_t ticks)
|
||||
{
|
||||
m_elapsedMilliSeconds[m_playMode] = MidiTime::ticksToMilliseconds(ticks, getTempo());
|
||||
m_elapsedMilliSeconds[m_playMode] = TimePos::ticksToMilliseconds(ticks, getTempo());
|
||||
m_playPos[m_playMode].setTicks(ticks);
|
||||
}
|
||||
|
||||
inline void setToTimeByTicks(tick_t ticks, PlayModes playMode)
|
||||
{
|
||||
m_elapsedMilliSeconds[playMode] = MidiTime::ticksToMilliseconds(ticks, getTempo());
|
||||
m_elapsedMilliSeconds[playMode] = TimePos::ticksToMilliseconds(ticks, getTempo());
|
||||
m_playPos[playMode].setTicks(ticks);
|
||||
}
|
||||
|
||||
@@ -162,7 +164,7 @@ public:
|
||||
|
||||
inline int ticksPerBar() const
|
||||
{
|
||||
return MidiTime::ticksPerBar(m_timeSigModel);
|
||||
return TimePos::ticksPerBar(m_timeSigModel);
|
||||
}
|
||||
|
||||
// Returns the beat position inside the bar, 0-based
|
||||
@@ -248,6 +250,10 @@ public:
|
||||
{
|
||||
return m_playPos[pm];
|
||||
}
|
||||
inline PlayPos & getPlayPos()
|
||||
{
|
||||
return getPlayPos(m_playMode);
|
||||
}
|
||||
inline const PlayPos & getPlayPos() const
|
||||
{
|
||||
return getPlayPos(m_playMode);
|
||||
@@ -269,7 +275,7 @@ public:
|
||||
}
|
||||
|
||||
//TODO: Add Q_DECL_OVERRIDE when Qt4 is dropped
|
||||
AutomatedValueMap automatedValuesAt(MidiTime time, int tcoNum = -1) const override;
|
||||
AutomatedValueMap automatedValuesAt(TimePos time, int tcoNum = -1) const override;
|
||||
|
||||
// file management
|
||||
void createNewProject();
|
||||
@@ -405,7 +411,7 @@ private:
|
||||
|
||||
void removeAllControllers();
|
||||
|
||||
void processAutomations(const TrackList& tracks, MidiTime timeStart, fpp_t frames);
|
||||
void processAutomations(const TrackList& tracks, TimePos timeStart, fpp_t frames);
|
||||
|
||||
void setModified(bool value);
|
||||
|
||||
@@ -441,7 +447,7 @@ private:
|
||||
|
||||
SaveOptions m_saveOptions;
|
||||
|
||||
QStringList m_errors;
|
||||
QHash<QString, int> m_errors;
|
||||
|
||||
PlayModes m_playMode;
|
||||
PlayPos m_playPos[Mode_Count];
|
||||
@@ -458,11 +464,11 @@ private:
|
||||
|
||||
int m_loopRenderCount;
|
||||
int m_loopRenderRemaining;
|
||||
MidiTime m_exportSongBegin;
|
||||
MidiTime m_exportLoopBegin;
|
||||
MidiTime m_exportLoopEnd;
|
||||
MidiTime m_exportSongEnd;
|
||||
MidiTime m_exportEffectiveLength;
|
||||
TimePos m_exportSongBegin;
|
||||
TimePos m_exportLoopBegin;
|
||||
TimePos m_exportLoopEnd;
|
||||
TimePos m_exportSongEnd;
|
||||
TimePos m_exportEffectiveLength;
|
||||
|
||||
friend class LmmsCore;
|
||||
friend class SongEditor;
|
||||
|
||||
@@ -28,10 +28,12 @@
|
||||
#define SONG_EDITOR_H
|
||||
|
||||
#include <QVector>
|
||||
#include <QLinearGradient>
|
||||
|
||||
#include "ActionGroup.h"
|
||||
#include "Editor.h"
|
||||
#include "TrackContainerView.h"
|
||||
#include "PositionLine.h"
|
||||
|
||||
class QLabel;
|
||||
class QScrollBar;
|
||||
@@ -45,16 +47,6 @@ class Song;
|
||||
class TextFloat;
|
||||
class TimeLineWidget;
|
||||
|
||||
class positionLine : public QWidget
|
||||
{
|
||||
public:
|
||||
positionLine( QWidget * parent );
|
||||
|
||||
private:
|
||||
void paintEvent( QPaintEvent * pe ) override;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
class SongEditor : public TrackContainerView
|
||||
{
|
||||
@@ -88,7 +80,7 @@ public slots:
|
||||
void setEditModeSelect();
|
||||
void toggleProportionalSnap();
|
||||
|
||||
void updatePosition( const MidiTime & t );
|
||||
void updatePosition( const TimePos & t );
|
||||
void updatePositionLine();
|
||||
void selectAllTcos( bool select );
|
||||
|
||||
@@ -140,7 +132,7 @@ private:
|
||||
TextFloat * m_mvsStatus;
|
||||
TextFloat * m_mpsStatus;
|
||||
|
||||
positionLine * m_positionLine;
|
||||
PositionLine * m_positionLine;
|
||||
|
||||
ComboBoxModel* m_zoomingModel;
|
||||
ComboBoxModel* m_snappingModel;
|
||||
@@ -158,12 +150,15 @@ private:
|
||||
QPoint m_scrollPos;
|
||||
QPoint m_mousePos;
|
||||
int m_rubberBandStartTrackview;
|
||||
MidiTime m_rubberbandStartMidipos;
|
||||
TimePos m_rubberbandStartTimePos;
|
||||
int m_currentZoomingValue;
|
||||
int m_trackHeadWidth;
|
||||
bool m_selectRegion;
|
||||
|
||||
friend class SongEditorWindow;
|
||||
|
||||
signals:
|
||||
void zoomingValueChanged( double );
|
||||
} ;
|
||||
|
||||
|
||||
@@ -215,6 +210,9 @@ private:
|
||||
ComboBox * m_zoomingComboBox;
|
||||
ComboBox * m_snappingComboBox;
|
||||
QLabel* m_snapSizeLabel;
|
||||
|
||||
QAction* m_insertBarAction;
|
||||
QAction* m_removeBarAction;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#ifndef STEP_RECORDER_H
|
||||
#define STEP_RECORDER_H
|
||||
|
||||
#include <QTime>
|
||||
#include <QElapsedTimer>
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
#include <QKeyEvent>
|
||||
@@ -41,14 +41,14 @@ class StepRecorder : public QObject
|
||||
StepRecorder(PianoRoll& pianoRoll, StepRecorderWidget& stepRecorderWidget);
|
||||
|
||||
void initialize();
|
||||
void start(const MidiTime& currentPosition,const MidiTime& stepLength);
|
||||
void start(const TimePos& currentPosition,const TimePos& stepLength);
|
||||
void stop();
|
||||
void notePressed(const Note & n);
|
||||
void noteReleased(const Note & n);
|
||||
bool keyPressEvent(QKeyEvent* ke);
|
||||
bool mousePressEvent(QMouseEvent* ke);
|
||||
void setCurrentPattern(Pattern* newPattern);
|
||||
void setStepsLength(const MidiTime& newLength);
|
||||
void setStepsLength(const TimePos& newLength);
|
||||
|
||||
QVector<Note*> getCurStepNotes();
|
||||
|
||||
@@ -73,7 +73,7 @@ class StepRecorder : public QObject
|
||||
void dismissStep();
|
||||
void prepareNewStep();
|
||||
|
||||
MidiTime getCurStepEndPos();
|
||||
TimePos getCurStepEndPos();
|
||||
|
||||
void updateCurStepNotes();
|
||||
void updateWidget();
|
||||
@@ -84,11 +84,11 @@ class StepRecorder : public QObject
|
||||
StepRecorderWidget& m_stepRecorderWidget;
|
||||
|
||||
bool m_isRecording = false;
|
||||
MidiTime m_curStepStartPos = 0;
|
||||
MidiTime m_curStepEndPos = 0;
|
||||
TimePos m_curStepStartPos = 0;
|
||||
TimePos m_curStepEndPos = 0;
|
||||
|
||||
MidiTime m_stepsLength;
|
||||
MidiTime m_curStepLength; // current step length refers to the step currently recorded. it may defer from m_stepsLength
|
||||
TimePos m_stepsLength;
|
||||
TimePos m_curStepLength; // current step length refers to the step currently recorded. it may defer from m_stepsLength
|
||||
// since the user can make current step larger
|
||||
|
||||
QTimer m_updateReleasedTimer;
|
||||
@@ -130,7 +130,7 @@ class StepRecorder : public QObject
|
||||
|
||||
private:
|
||||
bool m_pressed;
|
||||
QTime releasedTimer;
|
||||
QElapsedTimer releasedTimer;
|
||||
} ;
|
||||
|
||||
QVector<StepNote*> m_curStepNotes; // contains the current recorded step notes (i.e. while user still press the notes; before they are applied to the pattern)
|
||||
@@ -140,4 +140,4 @@ class StepRecorder : public QObject
|
||||
bool m_isStepInProgress = false;
|
||||
};
|
||||
|
||||
#endif //STEP_RECORDER_H
|
||||
#endif //STEP_RECORDER_H
|
||||
|
||||
@@ -44,13 +44,15 @@ public:
|
||||
|
||||
//API used by PianoRoll
|
||||
void setPixelsPerBar(int ppb);
|
||||
void setCurrentPosition(MidiTime currentPosition);
|
||||
void setCurrentPosition(TimePos currentPosition);
|
||||
void setMargins(const QMargins &qm);
|
||||
void setBottomMargin(const int marginBottom);
|
||||
QMargins margins();
|
||||
|
||||
//API used by StepRecorder
|
||||
void setStepsLength(MidiTime stepsLength);
|
||||
void setStartPosition(MidiTime pos);
|
||||
void setEndPosition(MidiTime pos);
|
||||
void setStepsLength(TimePos stepsLength);
|
||||
void setStartPosition(TimePos pos);
|
||||
void setEndPosition(TimePos pos);
|
||||
|
||||
void showHint();
|
||||
|
||||
@@ -60,16 +62,16 @@ private:
|
||||
int xCoordOfTick(int tick);
|
||||
|
||||
void drawVerLine(QPainter* painter, int x, const QColor& color, int top, int bottom);
|
||||
void drawVerLine(QPainter* painter, const MidiTime& pos, const QColor& color, int top, int bottom);
|
||||
void drawVerLine(QPainter* painter, const TimePos& pos, const QColor& color, int top, int bottom);
|
||||
|
||||
void updateBoundaries();
|
||||
|
||||
MidiTime m_stepsLength;
|
||||
MidiTime m_curStepStartPos;
|
||||
MidiTime m_curStepEndPos;
|
||||
TimePos m_stepsLength;
|
||||
TimePos m_curStepStartPos;
|
||||
TimePos m_curStepEndPos;
|
||||
|
||||
int m_ppb; // pixels per bar
|
||||
MidiTime m_currentPosition; // current position showed by on PianoRoll
|
||||
TimePos m_currentPosition; // current position showed by on PianoRoll
|
||||
|
||||
QColor m_colorLineStart;
|
||||
QColor m_colorLineEnd;
|
||||
@@ -86,7 +88,7 @@ private:
|
||||
const int m_marginRight;
|
||||
|
||||
signals:
|
||||
void positionChanged(const MidiTime & t);
|
||||
void positionChanged(const TimePos & t);
|
||||
} ;
|
||||
|
||||
#endif //STEP_RECOREDER_WIDGET_H
|
||||
|
||||
@@ -45,16 +45,8 @@ public:
|
||||
|
||||
static bool processDragEnterEvent( QDragEnterEvent * _dee,
|
||||
const QString & _allowed_keys );
|
||||
static QString decodeMimeKey( const QMimeData * mimeData );
|
||||
static QString decodeMimeValue( const QMimeData * mimeData );
|
||||
static QString decodeKey( QDropEvent * _de );
|
||||
static QString decodeValue( QDropEvent * _de );
|
||||
|
||||
static const char * mimeType()
|
||||
{
|
||||
return( "application/x-lmms-stringpair" );
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class LMMS_EXPORT SubWindow : public QMdiSubWindow
|
||||
Q_PROPERTY( QColor borderColor READ borderColor WRITE setBorderColor )
|
||||
|
||||
public:
|
||||
SubWindow( QWidget *parent = NULL, Qt::WindowFlags windowFlags = 0 );
|
||||
SubWindow( QWidget *parent = NULL, Qt::WindowFlags windowFlags = QFlag(0) );
|
||||
// same as QWidet::normalGeometry, but works properly under X11 (see https://bugreports.qt.io/browse/QTBUG-256)
|
||||
QRect getTrueNormalGeometry() const;
|
||||
QBrush activeColor() const;
|
||||
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
|
||||
|
||||
TimeLineWidget(int xoff, int yoff, float ppb, Song::PlayPos & pos,
|
||||
const MidiTime & begin, Song::PlayModes mode, QWidget * parent);
|
||||
const TimePos & begin, Song::PlayModes mode, QWidget * parent);
|
||||
virtual ~TimeLineWidget();
|
||||
|
||||
inline QColor const & getBarLineColor() const { return m_barLineColor; }
|
||||
@@ -123,23 +123,23 @@ public:
|
||||
return m_loopPoints == LoopPointsEnabled;
|
||||
}
|
||||
|
||||
inline const MidiTime & loopBegin() const
|
||||
inline const TimePos & loopBegin() const
|
||||
{
|
||||
return ( m_loopPos[0] < m_loopPos[1] ) ?
|
||||
m_loopPos[0] : m_loopPos[1];
|
||||
}
|
||||
|
||||
inline const MidiTime & loopEnd() const
|
||||
inline const TimePos & loopEnd() const
|
||||
{
|
||||
return ( m_loopPos[0] > m_loopPos[1] ) ?
|
||||
m_loopPos[0] : m_loopPos[1];
|
||||
}
|
||||
|
||||
inline void savePos( const MidiTime & pos )
|
||||
inline void savePos( const TimePos & pos )
|
||||
{
|
||||
m_savedPos = pos;
|
||||
}
|
||||
inline const MidiTime & savedPos() const
|
||||
inline const TimePos & savedPos() const
|
||||
{
|
||||
return m_savedPos;
|
||||
}
|
||||
@@ -150,6 +150,8 @@ public:
|
||||
update();
|
||||
}
|
||||
|
||||
void setXOffset(const int x);
|
||||
|
||||
void addToolButtons(QToolBar* _tool_bar );
|
||||
|
||||
|
||||
@@ -160,10 +162,10 @@ public:
|
||||
return "timeline";
|
||||
}
|
||||
|
||||
inline int markerX( const MidiTime & _t ) const
|
||||
inline int markerX( const TimePos & _t ) const
|
||||
{
|
||||
return m_xOffset + static_cast<int>( ( _t - m_begin ) *
|
||||
m_ppb / MidiTime::ticksPerBar() );
|
||||
m_ppb / TimePos::ticksPerBar() );
|
||||
}
|
||||
|
||||
signals:
|
||||
@@ -173,10 +175,10 @@ signals:
|
||||
|
||||
|
||||
public slots:
|
||||
void updatePosition( const MidiTime & );
|
||||
void updatePosition( const TimePos & );
|
||||
void updatePosition()
|
||||
{
|
||||
updatePosition( MidiTime() );
|
||||
updatePosition( TimePos() );
|
||||
}
|
||||
void toggleAutoScroll( int _n );
|
||||
void toggleLoopPoints( int _n );
|
||||
@@ -216,11 +218,11 @@ private:
|
||||
int m_posMarkerX;
|
||||
float m_ppb;
|
||||
Song::PlayPos & m_pos;
|
||||
const MidiTime & m_begin;
|
||||
const TimePos & m_begin;
|
||||
const Song::PlayModes m_mode;
|
||||
MidiTime m_loopPos[2];
|
||||
TimePos m_loopPos[2];
|
||||
|
||||
MidiTime m_savedPos;
|
||||
TimePos m_savedPos;
|
||||
|
||||
|
||||
TextFloat * m_hint;
|
||||
@@ -240,9 +242,10 @@ private:
|
||||
|
||||
|
||||
signals:
|
||||
void positionChanged( const MidiTime & _t );
|
||||
void positionChanged( const TimePos & _t );
|
||||
void loopPointStateLoaded( int _n );
|
||||
void positionMarkerMoved();
|
||||
void loadBehaviourAtStop( int _n );
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* MidiTime.h - declaration of class MidiTime which provides data type for
|
||||
* position- and length-variables
|
||||
* TimePos.h - declaration of class TimePos which provides data type for
|
||||
* position- and length-variables
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net
|
||||
*
|
||||
@@ -24,8 +24,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MIDI_TIME_H
|
||||
#define MIDI_TIME_H
|
||||
#ifndef TIME_POS_H
|
||||
#define TIME_POS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
@@ -40,13 +40,15 @@ const int DefaultBeatsPerBar = DefaultTicksPerBar / DefaultStepsPerBar;
|
||||
|
||||
class MeterModel;
|
||||
|
||||
/**
|
||||
Represents a time signature, in which the numerator is the number of beats
|
||||
in a bar, while the denominator is the type of note representing a beat.
|
||||
|
||||
Example: 6/8 means 6 beats in a bar with each beat having a duration of one 8th-note.
|
||||
*/
|
||||
class LMMS_EXPORT TimeSig
|
||||
{
|
||||
public:
|
||||
// in a time signature,
|
||||
// the numerator represents the number of beats in a measure.
|
||||
// the denominator indicates which type of note represents a beat.
|
||||
// example: 6/8 means 6 beats in a measure, where each beat has duration equal to one 8th-note.
|
||||
TimeSig( int num, int denom );
|
||||
TimeSig( const MeterModel &model );
|
||||
int numerator() const;
|
||||
@@ -57,17 +59,20 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class LMMS_EXPORT MidiTime
|
||||
/**
|
||||
Represents a position in time or length of a note or event, in ticks, beats, and bars
|
||||
*/
|
||||
class LMMS_EXPORT TimePos
|
||||
{
|
||||
public:
|
||||
MidiTime( const bar_t bar, const tick_t ticks );
|
||||
MidiTime( const tick_t ticks = 0 );
|
||||
TimePos( const bar_t bar, const tick_t ticks );
|
||||
TimePos( const tick_t ticks = 0 );
|
||||
|
||||
MidiTime quantize(float) const;
|
||||
MidiTime toAbsoluteBar() const;
|
||||
TimePos quantize(float) const;
|
||||
TimePos toAbsoluteBar() const;
|
||||
|
||||
MidiTime& operator+=( const MidiTime& time );
|
||||
MidiTime& operator-=( const MidiTime& time );
|
||||
TimePos& operator+=( const TimePos& time );
|
||||
TimePos& operator-=( const TimePos& time );
|
||||
|
||||
// return the bar, rounded down and 0-based
|
||||
bar_t getBar() const;
|
||||
@@ -92,12 +97,12 @@ public:
|
||||
|
||||
double getTimeInMilliseconds( bpm_t beatsPerMinute ) const;
|
||||
|
||||
static MidiTime fromFrames( const f_cnt_t frames, const float framesPerTick );
|
||||
static TimePos fromFrames( const f_cnt_t frames, const float framesPerTick );
|
||||
static tick_t ticksPerBar();
|
||||
static tick_t ticksPerBar( const TimeSig &sig );
|
||||
static int stepsPerBar();
|
||||
static void setTicksPerBar( tick_t tpt );
|
||||
static MidiTime stepPosition( int step );
|
||||
static TimePos stepPosition( int step );
|
||||
static double ticksToMilliseconds( tick_t ticks, bpm_t beatsPerMinute );
|
||||
static double ticksToMilliseconds( double ticks, bpm_t beatsPerMinute );
|
||||
|
||||
580
include/Track.h
580
include/Track.h
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Track.h - declaration of classes concerning tracks -> necessary for all
|
||||
* track-like objects (beat/bassline, sample-track...)
|
||||
* Track.h - declaration of Track class
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -26,42 +25,22 @@
|
||||
#ifndef TRACK_H
|
||||
#define TRACK_H
|
||||
|
||||
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QList>
|
||||
#include <QWidget>
|
||||
#include <QColor>
|
||||
#include <QMimeData>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "MidiTime.h"
|
||||
#include "Rubberband.h"
|
||||
#include "JournallingObject.h"
|
||||
#include "AutomatableModel.h"
|
||||
#include "ModelView.h"
|
||||
#include "DataFile.h"
|
||||
#include "FadeButton.h"
|
||||
#include "JournallingObject.h"
|
||||
#include "lmms_basics.h"
|
||||
|
||||
|
||||
class QMenu;
|
||||
class QPushButton;
|
||||
|
||||
class PixmapButton;
|
||||
class TextFloat;
|
||||
class Track;
|
||||
class TrackContentObjectView;
|
||||
class TimePos;
|
||||
class TrackContainer;
|
||||
class TrackContainerView;
|
||||
class TrackContentWidget;
|
||||
class TrackContentObject;
|
||||
class TrackView;
|
||||
|
||||
|
||||
const int DEFAULT_SETTINGS_WIDGET_WIDTH = 224;
|
||||
const int TRACK_OP_WIDTH = 78;
|
||||
// This shaves 150-ish pixels off track buttons,
|
||||
// ruled from config: ui.compacttrackbuttons
|
||||
const int DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT = 96;
|
||||
const int TRACK_OP_WIDTH_COMPACT = 62;
|
||||
|
||||
/*! The minimum track height in pixels
|
||||
*
|
||||
* Tracks can be resized by shift-dragging anywhere inside the track
|
||||
@@ -70,409 +49,10 @@ const int TRACK_OP_WIDTH_COMPACT = 62;
|
||||
const int MINIMAL_TRACK_HEIGHT = 32;
|
||||
const int DEFAULT_TRACK_HEIGHT = 32;
|
||||
|
||||
const int TCO_BORDER_WIDTH = 2;
|
||||
|
||||
char const *const FILENAME_FILTER = "[\\0000-\x1f\"*/:<>?\\\\|\x7f]";
|
||||
|
||||
|
||||
class LMMS_EXPORT TrackContentObject : public Model, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
MM_OPERATORS
|
||||
mapPropertyFromModel(bool,isMuted,setMuted,m_mutedModel);
|
||||
mapPropertyFromModel(bool,isSolo,setSolo,m_soloModel);
|
||||
public:
|
||||
TrackContentObject( Track * track );
|
||||
virtual ~TrackContentObject();
|
||||
|
||||
inline Track * getTrack() const
|
||||
{
|
||||
return m_track;
|
||||
}
|
||||
|
||||
inline const QString & name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
inline void setName( const QString & name )
|
||||
{
|
||||
m_name = name;
|
||||
emit dataChanged();
|
||||
}
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return name();
|
||||
}
|
||||
|
||||
|
||||
inline const MidiTime & startPosition() const
|
||||
{
|
||||
return m_startPosition;
|
||||
}
|
||||
|
||||
inline MidiTime endPosition() const
|
||||
{
|
||||
const int sp = m_startPosition;
|
||||
return sp + m_length;
|
||||
}
|
||||
|
||||
inline const MidiTime & length() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
inline void setAutoResize( const bool r )
|
||||
{
|
||||
m_autoResize = r;
|
||||
}
|
||||
|
||||
inline const bool getAutoResize() const
|
||||
{
|
||||
return m_autoResize;
|
||||
}
|
||||
|
||||
virtual void movePosition( const MidiTime & pos );
|
||||
virtual void changeLength( const MidiTime & length );
|
||||
|
||||
virtual TrackContentObjectView * createView( TrackView * tv ) = 0;
|
||||
|
||||
inline void selectViewOnCreate( bool select )
|
||||
{
|
||||
m_selectViewOnCreate = select;
|
||||
}
|
||||
|
||||
inline bool getSelectViewOnCreate()
|
||||
{
|
||||
return m_selectViewOnCreate;
|
||||
}
|
||||
|
||||
/// Returns true if and only if a->startPosition() < b->startPosition()
|
||||
static bool comparePosition(const TrackContentObject* a, const TrackContentObject* b);
|
||||
|
||||
MidiTime startTimeOffset() const;
|
||||
void setStartTimeOffset( const MidiTime &startTimeOffset );
|
||||
|
||||
public slots:
|
||||
void copy();
|
||||
void paste();
|
||||
void toggleMute();
|
||||
|
||||
|
||||
signals:
|
||||
void lengthChanged();
|
||||
void positionChanged();
|
||||
void destroyedTCO();
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
NoAction,
|
||||
Move,
|
||||
Resize
|
||||
} ;
|
||||
|
||||
Track * m_track;
|
||||
QString m_name;
|
||||
|
||||
MidiTime m_startPosition;
|
||||
MidiTime m_length;
|
||||
MidiTime m_startTimeOffset;
|
||||
|
||||
BoolModel m_mutedModel;
|
||||
BoolModel m_soloModel;
|
||||
bool m_autoResize;
|
||||
|
||||
bool m_selectViewOnCreate;
|
||||
|
||||
friend class TrackContentObjectView;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
class TrackContentObjectView : public selectableObject, public ModelView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// theming qproperties
|
||||
Q_PROPERTY( QColor mutedColor READ mutedColor WRITE setMutedColor )
|
||||
Q_PROPERTY( QColor mutedBackgroundColor READ mutedBackgroundColor WRITE setMutedBackgroundColor )
|
||||
Q_PROPERTY( QColor selectedColor READ selectedColor WRITE setSelectedColor )
|
||||
Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor )
|
||||
Q_PROPERTY( QColor textBackgroundColor READ textBackgroundColor WRITE setTextBackgroundColor )
|
||||
Q_PROPERTY( QColor textShadowColor READ textShadowColor WRITE setTextShadowColor )
|
||||
Q_PROPERTY( QColor BBPatternBackground READ BBPatternBackground WRITE setBBPatternBackground )
|
||||
Q_PROPERTY( bool gradient READ gradient WRITE setGradient )
|
||||
|
||||
public:
|
||||
TrackContentObjectView( TrackContentObject * tco, TrackView * tv );
|
||||
virtual ~TrackContentObjectView();
|
||||
|
||||
bool fixedTCOs();
|
||||
|
||||
inline TrackContentObject * getTrackContentObject()
|
||||
{
|
||||
return m_tco;
|
||||
}
|
||||
|
||||
inline TrackView * getTrackView()
|
||||
{
|
||||
return m_trackView;
|
||||
}
|
||||
|
||||
// qproperty access func
|
||||
QColor mutedColor() const;
|
||||
QColor mutedBackgroundColor() const;
|
||||
QColor selectedColor() const;
|
||||
QColor textColor() const;
|
||||
QColor textBackgroundColor() const;
|
||||
QColor textShadowColor() const;
|
||||
QColor BBPatternBackground() const;
|
||||
bool gradient() const;
|
||||
void setMutedColor( const QColor & c );
|
||||
void setMutedBackgroundColor( const QColor & c );
|
||||
void setSelectedColor( const QColor & c );
|
||||
void setTextColor( const QColor & c );
|
||||
void setTextBackgroundColor( const QColor & c );
|
||||
void setTextShadowColor( const QColor & c );
|
||||
void setBBPatternBackground( const QColor & c );
|
||||
void setGradient( const bool & b );
|
||||
|
||||
// access needsUpdate member variable
|
||||
bool needsUpdate();
|
||||
void setNeedsUpdate( bool b );
|
||||
|
||||
public slots:
|
||||
virtual bool close();
|
||||
void cut();
|
||||
void remove();
|
||||
void update() override;
|
||||
|
||||
protected:
|
||||
virtual void constructContextMenu( QMenu * )
|
||||
{
|
||||
}
|
||||
|
||||
void contextMenuEvent( QContextMenuEvent * cme ) override;
|
||||
void dragEnterEvent( QDragEnterEvent * dee ) override;
|
||||
void dropEvent( QDropEvent * de ) override;
|
||||
void leaveEvent( QEvent * e ) override;
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void mouseMoveEvent( QMouseEvent * me ) override;
|
||||
void mouseReleaseEvent( QMouseEvent * me ) override;
|
||||
void resizeEvent( QResizeEvent * re ) override
|
||||
{
|
||||
m_needsUpdate = true;
|
||||
selectableObject::resizeEvent( re );
|
||||
}
|
||||
|
||||
float pixelsPerBar();
|
||||
|
||||
|
||||
DataFile createTCODataFiles(const QVector<TrackContentObjectView *> & tcos) const;
|
||||
|
||||
virtual void paintTextLabel(QString const & text, QPainter & painter);
|
||||
|
||||
|
||||
protected slots:
|
||||
void updateLength();
|
||||
void updatePosition();
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
NoAction,
|
||||
Move,
|
||||
MoveSelection,
|
||||
Resize,
|
||||
ResizeLeft,
|
||||
CopySelection,
|
||||
ToggleSelected
|
||||
} ;
|
||||
|
||||
static TextFloat * s_textFloat;
|
||||
|
||||
TrackContentObject * m_tco;
|
||||
TrackView * m_trackView;
|
||||
Actions m_action;
|
||||
QPoint m_initialMousePos;
|
||||
QPoint m_initialMouseGlobalPos;
|
||||
MidiTime m_initialTCOPos;
|
||||
MidiTime m_initialTCOEnd;
|
||||
QVector<MidiTime> m_initialOffsets;
|
||||
|
||||
TextFloat * m_hint;
|
||||
|
||||
// qproperty fields
|
||||
QColor m_mutedColor;
|
||||
QColor m_mutedBackgroundColor;
|
||||
QColor m_selectedColor;
|
||||
QColor m_textColor;
|
||||
QColor m_textBackgroundColor;
|
||||
QColor m_textShadowColor;
|
||||
QColor m_BBPatternBackground;
|
||||
bool m_gradient;
|
||||
|
||||
bool m_needsUpdate;
|
||||
inline void setInitialPos( QPoint pos )
|
||||
{
|
||||
m_initialMousePos = pos;
|
||||
m_initialMouseGlobalPos = mapToGlobal( pos );
|
||||
m_initialTCOPos = m_tco->startPosition();
|
||||
m_initialTCOEnd = m_initialTCOPos + m_tco->length();
|
||||
}
|
||||
void setInitialOffsets();
|
||||
|
||||
bool mouseMovedDistance( QMouseEvent * me, int distance );
|
||||
MidiTime draggedTCOPos( QMouseEvent * me );
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TrackContentWidget : public QWidget, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// qproperties for track background gradients
|
||||
Q_PROPERTY( QBrush darkerColor READ darkerColor WRITE setDarkerColor )
|
||||
Q_PROPERTY( QBrush lighterColor READ lighterColor WRITE setLighterColor )
|
||||
Q_PROPERTY( QBrush gridColor READ gridColor WRITE setGridColor )
|
||||
Q_PROPERTY( QBrush embossColor READ embossColor WRITE setEmbossColor )
|
||||
|
||||
public:
|
||||
TrackContentWidget( TrackView * parent );
|
||||
virtual ~TrackContentWidget();
|
||||
|
||||
/*! \brief Updates the background tile pixmap. */
|
||||
void updateBackground();
|
||||
|
||||
void addTCOView( TrackContentObjectView * tcov );
|
||||
void removeTCOView( TrackContentObjectView * tcov );
|
||||
void removeTCOView( int tcoNum )
|
||||
{
|
||||
if( tcoNum >= 0 && tcoNum < m_tcoViews.size() )
|
||||
{
|
||||
removeTCOView( m_tcoViews[tcoNum] );
|
||||
}
|
||||
}
|
||||
|
||||
bool canPasteSelection( MidiTime tcoPos, const QDropEvent *de );
|
||||
bool pasteSelection( MidiTime tcoPos, QDropEvent * de );
|
||||
|
||||
MidiTime endPosition( const MidiTime & posStart );
|
||||
|
||||
// qproperty access methods
|
||||
|
||||
QBrush darkerColor() const;
|
||||
QBrush lighterColor() const;
|
||||
QBrush gridColor() const;
|
||||
QBrush embossColor() const;
|
||||
|
||||
void setDarkerColor( const QBrush & c );
|
||||
void setLighterColor( const QBrush & c );
|
||||
void setGridColor( const QBrush & c );
|
||||
void setEmbossColor( const QBrush & c);
|
||||
|
||||
public slots:
|
||||
void update();
|
||||
void changePosition( const MidiTime & newPos = MidiTime( -1 ) );
|
||||
|
||||
protected:
|
||||
void dragEnterEvent( QDragEnterEvent * dee ) override;
|
||||
void dropEvent( QDropEvent * de ) override;
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void paintEvent( QPaintEvent * pe ) override;
|
||||
void resizeEvent( QResizeEvent * re ) override;
|
||||
|
||||
QString nodeName() const override
|
||||
{
|
||||
return "trackcontentwidget";
|
||||
}
|
||||
|
||||
void saveSettings( QDomDocument& doc, QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(doc)
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
void loadSettings( const QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Track * getTrack();
|
||||
MidiTime getPosition( int mouseX );
|
||||
|
||||
TrackView * m_trackView;
|
||||
|
||||
typedef QVector<TrackContentObjectView *> tcoViewVector;
|
||||
tcoViewVector m_tcoViews;
|
||||
|
||||
QPixmap m_background;
|
||||
|
||||
// qproperty fields
|
||||
QBrush m_darkerColor;
|
||||
QBrush m_lighterColor;
|
||||
QBrush m_gridColor;
|
||||
QBrush m_embossColor;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TrackOperationsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrackOperationsWidget( TrackView * parent );
|
||||
~TrackOperationsWidget();
|
||||
|
||||
|
||||
protected:
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void paintEvent( QPaintEvent * pe ) override;
|
||||
|
||||
|
||||
private slots:
|
||||
void cloneTrack();
|
||||
void removeTrack();
|
||||
void updateMenu();
|
||||
void toggleRecording(bool on);
|
||||
void recordingOn();
|
||||
void recordingOff();
|
||||
void clearTrack();
|
||||
|
||||
private:
|
||||
static QPixmap * s_grip;
|
||||
|
||||
TrackView * m_trackView;
|
||||
|
||||
QPushButton * m_trackOps;
|
||||
PixmapButton * m_muteBtn;
|
||||
PixmapButton * m_soloBtn;
|
||||
|
||||
|
||||
friend class TrackView;
|
||||
|
||||
signals:
|
||||
void trackRemovalScheduled( TrackView * t );
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// base-class for all tracks
|
||||
//! Base-class for all tracks
|
||||
class LMMS_EXPORT Track : public Model, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -509,12 +89,12 @@ public:
|
||||
return m_type;
|
||||
}
|
||||
|
||||
virtual bool play( const MidiTime & start, const fpp_t frames,
|
||||
virtual bool play( const TimePos & start, const fpp_t frames,
|
||||
const f_cnt_t frameBase, int tcoNum = -1 ) = 0;
|
||||
|
||||
|
||||
virtual TrackView * createView( TrackContainerView * view ) = 0;
|
||||
virtual TrackContentObject * createTCO( const MidiTime & pos ) = 0;
|
||||
virtual TrackContentObject * createTCO( const TimePos & pos ) = 0;
|
||||
|
||||
virtual void saveTrackSpecificSettings( QDomDocument & doc,
|
||||
QDomElement & parent ) = 0;
|
||||
@@ -543,15 +123,15 @@ public:
|
||||
{
|
||||
return m_trackContentObjects;
|
||||
}
|
||||
void getTCOsInRange( tcoVector & tcoV, const MidiTime & start,
|
||||
const MidiTime & end );
|
||||
void getTCOsInRange( tcoVector & tcoV, const TimePos & start,
|
||||
const TimePos & end );
|
||||
void swapPositionOfTCOs( int tcoNum1, int tcoNum2 );
|
||||
|
||||
void createTCOsForBB( int bb );
|
||||
|
||||
|
||||
void insertBar( const MidiTime & pos );
|
||||
void removeBar( const MidiTime & pos );
|
||||
void insertBar( const TimePos & pos );
|
||||
void removeBar( const TimePos & pos );
|
||||
|
||||
bar_t length() const;
|
||||
|
||||
@@ -597,7 +177,16 @@ public:
|
||||
{
|
||||
return m_processingLock.tryLock();
|
||||
}
|
||||
|
||||
|
||||
QColor color()
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
bool useColor()
|
||||
{
|
||||
return m_hasColor;
|
||||
}
|
||||
|
||||
BoolModel* getMutedModel();
|
||||
|
||||
public slots:
|
||||
@@ -609,6 +198,8 @@ public slots:
|
||||
|
||||
void toggleSolo();
|
||||
|
||||
void trackColorChanged( QColor & c );
|
||||
void trackColorReset();
|
||||
|
||||
private:
|
||||
TrackContainer* m_trackContainer;
|
||||
@@ -627,6 +218,9 @@ private:
|
||||
tcoVector m_trackContentObjects;
|
||||
|
||||
QMutex m_processingLock;
|
||||
|
||||
QColor m_color;
|
||||
bool m_hasColor;
|
||||
|
||||
friend class TrackView;
|
||||
|
||||
@@ -640,122 +234,4 @@ signals:
|
||||
|
||||
|
||||
|
||||
|
||||
class TrackView : public QWidget, public ModelView, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrackView( Track * _track, TrackContainerView* tcv );
|
||||
virtual ~TrackView();
|
||||
|
||||
inline const Track * getTrack() const
|
||||
{
|
||||
return m_track;
|
||||
}
|
||||
|
||||
inline Track * getTrack()
|
||||
{
|
||||
return m_track;
|
||||
}
|
||||
|
||||
inline TrackContainerView* trackContainerView()
|
||||
{
|
||||
return m_trackContainerView;
|
||||
}
|
||||
|
||||
inline TrackOperationsWidget * getTrackOperationsWidget()
|
||||
{
|
||||
return &m_trackOperationsWidget;
|
||||
}
|
||||
|
||||
inline QWidget * getTrackSettingsWidget()
|
||||
{
|
||||
return &m_trackSettingsWidget;
|
||||
}
|
||||
|
||||
inline TrackContentWidget * getTrackContentWidget()
|
||||
{
|
||||
return &m_trackContentWidget;
|
||||
}
|
||||
|
||||
bool isMovingTrack() const
|
||||
{
|
||||
return m_action == MoveTrack;
|
||||
}
|
||||
|
||||
virtual void update();
|
||||
|
||||
// Create a menu for assigning/creating channels for this track
|
||||
// Currently instrument track and sample track supports it
|
||||
virtual QMenu * createFxMenu(QString title, QString newFxLabel);
|
||||
|
||||
|
||||
public slots:
|
||||
virtual bool close();
|
||||
|
||||
|
||||
protected:
|
||||
void modelChanged() override;
|
||||
|
||||
void saveSettings( QDomDocument& doc, QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(doc)
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
void loadSettings( const QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
QString nodeName() const override
|
||||
{
|
||||
return "trackview";
|
||||
}
|
||||
|
||||
|
||||
void dragEnterEvent( QDragEnterEvent * dee ) override;
|
||||
void dropEvent( QDropEvent * de ) override;
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void mouseMoveEvent( QMouseEvent * me ) override;
|
||||
void mouseReleaseEvent( QMouseEvent * me ) override;
|
||||
void paintEvent( QPaintEvent * pe ) override;
|
||||
void resizeEvent( QResizeEvent * re ) override;
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
NoAction,
|
||||
MoveTrack,
|
||||
ResizeTrack
|
||||
} ;
|
||||
|
||||
Track * m_track;
|
||||
TrackContainerView * m_trackContainerView;
|
||||
|
||||
TrackOperationsWidget m_trackOperationsWidget;
|
||||
QWidget m_trackSettingsWidget;
|
||||
TrackContentWidget m_trackContentWidget;
|
||||
|
||||
Actions m_action;
|
||||
|
||||
virtual FadeButton * getActivityIndicator()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void setIndicatorMute(FadeButton* indicator, bool muted);
|
||||
|
||||
friend class TrackLabelButton;
|
||||
|
||||
|
||||
private slots:
|
||||
void createTCOView( TrackContentObject * tco );
|
||||
void muteChanged();
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -93,13 +93,13 @@ public:
|
||||
return m_TrackContainerType;
|
||||
}
|
||||
|
||||
virtual AutomatedValueMap automatedValuesAt(MidiTime time, int tcoNum = -1) const;
|
||||
virtual AutomatedValueMap automatedValuesAt(TimePos time, int tcoNum = -1) const;
|
||||
|
||||
signals:
|
||||
void trackAdded( Track * _track );
|
||||
|
||||
protected:
|
||||
static AutomatedValueMap automatedValuesFromTracks(const TrackList &tracks, MidiTime timeStart, int tcoNum = -1);
|
||||
static AutomatedValueMap automatedValuesFromTracks(const TrackList &tracks, TimePos timeStart, int tcoNum = -1);
|
||||
|
||||
mutable QReadWriteLock m_tracksMutex;
|
||||
|
||||
@@ -115,30 +115,4 @@ private:
|
||||
} ;
|
||||
|
||||
|
||||
class DummyTrackContainer : public TrackContainer
|
||||
{
|
||||
public:
|
||||
DummyTrackContainer();
|
||||
|
||||
virtual ~DummyTrackContainer()
|
||||
{
|
||||
}
|
||||
|
||||
QString nodeName() const override
|
||||
{
|
||||
return "DummyTrackContainer";
|
||||
}
|
||||
|
||||
InstrumentTrack * dummyInstrumentTrack()
|
||||
{
|
||||
return m_dummyInstrumentTrack;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
InstrumentTrack * m_dummyInstrumentTrack;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,12 +31,15 @@
|
||||
#include <QWidget>
|
||||
#include <QThread>
|
||||
|
||||
#include "Track.h"
|
||||
#include "JournallingObject.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "ModelView.h"
|
||||
#include "Rubberband.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
|
||||
class QVBoxLayout;
|
||||
|
||||
class InstrumentTrack;
|
||||
class TrackContainer;
|
||||
|
||||
|
||||
@@ -57,7 +60,7 @@ public:
|
||||
return m_scrollArea;
|
||||
}
|
||||
|
||||
inline const MidiTime & currentPosition() const
|
||||
inline const TimePos & currentPosition() const
|
||||
{
|
||||
return m_currentPosition;
|
||||
}
|
||||
@@ -143,7 +146,7 @@ protected:
|
||||
|
||||
void resizeEvent( QResizeEvent * ) override;
|
||||
|
||||
MidiTime m_currentPosition;
|
||||
TimePos m_currentPosition;
|
||||
|
||||
|
||||
private:
|
||||
@@ -182,7 +185,7 @@ private:
|
||||
|
||||
|
||||
signals:
|
||||
void positionChanged( const MidiTime & _pos );
|
||||
void positionChanged( const TimePos & _pos );
|
||||
|
||||
|
||||
} ;
|
||||
|
||||
183
include/TrackContentObject.h
Normal file
183
include/TrackContentObject.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* TrackConteintObject.h - declaration of TrackContentObject class
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 TRACK_CONTENT_OBJECT_H
|
||||
#define TRACK_CONTENT_OBJECT_H
|
||||
|
||||
#include <QColor>
|
||||
|
||||
#include "AutomatableModel.h"
|
||||
#include "lmms_basics.h"
|
||||
|
||||
|
||||
class Track;
|
||||
class TrackContentObjectView;
|
||||
class TrackContainer;
|
||||
class TrackView;
|
||||
|
||||
|
||||
class LMMS_EXPORT TrackContentObject : public Model, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
MM_OPERATORS
|
||||
mapPropertyFromModel(bool,isMuted,setMuted,m_mutedModel);
|
||||
mapPropertyFromModel(bool,isSolo,setSolo,m_soloModel);
|
||||
public:
|
||||
TrackContentObject( Track * track );
|
||||
virtual ~TrackContentObject();
|
||||
|
||||
inline Track * getTrack() const
|
||||
{
|
||||
return m_track;
|
||||
}
|
||||
|
||||
inline const QString & name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
inline void setName( const QString & name )
|
||||
{
|
||||
m_name = name;
|
||||
emit dataChanged();
|
||||
}
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return name();
|
||||
}
|
||||
|
||||
|
||||
inline const TimePos & startPosition() const
|
||||
{
|
||||
return m_startPosition;
|
||||
}
|
||||
|
||||
inline TimePos endPosition() const
|
||||
{
|
||||
const int sp = m_startPosition;
|
||||
return sp + m_length;
|
||||
}
|
||||
|
||||
inline const TimePos & length() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
inline void setAutoResize( const bool r )
|
||||
{
|
||||
m_autoResize = r;
|
||||
}
|
||||
|
||||
inline const bool getAutoResize() const
|
||||
{
|
||||
return m_autoResize;
|
||||
}
|
||||
|
||||
QColor color() const
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void setColor( const QColor & c )
|
||||
{
|
||||
m_color = c;
|
||||
}
|
||||
|
||||
bool hasColor();
|
||||
|
||||
void useCustomClipColor( bool b );
|
||||
|
||||
bool usesCustomClipColor()
|
||||
{
|
||||
return m_useCustomClipColor;
|
||||
}
|
||||
|
||||
virtual void movePosition( const TimePos & pos );
|
||||
virtual void changeLength( const TimePos & length );
|
||||
|
||||
virtual TrackContentObjectView * createView( TrackView * tv ) = 0;
|
||||
|
||||
inline void selectViewOnCreate( bool select )
|
||||
{
|
||||
m_selectViewOnCreate = select;
|
||||
}
|
||||
|
||||
inline bool getSelectViewOnCreate()
|
||||
{
|
||||
return m_selectViewOnCreate;
|
||||
}
|
||||
|
||||
/// Returns true if and only if a->startPosition() < b->startPosition()
|
||||
static bool comparePosition(const TrackContentObject* a, const TrackContentObject* b);
|
||||
|
||||
TimePos startTimeOffset() const;
|
||||
void setStartTimeOffset( const TimePos &startTimeOffset );
|
||||
|
||||
void updateColor();
|
||||
|
||||
// Will copy the state of a TCO to another TCO
|
||||
static void copyStateTo( TrackContentObject *src, TrackContentObject *dst );
|
||||
|
||||
public slots:
|
||||
void toggleMute();
|
||||
|
||||
|
||||
signals:
|
||||
void lengthChanged();
|
||||
void positionChanged();
|
||||
void destroyedTCO();
|
||||
void trackColorChanged();
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
NoAction,
|
||||
Move,
|
||||
Resize
|
||||
} ;
|
||||
|
||||
Track * m_track;
|
||||
QString m_name;
|
||||
|
||||
TimePos m_startPosition;
|
||||
TimePos m_length;
|
||||
TimePos m_startTimeOffset;
|
||||
|
||||
BoolModel m_mutedModel;
|
||||
BoolModel m_soloModel;
|
||||
bool m_autoResize;
|
||||
|
||||
bool m_selectViewOnCreate;
|
||||
|
||||
QColor m_color;
|
||||
bool m_useCustomClipColor;
|
||||
|
||||
friend class TrackContentObjectView;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user