Merge pull request #1 from teeberg/coding
This commit is contained in:
@@ -1 +1 @@
|
||||
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ..
|
||||
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DUSE_WERROR=ON ..
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
sudo add-apt-repository ppa:tobydox/mingw -y
|
||||
sudo add-apt-repository ppa:tobydox/mingw-x-precise -y
|
||||
sudo apt-get update -qq
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export CMAKE_OPTS="-DUSE_WERROR=ON"
|
||||
../build_mingw32 || ../build_mingw32
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export CMAKE_OPTS="-DUSE_WERROR=ON"
|
||||
../build_mingw64 || ../build_mingw64
|
||||
|
||||
@@ -1 +1 @@
|
||||
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ..
|
||||
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. -DUSE_WERROR=OFF
|
||||
|
||||
@@ -358,7 +358,8 @@ CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/plugins/zynaddsubfx/zynaddsubfx.rc.in" "${CM
|
||||
|
||||
# set compiler flags
|
||||
SET(WERROR_FLAGS "-Wall -Werror=unused-function -Wno-sign-compare -Wno-strict-overflow")
|
||||
IF(NOT LMMS_BUILD_APPLE)
|
||||
OPTION(USE_WERROR "Add -werror to the build flags. Stops the build on warnings" OFF)
|
||||
IF(${USE_WERROR})
|
||||
SET(WERROR_FLAGS "${WERROR_FLAGS} -Werror")
|
||||
ENDIF()
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -13,7 +13,11 @@
|
||||
* Farbro-Tectonic.mmpz
|
||||
- CC (by)
|
||||
- http://lmms.io/lsp/index.php?action=show&file=1327
|
||||
|
||||
|
||||
* Greippi - Krem Kaakkuja (Second Flight Remix)
|
||||
- CC (by)
|
||||
- http://lmms.io/lsp/index.php?action=show&file=6337
|
||||
|
||||
* Greippi-ardudar.mmpz
|
||||
- CC (by-sa)
|
||||
- http://lmms.io/lsp/index.php?action=show&file=4916
|
||||
@@ -57,7 +61,7 @@
|
||||
* TameAnderson-MakeMe.mmpz
|
||||
- Artistic 2.0
|
||||
- http://lmms.io/lsp/index.php?action=show&file=1060
|
||||
|
||||
|
||||
* unfa-Spoken.mmpz
|
||||
- CC (by-nc)
|
||||
- http://lmms.io/lsp/index.php?action=show&file=4929
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#ifndef AUTOMATABLE_MODEL_H
|
||||
#define AUTOMATABLE_MODEL_H
|
||||
|
||||
#include "lmms_math.h"
|
||||
#include <QtCore/QMutex>
|
||||
|
||||
#include "JournallingObject.h"
|
||||
@@ -174,7 +173,7 @@ public:
|
||||
{
|
||||
return castValue<T>( m_step );
|
||||
}
|
||||
|
||||
|
||||
//! @brief Returns value scaled with the scale type and min/max values of this model
|
||||
float scaledValue( float value ) const;
|
||||
//! @brief Returns value applied with the inverse of this model's scale type
|
||||
@@ -265,22 +264,22 @@ public:
|
||||
}
|
||||
|
||||
float globalAutomationValueAt( const MidiTime& time );
|
||||
|
||||
|
||||
bool hasStrictStepSize() const
|
||||
{
|
||||
return m_hasStrictStepSize;
|
||||
}
|
||||
|
||||
|
||||
void setStrictStepSize( const bool b )
|
||||
{
|
||||
m_hasStrictStepSize = b;
|
||||
}
|
||||
|
||||
|
||||
static void incrementPeriodCounter()
|
||||
{
|
||||
++s_periodCounter;
|
||||
}
|
||||
|
||||
|
||||
static void resetPeriodCounter()
|
||||
{
|
||||
s_periodCounter = 0;
|
||||
@@ -333,13 +332,13 @@ private:
|
||||
float m_step;
|
||||
float m_range;
|
||||
float m_centerValue;
|
||||
|
||||
|
||||
bool m_valueChanged;
|
||||
|
||||
// currently unused?
|
||||
float m_oldValue;
|
||||
int m_setValueDepth;
|
||||
|
||||
|
||||
// used to determine if step size should be applied strictly (ie. always)
|
||||
// or only when value set from gui (default)
|
||||
bool m_hasStrictStepSize;
|
||||
@@ -357,9 +356,9 @@ private:
|
||||
ValueBuffer m_valueBuffer;
|
||||
long m_lastUpdatedPeriod;
|
||||
static long s_periodCounter;
|
||||
|
||||
|
||||
bool m_hasSampleExactData;
|
||||
|
||||
|
||||
// prevent several threads from attempting to write the same vb at the same time
|
||||
QMutex m_valueBufferMutex;
|
||||
|
||||
|
||||
@@ -262,6 +262,9 @@ public:
|
||||
void setCurrentPattern(AutomationPattern* pattern);
|
||||
const AutomationPattern* currentPattern();
|
||||
|
||||
virtual void dropEvent( QDropEvent * _de );
|
||||
virtual void dragEnterEvent( QDragEnterEvent * _dee );
|
||||
|
||||
void open(AutomationPattern* pattern);
|
||||
|
||||
AutomationEditor* m_editor;
|
||||
|
||||
@@ -57,9 +57,6 @@ public slots:
|
||||
void play();
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
virtual void closeEvent( QCloseEvent * _ce );
|
||||
|
||||
private:
|
||||
BBTrackContainerView* m_trackContainerView;
|
||||
ComboBox * m_bbComboBox;
|
||||
@@ -80,13 +77,16 @@ public:
|
||||
|
||||
void removeBBView(int bb);
|
||||
|
||||
void saveSettings(QDomDocument& doc, QDomElement& element);
|
||||
void loadSettings(const QDomElement& element);
|
||||
|
||||
public slots:
|
||||
void addSteps();
|
||||
void removeSteps();
|
||||
void addAutomationTrack();
|
||||
|
||||
protected slots:
|
||||
virtual void dropEvent(QDropEvent * de );
|
||||
void dropEvent(QDropEvent * de );
|
||||
void updatePosition();
|
||||
|
||||
private:
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#define BB_TRACK_CONTAINER_H
|
||||
|
||||
#include "TrackContainer.h"
|
||||
#include "ComboBox.h"
|
||||
#include "ComboBoxModel.h"
|
||||
|
||||
|
||||
class EXPORT BBTrackContainer : public TrackContainer
|
||||
|
||||
@@ -26,11 +26,9 @@
|
||||
#ifndef BANDLIMITEDWAVE_H
|
||||
#define BANDLIMITEDWAVE_H
|
||||
|
||||
#include <QString>
|
||||
#include <QDataStream>
|
||||
#include <QFile>
|
||||
class QDataStream;
|
||||
class QString;
|
||||
|
||||
#include "ConfigManager.h"
|
||||
#include "export.h"
|
||||
#include "interpolation.h"
|
||||
#include "lmms_basics.h"
|
||||
|
||||
@@ -22,17 +22,14 @@
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BUFFER_MANAGER_H
|
||||
#define BUFFER_MANAGER_H
|
||||
|
||||
#include "MemoryManager.h"
|
||||
#include "export.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "Engine.h"
|
||||
#include "Mixer.h"
|
||||
#include <QtCore/QAtomicInt>
|
||||
#include <QtCore/QReadWriteLock>
|
||||
|
||||
class QAtomicInt;
|
||||
|
||||
const int BM_INITIAL_BUFFERS = 512;
|
||||
//const int BM_INCREMENT = 64;
|
||||
@@ -45,11 +42,11 @@ public:
|
||||
static void release( sampleFrame * buf );
|
||||
static void refresh();
|
||||
// static void extend( int c );
|
||||
|
||||
|
||||
private:
|
||||
static sampleFrame ** s_available;
|
||||
static QAtomicInt s_availableIndex;
|
||||
|
||||
|
||||
static sampleFrame ** s_released;
|
||||
static QAtomicInt s_releasedIndex;
|
||||
// static QReadWriteLock s_mutex;
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <QtCore/QPair>
|
||||
|
||||
#include "AutomatableModel.h"
|
||||
#include "templates.h"
|
||||
|
||||
class PixmapLoader;
|
||||
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
#define DATA_FILE_H
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "export.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "MemoryManager.h"
|
||||
|
||||
class QTextStream;
|
||||
|
||||
class EXPORT DataFile : public QDomDocument
|
||||
{
|
||||
MM_OPERATORS
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 1998-2000 Paul Kellett (mda-vst.com)
|
||||
* Copyright (c) 2007 Paul Giblock <drfaygo/at/gmail.com>
|
||||
*
|
||||
*
|
||||
* This file is part of LMMS - http://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -42,11 +42,11 @@ class DrumSynth {
|
||||
void GetEnv(int env, const char *sec, const char *key, const char *ini);
|
||||
|
||||
float waveform(float ph, int form);
|
||||
|
||||
|
||||
int GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, const char *file);
|
||||
int GetPrivateProfileInt(const char *sec, const char *key, int def, const char *file);
|
||||
float GetPrivateProfileFloat(const char *sec, const char *key, float def, const char *file);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -26,28 +26,17 @@
|
||||
#ifndef ENGINE_H
|
||||
#define ENGINE_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
#include "MemoryManager.h"
|
||||
|
||||
#include <QtCore/QMap>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
class AutomationEditorWindow;
|
||||
class BBEditor;
|
||||
class BBTrackContainer;
|
||||
class DummyTrackContainer;
|
||||
class FxMixer;
|
||||
class FxMixerView;
|
||||
class ProjectJournal;
|
||||
class MainWindow;
|
||||
class Mixer;
|
||||
class PianoRollWindow;
|
||||
class ProjectNotes;
|
||||
class Song;
|
||||
class SongEditorWindow;
|
||||
class Ladspa2LMMS;
|
||||
class ControllerRackView;
|
||||
|
||||
|
||||
class EXPORT Engine
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
_activated_color, QWidget * _parent );
|
||||
|
||||
virtual ~FadeButton();
|
||||
void setActiveColor( const QColor & activated_color );
|
||||
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -26,17 +26,18 @@
|
||||
#ifndef INSTRUMENT_H
|
||||
#define INSTRUMENT_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <QString>
|
||||
#include <QtGlobal>
|
||||
#include "export.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "MidiTime.h"
|
||||
#include "Plugin.h"
|
||||
#include "Mixer.h"
|
||||
|
||||
|
||||
// forward-declarations
|
||||
class InstrumentTrack;
|
||||
class InstrumentView;
|
||||
class MidiEvent;
|
||||
class MidiTime;
|
||||
class NotePlayHandle;
|
||||
class Track;
|
||||
|
||||
|
||||
@@ -306,6 +306,9 @@ public:
|
||||
|
||||
static void cleanupWindowCache();
|
||||
|
||||
// Create a menu for assigning/creating channels for this track
|
||||
QMenu * createFxMenu( QString title, QString newFxLabel );
|
||||
|
||||
|
||||
protected:
|
||||
virtual void dragEnterEvent( QDragEnterEvent * _dee );
|
||||
@@ -320,6 +323,10 @@ private slots:
|
||||
void midiInSelected();
|
||||
void midiOutSelected();
|
||||
void midiConfigChanged();
|
||||
void muteChanged();
|
||||
|
||||
void assignFxLine( int channelIndex );
|
||||
void createFxLine();
|
||||
|
||||
|
||||
private:
|
||||
@@ -374,6 +381,12 @@ public:
|
||||
|
||||
void setInstrumentTrackView( InstrumentTrackView * _tv );
|
||||
|
||||
InstrumentTrackView *instrumentTrackView()
|
||||
{
|
||||
return m_itv;
|
||||
}
|
||||
|
||||
|
||||
PianoView * pianoView()
|
||||
{
|
||||
return m_pianoView;
|
||||
|
||||
@@ -28,11 +28,12 @@
|
||||
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QMutex>
|
||||
#include <QtCore/QReadWriteLock>
|
||||
#include <QtCore/QHash>
|
||||
#include "MemoryHelper.h"
|
||||
#include "export.h"
|
||||
|
||||
class QReadWriteLock;
|
||||
|
||||
const int MM_CHUNK_SIZE = 64; // granularity of managed memory
|
||||
const int MM_INITIAL_CHUNKS = 1024 * 1024; // how many chunks to allocate at startup - TODO: make configurable
|
||||
const int MM_INCREMENT_CHUNKS = 16 * 1024; // min. amount of chunks to increment at a time
|
||||
|
||||
@@ -28,15 +28,9 @@
|
||||
#include <QtCore/QAtomicPointer>
|
||||
#include <QtCore/QThread>
|
||||
|
||||
#include "ThreadableJob.h"
|
||||
#include "Mixer.h"
|
||||
|
||||
#ifdef __SSE__
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
#ifdef __SSE3__
|
||||
#include <pmmintrin.h>
|
||||
#endif
|
||||
class QWaitCondition;
|
||||
class Mixer;
|
||||
class ThreadableJob;
|
||||
|
||||
class MixerWorkerThread : public QThread
|
||||
{
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#ifndef MODEL_H
|
||||
#define MODEL_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef MODEL_VIEW_H
|
||||
#define MODEL_VIEW_H
|
||||
|
||||
#include <QtCore/QPointer>
|
||||
#include "Model.h"
|
||||
|
||||
|
||||
|
||||
@@ -26,14 +26,13 @@
|
||||
#ifndef NOTE_PLAY_HANDLE_H
|
||||
#define NOTE_PLAY_HANDLE_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
#include "Note.h"
|
||||
#include "PlayHandle.h"
|
||||
#include "Track.h"
|
||||
#include "MemoryManager.h"
|
||||
#include <QtCore/QAtomicInt>
|
||||
#include <QtCore/QReadWriteLock>
|
||||
|
||||
class QAtomicInt;
|
||||
class QReadWriteLock;
|
||||
class InstrumentTrack;
|
||||
class NotePlayHandle;
|
||||
|
||||
@@ -59,7 +58,7 @@ public:
|
||||
OriginCount
|
||||
};
|
||||
typedef Origins Origin;
|
||||
|
||||
|
||||
NotePlayHandle( InstrumentTrack* instrumentTrack,
|
||||
const f_cnt_t offset,
|
||||
const f_cnt_t frames,
|
||||
@@ -83,9 +82,9 @@ public:
|
||||
{
|
||||
return m_midiChannel;
|
||||
}
|
||||
|
||||
|
||||
/*! convenience function that returns offset for the first period and zero otherwise,
|
||||
used by instruments to handle the offset: instruments have to check this property and
|
||||
used by instruments to handle the offset: instruments have to check this property and
|
||||
add the correct number of empty frames in the beginning of the period */
|
||||
f_cnt_t noteOffset() const
|
||||
{
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
#include "SampleBuffer.h"
|
||||
#include "lmms_constants.h"
|
||||
|
||||
|
||||
class SampleBuffer;
|
||||
class IntModel;
|
||||
|
||||
|
||||
|
||||
@@ -160,6 +160,8 @@ protected slots:
|
||||
|
||||
void hidePattern( Pattern* pattern );
|
||||
|
||||
void selectRegionFromPixels( int xStart, int xEnd );
|
||||
|
||||
|
||||
signals:
|
||||
void currentPatternChanged();
|
||||
@@ -229,7 +231,7 @@ private:
|
||||
inline int noteEditRight() const;
|
||||
inline int noteEditLeft() const;
|
||||
|
||||
void dragNotes( int x, int y, bool alt, bool shift );
|
||||
void dragNotes( int x, int y, bool alt, bool shift, bool ctrl );
|
||||
|
||||
static const int cm_scrollAmtHoriz = 10;
|
||||
static const int cm_scrollAmtVert = 1;
|
||||
@@ -295,7 +297,7 @@ private:
|
||||
|
||||
int m_oldNotesEditHeight;
|
||||
int m_notesEditHeight;
|
||||
int m_ppt;
|
||||
int m_ppt; // pixels per tact
|
||||
int m_totalKeysToScroll;
|
||||
|
||||
// remember these values to use them
|
||||
|
||||
@@ -148,8 +148,8 @@ public:
|
||||
// returns display-name out of descriptor
|
||||
virtual QString displayName() const
|
||||
{
|
||||
return Model::displayName().isEmpty()
|
||||
? m_descriptor->displayName
|
||||
return Model::displayName().isEmpty()
|
||||
? m_descriptor->displayName
|
||||
: Model::displayName();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ class QPixmap;
|
||||
class QToolBar;
|
||||
class NStateButton;
|
||||
class TextFloat;
|
||||
class SongEditor;
|
||||
|
||||
|
||||
class TimeLineWidget : public QWidget, public JournallingObject
|
||||
@@ -128,6 +129,11 @@ public:
|
||||
m_ppt / MidiTime::ticksPerTact() );
|
||||
}
|
||||
|
||||
signals:
|
||||
|
||||
void regionSelectedFromPixels( int, int );
|
||||
void selectionFinished();
|
||||
|
||||
|
||||
public slots:
|
||||
void updatePosition( const MidiTime & );
|
||||
@@ -171,6 +177,7 @@ private:
|
||||
|
||||
|
||||
TextFloat * m_hint;
|
||||
int m_initalXSelect;
|
||||
|
||||
|
||||
enum actions
|
||||
@@ -178,7 +185,8 @@ private:
|
||||
NoAction,
|
||||
MovePositionMarker,
|
||||
MoveLoopBegin,
|
||||
MoveLoopEnd
|
||||
MoveLoopEnd,
|
||||
SelectSongTCO,
|
||||
} m_action;
|
||||
|
||||
int m_moveXOff;
|
||||
|
||||
@@ -391,8 +391,6 @@ private slots:
|
||||
void recordingOn();
|
||||
void recordingOff();
|
||||
void clearTrack();
|
||||
void assignFxLine( int channelIndex );
|
||||
void createFxLine();
|
||||
|
||||
private:
|
||||
static QPixmap * s_grip;
|
||||
|
||||
@@ -126,6 +126,17 @@ public slots:
|
||||
|
||||
virtual void dropEvent( QDropEvent * _de );
|
||||
virtual void dragEnterEvent( QDragEnterEvent * _dee );
|
||||
///
|
||||
/// \brief selectRegionFromPixels
|
||||
/// \param x
|
||||
/// \param y
|
||||
/// Use the rubber band to select TCO from all tracks using x, y pixels
|
||||
void selectRegionFromPixels(int xStart, int xEnd);
|
||||
|
||||
///
|
||||
/// \brief stopRubberBand
|
||||
/// Removes the rubber band from display when finished with.
|
||||
void stopRubberBand();
|
||||
|
||||
protected:
|
||||
static const int DEFAULT_PIXELS_PER_TACT = 16;
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#ifndef FFT_HELPERS_H
|
||||
#define FFT_HELPERS_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
#include "export.h"
|
||||
|
||||
#include <fftw3.h>
|
||||
|
||||
@@ -78,9 +78,9 @@ struct typeInfo
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline bool isEqual( T _x, T _y )
|
||||
static inline bool isEqual( T x, T y )
|
||||
{
|
||||
return _x == _y;
|
||||
return x == y;
|
||||
}
|
||||
|
||||
static inline T absVal( T t )
|
||||
@@ -97,13 +97,13 @@ inline float typeInfo<float>::minEps()
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool typeInfo<float>::isEqual( float _x, float _y )
|
||||
inline bool typeInfo<float>::isEqual( float x, float y )
|
||||
{
|
||||
if( likely( _x == _y ) )
|
||||
if( x == y )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return absVal( _x - _y ) < minEps();
|
||||
return absVal( x - y ) < minEps();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -497,6 +497,15 @@ bool MidiImport::readSMF( TrackContainer* tc )
|
||||
}
|
||||
}
|
||||
|
||||
// Set channel 10 to drums as per General MIDI's orders
|
||||
if( chs[9].hasNotes && chs[9].it_inst && chs[9].isSF2 )
|
||||
{
|
||||
// AFAIK, 128 should be the standard bank for drums in SF2.
|
||||
// If not, this has to be made configurable.
|
||||
chs[9].it_inst->childModel( "bank" )->setValue( 128 );
|
||||
chs[9].it_inst->childModel( "patch" )->setValue( 0 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QDomElement>
|
||||
|
||||
#include "AutomatableModel.h"
|
||||
|
||||
#include "AutomationPattern.h"
|
||||
#include "ControllerConnection.h"
|
||||
#include "lmms_math.h"
|
||||
@@ -75,7 +74,7 @@ AutomatableModel::~AutomatableModel()
|
||||
{
|
||||
delete m_controllerConnection;
|
||||
}
|
||||
|
||||
|
||||
m_valueBuffer.clear();
|
||||
|
||||
emit destroyed( id() );
|
||||
@@ -171,7 +170,7 @@ void AutomatableModel::loadSettings( const QDomElement& element, const QString&
|
||||
//m_controllerConnection->setTargetName( displayName() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// models can be stored as elements (port00) or attributes (port10):
|
||||
// <ladspacontrols port10="4.41">
|
||||
// <port00 value="4.41" id="4249278"/>
|
||||
@@ -566,7 +565,7 @@ ValueBuffer * AutomatableModel::valueBuffer()
|
||||
}
|
||||
}
|
||||
AutomatableModel* lm = NULL;
|
||||
if( m_hasLinkedModels )
|
||||
if( m_hasLinkedModels )
|
||||
{
|
||||
lm = m_linkedModels.first();
|
||||
}
|
||||
@@ -583,7 +582,7 @@ ValueBuffer * AutomatableModel::valueBuffer()
|
||||
m_hasSampleExactData = true;
|
||||
return &m_valueBuffer;
|
||||
}
|
||||
|
||||
|
||||
if( m_oldValue != val )
|
||||
{
|
||||
m_valueBuffer.interpolate( m_oldValue, val );
|
||||
@@ -592,7 +591,7 @@ ValueBuffer * AutomatableModel::valueBuffer()
|
||||
m_hasSampleExactData = true;
|
||||
return &m_valueBuffer;
|
||||
}
|
||||
|
||||
|
||||
// if we have no sample-exact source for a ValueBuffer, return NULL to signify that no data is available at the moment
|
||||
// in which case the recipient knows to use the static value() instead
|
||||
m_lastUpdatedPeriod = s_periodCounter;
|
||||
@@ -667,11 +666,11 @@ float AutomatableModel::globalAutomationValueAt( const MidiTime& time )
|
||||
{
|
||||
int s = ( *it )->startPosition();
|
||||
int e = ( *it )->endPosition();
|
||||
if( s <= time && e >= time ) { patternsInRange += ( *it ); }
|
||||
if( s <= time && e >= time ) { patternsInRange += ( *it ); }
|
||||
}
|
||||
|
||||
|
||||
AutomationPattern * latestPattern = NULL;
|
||||
|
||||
|
||||
if( ! patternsInRange.isEmpty() )
|
||||
{
|
||||
// if there are more than one overlapping patterns, just use the first one because
|
||||
@@ -682,7 +681,7 @@ float AutomatableModel::globalAutomationValueAt( const MidiTime& time )
|
||||
// if we find no patterns at the exact miditime, we need to search for the last pattern before time and use that
|
||||
{
|
||||
int latestPosition = 0;
|
||||
|
||||
|
||||
for( QVector<AutomationPattern *>::ConstIterator it = patterns.begin(); it != patterns.end(); it++ )
|
||||
{
|
||||
int e = ( *it )->endPosition();
|
||||
@@ -693,7 +692,7 @@ float AutomatableModel::globalAutomationValueAt( const MidiTime& time )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( latestPattern )
|
||||
{
|
||||
// scale/fit the value appropriately and return it
|
||||
@@ -701,7 +700,7 @@ float AutomatableModel::globalAutomationValueAt( const MidiTime& time )
|
||||
const float scaled_value = scaledValue( value );
|
||||
return fittedValue( scaled_value );
|
||||
}
|
||||
// if we still find no pattern, the value at that time is undefined so
|
||||
// if we still find no pattern, the value at that time is undefined so
|
||||
// just return current value as the best we can do
|
||||
else return m_value;
|
||||
}
|
||||
|
||||
@@ -24,9 +24,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QDomElement>
|
||||
|
||||
#include "AutomationPattern.h"
|
||||
|
||||
#include "AutomationPatternView.h"
|
||||
#include "AutomationTrack.h"
|
||||
#include "ProjectJournal.h"
|
||||
@@ -192,7 +191,7 @@ const AutomatableModel * AutomationPattern::firstObject() const
|
||||
MidiTime AutomationPattern::length() const
|
||||
{
|
||||
if( m_timeMap.isEmpty() ) return 0;
|
||||
timeMap::const_iterator it = m_timeMap.end();
|
||||
timeMap::const_iterator it = m_timeMap.end();
|
||||
return MidiTime( qMax( MidiTime( (it-1).key() ).getTact() + 1, 1 ), 0 );
|
||||
}
|
||||
|
||||
@@ -412,7 +411,7 @@ void AutomationPattern::flipY( int min, int max )
|
||||
{
|
||||
numPoints++;
|
||||
}
|
||||
|
||||
|
||||
for( int i = 0; i <= numPoints; i++ )
|
||||
{
|
||||
|
||||
@@ -501,7 +500,7 @@ void AutomationPattern::flipX( int length )
|
||||
tempMap[newTime] = tempValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_timeMap.clear();
|
||||
|
||||
m_timeMap = tempMap;
|
||||
@@ -617,7 +616,7 @@ void AutomationPattern::processMidiTime( const MidiTime & time )
|
||||
( *it )->setAutomatedValue( val );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -625,7 +624,7 @@ void AutomationPattern::processMidiTime( const MidiTime & time )
|
||||
if( time >= 0 && ! m_objects.isEmpty() )
|
||||
{
|
||||
const float value = static_cast<float>( firstObject()->value<float>() );
|
||||
if( value != m_lastRecordedValue )
|
||||
if( value != m_lastRecordedValue )
|
||||
{
|
||||
putValue( time, value, true );
|
||||
m_lastRecordedValue = value;
|
||||
@@ -692,7 +691,7 @@ QVector<AutomationPattern *> AutomationPattern::patternsForModel( const Automata
|
||||
l += Engine::getSong()->tracks();
|
||||
l += Engine::getBBTrackContainer()->tracks();
|
||||
l += Engine::getSong()->globalAutomationTrack();
|
||||
|
||||
|
||||
// go through all tracks...
|
||||
for( TrackContainer::TrackList::ConstIterator it = l.begin(); it != l.end(); ++it )
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* BBTrackContainer.cpp - model-component of BB-Editor
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
*
|
||||
* This file is part of LMMS - http://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -25,8 +25,6 @@
|
||||
|
||||
#include "BBTrackContainer.h"
|
||||
#include "BBTrack.h"
|
||||
#include "ComboBox.h"
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
#include "Song.h"
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "BandLimitedWave.h"
|
||||
|
||||
#include "ConfigManager.h"
|
||||
|
||||
WaveMipMap BandLimitedWave::s_waveforms[4] = { };
|
||||
bool BandLimitedWave::s_wavesGenerated = false;
|
||||
@@ -62,7 +63,7 @@ void BandLimitedWave::generateWaves()
|
||||
{
|
||||
// don't generate if they already exist
|
||||
if( s_wavesGenerated ) return;
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
// set wavetable directory
|
||||
@@ -90,7 +91,7 @@ void BandLimitedWave::generateWaves()
|
||||
const int len = TLENS[i];
|
||||
//const double om = 1.0 / len;
|
||||
double max = 0.0;
|
||||
|
||||
|
||||
for( int ph = 0; ph < len; ph++ )
|
||||
{
|
||||
int harm = 1;
|
||||
@@ -115,7 +116,7 @@ void BandLimitedWave::generateWaves()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// square wave - BLSquare
|
||||
// check for file and use it if exists
|
||||
if( sqr_file.exists() )
|
||||
@@ -132,7 +133,7 @@ void BandLimitedWave::generateWaves()
|
||||
const int len = TLENS[i];
|
||||
//const double om = 1.0 / len;
|
||||
double max = 0.0;
|
||||
|
||||
|
||||
for( int ph = 0; ph < len; ph++ )
|
||||
{
|
||||
int harm = 1;
|
||||
@@ -173,7 +174,7 @@ void BandLimitedWave::generateWaves()
|
||||
const int len = TLENS[i];
|
||||
//const double om = 1.0 / len;
|
||||
double max = 0.0;
|
||||
|
||||
|
||||
for( int ph = 0; ph < len; ph++ )
|
||||
{
|
||||
int harm = 1;
|
||||
@@ -184,7 +185,7 @@ void BandLimitedWave::generateWaves()
|
||||
hlen = static_cast<double>( len ) / static_cast<double>( harm );
|
||||
const double amp = 1.0 / static_cast<double>( harm * harm );
|
||||
//const double a2 = cos( om * harm * F_2PI );
|
||||
s += amp * /*a2 **/ sin( ( static_cast<double>( ph * harm ) / static_cast<double>( len ) +
|
||||
s += amp * /*a2 **/ sin( ( static_cast<double>( ph * harm ) / static_cast<double>( len ) +
|
||||
( ( harm + 1 ) % 4 == 0 ? 0.5 : 0.0 ) ) * F_2PI );
|
||||
harm += 2;
|
||||
} while( hlen > 2.0 );
|
||||
@@ -199,7 +200,7 @@ void BandLimitedWave::generateWaves()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// moog saw wave - BLMoog
|
||||
// basically, just add in triangle + 270-phase saw
|
||||
if( moog_file.exists() )
|
||||
@@ -214,7 +215,7 @@ void BandLimitedWave::generateWaves()
|
||||
for( i = 0; i <= MAXTBL; i++ )
|
||||
{
|
||||
const int len = TLENS[i];
|
||||
|
||||
|
||||
for( int ph = 0; ph < len; ph++ )
|
||||
{
|
||||
const int sawph = ( ph + static_cast<int>( len * 0.75 ) ) % len;
|
||||
@@ -224,7 +225,7 @@ void BandLimitedWave::generateWaves()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// set the generated flag so we don't load/generate them again needlessly
|
||||
s_wavesGenerated = true;
|
||||
|
||||
@@ -232,14 +233,14 @@ void BandLimitedWave::generateWaves()
|
||||
// generate files, serialize mipmaps as QDataStreams and save them on disk
|
||||
//
|
||||
// normally these are now provided with LMMS as pre-generated so we don't have to do this,
|
||||
// but I'm leaving the code here in case it's needed in the future
|
||||
// but I'm leaving the code here in case it's needed in the future
|
||||
// (maybe we add more waveforms or change the generation code or mipmap format, etc.)
|
||||
|
||||
/*
|
||||
|
||||
// if you want to generate the files, you need to set the filenames and paths here -
|
||||
// if you want to generate the files, you need to set the filenames and paths here -
|
||||
// can't use the usual wavetable directory here as it can require permissions on
|
||||
// some systems...
|
||||
// some systems...
|
||||
|
||||
QFile sawfile( "path-to-wavetables/saw.bin" );
|
||||
QFile sqrfile( "path-to-wavetables/sqr.bin" );
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
|
||||
#include "BufferManager.h"
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
#include <QtCore/QAtomicInt>
|
||||
|
||||
#include "MemoryManager.h"
|
||||
|
||||
sampleFrame ** BufferManager::s_available;
|
||||
QAtomicInt BufferManager::s_availableIndex = 0;
|
||||
@@ -41,7 +45,7 @@ void BufferManager::init( fpp_t framesPerPeriod )
|
||||
|
||||
int c = framesPerPeriod * BM_INITIAL_BUFFERS;
|
||||
sampleFrame * b = MM_ALLOC( sampleFrame, c );
|
||||
|
||||
|
||||
for( int i = 0; i < BM_INITIAL_BUFFERS; ++i )
|
||||
{
|
||||
s_available[ i ] = b;
|
||||
@@ -58,10 +62,10 @@ sampleFrame * BufferManager::acquire()
|
||||
{
|
||||
qFatal( "BufferManager: out of buffers" );
|
||||
}
|
||||
|
||||
|
||||
int i = s_availableIndex.fetchAndAddOrdered( -1 );
|
||||
sampleFrame * b = s_available[ i ];
|
||||
|
||||
|
||||
//qDebug( "acquired buffer: %p - index %d", b, i );
|
||||
return b;
|
||||
}
|
||||
@@ -79,7 +83,7 @@ void BufferManager::refresh() // non-threadsafe, hence it's called periodically
|
||||
{
|
||||
if( s_releasedIndex == 0 ) return;
|
||||
//qDebug( "refresh: %d buffers", int( s_releasedIndex ) );
|
||||
|
||||
|
||||
int j = s_availableIndex;
|
||||
for( int i = 0; i < s_releasedIndex; ++i )
|
||||
{
|
||||
@@ -101,7 +105,7 @@ void BufferManager::extend( int c )
|
||||
|
||||
int cc = c * Engine::mixer()->framesPerPeriod();
|
||||
sampleFrame * b = MM_ALLOC( sampleFrame, cc );
|
||||
|
||||
|
||||
for( int i = 0; i < c; ++i )
|
||||
{
|
||||
s_available[ s_availableIndex.fetchAndAddOrdered( 1 ) + 1 ] = b;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* ControllerConnection.cpp - implementation of class controller connection
|
||||
* ControllerConnection.cpp - implementation of class controller connection
|
||||
* which handles the link between AutomatableModels and controllers
|
||||
*
|
||||
* Copyright (c) 2008 Paul Giblock <drfaygo/at/gmail.com>
|
||||
@@ -26,12 +26,10 @@
|
||||
|
||||
#include <QDomElement>
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
|
||||
#include "Song.h"
|
||||
#include "Engine.h"
|
||||
#include "Mixer.h"
|
||||
#include "ControllerConnection.h"
|
||||
|
||||
|
||||
@@ -123,7 +121,7 @@ void ControllerConnection::setController( Controller * _controller )
|
||||
this, SIGNAL( valueChanged() ) );
|
||||
}
|
||||
|
||||
m_ownsController =
|
||||
m_ownsController =
|
||||
( _controller->type() == Controller::MidiController );
|
||||
|
||||
// If we don't own the controller, allow deletion of controller
|
||||
@@ -150,8 +148,8 @@ inline void ControllerConnection::setTargetName( const QString & _name )
|
||||
/*
|
||||
* A connection may not be finalized. This means, the connection should exist,
|
||||
* but the controller does not yet exist. This happens when loading. Even
|
||||
* loading connections last won't help, since there can be connections BETWEEN
|
||||
* controllers. So, we remember the controller-ID and use a dummyController
|
||||
* loading connections last won't help, since there can be connections BETWEEN
|
||||
* controllers. So, we remember the controller-ID and use a dummyController
|
||||
* instead. Once the song is loaded, finalizeConnections() connects to the proper controllers
|
||||
*/
|
||||
void ControllerConnection::finalizeConnections()
|
||||
|
||||
@@ -37,14 +37,12 @@
|
||||
|
||||
#include "ConfigManager.h"
|
||||
#include "ProjectVersion.h"
|
||||
#include "ProjectVersion.h"
|
||||
#include "SongEditor.h"
|
||||
#include "Effect.h"
|
||||
#include "lmmsversion.h"
|
||||
#include "base64.h"
|
||||
|
||||
// bbTCO::defaultColor()
|
||||
#include "BBTrack.h"
|
||||
|
||||
|
||||
|
||||
DataFile::typeDescStruct
|
||||
@@ -127,14 +125,18 @@ DataFile::DataFile( const QString & _fileName ) :
|
||||
QFile inFile( _fileName );
|
||||
if( !inFile.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
QMessageBox::critical( NULL,
|
||||
SongEditor::tr( "Could not open file" ),
|
||||
SongEditor::tr( "Could not open file %1. You probably "
|
||||
"have no permissions to read this "
|
||||
"file.\n Please make sure to have at "
|
||||
"least read permissions to the file "
|
||||
"and try again." ).arg( _fileName ) );
|
||||
return;
|
||||
if( Engine::hasGUI() )
|
||||
{
|
||||
QMessageBox::critical( NULL,
|
||||
SongEditor::tr( "Could not open file" ),
|
||||
SongEditor::tr( "Could not open file %1. You probably "
|
||||
"have no permissions to read this "
|
||||
"file.\n Please make sure to have at "
|
||||
"least read permissions to the file "
|
||||
"and try again." ).arg( _fileName ) );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
loadData( inFile.readAll(), _fileName );
|
||||
@@ -222,11 +224,15 @@ bool DataFile::writeFile( const QString& filename )
|
||||
|
||||
if( !outfile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
|
||||
{
|
||||
QMessageBox::critical( NULL,
|
||||
SongEditor::tr( "Could not write file" ),
|
||||
SongEditor::tr( "Could not open %1 for writing. You probably are not permitted to "
|
||||
"write to this file. Please make sure you have write-access to "
|
||||
"the file and try again." ).arg( fullName ) );
|
||||
if( Engine::hasGUI() )
|
||||
{
|
||||
QMessageBox::critical( NULL,
|
||||
SongEditor::tr( "Could not write file" ),
|
||||
SongEditor::tr( "Could not open %1 for writing. You probably are not permitted to "
|
||||
"write to this file. Please make sure you have write-access to "
|
||||
"the file and try again." ).arg( fullName ) );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -628,7 +634,7 @@ void DataFile::upgrade()
|
||||
el.setAttribute( "lp1pos",
|
||||
el.attribute( "lp1pos" ).toInt()*3 );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if( version < "0.4.0-20080607" )
|
||||
@@ -768,12 +774,16 @@ void DataFile::loadData( const QByteArray & _data, const QString & _sourceFile )
|
||||
if( line >= 0 && col >= 0 )
|
||||
{
|
||||
qWarning() << "at line" << line << "column" << errorMsg;
|
||||
QMessageBox::critical( NULL,
|
||||
SongEditor::tr( "Error in file" ),
|
||||
SongEditor::tr( "The file %1 seems to contain "
|
||||
"errors and therefore can't be "
|
||||
"loaded." ).
|
||||
arg( _sourceFile ) );
|
||||
if( Engine::hasGUI() )
|
||||
{
|
||||
QMessageBox::critical( NULL,
|
||||
SongEditor::tr( "Error in file" ),
|
||||
SongEditor::tr( "The file %1 seems to contain "
|
||||
"errors and therefore can't be "
|
||||
"loaded." ).
|
||||
arg( _sourceFile ) );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -782,10 +792,37 @@ void DataFile::loadData( const QByteArray & _data, const QString & _sourceFile )
|
||||
m_type = type( root.attribute( "type" ) );
|
||||
m_head = root.elementsByTagName( "head" ).item( 0 ).toElement();
|
||||
|
||||
if( root.hasAttribute( "creatorversion" ) &&
|
||||
root.attribute( "creatorversion" ) != LMMS_VERSION )
|
||||
|
||||
if( root.hasAttribute( "creatorversion" ) )
|
||||
{
|
||||
upgrade();
|
||||
// compareType defaults to Build,so it doesn't have to be set here
|
||||
ProjectVersion createdWith = root.attribute( "creatorversion" );
|
||||
ProjectVersion openedWith = LMMS_VERSION;;
|
||||
|
||||
if ( createdWith != openedWith )
|
||||
{
|
||||
// only one compareType needs to be set, and we can compare on one line because setCompareType returns ProjectVersion
|
||||
if ( createdWith.setCompareType(Minor) != openedWith)
|
||||
{
|
||||
if( Engine::hasGUI() )
|
||||
{
|
||||
QMessageBox::information( NULL,
|
||||
SongEditor::tr( "Project Version Mismatch" ),
|
||||
SongEditor::tr(
|
||||
"This project was created with "
|
||||
"LMMS version %1, but version %2 "
|
||||
"is installed")
|
||||
.arg( root.attribute( "creatorversion" ) )
|
||||
.arg( LMMS_VERSION ) );
|
||||
}
|
||||
}
|
||||
|
||||
// the upgrade needs to happen after the warning as it updates the project version.
|
||||
if( createdWith.setCompareType(Build) < openedWith )
|
||||
{
|
||||
upgrade();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_content = root.elementsByTagName( typeName( m_type ) ).
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 1998-2000 Paul Kellett (mda-vst.com)
|
||||
* Copyright (c) 2007 Paul Giblock <drfaygo/at/gmail.com>
|
||||
*
|
||||
*
|
||||
* This file is part of LMMS - http://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
|
||||
#include "DrumSynth.h"
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
@@ -71,13 +70,13 @@ float mem_t=1.0f, mem_o=1.0f, mem_n=1.0f, mem_b=1.0f, mem_tune=1.0f, mem_time=1.
|
||||
int DrumSynth::LongestEnv(void)
|
||||
{
|
||||
long e, eon, p;
|
||||
float l=0.f;
|
||||
|
||||
float l=0.f;
|
||||
|
||||
for(e=1; e<7; e++) //3
|
||||
{
|
||||
eon = e - 1; if(eon>2) eon=eon-1;
|
||||
p = 0;
|
||||
while (envpts[e][0][p + 1] >= 0.f) p++;
|
||||
while (envpts[e][0][p + 1] >= 0.f) p++;
|
||||
envData[e][MAX] = envpts[e][0][p] * timestretch;
|
||||
if(chkOn[eon]==1) if(envData[e][MAX]>l) l=envData[e][MAX];
|
||||
}
|
||||
@@ -88,7 +87,7 @@ int DrumSynth::LongestEnv(void)
|
||||
|
||||
|
||||
float DrumSynth::LoudestEnv(void)
|
||||
{
|
||||
{
|
||||
float loudest=0.f;
|
||||
int i=0;
|
||||
|
||||
@@ -102,9 +101,9 @@ float DrumSynth::LoudestEnv(void)
|
||||
|
||||
|
||||
void DrumSynth::UpdateEnv(int e, long t)
|
||||
{
|
||||
{
|
||||
float endEnv, dT;
|
||||
//0.2's added
|
||||
//0.2's added
|
||||
envData[e][NEXTT] = envpts[e][0][(long)(envData[e][PNT] + 1.f)] * timestretch; //get next point
|
||||
if(envData[e][NEXTT] < 0) envData[e][NEXTT] = 442000 * timestretch; //if end point, hold
|
||||
envData[e][ENV] = envpts[e][1][(long)(envData[e][PNT] + 0.f)] * 0.01f; //this level
|
||||
@@ -122,14 +121,14 @@ void DrumSynth::GetEnv(int env, const char *sec, const char *key, const char *in
|
||||
int i=0, o=0, ep=0;
|
||||
GetPrivateProfileString(sec, key, "0,0 100,0", en, sizeof(en), ini);
|
||||
en[255]=0; //be safe!
|
||||
|
||||
|
||||
while(en[i]!=0)
|
||||
{
|
||||
if(en[i] == ',')
|
||||
if(en[i] == ',')
|
||||
{
|
||||
if(sscanf(s, "%f", &envpts[env][0][ep])==0) envpts[env][0][ep] = 0.f;
|
||||
o=0;
|
||||
}
|
||||
}
|
||||
else if(en[i] == ' ')
|
||||
{
|
||||
if(sscanf(s, "%f", &envpts[env][1][ep])==0) envpts[env][1][ep] = 0.f;
|
||||
@@ -148,7 +147,7 @@ void DrumSynth::GetEnv(int env, const char *sec, const char *key, const char *in
|
||||
float DrumSynth::waveform(float ph, int form)
|
||||
{
|
||||
float w;
|
||||
|
||||
|
||||
switch (form)
|
||||
{
|
||||
case 0: w = (float)sin(fmod(ph,TwoPi)); break; //sine
|
||||
@@ -157,15 +156,15 @@ float DrumSynth::waveform(float ph, int form)
|
||||
w = 0.6366197f * (float)fmod(ph,TwoPi) - 1.f; //tri
|
||||
if(w>1.f) w=2.f-w; break;
|
||||
case 3: w = ph - TwoPi * (float)(int)(ph / TwoPi); //saw
|
||||
w = (0.3183098f * w) - 1.f; break;
|
||||
w = (0.3183098f * w) - 1.f; break;
|
||||
default: w = (sin(fmod(ph,TwoPi))>0.0)? 1.f: -1.f; break; //square
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, const char *file)
|
||||
int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, const char *file)
|
||||
{
|
||||
ifstream is;
|
||||
bool inSection = false;
|
||||
@@ -190,12 +189,12 @@ int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const c
|
||||
}
|
||||
else if (!is.eof()) {
|
||||
is.getline(line, 200);
|
||||
if (line[0] == '[')
|
||||
if (line[0] == '[')
|
||||
break;
|
||||
|
||||
k = strtok(line, " \t=");
|
||||
b = strtok(NULL, "\n\r\0");
|
||||
|
||||
|
||||
if (k != 0 && strcasecmp(k, key)==0) {
|
||||
if (b==0) {
|
||||
len = 0;
|
||||
@@ -203,7 +202,7 @@ int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const c
|
||||
}
|
||||
else {
|
||||
k = (char *)(b + strlen(b)-1);
|
||||
while ( (k>=b) && (*k==' ' || *k=='\t') )
|
||||
while ( (k>=b) && (*k==' ' || *k=='\t') )
|
||||
--k;
|
||||
*(k+1) = '\0';
|
||||
|
||||
@@ -233,9 +232,9 @@ int DrumSynth::GetPrivateProfileInt(const char *sec, const char *key, int def, c
|
||||
int i=0;
|
||||
|
||||
GetPrivateProfileString(sec, key, "", tmp, sizeof(tmp), file);
|
||||
sscanf(tmp, "%d", &i); if(tmp[0]==0) i=def;
|
||||
|
||||
return i;
|
||||
sscanf(tmp, "%d", &i); if(tmp[0]==0) i=def;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float def, const char *file)
|
||||
@@ -244,9 +243,9 @@ float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float
|
||||
float f=0.f;
|
||||
|
||||
GetPrivateProfileString(sec, key, "", tmp, sizeof(tmp), file);
|
||||
sscanf(tmp, "%f", &f); if(tmp[0]==0) f=def;
|
||||
sscanf(tmp, "%f", &f); if(tmp[0]==0) f=def;
|
||||
|
||||
return f;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
@@ -259,7 +258,7 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
{
|
||||
//input file
|
||||
char sec[32];
|
||||
char ver[32];
|
||||
char ver[32];
|
||||
char comment[256];
|
||||
int commentLen=0;
|
||||
|
||||
@@ -268,11 +267,11 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
float x[3] = {0.f, 0.f, 0.f};
|
||||
float MasterTune, randmax, randmax2;
|
||||
int MainFilter, HighPass;
|
||||
|
||||
|
||||
long NON, NT, TON, DiON, TDroop=0, DStep;
|
||||
float a, b=0.f, c=0.f, d=0.f, g, TT=0.f, TL, NL, F1, F2;
|
||||
float TphiStart=0.f, Tphi, TDroopRate, ddF, DAtten, DGain;
|
||||
|
||||
|
||||
long BON, BON2, BFStep, BFStep2, botmp;
|
||||
float BdF=0.f, BdF2=0.f, BPhi, BPhi2, BF, BF2, BQ, BQ2, BL, BL2;
|
||||
|
||||
@@ -282,7 +281,7 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
float Oc0=0.0f, Oc1=0.0f, Oc2=0.0f;
|
||||
|
||||
float MFfb, MFtmp, MFres, MFin=0.f, MFout=0.f;
|
||||
float DownAve;
|
||||
float DownAve;
|
||||
long DownStart, DownEnd, jj;
|
||||
|
||||
|
||||
@@ -297,22 +296,22 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
}
|
||||
|
||||
//try to read version from input file
|
||||
strcpy(sec, "General");
|
||||
strcpy(sec, "General");
|
||||
GetPrivateProfileString(sec,"Version","",ver,sizeof(ver),dsfile);
|
||||
ver[9]=0;
|
||||
ver[9]=0;
|
||||
if(strcasecmp(ver, "DrumSynth") != 0) {return 0;} //input fail
|
||||
if(ver[11] != '1' && ver[11] != '2') {return 0;} //version fail
|
||||
|
||||
|
||||
|
||||
//read master parameters
|
||||
GetPrivateProfileString(sec,"Comment","",comment,sizeof(comment),dsfile);
|
||||
while((comment[commentLen]!=0) && (commentLen<254)) commentLen++;
|
||||
if(commentLen==0) { comment[0]=32; comment[1]=0; commentLen=1;}
|
||||
comment[commentLen+1]=0; commentLen++;
|
||||
if((commentLen % 2)==1) commentLen++;
|
||||
|
||||
if((commentLen % 2)==1) commentLen++;
|
||||
|
||||
timestretch = .01f * mem_time * GetPrivateProfileFloat(sec,"Stretch",100.0,dsfile);
|
||||
if(timestretch<0.2f) timestretch=0.2f;
|
||||
if(timestretch<0.2f) timestretch=0.2f;
|
||||
if(timestretch>10.f) timestretch=10.f;
|
||||
|
||||
DGain = 1.0f; //leave this here!
|
||||
@@ -320,35 +319,35 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
|
||||
MasterTune = GetPrivateProfileFloat(sec,"Tuning",0.0,dsfile);
|
||||
MasterTune = (float)powf(1.0594631f, MasterTune + mem_tune);
|
||||
MainFilter = 2 * GetPrivateProfileInt(sec,"Filter",0,dsfile);
|
||||
MainFilter = 2 * GetPrivateProfileInt(sec,"Filter",0,dsfile);
|
||||
MFres = 0.0101f * GetPrivateProfileFloat(sec,"Resonance",0.0,dsfile);
|
||||
MFres = (float)powf(MFres, 0.5f);
|
||||
|
||||
|
||||
HighPass = GetPrivateProfileInt(sec,"HighPass",0,dsfile);
|
||||
GetEnv(7, sec, "FilterEnv", dsfile);
|
||||
|
||||
|
||||
|
||||
//read noise parameters
|
||||
strcpy(sec, "Noise");
|
||||
chkOn[1] = GetPrivateProfileInt(sec,"On",0,dsfile);
|
||||
sliLev[1] = GetPrivateProfileInt(sec,"Level",0,dsfile);
|
||||
NT = GetPrivateProfileInt(sec,"Slope",0,dsfile);
|
||||
sliLev[1] = GetPrivateProfileInt(sec,"Level",0,dsfile);
|
||||
NT = GetPrivateProfileInt(sec,"Slope",0,dsfile);
|
||||
GetEnv(2, sec, "Envelope", dsfile);
|
||||
NON = chkOn[1];
|
||||
NON = chkOn[1];
|
||||
NL = (float)(sliLev[1] * sliLev[1]) * mem_n;
|
||||
if(NT<0)
|
||||
{ a = 1.f + (NT / 105.f); d = -NT / 105.f;
|
||||
g = (1.f + 0.0005f * NT * NT) * NL; }
|
||||
else
|
||||
{ a = 1.f; b = -NT / 50.f; c = (float)fabs((float)NT) / 100.f; g = NL; }
|
||||
|
||||
//if(GetPrivateProfileInt(sec,"FixedSeq",0,dsfile)!=0)
|
||||
|
||||
//if(GetPrivateProfileInt(sec,"FixedSeq",0,dsfile)!=0)
|
||||
//srand(1); //fixed random sequence
|
||||
|
||||
|
||||
//read tone parameters
|
||||
strcpy(sec, "Tone");
|
||||
chkOn[0] = GetPrivateProfileInt(sec,"On",0,dsfile); TON = chkOn[0];
|
||||
sliLev[0] = GetPrivateProfileInt(sec,"Level",128,dsfile);
|
||||
sliLev[0] = GetPrivateProfileInt(sec,"Level",128,dsfile);
|
||||
TL = (float)(sliLev[0] * sliLev[0]) * mem_t;
|
||||
GetEnv(1, sec, "Envelope", dsfile);
|
||||
F1 = MasterTune * TwoPi * GetPrivateProfileFloat(sec,"F1",200.0,dsfile) / Fs;
|
||||
@@ -364,13 +363,13 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
ddF = F1 - F2;
|
||||
}
|
||||
else ddF = F2-F1;
|
||||
|
||||
|
||||
Tphi = GetPrivateProfileFloat(sec,"Phase",90.f,dsfile) / 57.29578f; //degrees>radians
|
||||
|
||||
//read overtone parameters
|
||||
strcpy(sec, "Overtones");
|
||||
chkOn[2] = GetPrivateProfileInt(sec,"On",0,dsfile); OON = chkOn[2];
|
||||
sliLev[2] = GetPrivateProfileInt(sec,"Level",128,dsfile);
|
||||
sliLev[2] = GetPrivateProfileInt(sec,"Level",128,dsfile);
|
||||
OL = (float)(sliLev[2] * sliLev[2]) * mem_o;
|
||||
GetEnv(3, sec, "Envelope1", dsfile);
|
||||
GetEnv(4, sec, "Envelope2", dsfile);
|
||||
@@ -381,11 +380,11 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
OW2 = GetPrivateProfileInt(sec,"Wave2",0,dsfile);
|
||||
OBal2 = (float)GetPrivateProfileInt(sec,"Param",50,dsfile);
|
||||
ODrive = (float)powf(OBal2, 3.0f) / (float)powf(50.0f, 3.0f);
|
||||
OBal2 *= 0.01f;
|
||||
OBal2 *= 0.01f;
|
||||
OBal1 = 1.f - OBal2;
|
||||
Ophi1 = Tphi;
|
||||
Ophi1 = Tphi;
|
||||
Ophi2 = Tphi;
|
||||
if(MainFilter==0)
|
||||
if(MainFilter==0)
|
||||
MainFilter = GetPrivateProfileInt(sec,"Filter",0,dsfile);
|
||||
if((GetPrivateProfileInt(sec,"Track1",0,dsfile)==1) && (TON==1))
|
||||
{ OF1Sync = 1; OF1 = OF1 / F1; }
|
||||
@@ -403,28 +402,28 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
//read noise band parameters
|
||||
strcpy(sec, "NoiseBand");
|
||||
chkOn[3] = GetPrivateProfileInt(sec,"On",0,dsfile); BON = chkOn[3];
|
||||
sliLev[3] = GetPrivateProfileInt(sec,"Level",128,dsfile);
|
||||
sliLev[3] = GetPrivateProfileInt(sec,"Level",128,dsfile);
|
||||
BL = (float)(sliLev[3] * sliLev[3]) * mem_b;
|
||||
BF = MasterTune * TwoPi * GetPrivateProfileFloat(sec,"F",1000.0,dsfile) / Fs;
|
||||
BPhi = TwoPi / 8.f;
|
||||
GetEnv(5, sec, "Envelope", dsfile);
|
||||
BFStep = GetPrivateProfileInt(sec,"dF",50,dsfile);
|
||||
BQ = (float)BFStep;
|
||||
BFStep = GetPrivateProfileInt(sec,"dF",50,dsfile);
|
||||
BQ = (float)BFStep;
|
||||
BQ = BQ * BQ / (10000.f-6600.f*((float)sqrt(BF)-0.19f));
|
||||
BFStep = 1 + (int)((40.f - (BFStep / 2.5f)) / (BQ + 1.f + (1.f * BF)));
|
||||
|
||||
strcpy(sec, "NoiseBand2");
|
||||
chkOn[4] = GetPrivateProfileInt(sec,"On",0,dsfile); BON2 = chkOn[4];
|
||||
sliLev[4] = GetPrivateProfileInt(sec,"Level",128,dsfile);
|
||||
sliLev[4] = GetPrivateProfileInt(sec,"Level",128,dsfile);
|
||||
BL2 = (float)(sliLev[4] * sliLev[4]) * mem_b;
|
||||
BF2 = MasterTune * TwoPi * GetPrivateProfileFloat(sec,"F",1000.0,dsfile) / Fs;
|
||||
BPhi2 = TwoPi / 8.f;
|
||||
GetEnv(6, sec, "Envelope", dsfile);
|
||||
BFStep2 = GetPrivateProfileInt(sec,"dF",50,dsfile);
|
||||
BFStep2 = GetPrivateProfileInt(sec,"dF",50,dsfile);
|
||||
BQ2 = (float)BFStep2;
|
||||
BQ2 = BQ2 * BQ2 / (10000.f-6600.f*((float)sqrt(BF2)-0.19f));
|
||||
BFStep2 = 1 + (int)((40 - (BFStep2 / 2.5)) / (BQ2 + 1 + (1 * BF2)));
|
||||
|
||||
|
||||
//read distortion parameters
|
||||
strcpy(sec, "Distortion");
|
||||
chkOn[5] = GetPrivateProfileInt(sec,"On",0,dsfile); DiON = chkOn[5];
|
||||
@@ -434,14 +433,14 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
clippoint = 32700;
|
||||
DAtten = 1.0f;
|
||||
|
||||
if(DiON==1)
|
||||
if(DiON==1)
|
||||
{
|
||||
DAtten = DGain * (short)LoudestEnv();
|
||||
if(DAtten>32700) clippoint=32700; else clippoint=(short)DAtten;
|
||||
DAtten = DGain * (short)LoudestEnv();
|
||||
if(DAtten>32700) clippoint=32700; else clippoint=(short)DAtten;
|
||||
DAtten = (float)powf(2.0, 2.0 * GetPrivateProfileInt(sec,"Bits",0,dsfile));
|
||||
DGain = DAtten * DGain * (float)powf(10.0, 0.05 * GetPrivateProfileInt(sec,"Clipping",0,dsfile));
|
||||
}
|
||||
|
||||
|
||||
//prepare envelopes
|
||||
randmax = 1.f / RAND_MAX; randmax2 = 2.f * randmax;
|
||||
for (i=1;i<8;i++) { envData[i][NEXTT]=0; envData[i][PNT]=0; }
|
||||
@@ -473,7 +472,7 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
|
||||
//write WAV header
|
||||
WH.riff = 0x46464952;
|
||||
WH.riffLength = 36 + (2 * Length) + 44 + commentLen;
|
||||
WH.riffLength = 36 + (2 * Length) + 44 + commentLen;
|
||||
WH.wave = 0x45564157;
|
||||
WH.fmt = 0x20746D66;
|
||||
WH.waveLength = 16;
|
||||
@@ -503,7 +502,7 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
else UpdateEnv(2, t);
|
||||
x[2] = x[1];
|
||||
x[1] = x[0];
|
||||
x[0] = (randmax2 * (float)rand()) - 1.f;
|
||||
x[0] = (randmax2 * (float)rand()) - 1.f;
|
||||
TT = a * x[0] + b * x[1] + c * x[2] + d * TT;
|
||||
DF[t - tpos] = TT * g * envData[2][ENV];
|
||||
}
|
||||
@@ -512,7 +511,7 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
else {
|
||||
for(j=0; j<1200; j++) DF[j]=0.f;
|
||||
}
|
||||
|
||||
|
||||
if(TON==1) //tone
|
||||
{
|
||||
TphiStart = Tphi;
|
||||
@@ -520,16 +519,16 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
{
|
||||
for(t=tpos; t<=tplus; t++)
|
||||
phi[t - tpos] = F2 + (ddF * (float)exp(t * TDroopRate));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(t=tpos; t<=tplus; t++)
|
||||
phi[t - tpos] = F1 + (t / envData[1][MAX]) * ddF;
|
||||
}
|
||||
}
|
||||
for(t=tpos; t<=tplus; t++)
|
||||
{
|
||||
totmp = t - tpos;
|
||||
if(t < envData[1][NEXTT])
|
||||
if(t < envData[1][NEXTT])
|
||||
envData[1][ENV] = envData[1][ENV] + envData[1][dENV];
|
||||
else UpdateEnv(1, t);
|
||||
Tphi = Tphi + phi[totmp];
|
||||
@@ -538,7 +537,7 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
if(t>=envData[1][MAX]) TON=0;
|
||||
}
|
||||
else for(j=0; j<1200; j++) phi[j]=F2; //for overtone sync
|
||||
|
||||
|
||||
if(BON==1) //noise band 1
|
||||
{
|
||||
for(t=tpos; t<=tplus; t++)
|
||||
@@ -580,8 +579,8 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
{
|
||||
if(t>=envData[3][MAX]) //wait for OT2
|
||||
{
|
||||
envData[3][ENV] = 0;
|
||||
envData[3][dENV] = 0;
|
||||
envData[3][ENV] = 0;
|
||||
envData[3][dENV] = 0;
|
||||
envData[3][NEXTT] = 999999;
|
||||
}
|
||||
else UpdateEnv(3, t);
|
||||
@@ -610,12 +609,12 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
Ot = OBal1 * envData[3][ENV] * waveform(Ophi1, OW1);
|
||||
Ot = OL * (Ot + OBal2 * envData[4][ENV] * waveform(Ophi2, OW2));
|
||||
break;
|
||||
|
||||
|
||||
case 1: //FM
|
||||
Ot = ODrive * envData[4][ENV] * waveform(Ophi2, OW2);
|
||||
Ot = OL * envData[3][ENV] * waveform(Ophi1 + Ot, OW1);
|
||||
break;
|
||||
|
||||
|
||||
case 2: //RM
|
||||
Ot = (1 - ODrive / 8) + (((ODrive / 8) * envData[4][ENV]) * waveform(Ophi2, OW2));
|
||||
Ot = OL * envData[3][ENV] * waveform(Ophi1, OW1) * Ot;
|
||||
@@ -625,10 +624,10 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
for(j=0; j<6; j++)
|
||||
{
|
||||
Oc[j][0] += 1.0f;
|
||||
|
||||
|
||||
if(Oc[j][0]>Oc[j][1])
|
||||
{
|
||||
Oc[j][0] -= Oc[j][1];
|
||||
{
|
||||
Oc[j][0] -= Oc[j][1];
|
||||
Ot = OL * envData[3][ENV];
|
||||
}
|
||||
}
|
||||
@@ -639,8 +638,8 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
Ot = Oc1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(MainFilter==1) //filter overtones
|
||||
{
|
||||
if(t<envData[7][NEXTT])
|
||||
@@ -651,9 +650,9 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
if(MFtmp >0.2f)
|
||||
MFfb = 1.001f - (float)powf(10.0f, MFtmp - 1);
|
||||
else
|
||||
MFfb = 0.999f - 0.7824f * MFtmp;
|
||||
|
||||
MFtmp = Ot + MFres * (1.f + (1.f/MFfb)) * (MFin - MFout);
|
||||
MFfb = 0.999f - 0.7824f * MFtmp;
|
||||
|
||||
MFtmp = Ot + MFres * (1.f + (1.f/MFfb)) * (MFin - MFout);
|
||||
MFin = MFfb * (MFin - MFtmp) + MFtmp;
|
||||
MFout = MFfb * (MFout - MFin) + MFin;
|
||||
|
||||
@@ -669,48 +668,48 @@ int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels
|
||||
if(MFtmp >0.2f)
|
||||
MFfb = 1.001f - (float)powf(10.0f, MFtmp - 1);
|
||||
else
|
||||
MFfb = 0.999f - 0.7824f * MFtmp;
|
||||
|
||||
MFtmp = DF[t - tpos] + Ot + MFres * (1.f + (1.f/MFfb)) * (MFin - MFout);
|
||||
MFfb = 0.999f - 0.7824f * MFtmp;
|
||||
|
||||
MFtmp = DF[t - tpos] + Ot + MFres * (1.f + (1.f/MFfb)) * (MFin - MFout);
|
||||
MFin = MFfb * (MFin - MFtmp) + MFtmp;
|
||||
MFout = MFfb * (MFout - MFin) + MFin;
|
||||
|
||||
|
||||
DF[t - tpos] = MFout - (HighPass * (DF[t - tpos] + Ot));
|
||||
}
|
||||
// PG: Ot is uninitialized
|
||||
else DF[t - tpos] = DF[t - tpos] + Ot; //no filter
|
||||
}
|
||||
|
||||
|
||||
if(DiON==1) //bit resolution
|
||||
{
|
||||
for(j=0; j<1200; j++)
|
||||
DF[j] = DGain * (int)(DF[j] / DAtten);
|
||||
|
||||
|
||||
for(j=0; j<1200; j+=DStep) //downsampling
|
||||
{
|
||||
DownAve = 0;
|
||||
DownStart = j;
|
||||
DownEnd = j + DStep - 1;
|
||||
for(jj = DownStart; jj<=DownEnd; jj++)
|
||||
for(jj = DownStart; jj<=DownEnd; jj++)
|
||||
DownAve = DownAve + DF[jj];
|
||||
DownAve = DownAve / DStep;
|
||||
for(jj = DownStart; jj<=DownEnd; jj++)
|
||||
for(jj = DownStart; jj<=DownEnd; jj++)
|
||||
DF[jj] = DownAve;
|
||||
}
|
||||
}
|
||||
}
|
||||
else for(j=0; j<1200; j++) DF[j] *= DGain;
|
||||
|
||||
|
||||
for(j = 0; j<1200; j++) //clipping + output
|
||||
{
|
||||
if(DF[j] > clippoint)
|
||||
wave[wavewords++] = clippoint;
|
||||
else if(DF[j] < -clippoint)
|
||||
else if(DF[j] < -clippoint)
|
||||
wave[wavewords++] = -clippoint;
|
||||
else
|
||||
else
|
||||
wave[wavewords++] = (short)DF[j];
|
||||
|
||||
for (int c = 1; c < channels; c++) {
|
||||
wave[wavewords] = wave[wavewords-1];
|
||||
wave[wavewords] = wave[wavewords-1];
|
||||
wavewords++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "EffectChain.h"
|
||||
#include "Effect.h"
|
||||
#include "Engine.h"
|
||||
#include "debug.h"
|
||||
#include "DummyEffect.h"
|
||||
#include "MixHelpers.h"
|
||||
#include "Song.h"
|
||||
@@ -148,7 +147,7 @@ void EffectChain::moveDown( Effect * _effect )
|
||||
if( _effect != m_effects.last() )
|
||||
{
|
||||
int i = 0;
|
||||
for( EffectList::Iterator it = m_effects.begin();
|
||||
for( EffectList::Iterator it = m_effects.begin();
|
||||
it != m_effects.end(); it++, i++ )
|
||||
{
|
||||
if( *it == _effect )
|
||||
@@ -156,10 +155,10 @@ void EffectChain::moveDown( Effect * _effect )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Effect * temp = m_effects[i + 1];
|
||||
m_effects[i + 1] = _effect;
|
||||
m_effects[i] = temp;
|
||||
m_effects[i] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +170,7 @@ void EffectChain::moveUp( Effect * _effect )
|
||||
if( _effect != m_effects.first() )
|
||||
{
|
||||
int i = 0;
|
||||
for( EffectList::Iterator it = m_effects.begin();
|
||||
for( EffectList::Iterator it = m_effects.begin();
|
||||
it != m_effects.end(); it++, i++ )
|
||||
{
|
||||
if( *it == _effect )
|
||||
@@ -179,10 +178,10 @@ void EffectChain::moveUp( Effect * _effect )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Effect * temp = m_effects[i - 1];
|
||||
m_effects[i - 1] = _effect;
|
||||
m_effects[i] = temp;
|
||||
m_effects[i] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,8 +239,8 @@ void EffectChain::startRunning()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( EffectList::Iterator it = m_effects.begin();
|
||||
|
||||
for( EffectList::Iterator it = m_effects.begin();
|
||||
it != m_effects.end(); it++ )
|
||||
{
|
||||
( *it )->startRunning();
|
||||
|
||||
@@ -27,13 +27,10 @@
|
||||
#include "BBTrackContainer.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "FxMixer.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "Ladspa2LMMS.h"
|
||||
#include "Mixer.h"
|
||||
#include "Pattern.h"
|
||||
#include "PresetPreviewPlayHandle.h"
|
||||
#include "ProjectJournal.h"
|
||||
#include "ProjectNotes.h"
|
||||
#include "Plugin.h"
|
||||
#include "Song.h"
|
||||
#include "BandLimitedWave.h"
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <QDomElement>
|
||||
|
||||
#include "EnvelopeAndLfoParameters.h"
|
||||
#include "debug.h"
|
||||
#include "Engine.h"
|
||||
#include "Mixer.h"
|
||||
#include "Oscillator.h"
|
||||
@@ -379,7 +378,7 @@ void EnvelopeAndLfoParameters::loadSettings( const QDomElement & _this )
|
||||
with 4.15 file format*/
|
||||
|
||||
if( _this.hasAttribute( "sus" ) )
|
||||
{
|
||||
{
|
||||
m_sustainModel.loadSettings( _this, "sus" );
|
||||
m_sustainModel.setValue( 1.0 - m_sustainModel.value() );
|
||||
}
|
||||
@@ -392,7 +391,7 @@ void EnvelopeAndLfoParameters::loadSettings( const QDomElement & _this )
|
||||
( TempoSyncKnob::TtempoSyncMode ) _this.attribute(
|
||||
"lfosyncmode" ).toInt() );
|
||||
}*/
|
||||
|
||||
|
||||
m_userWave.setAudioFile( _this.attribute( "userwavefile" ) );
|
||||
|
||||
updateSampleVars();
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "FxMixer.h"
|
||||
#include "MixerWorkerThread.h"
|
||||
#include "MixHelpers.h"
|
||||
#include "Effect.h"
|
||||
#include "Song.h"
|
||||
|
||||
#include "InstrumentTrack.h"
|
||||
@@ -530,7 +529,10 @@ FloatModel * FxMixer::channelSendModel( fx_ch_t fromChannel, fx_ch_t toChannel )
|
||||
|
||||
void FxMixer::mixToChannel( const sampleFrame * _buf, fx_ch_t _ch )
|
||||
{
|
||||
if( m_fxChannels[_ch]->m_muteModel.value() == false )
|
||||
// The first check is for the case where the last fxchannel was deleted but
|
||||
// there was a race condition where it had to be processed.
|
||||
if( _ch < m_fxChannels.size() &&
|
||||
m_fxChannels[_ch]->m_muteModel.value() == false )
|
||||
{
|
||||
m_fxChannels[_ch]->m_lock.lock();
|
||||
MixHelpers::add( m_fxChannels[_ch]->m_buffer, _buf, Engine::mixer()->framesPerPeriod() );
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "InstrumentTrack.h"
|
||||
#include "DummyInstrument.h"
|
||||
#include "NotePlayHandle.h"
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "JournallingObject.h"
|
||||
#include "AutomatableModel.h"
|
||||
#include "ProjectJournal.h"
|
||||
#include "base64.h"
|
||||
#include "Engine.h"
|
||||
|
||||
|
||||
@@ -70,7 +69,7 @@ void JournallingObject::addJournalCheckPoint()
|
||||
QDomElement JournallingObject::saveState( QDomDocument & _doc,
|
||||
QDomElement & _parent )
|
||||
{
|
||||
if( isJournalling() )
|
||||
if( isJournalling() )
|
||||
{
|
||||
QDomElement _this = SerializingObject::saveState( _doc, _parent );
|
||||
|
||||
|
||||
@@ -23,17 +23,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <QDomElement>
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
|
||||
#include "Song.h"
|
||||
#include "Engine.h"
|
||||
#include "Mixer.h"
|
||||
#include "LfoController.h"
|
||||
#include "ControllerDialog.h"
|
||||
#include "lmms_math.h"
|
||||
|
||||
|
||||
@@ -47,7 +44,7 @@ LfoController::LfoController( Model * _parent ) :
|
||||
this, tr( "Oscillator waveform" ) ),
|
||||
m_multiplierModel( 0, 0, 2, this, tr( "Frequency Multiplier" ) ),
|
||||
m_duration( 1000 ),
|
||||
m_phaseOffset( 0 ),
|
||||
m_phaseOffset( 0 ),
|
||||
m_currentPhase( 0 ),
|
||||
m_sampleFunction( &Oscillator::sinSample ),
|
||||
m_userDefSampleBuffer( new SampleBuffer )
|
||||
@@ -55,19 +52,19 @@ LfoController::LfoController( Model * _parent ) :
|
||||
setSampleExact( true );
|
||||
connect( &m_waveModel, SIGNAL( dataChanged() ),
|
||||
this, SLOT( updateSampleFunction() ) );
|
||||
|
||||
|
||||
connect( &m_speedModel, SIGNAL( dataChanged() ),
|
||||
this, SLOT( updateDuration() ) );
|
||||
connect( &m_multiplierModel, SIGNAL( dataChanged() ),
|
||||
this, SLOT( updateDuration() ) );
|
||||
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ),
|
||||
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ),
|
||||
this, SLOT( updateDuration() ) );
|
||||
|
||||
|
||||
connect( Engine::getSong(), SIGNAL( playbackStateChanged() ),
|
||||
this, SLOT( updatePhase() ) );
|
||||
connect( Engine::getSong(), SIGNAL( playbackPositionChanged() ),
|
||||
this, SLOT( updatePhase() ) );
|
||||
|
||||
|
||||
updateDuration();
|
||||
}
|
||||
|
||||
@@ -88,12 +85,12 @@ LfoController::~LfoController()
|
||||
|
||||
void LfoController::updateValueBuffer()
|
||||
{
|
||||
m_phaseOffset = m_phaseModel.value() / 360.0;
|
||||
float * values = m_valueBuffer.values();
|
||||
m_phaseOffset = m_phaseModel.value() / 360.0;
|
||||
float * values = m_valueBuffer.values();
|
||||
float phase = m_currentPhase + m_phaseOffset;
|
||||
|
||||
// roll phase up until we're in sync with period counter
|
||||
m_bufferLastUpdated++;
|
||||
m_bufferLastUpdated++;
|
||||
if( m_bufferLastUpdated < s_periods )
|
||||
{
|
||||
int diff = s_periods - m_bufferLastUpdated;
|
||||
@@ -103,16 +100,16 @@ void LfoController::updateValueBuffer()
|
||||
|
||||
|
||||
for( int i = 0; i < m_valueBuffer.length(); i++ )
|
||||
{
|
||||
const float currentSample = m_sampleFunction != NULL
|
||||
{
|
||||
const float currentSample = m_sampleFunction != NULL
|
||||
? m_sampleFunction( phase )
|
||||
: m_userDefSampleBuffer->userWaveSample( phase );
|
||||
|
||||
|
||||
values[i] = qBound( 0.0f, m_baseModel.value() + ( m_amountModel.value() * currentSample / 2.0f ), 1.0f );
|
||||
|
||||
phase += 1.0 / m_duration;
|
||||
}
|
||||
|
||||
|
||||
m_currentPhase = absFraction( phase - m_phaseOffset );
|
||||
}
|
||||
|
||||
@@ -141,7 +138,7 @@ void LfoController::updateDuration()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
m_duration = newDurationF;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "MemoryManager.h"
|
||||
#include <QtGlobal>
|
||||
#include <QReadWriteLock>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lmms_math.h"
|
||||
#include "MixHelpers.h"
|
||||
#include "lmms_math.h"
|
||||
#include "ValueBuffer.h"
|
||||
|
||||
|
||||
|
||||
@@ -22,18 +22,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "Mixer.h"
|
||||
|
||||
#include "AudioPort.h"
|
||||
#include "FxMixer.h"
|
||||
#include "MixHelpers.h"
|
||||
#include "MixerWorkerThread.h"
|
||||
#include "Song.h"
|
||||
#include "templates.h"
|
||||
#include "EnvelopeAndLfoParameters.h"
|
||||
#include "NotePlayHandle.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "debug.h"
|
||||
#include "Engine.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "SamplePlayHandle.h"
|
||||
@@ -292,7 +288,7 @@ void Mixer::pushInputFrames( sampleFrame * _ab, const f_cnt_t _frames )
|
||||
f_cnt_t frames = m_inputBufferFrames[ m_inputBufferWrite ];
|
||||
int size = m_inputBufferSize[ m_inputBufferWrite ];
|
||||
sampleFrame * buf = m_inputBuffer[ m_inputBufferWrite ];
|
||||
|
||||
|
||||
if( frames + _frames > size )
|
||||
{
|
||||
size = qMax( size * 2, frames + _frames );
|
||||
@@ -305,10 +301,10 @@ void Mixer::pushInputFrames( sampleFrame * _ab, const f_cnt_t _frames )
|
||||
|
||||
buf = ab;
|
||||
}
|
||||
|
||||
|
||||
memcpy( &buf[ frames ], _ab, _frames * sizeof( sampleFrame ) );
|
||||
m_inputBufferFrames[ m_inputBufferWrite ] += _frames;
|
||||
|
||||
|
||||
unlockInputFrames();
|
||||
}
|
||||
|
||||
@@ -359,7 +355,7 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
|
||||
if( it != m_playHandles.end() )
|
||||
{
|
||||
( *it )->audioPort()->removePlayHandle( ( *it ) );
|
||||
if( ( *it )->type() == PlayHandle::TypeNotePlayHandle )
|
||||
if( ( *it )->type() == PlayHandle::TypeNotePlayHandle )
|
||||
{
|
||||
NotePlayHandleManager::release( (NotePlayHandle*) *it );
|
||||
}
|
||||
@@ -415,7 +411,7 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
|
||||
if( ( *it )->isFinished() )
|
||||
{
|
||||
( *it )->audioPort()->removePlayHandle( ( *it ) );
|
||||
if( ( *it )->type() == PlayHandle::TypeNotePlayHandle )
|
||||
if( ( *it )->type() == PlayHandle::TypeNotePlayHandle )
|
||||
{
|
||||
NotePlayHandleManager::release( (NotePlayHandle*) *it );
|
||||
}
|
||||
@@ -446,7 +442,7 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
|
||||
EnvelopeAndLfoParameters::instances()->trigger();
|
||||
Controller::triggerFrameCounter();
|
||||
AutomatableModel::incrementPeriodCounter();
|
||||
|
||||
|
||||
// refresh buffer pool
|
||||
BufferManager::refresh();
|
||||
|
||||
@@ -639,7 +635,7 @@ bool Mixer::addPlayHandle( PlayHandle* handle )
|
||||
return true;
|
||||
}
|
||||
|
||||
if( handle->type() == PlayHandle::TypeNotePlayHandle )
|
||||
if( handle->type() == PlayHandle::TypeNotePlayHandle )
|
||||
{
|
||||
NotePlayHandleManager::release( (NotePlayHandle*)handle );
|
||||
}
|
||||
@@ -664,7 +660,7 @@ void Mixer::removePlayHandle( PlayHandle * _ph )
|
||||
if( it != m_playHandles.end() )
|
||||
{
|
||||
m_playHandles.erase( it );
|
||||
if( _ph->type() == PlayHandle::TypeNotePlayHandle )
|
||||
if( _ph->type() == PlayHandle::TypeNotePlayHandle )
|
||||
{
|
||||
NotePlayHandleManager::release( (NotePlayHandle*) _ph );
|
||||
}
|
||||
@@ -690,7 +686,7 @@ void Mixer::removePlayHandles( Track * _track, bool removeIPHs )
|
||||
if( ( *it )->isFromTrack( _track ) && ( removeIPHs || ( *it )->type() != PlayHandle::TypeInstrumentPlayHandle ) )
|
||||
{
|
||||
( *it )->audioPort()->removePlayHandle( ( *it ) );
|
||||
if( ( *it )->type() == PlayHandle::TypeNotePlayHandle )
|
||||
if( ( *it )->type() == PlayHandle::TypeNotePlayHandle )
|
||||
{
|
||||
NotePlayHandleManager::release( (NotePlayHandle*) *it );
|
||||
}
|
||||
@@ -942,8 +938,8 @@ void Mixer::fifoWriter::run()
|
||||
#ifdef __SSE__
|
||||
/* FTZ flag */
|
||||
_MM_SET_FLUSH_ZERO_MODE( _MM_FLUSH_ZERO_ON );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
#ifdef LMMS_HAVE_SCHED_H
|
||||
|
||||
@@ -23,8 +23,18 @@
|
||||
*/
|
||||
|
||||
#include "MixerWorkerThread.h"
|
||||
#include "Engine.h"
|
||||
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include "ThreadableJob.h"
|
||||
#include "Mixer.h"
|
||||
|
||||
#ifdef __SSE__
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
#ifdef __SSE3__
|
||||
#include <pmmintrin.h>
|
||||
#endif
|
||||
|
||||
MixerWorkerThread::JobQueue MixerWorkerThread::globalJobQueue;
|
||||
QWaitCondition * MixerWorkerThread::queueReadyWaitCond = NULL;
|
||||
@@ -157,7 +167,7 @@ void MixerWorkerThread::run()
|
||||
#ifdef __SSE__
|
||||
/* FTZ flag */
|
||||
_MM_SET_FLUSH_ZERO_MODE( _MM_FLUSH_ZERO_ON );
|
||||
#endif
|
||||
#endif
|
||||
QMutex m;
|
||||
while( m_quit == false )
|
||||
{
|
||||
|
||||
@@ -68,7 +68,7 @@ Note::Note( const Note & note ) :
|
||||
m_selected( note.m_selected ),
|
||||
m_oldKey( note.m_oldKey ),
|
||||
m_oldPos( note.m_oldPos ),
|
||||
m_oldLength( note.m_oldLength ),
|
||||
m_oldLength( note.m_oldLength ),
|
||||
m_isPlaying( note.m_isPlaying ),
|
||||
m_key( note.m_key),
|
||||
m_volume( note.m_volume ),
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#include "NotePlayHandle.h"
|
||||
#include "BasicFilters.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "DetuningHelper.h"
|
||||
#include "InstrumentSoundShaping.h"
|
||||
#include "InstrumentTrack.h"
|
||||
@@ -93,14 +92,14 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
|
||||
parent->m_hadChildren = true;
|
||||
|
||||
m_bbTrack = parent->m_bbTrack;
|
||||
|
||||
|
||||
parent->setUsesBuffer( false );
|
||||
}
|
||||
|
||||
updateFrequency();
|
||||
|
||||
setFrames( _frames );
|
||||
|
||||
|
||||
// inform attached components about new MIDI note (used for recording in Piano Roll)
|
||||
if( m_origin == OriginMidiInput )
|
||||
{
|
||||
@@ -114,7 +113,7 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
|
||||
// send MidiNoteOn event
|
||||
m_instrumentTrack->processOutEvent(
|
||||
MidiEvent( MidiNoteOn, midiChannel(), midiKey(), midiVelocity( baseVelocity ) ),
|
||||
MidiTime::fromFrames( offset(), Engine::framesPerTick() ),
|
||||
MidiTime::fromFrames( offset(), Engine::framesPerTick() ),
|
||||
offset() );
|
||||
}
|
||||
|
||||
@@ -122,9 +121,9 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
|
||||
{
|
||||
setUsesBuffer( false );
|
||||
}
|
||||
|
||||
|
||||
setAudioPort( instrumentTrack->audioPort() );
|
||||
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
@@ -133,7 +132,7 @@ void NotePlayHandle::done()
|
||||
{
|
||||
lock();
|
||||
noteOff( 0 );
|
||||
|
||||
|
||||
if( hasParent() == false )
|
||||
{
|
||||
delete m_baseDetuning;
|
||||
@@ -157,7 +156,7 @@ void NotePlayHandle::done()
|
||||
m_subNotes.clear();
|
||||
|
||||
delete m_filter;
|
||||
|
||||
|
||||
if( buffer() ) releaseBuffer();
|
||||
|
||||
unlock();
|
||||
@@ -212,7 +211,7 @@ void NotePlayHandle::play( sampleFrame * _working_buffer )
|
||||
setOffset( offset() - Engine::mixer()->framesPerPeriod() );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
lock();
|
||||
if( m_frequencyNeedsUpdate )
|
||||
{
|
||||
@@ -220,7 +219,7 @@ void NotePlayHandle::play( sampleFrame * _working_buffer )
|
||||
}
|
||||
|
||||
// number of frames that can be played this period
|
||||
f_cnt_t framesThisPeriod = m_totalFramesPlayed == 0
|
||||
f_cnt_t framesThisPeriod = m_totalFramesPlayed == 0
|
||||
? Engine::mixer()->framesPerPeriod() - offset()
|
||||
: Engine::mixer()->framesPerPeriod();
|
||||
|
||||
@@ -386,7 +385,7 @@ void NotePlayHandle::noteOff( const f_cnt_t _s )
|
||||
// send MidiNoteOff event
|
||||
m_instrumentTrack->processOutEvent(
|
||||
MidiEvent( MidiNoteOff, midiChannel(), midiKey(), 0 ),
|
||||
MidiTime::fromFrames( _s, Engine::framesPerTick() ),
|
||||
MidiTime::fromFrames( _s, Engine::framesPerTick() ),
|
||||
_s );
|
||||
}
|
||||
|
||||
@@ -597,7 +596,7 @@ NotePlayHandle * NotePlayHandleManager::acquire( InstrumentTrack* instrumentTrac
|
||||
s_mutex.lockForRead();
|
||||
NotePlayHandle * nph = s_available[ s_availableIndex.fetchAndAddOrdered( -1 ) ];
|
||||
s_mutex.unlock();
|
||||
|
||||
|
||||
new( (void*)nph ) NotePlayHandle( instrumentTrack, offset, frames, noteToPlay, parent, midiEventChannel, origin );
|
||||
return nph;
|
||||
}
|
||||
@@ -618,7 +617,7 @@ void NotePlayHandleManager::extend( int c )
|
||||
NotePlayHandle ** tmp = MM_ALLOC( NotePlayHandle*, s_size );
|
||||
MM_FREE( s_available );
|
||||
s_available = tmp;
|
||||
|
||||
|
||||
NotePlayHandle * n = MM_ALLOC( NotePlayHandle, c );
|
||||
|
||||
for( int i=0; i < c; ++i )
|
||||
|
||||
@@ -23,24 +23,20 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PeakController.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <QDomElement>
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
#include <QMessageBox>
|
||||
|
||||
|
||||
#include "Song.h"
|
||||
#include "Engine.h"
|
||||
#include "Mixer.h"
|
||||
#include "PeakController.h"
|
||||
#include "EffectChain.h"
|
||||
#include "ControllerDialog.h"
|
||||
#include "plugins/peak_controller_effect/peak_controller_effect.h"
|
||||
#include "PresetPreviewPlayHandle.h"
|
||||
#include "lmms_math.h"
|
||||
#include "interpolation.h"
|
||||
|
||||
class ControllerDialog;
|
||||
|
||||
PeakControllerEffectVector PeakController::s_effects;
|
||||
int PeakController::m_getCount;
|
||||
@@ -48,7 +44,7 @@ int PeakController::m_loadCount;
|
||||
bool PeakController::m_buggedFile;
|
||||
|
||||
|
||||
PeakController::PeakController( Model * _parent,
|
||||
PeakController::PeakController( Model * _parent,
|
||||
PeakControllerEffect * _peak_effect ) :
|
||||
Controller( Controller::PeakController, _parent, tr( "Peak Controller" ) ),
|
||||
m_peakEffect( _peak_effect ),
|
||||
@@ -99,7 +95,7 @@ void PeakController::updateValueBuffer()
|
||||
{
|
||||
const f_cnt_t frames = Engine::mixer()->framesPerPeriod();
|
||||
float * values = m_valueBuffer.values();
|
||||
|
||||
|
||||
for( f_cnt_t f = 0; f < frames; ++f )
|
||||
{
|
||||
const float diff = ( targetSample - m_currentSample );
|
||||
|
||||
@@ -116,7 +116,7 @@ Song::Song() :
|
||||
/* connect( &m_masterPitchModel, SIGNAL( dataChanged() ),
|
||||
this, SLOT( masterPitchChanged() ) );*/
|
||||
|
||||
qRegisterMetaType<Note>( "note" );
|
||||
qRegisterMetaType<Note>( "Note" );
|
||||
setType( SongContainer );
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationTrack.h"
|
||||
#include "AutomationEditor.h"
|
||||
#include "BBEditor.h"
|
||||
#include "BBTrack.h"
|
||||
#include "BBTrackContainer.h"
|
||||
@@ -207,6 +208,8 @@ void TrackContentObject::paste()
|
||||
restoreState( *( Clipboard::getContent( nodeName() ) ) );
|
||||
movePosition( pos );
|
||||
}
|
||||
AutomationPattern::resolveAllIDs();
|
||||
GuiApplication::instance()->automationEditor()->m_editor->updateAfterPatternChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -1436,6 +1439,7 @@ void TrackContentWidget::mousePressEvent( QMouseEvent * me )
|
||||
else if( me->button() == Qt::LeftButton &&
|
||||
!m_trackView->trackContainerView()->fixedTCOs() )
|
||||
{
|
||||
getTrack()->addJournalCheckPoint();
|
||||
const MidiTime pos = getPosition( me->x() ).getTact() *
|
||||
MidiTime::ticksPerTact();
|
||||
TrackContentObject * tco = getTrack()->createTCO( pos );
|
||||
@@ -1705,29 +1709,6 @@ void TrackOperationsWidget::clearTrack()
|
||||
|
||||
|
||||
|
||||
/*! \brief Create and assign a new FX Channel for this track */
|
||||
void TrackOperationsWidget::createFxLine()
|
||||
{
|
||||
int channelIndex = gui->fxMixerView()->addNewChannel();
|
||||
|
||||
Engine::fxMixer()->effectChannel( channelIndex )->m_name = m_trackView->getTrack()->name();
|
||||
|
||||
assignFxLine(channelIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! \brief Assign a specific FX Channel for this track */
|
||||
void TrackOperationsWidget::assignFxLine(int channelIndex)
|
||||
{
|
||||
Track * track = m_trackView->getTrack();
|
||||
dynamic_cast<InstrumentTrack *>( track )->effectChannelModel()->setValue( channelIndex );
|
||||
|
||||
gui->fxMixerView()->setCurrentFxLine( channelIndex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! \brief Remove this track from the track list
|
||||
*
|
||||
*/
|
||||
@@ -1764,31 +1745,8 @@ void TrackOperationsWidget::updateMenu()
|
||||
}
|
||||
if( InstrumentTrackView * trackView = dynamic_cast<InstrumentTrackView *>( m_trackView ) )
|
||||
{
|
||||
int channelIndex = trackView->model()->effectChannelModel()->value();
|
||||
|
||||
FxChannel * fxChannel = Engine::fxMixer()->effectChannel( channelIndex );
|
||||
|
||||
QMenu * fxMenu = new QMenu( tr( "FX %1: %2" ).arg( channelIndex ).arg( fxChannel->m_name ), toMenu );
|
||||
QSignalMapper * fxMenuSignalMapper = new QSignalMapper(this);
|
||||
|
||||
fxMenu->addAction("Assign to new FX Channel" , this, SLOT( createFxLine() ) );
|
||||
fxMenu->addSeparator();
|
||||
|
||||
|
||||
for (int i = 0; i < Engine::fxMixer()->fxChannels().size(); ++i)
|
||||
{
|
||||
FxChannel * currentChannel = Engine::fxMixer()->fxChannels()[i];
|
||||
|
||||
if ( currentChannel != fxChannel )
|
||||
{
|
||||
QString label = tr( "FX %1: %2" ).arg( currentChannel->m_channelIndex ).arg( currentChannel->m_name );
|
||||
QAction * action = fxMenu->addAction( label, fxMenuSignalMapper, SLOT( map() ) );
|
||||
fxMenuSignalMapper->setMapping(action, currentChannel->m_channelIndex);
|
||||
}
|
||||
}
|
||||
|
||||
QMenu *fxMenu = trackView->createFxMenu( tr( "FX %1: %2" ), tr( "Assign to new FX Channel" ));
|
||||
toMenu->addMenu(fxMenu);
|
||||
connect(fxMenuSignalMapper, SIGNAL(mapped(int)), this, SLOT(assignFxLine(int)));
|
||||
|
||||
toMenu->addSeparator();
|
||||
toMenu->addMenu( trackView->midiMenu() );
|
||||
@@ -2610,7 +2568,11 @@ void TrackView::mousePressEvent( QMouseEvent * me )
|
||||
}
|
||||
|
||||
|
||||
if( m_trackContainerView->allowRubberband() == true )
|
||||
int widgetTotal = ConfigManager::inst()->value( "ui",
|
||||
"compacttrackbuttons" ).toInt()==1 ?
|
||||
DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT :
|
||||
DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH;
|
||||
if( m_trackContainerView->allowRubberband() == true && me->x() > widgetTotal )
|
||||
{
|
||||
QWidget::mousePressEvent( me );
|
||||
}
|
||||
@@ -2664,8 +2626,11 @@ void TrackView::mousePressEvent( QMouseEvent * me )
|
||||
*/
|
||||
void TrackView::mouseMoveEvent( QMouseEvent * me )
|
||||
{
|
||||
|
||||
if( m_trackContainerView->allowRubberband() == true )
|
||||
int widgetTotal = ConfigManager::inst()->value( "ui",
|
||||
"compacttrackbuttons" ).toInt()==1 ?
|
||||
DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT :
|
||||
DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH;
|
||||
if( m_trackContainerView->allowRubberband() == true && me->x() > widgetTotal )
|
||||
{
|
||||
QWidget::mouseMoveEvent( me );
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* to/from base64
|
||||
*
|
||||
* Copyright (c) 2006-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
*
|
||||
* This file is part of LMMS - http://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
|
||||
#include "base64.h"
|
||||
#include "lmms_basics.h"
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QVariant>
|
||||
@@ -34,7 +33,7 @@
|
||||
namespace base64
|
||||
{
|
||||
|
||||
|
||||
|
||||
QString encode( const QVariant & _data )
|
||||
{
|
||||
QBuffer buf;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* fft_helpers.cpp - some functions around FFT analysis
|
||||
*
|
||||
* Copyright (c) 2008-2012 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
*
|
||||
* This file is part of LMMS - http://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
#include "fft_helpers.h"
|
||||
|
||||
#include "lmms_math.h"
|
||||
|
||||
#include <cmath>
|
||||
#include "lmms_constants.h"
|
||||
|
||||
/* returns biggest value from abs_spectrum[spec_size] array
|
||||
|
||||
@@ -36,10 +36,10 @@ float maximum(float *abs_spectrum, unsigned int spec_size)
|
||||
{
|
||||
float maxi=0;
|
||||
unsigned int i;
|
||||
|
||||
|
||||
if ( abs_spectrum==NULL )
|
||||
return -1;
|
||||
|
||||
|
||||
if (spec_size<=0)
|
||||
return -1;
|
||||
|
||||
@@ -48,7 +48,7 @@ float maximum(float *abs_spectrum, unsigned int spec_size)
|
||||
if ( abs_spectrum[i]>maxi )
|
||||
maxi=abs_spectrum[i];
|
||||
}
|
||||
|
||||
|
||||
return maxi;
|
||||
}
|
||||
|
||||
@@ -60,21 +60,21 @@ int hanming(float *timebuffer, int length, WINDOWS type)
|
||||
{
|
||||
int i;
|
||||
float alpha;
|
||||
|
||||
|
||||
if ( (timebuffer==NULL)||(length<=0) )
|
||||
return -1;
|
||||
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case HAMMING: alpha=0.54; break;
|
||||
case HANNING:
|
||||
case HANNING:
|
||||
default: alpha=0.5; break;
|
||||
}
|
||||
|
||||
|
||||
for ( i=0; i<length; i++ )
|
||||
{
|
||||
timebuffer[i]=timebuffer[i]*(alpha+(1-alpha)*cos(2*F_PI*i/((float)length-1.0)));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -88,7 +88,7 @@ int hanming(float *timebuffer, int length, WINDOWS type)
|
||||
int absspec(fftwf_complex *complex_buffer, float *absspec_buffer, int compl_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
if ( (complex_buffer==NULL)||(absspec_buffer==NULL) )
|
||||
return -1;
|
||||
if ( compl_length<=0 )
|
||||
@@ -98,7 +98,7 @@ int absspec(fftwf_complex *complex_buffer, float *absspec_buffer, int compl_leng
|
||||
{
|
||||
absspec_buffer[i]=(float )sqrt(complex_buffer[i][0]*complex_buffer[i][0] + complex_buffer[i][1]*complex_buffer[i][1]);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ int absspec(fftwf_complex *complex_buffer, float *absspec_buffer, int compl_leng
|
||||
/* build fewer subbands from many absolute spectrum values
|
||||
take care that - compressedbands[] array num_new elements long
|
||||
- num_old > num_new
|
||||
|
||||
|
||||
returns 0 on success, else -1 */
|
||||
int compressbands(float *absspec_buffer, float *compressedband, int num_old, int num_new, int bottom, int top)
|
||||
{
|
||||
@@ -114,13 +114,13 @@ int compressbands(float *absspec_buffer, float *compressedband, int num_old, int
|
||||
int i, usefromold;
|
||||
float j;
|
||||
float j_min, j_max;
|
||||
|
||||
|
||||
if ( (absspec_buffer==NULL)||(compressedband==NULL) )
|
||||
return -1;
|
||||
|
||||
|
||||
if ( num_old<num_new )
|
||||
return -1;
|
||||
|
||||
|
||||
if ( (num_old<=0)||(num_new<=0) )
|
||||
return -1;
|
||||
|
||||
@@ -138,15 +138,15 @@ int compressbands(float *absspec_buffer, float *compressedband, int num_old, int
|
||||
for ( i=0; i<num_new; i++ )
|
||||
{
|
||||
compressedband[i]=0;
|
||||
|
||||
|
||||
j_min=(i*ratio)+bottom;
|
||||
|
||||
if ( j_min<0 )
|
||||
j_min=bottom;
|
||||
|
||||
|
||||
j_max=j_min+ratio;
|
||||
|
||||
for ( j=(int)j_min; j<=j_max; j++ )
|
||||
for ( j=(int)j_min; j<=j_max; j++ )
|
||||
{
|
||||
compressedband[i]+=absspec_buffer[(int)j];
|
||||
}
|
||||
@@ -188,16 +188,16 @@ static const int onethirdoctavecenterfr[] = {20, 25, 31, 40, 50, 63, 80, 100, 12
|
||||
for ( i=0; i<31; i++ )
|
||||
{
|
||||
subbands[i]=0;
|
||||
|
||||
|
||||
// calculate bandwith for subband
|
||||
frequency=onethirdoctavecenterfr[i];
|
||||
|
||||
bandwith=(pow(2, 1.0/3.0)-1)*frequency;
|
||||
|
||||
|
||||
f_min=frequency-bandwith/2.0;
|
||||
f_max=frequency+bandwith/2.0;
|
||||
|
||||
j_min=(int)(f_min/max_frequency*(float)num_spec);
|
||||
j_min=(int)(f_min/max_frequency*(float)num_spec);
|
||||
|
||||
j_max=(int)(f_max/max_frequency*(float)num_spec);
|
||||
|
||||
@@ -215,7 +215,7 @@ static const int onethirdoctavecenterfr[] = {20, 25, 31, 40, 50, 63, 80, 100, 12
|
||||
}
|
||||
|
||||
} //for
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -231,13 +231,13 @@ float signalpower(float *timesignal, int num_values)
|
||||
|
||||
if( timesignal==NULL )
|
||||
return -1;
|
||||
|
||||
|
||||
float power=0;
|
||||
for ( int i=0; i<num_values; i++ )
|
||||
for ( int i=0; i<num_values; i++ )
|
||||
{
|
||||
power+=timesignal[i]*timesignal[i];
|
||||
}
|
||||
|
||||
return power;
|
||||
|
||||
return power;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,18 +35,13 @@
|
||||
#include <pmmintrin.h>
|
||||
#endif
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QLocale>
|
||||
#include <QProcess>
|
||||
#include <QTimer>
|
||||
#include <QTranslator>
|
||||
#include <QApplication>
|
||||
#include <QBitmap>
|
||||
#include <QDesktopWidget>
|
||||
#include <QMessageBox>
|
||||
#include <QPainter>
|
||||
#include <QSplashScreen>
|
||||
#include <QTextStream>
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
#include <windows.h>
|
||||
@@ -71,16 +66,13 @@
|
||||
#include "MemoryManager.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "NotePlayHandle.h"
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "LmmsStyle.h"
|
||||
#include "ImportFilter.h"
|
||||
#include "MainWindow.h"
|
||||
#include "ProjectRenderer.h"
|
||||
#include "DataFile.h"
|
||||
#include "Song.h"
|
||||
#include "LmmsPalette.h"
|
||||
|
||||
static inline QString baseName( const QString & _file )
|
||||
{
|
||||
@@ -199,6 +191,7 @@ int main( int argc, char * * argv )
|
||||
"-x, --oversampling <value> specify oversampling\n"
|
||||
" possible values: 1, 2, 4, 8\n"
|
||||
" default: 2\n"
|
||||
"-a, --float 32bit float bit depth\n"
|
||||
"-u, --upgrade <in> [out] upgrade file <in> and save as <out>\n"
|
||||
" standard out is used if no output file is specifed\n"
|
||||
"-d, --dump <in> dump XML of compressed file <in>\n"
|
||||
@@ -304,6 +297,12 @@ int main( int argc, char * * argv )
|
||||
}
|
||||
++i;
|
||||
}
|
||||
else if ( argc > i &&
|
||||
( QString( argv[i] ) =="--float" ||
|
||||
QString( argv[i] ) == "-a" ) )
|
||||
{
|
||||
os.depth = ProjectRenderer::Depth_32Bit;
|
||||
}
|
||||
else if( argc > i &&
|
||||
( QString( argv[i] ) == "--interpolation" ||
|
||||
QString( argv[i] ) == "-i" ) )
|
||||
|
||||
@@ -518,6 +518,10 @@ void FileBrowserTreeWidget::mouseMoveEvent( QMouseEvent * me )
|
||||
new StringPairDrag( "importedproject", f->fullName(),
|
||||
embed::getIconPixmap( "midi_file" ), this );
|
||||
break;
|
||||
case FileItem::ProjectFile:
|
||||
new StringPairDrag( "projectfile", f->fullName(),
|
||||
embed::getIconPixmap( "project_file" ), this );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -83,7 +83,6 @@ MainWindow::MainWindow() :
|
||||
vbox->setSpacing( 0 );
|
||||
vbox->setMargin( 0 );
|
||||
|
||||
|
||||
QWidget * w = new QWidget( main_widget );
|
||||
QHBoxLayout * hbox = new QHBoxLayout( w );
|
||||
hbox->setSpacing( 0 );
|
||||
@@ -94,24 +93,25 @@ MainWindow::MainWindow() :
|
||||
QSplitter * splitter = new QSplitter( Qt::Horizontal, w );
|
||||
splitter->setChildrenCollapsible( false );
|
||||
|
||||
QString wdir = ConfigManager::inst()->workingDir();
|
||||
ConfigManager* confMgr = ConfigManager::inst();
|
||||
|
||||
sideBar->appendTab( new PluginBrowser( splitter ) );
|
||||
sideBar->appendTab( new FileBrowser(
|
||||
ConfigManager::inst()->userProjectsDir() + "*" +
|
||||
ConfigManager::inst()->factoryProjectsDir(),
|
||||
confMgr->userProjectsDir() + "*" +
|
||||
confMgr->factoryProjectsDir(),
|
||||
"*.mmp *.mmpz *.xml *.mid *.flp",
|
||||
tr( "My Projects" ),
|
||||
embed::getIconPixmap( "project_file" ).transformed( QTransform().rotate( 90 ) ),
|
||||
splitter, false, true ) );
|
||||
sideBar->appendTab( new FileBrowser(
|
||||
ConfigManager::inst()->userSamplesDir() + "*" +
|
||||
ConfigManager::inst()->factorySamplesDir(),
|
||||
confMgr->userSamplesDir() + "*" +
|
||||
confMgr->factorySamplesDir(),
|
||||
"*", tr( "My Samples" ),
|
||||
embed::getIconPixmap( "sample_file" ).transformed( QTransform().rotate( 90 ) ),
|
||||
splitter, false, true ) );
|
||||
sideBar->appendTab( new FileBrowser(
|
||||
ConfigManager::inst()->userPresetsDir() + "*" +
|
||||
ConfigManager::inst()->factoryPresetsDir(),
|
||||
confMgr->userPresetsDir() + "*" +
|
||||
confMgr->factoryPresetsDir(),
|
||||
"*.xpf *.cs.xml *.xiz",
|
||||
tr( "My Presets" ),
|
||||
embed::getIconPixmap( "preset_file" ).transformed( QTransform().rotate( 90 ) ),
|
||||
@@ -121,33 +121,30 @@ MainWindow::MainWindow() :
|
||||
embed::getIconPixmap( "home" ).transformed( QTransform().rotate( 90 ) ),
|
||||
splitter, false, true ) );
|
||||
|
||||
|
||||
QStringList root_paths;
|
||||
QString title = tr( "Root directory" );
|
||||
bool dirs_as_items = false;
|
||||
|
||||
#ifdef LMMS_BUILD_APPLE
|
||||
title = tr( "Volumes" );
|
||||
root_paths += "/Volumes";
|
||||
#else
|
||||
#elif defined(LMMS_BUILD_WIN32)
|
||||
title = tr( "My Computer" );
|
||||
dirs_as_items = true;
|
||||
#endif
|
||||
|
||||
#if ! defined(LMMS_BUILD_APPLE)
|
||||
QFileInfoList drives = QDir::drives();
|
||||
foreach( const QFileInfo & drive, drives )
|
||||
{
|
||||
root_paths += drive.absolutePath();
|
||||
}
|
||||
#endif
|
||||
sideBar->appendTab( new FileBrowser( root_paths.join( "*" ), "*",
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
tr( "My Computer" ),
|
||||
#elif defined(LMMS_BUILD_APPLE)
|
||||
tr( "Volumes" ),
|
||||
#else
|
||||
tr( "Root Directory" ),
|
||||
#endif
|
||||
|
||||
sideBar->appendTab( new FileBrowser( root_paths.join( "*" ), "*", title,
|
||||
embed::getIconPixmap( "computer" ).transformed( QTransform().rotate( 90 ) ),
|
||||
splitter,
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
) );
|
||||
splitter, dirs_as_items) );
|
||||
|
||||
m_workspace = new QMdiArea( splitter );
|
||||
|
||||
@@ -190,13 +187,13 @@ MainWindow::MainWindow() :
|
||||
vbox->addWidget( w );
|
||||
setCentralWidget( main_widget );
|
||||
|
||||
m_updateTimer.start( 1000 / 20, this ); // 20 fps
|
||||
m_updateTimer.start( 1000 / 20, this ); // 20 fps
|
||||
|
||||
if( ConfigManager::inst()->value( "ui", "enableautosave" ).toInt() )
|
||||
{
|
||||
// connect auto save
|
||||
connect(&m_autoSaveTimer, SIGNAL(timeout()), this, SLOT(autoSave()));
|
||||
m_autoSaveTimer.start(1000 * 60); // 1 minute
|
||||
m_autoSaveTimer.start(1000 * 60); // 1 minute
|
||||
}
|
||||
|
||||
connect( Engine::getSong(), SIGNAL( playbackStateChanged() ),
|
||||
@@ -208,12 +205,10 @@ MainWindow::MainWindow() :
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
for( QList<PluginView *>::iterator it = m_tools.begin();
|
||||
it != m_tools.end(); ++it )
|
||||
for( PluginView *view : m_tools )
|
||||
{
|
||||
Model * m = ( *it )->model();
|
||||
delete *it;
|
||||
delete m;
|
||||
delete view->model();
|
||||
delete view;
|
||||
}
|
||||
// TODO: Close tools
|
||||
// destroy engine which will do further cleanups etc.
|
||||
@@ -835,8 +830,13 @@ bool MainWindow::saveProjectAs()
|
||||
if( sfd.exec () == FileDialog::Accepted &&
|
||||
!sfd.selectedFiles().isEmpty() && sfd.selectedFiles()[0] != "" )
|
||||
{
|
||||
QString fname = sfd.selectedFiles()[0] ;
|
||||
if( sfd.selectedNameFilter().contains( "(*.mpt)" ) && !sfd.selectedFiles()[0].endsWith( ".mpt" ) )
|
||||
{
|
||||
fname += ".mpt";
|
||||
}
|
||||
Engine::getSong()->guiSaveProjectAs(
|
||||
sfd.selectedFiles()[0] );
|
||||
fname );
|
||||
return( true );
|
||||
}
|
||||
return( false );
|
||||
|
||||
@@ -88,8 +88,6 @@ PluginBrowser::~PluginBrowser()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PluginDescList::PluginDescList(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
@@ -98,7 +96,6 @@ PluginDescList::PluginDescList(QWidget *parent) :
|
||||
Plugin::getDescriptorsOfAvailPlugins( m_pluginDescriptors );
|
||||
std::sort(m_pluginDescriptors.begin(), m_pluginDescriptors.end(), pluginBefore);
|
||||
|
||||
|
||||
for( Plugin::DescriptorList::const_iterator it = m_pluginDescriptors.constBegin();
|
||||
it != m_pluginDescriptors.constEnd(); ++it )
|
||||
{
|
||||
@@ -117,8 +114,6 @@ PluginDescList::PluginDescList(QWidget *parent) :
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PluginDescWidget::PluginDescWidget( const Plugin::Descriptor & _pd,
|
||||
QWidget * _parent ) :
|
||||
QWidget( _parent ),
|
||||
@@ -181,7 +176,6 @@ void PluginDescWidget::paintEvent( QPaintEvent * )
|
||||
m_targetHeight = qMax( 60, 25 + br.height() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +231,7 @@ void PluginDescWidget::updateHeight()
|
||||
m_updateTimer.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if( !m_updateTimer.isActive() )
|
||||
{
|
||||
m_updateTimer.start( 15 );
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "NStateButton.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "TextFloat.h"
|
||||
#include "SongEditor.h"
|
||||
|
||||
|
||||
#if QT_VERSION < 0x040800
|
||||
@@ -280,7 +281,7 @@ void TimeLineWidget::mousePressEvent( QMouseEvent* event )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if( event->button() == Qt::LeftButton )
|
||||
if( event->button() == Qt::LeftButton && !(event->modifiers() & Qt::ShiftModifier) )
|
||||
{
|
||||
m_action = MovePositionMarker;
|
||||
if( event->x() - m_xOffset < s_posMarkerPixmap->width() )
|
||||
@@ -292,6 +293,11 @@ void TimeLineWidget::mousePressEvent( QMouseEvent* event )
|
||||
m_moveXOff = s_posMarkerPixmap->width() / 2;
|
||||
}
|
||||
}
|
||||
else if( event->button() == Qt::LeftButton && (event->modifiers() & Qt::ShiftModifier) )
|
||||
{
|
||||
m_action = SelectSongTCO;
|
||||
m_initalXSelect = event->x();
|
||||
}
|
||||
else if( event->button() == Qt::RightButton || event->button() == Qt::MiddleButton )
|
||||
{
|
||||
m_moveXOff = s_posMarkerPixmap->width() / 2;
|
||||
@@ -373,6 +379,9 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event )
|
||||
update();
|
||||
break;
|
||||
}
|
||||
case SelectSongTCO:
|
||||
emit regionSelectedFromPixels( m_initalXSelect , event->x() );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -386,6 +395,7 @@ void TimeLineWidget::mouseReleaseEvent( QMouseEvent* event )
|
||||
{
|
||||
delete m_hint;
|
||||
m_hint = NULL;
|
||||
if ( m_action == SelectSongTCO ) { emit selectionFinished(); }
|
||||
m_action = NoAction;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "Song.h"
|
||||
#include "StringPairDrag.h"
|
||||
#include "Track.h"
|
||||
#include "GuiApplication.h"
|
||||
|
||||
|
||||
TrackContainerView::TrackContainerView( TrackContainer * _tc ) :
|
||||
@@ -307,12 +308,25 @@ void TrackContainerView::dragEnterEvent( QDragEnterEvent * _dee )
|
||||
{
|
||||
StringPairDrag::processDragEnterEvent( _dee,
|
||||
QString( "presetfile,pluginpresetfile,samplefile,instrument,"
|
||||
"importedproject,soundfontfile,vstpluginfile,"
|
||||
"importedproject,soundfontfile,vstpluginfile,projectfile,"
|
||||
"track_%1,track_%2" ).
|
||||
arg( Track::InstrumentTrack ).
|
||||
arg( Track::SampleTrack ) );
|
||||
}
|
||||
|
||||
void TrackContainerView::selectRegionFromPixels(int xStart, int xEnd)
|
||||
{
|
||||
m_rubberBand->setEnabled( true );
|
||||
m_rubberBand->show();
|
||||
m_rubberBand->setGeometry( min( xStart, xEnd ), 0, max( xStart, xEnd ) - min( xStart, xEnd ), std::numeric_limits<int>::max() );
|
||||
}
|
||||
|
||||
void TrackContainerView::stopRubberBand()
|
||||
{
|
||||
m_rubberBand->hide();
|
||||
m_rubberBand->setEnabled( false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -360,6 +374,16 @@ void TrackContainerView::dropEvent( QDropEvent * _de )
|
||||
ImportFilter::import( value, m_tc );
|
||||
_de->accept();
|
||||
}
|
||||
|
||||
else if( type == "projectfile")
|
||||
{
|
||||
if( gui->mainWindow()->mayChangeProject() )
|
||||
{
|
||||
Engine::getSong()->loadProject( value );
|
||||
}
|
||||
_de->accept();
|
||||
}
|
||||
|
||||
else if( type.left( 6 ) == "track_" )
|
||||
{
|
||||
DataFile dataFile( value.toUtf8() );
|
||||
|
||||
@@ -72,7 +72,7 @@ VersionedSaveDialog::VersionedSaveDialog( QWidget *parent,
|
||||
|
||||
bool VersionedSaveDialog::changeFileNameVersion(QString &fileName, bool increment )
|
||||
{
|
||||
static QRegExp regexp( "-\\d+(\\.\\w+)?$" );
|
||||
static QRegExp regexp( "[- ]\\d+(\\.\\w+)?$" );
|
||||
|
||||
int idx = regexp.indexIn( fileName );
|
||||
// For file names without extension (no ".mmpz")
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
#include "PianoRoll.h"
|
||||
#include "debug.h"
|
||||
#include "MeterModel.h"
|
||||
#include "StringPairDrag.h"
|
||||
#include "ProjectJournal.h"
|
||||
|
||||
|
||||
QPixmap * AutomationEditor::s_toolDraw = NULL;
|
||||
@@ -445,7 +447,6 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( mouseEvent->y() > TOP_MARGIN )
|
||||
{
|
||||
float level = getLevel( mouseEvent->y() );
|
||||
@@ -491,6 +492,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
if( mouseEvent->button() == Qt::LeftButton &&
|
||||
m_editMode == DRAW )
|
||||
{
|
||||
m_pattern->addJournalCheckPoint();
|
||||
// Connect the dots
|
||||
if( mouseEvent->modifiers() & Qt::ShiftModifier )
|
||||
{
|
||||
@@ -535,6 +537,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
m_editMode == DRAW ) ||
|
||||
m_editMode == ERASE )
|
||||
{
|
||||
m_pattern->addJournalCheckPoint();
|
||||
// erase single value
|
||||
if( it != time_map.end() )
|
||||
{
|
||||
@@ -564,6 +567,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
else if( mouseEvent->button() == Qt::LeftButton &&
|
||||
m_editMode == MOVE )
|
||||
{
|
||||
m_pattern->addJournalCheckPoint();
|
||||
// move selection (including selected values)
|
||||
|
||||
// save position where move-process began
|
||||
@@ -1658,6 +1662,7 @@ void AutomationEditor::setProgressionType(AutomationPattern::ProgressionTypes ty
|
||||
{
|
||||
if (validPattern())
|
||||
{
|
||||
m_pattern->addJournalCheckPoint();
|
||||
QMutexLocker m(&m_patternMutex);
|
||||
m_pattern->setProgressionType(type);
|
||||
Engine::getSong()->setModified();
|
||||
@@ -1797,6 +1802,7 @@ void AutomationEditor::cutSelectedValues()
|
||||
return;
|
||||
}
|
||||
|
||||
m_pattern->addJournalCheckPoint();
|
||||
m_valuesToCopy.clear();
|
||||
|
||||
timeMap selected_values;
|
||||
@@ -1826,6 +1832,7 @@ void AutomationEditor::pasteValues()
|
||||
QMutexLocker m( &m_patternMutex );
|
||||
if( validPattern() && !m_valuesToCopy.isEmpty() )
|
||||
{
|
||||
m_pattern->addJournalCheckPoint();
|
||||
for( timeMap::iterator it = m_valuesToCopy.begin();
|
||||
it != m_valuesToCopy.end(); ++it )
|
||||
{
|
||||
@@ -1852,6 +1859,7 @@ void AutomationEditor::deleteSelectedValues()
|
||||
return;
|
||||
}
|
||||
|
||||
m_pattern->addJournalCheckPoint();
|
||||
timeMap selected_values;
|
||||
getSelectedValues( selected_values );
|
||||
|
||||
@@ -2220,6 +2228,8 @@ AutomationEditorWindow::AutomationEditorWindow() :
|
||||
setFocusPolicy( Qt::StrongFocus );
|
||||
setFocus();
|
||||
setWindowIcon( embed::getIconPixmap( "automation" ) );
|
||||
setAcceptDrops( true );
|
||||
m_toolBar->setAcceptDrops( true );
|
||||
}
|
||||
|
||||
|
||||
@@ -2282,6 +2292,30 @@ const AutomationPattern* AutomationEditorWindow::currentPattern()
|
||||
return m_editor->currentPattern();
|
||||
}
|
||||
|
||||
void AutomationEditorWindow::dropEvent( QDropEvent *_de )
|
||||
{
|
||||
QString type = StringPairDrag::decodeKey( _de );
|
||||
QString val = StringPairDrag::decodeValue( _de );
|
||||
if( type == "automatable_model" )
|
||||
{
|
||||
AutomatableModel * mod = dynamic_cast<AutomatableModel *>(
|
||||
Engine::projectJournal()->
|
||||
journallingObject( val.toInt() ) );
|
||||
if( mod != NULL )
|
||||
{
|
||||
m_editor->m_pattern->addObject( mod );
|
||||
setCurrentPattern( m_editor->m_pattern );
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void AutomationEditorWindow::dragEnterEvent( QDragEnterEvent *_dee )
|
||||
{
|
||||
StringPairDrag::processDragEnterEvent( _dee, "automatable_model" );
|
||||
}
|
||||
|
||||
void AutomationEditorWindow::open(AutomationPattern* pattern)
|
||||
{
|
||||
setCurrentPattern(pattern);
|
||||
|
||||
@@ -22,13 +22,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BBEditor.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QMdiArea>
|
||||
|
||||
#include "BBEditor.h"
|
||||
#include "ComboBox.h"
|
||||
#include "BBTrackContainer.h"
|
||||
#include "embed.h"
|
||||
#include "MainWindow.h"
|
||||
@@ -156,8 +158,6 @@ void BBEditor::stop()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BBTrackContainerView::BBTrackContainerView(BBTrackContainer* tc) :
|
||||
TrackContainerView(tc),
|
||||
m_bbtc(tc)
|
||||
@@ -168,8 +168,6 @@ BBTrackContainerView::BBTrackContainerView(BBTrackContainer* tc) :
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BBTrackContainerView::addSteps()
|
||||
{
|
||||
TrackContainer::TrackList tl = model()->tracks();
|
||||
@@ -224,6 +222,18 @@ void BBTrackContainerView::removeBBView(int bb)
|
||||
|
||||
|
||||
|
||||
void BBTrackContainerView::saveSettings(QDomDocument& doc, QDomElement& element)
|
||||
{
|
||||
MainWindow::saveWidgetState(parentWidget(), element);
|
||||
}
|
||||
|
||||
void BBTrackContainerView::loadSettings(const QDomElement& element)
|
||||
{
|
||||
MainWindow::restoreWidgetState(parentWidget(), element);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void BBTrackContainerView::dropEvent(QDropEvent* de)
|
||||
{
|
||||
@@ -254,17 +264,3 @@ void BBTrackContainerView::updatePosition()
|
||||
//realignTracks();
|
||||
emit positionChanged( m_currentPosition );
|
||||
}
|
||||
|
||||
void BBEditor::closeEvent( QCloseEvent * _ce )
|
||||
{
|
||||
if( parentWidget() )
|
||||
{
|
||||
parentWidget()->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
hide();
|
||||
}
|
||||
_ce->ignore();
|
||||
}
|
||||
|
||||
|
||||
@@ -375,7 +375,8 @@ PianoRoll::PianoRoll() :
|
||||
this, SLOT( quantizeChanged() ) );
|
||||
|
||||
// Set up scale model
|
||||
const auto& chord_table = InstrumentFunctionNoteStacking::ChordTable::getInstance();
|
||||
const InstrumentFunctionNoteStacking::ChordTable& chord_table =
|
||||
InstrumentFunctionNoteStacking::ChordTable::getInstance();
|
||||
|
||||
m_scaleModel.addItem( tr("No scale") );
|
||||
for( const InstrumentFunctionNoteStacking::Chord& chord : chord_table )
|
||||
@@ -416,6 +417,10 @@ PianoRoll::PianoRoll() :
|
||||
|
||||
connect( Engine::getSong(), SIGNAL( timeSignatureChanged( int, int ) ),
|
||||
this, SLOT( update() ) );
|
||||
|
||||
//connection for selecion from timeline
|
||||
connect( m_timeLine, SIGNAL( regionSelectedFromPixels( int, int ) ),
|
||||
this, SLOT( selectRegionFromPixels( int, int ) ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -588,6 +593,44 @@ void PianoRoll::hidePattern( Pattern* pattern )
|
||||
}
|
||||
}
|
||||
|
||||
void PianoRoll::selectRegionFromPixels( int xStart, int xEnd )
|
||||
{
|
||||
|
||||
xStart -= WHITE_KEY_WIDTH;
|
||||
xEnd -= WHITE_KEY_WIDTH;
|
||||
|
||||
// select an area of notes
|
||||
int pos_ticks = xStart * MidiTime::ticksPerTact() / m_ppt +
|
||||
m_currentPosition;
|
||||
int key_num = 0;
|
||||
m_selectStartTick = pos_ticks;
|
||||
m_selectedTick = 0;
|
||||
m_selectStartKey = key_num;
|
||||
m_selectedKeys = 1;
|
||||
// change size of selection
|
||||
|
||||
// get tick in which the cursor is posated
|
||||
pos_ticks = xEnd * MidiTime::ticksPerTact() / m_ppt +
|
||||
m_currentPosition;
|
||||
key_num = 120;
|
||||
|
||||
m_selectedTick = pos_ticks - m_selectStartTick;
|
||||
if( (int) m_selectStartTick + m_selectedTick < 0 )
|
||||
{
|
||||
m_selectedTick = -static_cast<int>(
|
||||
m_selectStartTick );
|
||||
}
|
||||
m_selectedKeys = key_num - m_selectStartKey;
|
||||
if( key_num <= m_selectStartKey )
|
||||
{
|
||||
--m_selectedKeys;
|
||||
}
|
||||
|
||||
computeSelectedNotes( false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -906,7 +949,8 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke )
|
||||
{
|
||||
dragNotes( m_lastMouseX, m_lastMouseY,
|
||||
ke->modifiers() & Qt::AltModifier,
|
||||
ke->modifiers() & Qt::ShiftModifier );
|
||||
ke->modifiers() & Qt::ShiftModifier,
|
||||
ke->modifiers() & Qt::ControlModifier );
|
||||
}
|
||||
}
|
||||
ke->accept();
|
||||
@@ -938,7 +982,8 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke )
|
||||
{
|
||||
dragNotes( m_lastMouseX, m_lastMouseY,
|
||||
ke->modifiers() & Qt::AltModifier,
|
||||
ke->modifiers() & Qt::ShiftModifier );
|
||||
ke->modifiers() & Qt::ShiftModifier,
|
||||
ke->modifiers() & Qt::ControlModifier );
|
||||
}
|
||||
}
|
||||
ke->accept();
|
||||
@@ -979,7 +1024,8 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke )
|
||||
{
|
||||
dragNotes( m_lastMouseX, m_lastMouseY,
|
||||
ke->modifiers() & Qt::AltModifier,
|
||||
ke->modifiers() & Qt::ShiftModifier );
|
||||
ke->modifiers() & Qt::ShiftModifier,
|
||||
ke->modifiers() & Qt::ControlModifier );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1020,7 +1066,8 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke )
|
||||
{
|
||||
dragNotes( m_lastMouseX, m_lastMouseY,
|
||||
ke->modifiers() & Qt::AltModifier,
|
||||
ke->modifiers() & Qt::ShiftModifier );
|
||||
ke->modifiers() & Qt::ShiftModifier,
|
||||
ke->modifiers() & Qt::ControlModifier );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1077,7 +1124,11 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke )
|
||||
}
|
||||
|
||||
case Qt::Key_Control:
|
||||
if ( isActiveWindow() )
|
||||
// Enter selection mode if:
|
||||
// -> this window is active
|
||||
// -> shift is not pressed
|
||||
// (<S-C-drag> is shortcut for sticky note resize)
|
||||
if ( !( ke->modifiers() & Qt::ShiftModifier ) && isActiveWindow() )
|
||||
{
|
||||
m_ctrlMode = m_editMode;
|
||||
m_editMode = ModeSelect;
|
||||
@@ -1222,7 +1273,7 @@ void PianoRoll::mousePressEvent(QMouseEvent * me )
|
||||
return;
|
||||
}
|
||||
|
||||
// if holding control, go to selection mode
|
||||
// if holding control, go to selection mode unless shift is also pressed
|
||||
if( me->modifiers() & Qt::ControlModifier && m_editMode != ModeSelect )
|
||||
{
|
||||
m_ctrlMode = m_editMode;
|
||||
@@ -1948,12 +1999,10 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
|
||||
pauseTestNotes();
|
||||
}
|
||||
|
||||
dragNotes(
|
||||
me->x(),
|
||||
me->y(),
|
||||
dragNotes( me->x(), me->y(),
|
||||
me->modifiers() & Qt::AltModifier,
|
||||
me->modifiers() & Qt::ShiftModifier
|
||||
);
|
||||
me->modifiers() & Qt::ShiftModifier,
|
||||
me->modifiers() & Qt::ControlModifier );
|
||||
|
||||
if( replay_note && m_action == ActionMoveNote && ! ( ( me->modifiers() & Qt::ShiftModifier ) && ! m_startedWithShift ) )
|
||||
{
|
||||
@@ -2365,7 +2414,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
|
||||
|
||||
|
||||
|
||||
void PianoRoll::dragNotes( int x, int y, bool alt, bool shift )
|
||||
void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
|
||||
{
|
||||
// dragging one or more notes around
|
||||
|
||||
@@ -2411,13 +2460,19 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift )
|
||||
|
||||
// will be our iterator in the following loop
|
||||
NoteVector::ConstIterator it = notes.begin();
|
||||
|
||||
int sNotes = selectionCount();
|
||||
while( it != notes.end() )
|
||||
{
|
||||
Note *note = *it;
|
||||
const int pos = note->pos().getTicks();
|
||||
// when resizing a note and holding shift: shift the following
|
||||
// notes to preserve the melody
|
||||
if( m_action == ActionResizeNote && shift )
|
||||
|
||||
// When resizing notes:
|
||||
// If shift is pressed we resize and rearrange only the selected notes
|
||||
// If shift + ctrl then we also rearrange all posterior notes (sticky)
|
||||
// If shift is pressed but only one note is selected, apply sticky
|
||||
if( m_action == ActionResizeNote && shift &&
|
||||
( note->selected() || ctrl || sNotes == 1 ) )
|
||||
{
|
||||
int shifted_pos = note->oldPos().getTicks() + shift_offset;
|
||||
if( shifted_pos && pos == shift_ref_pos )
|
||||
@@ -3377,11 +3432,11 @@ void PianoRoll::finishRecordNote(const Note & n )
|
||||
{
|
||||
if( it->key() == n.key() )
|
||||
{
|
||||
Note n( n.length(), it->pos(),
|
||||
Note n1( n.length(), it->pos(),
|
||||
it->key(), it->getVolume(),
|
||||
it->getPanning() );
|
||||
n.quantizeLength( quantization() );
|
||||
m_pattern->addNote( n );
|
||||
n1.quantizeLength( quantization() );
|
||||
m_pattern->addNote( n1 );
|
||||
update();
|
||||
m_recordingNotes.erase( it );
|
||||
break;
|
||||
@@ -3814,7 +3869,8 @@ int PianoRoll::quantization() const
|
||||
|
||||
void PianoRoll::updateSemiToneMarkerMenu()
|
||||
{
|
||||
const auto& chord_table = InstrumentFunctionNoteStacking::ChordTable::getInstance();
|
||||
const InstrumentFunctionNoteStacking::ChordTable& chord_table =
|
||||
InstrumentFunctionNoteStacking::ChordTable::getInstance();
|
||||
const InstrumentFunctionNoteStacking::Chord& scale =
|
||||
chord_table.getScaleByName( m_scaleModel.currentText() );
|
||||
const InstrumentFunctionNoteStacking::Chord& chord =
|
||||
|
||||
@@ -98,6 +98,10 @@ SongEditor::SongEditor( Song * _song ) :
|
||||
SLOT( updatePosition( const MidiTime & ) ) );
|
||||
connect( m_timeLine, SIGNAL( positionChanged( const MidiTime & ) ),
|
||||
this, SLOT( updatePosition( const MidiTime & ) ) );
|
||||
connect( m_timeLine, SIGNAL( regionSelectedFromPixels( int, int ) ),
|
||||
this, SLOT( selectRegionFromPixels( int, int ) ) );
|
||||
connect( m_timeLine, SIGNAL( selectionFinished() ),
|
||||
this, SLOT( stopRubberBand() ) );
|
||||
|
||||
m_positionLine = new positionLine( this );
|
||||
|
||||
|
||||
@@ -45,73 +45,70 @@ namespace
|
||||
#include "embedded_resources.h"
|
||||
|
||||
|
||||
QPixmap getIconPixmap( const char * _name, int _w, int _h )
|
||||
QPixmap getIconPixmap( const char * pixmapName, int width, int height )
|
||||
{
|
||||
if( _w == -1 || _h == -1 )
|
||||
if( width == -1 || height == -1 )
|
||||
{
|
||||
// Return cached pixmap
|
||||
QPixmap cached = s_pixmapCache.value( _name );
|
||||
// Return cached pixmap
|
||||
QPixmap cached = s_pixmapCache.value( pixmapName );
|
||||
if( !cached.isNull() )
|
||||
{
|
||||
return cached;
|
||||
}
|
||||
|
||||
// Or try to load it
|
||||
QList<QByteArray> formats =
|
||||
QImageReader::supportedImageFormats();
|
||||
QList<QByteArray> formats = QImageReader::supportedImageFormats();
|
||||
QList<QString> candidates;
|
||||
QPixmap p;
|
||||
QPixmap pixmap;
|
||||
QString name;
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < formats.size() && p.isNull(); ++i )
|
||||
for ( i = 0; i < formats.size() && pixmap.isNull(); ++i )
|
||||
{
|
||||
candidates << QString( _name ) + "." + formats.at( i ).data();
|
||||
candidates << QString( pixmapName ) + "." + formats.at( i ).data();
|
||||
}
|
||||
|
||||
#ifdef PLUGIN_NAME
|
||||
for ( i = 0; i < candidates.size() && p.isNull(); ++i ) {
|
||||
for ( i = 0; i < candidates.size() && pixmap.isNull(); ++i ) {
|
||||
name = candidates.at( i );
|
||||
p = QPixmap( ConfigManager::inst()->artworkDir() + "plugins/" +
|
||||
pixmap = QPixmap( ConfigManager::inst()->artworkDir() + "plugins/" +
|
||||
STRINGIFY( PLUGIN_NAME ) + "_" + name );
|
||||
}
|
||||
#endif
|
||||
for ( i = 0; i < candidates.size() && p.isNull(); ++i ) {
|
||||
for ( i = 0; i < candidates.size() && pixmap.isNull(); ++i ) {
|
||||
name = candidates.at( i );
|
||||
p = QPixmap( ConfigManager::inst()->artworkDir() + name );
|
||||
pixmap = QPixmap( ConfigManager::inst()->artworkDir() + name );
|
||||
}
|
||||
|
||||
// nothing found, so look in default-artwork-dir
|
||||
for ( i = 0; i < candidates.size() && p.isNull(); ++i ) {
|
||||
for ( i = 0; i < candidates.size() && pixmap.isNull(); ++i ) {
|
||||
name = candidates.at( i );
|
||||
p = QPixmap( ConfigManager::inst()->defaultArtworkDir()
|
||||
+ name );
|
||||
pixmap = QPixmap( ConfigManager::inst()->defaultArtworkDir() + name );
|
||||
}
|
||||
|
||||
for ( i = 0; i < candidates.size() && p.isNull(); ++i ) {
|
||||
for ( i = 0; i < candidates.size() && pixmap.isNull(); ++i ) {
|
||||
name = candidates.at( i );
|
||||
const embed::descriptor & e =
|
||||
findEmbeddedData( name.toUtf8().constData() );
|
||||
// found?
|
||||
if( QString( e.name ) == name )
|
||||
if( name == e.name )
|
||||
{
|
||||
p.loadFromData( e.data, e.size );
|
||||
pixmap.loadFromData( e.data, e.size );
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback
|
||||
if(p.isNull())
|
||||
if( pixmap.isNull() )
|
||||
{
|
||||
p = QPixmap( 1, 1 );
|
||||
pixmap = QPixmap( 1, 1 );
|
||||
}
|
||||
// Save to cache and return
|
||||
s_pixmapCache.insert( _name, p );
|
||||
return p;
|
||||
|
||||
s_pixmapCache.insert( pixmapName, pixmap );
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
return getIconPixmap( _name ).
|
||||
scaled( _w, _h, Qt::IgnoreAspectRatio,
|
||||
return getIconPixmap( pixmapName ).
|
||||
scaled( width, height, Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation );
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,11 @@ FadeButton::~FadeButton()
|
||||
{
|
||||
}
|
||||
|
||||
void FadeButton::setActiveColor( const QColor & activated_color )
|
||||
{
|
||||
m_activatedColor = activated_color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -107,53 +107,56 @@ SideBar::~SideBar()
|
||||
|
||||
|
||||
|
||||
void SideBar::appendTab( SideBarWidget * _sbw )
|
||||
void SideBar::appendTab( SideBarWidget *widget )
|
||||
{
|
||||
SideBarButton * btn = new SideBarButton( orientation(), this );
|
||||
btn->setText( _sbw->title() );
|
||||
btn->setIcon( _sbw->icon() );
|
||||
btn->setCheckable( true );
|
||||
m_widgets[btn] = _sbw;
|
||||
m_btnGroup.addButton( btn );
|
||||
addWidget( btn );
|
||||
SideBarButton *button = new SideBarButton( orientation(), this );
|
||||
button->setText( widget->title() );
|
||||
button->setIcon( widget->icon() );
|
||||
button->setCheckable( true );
|
||||
m_widgets[button] = widget;
|
||||
m_btnGroup.addButton( button );
|
||||
addWidget( button );
|
||||
|
||||
_sbw->hide();
|
||||
_sbw->setMinimumWidth( 200 );
|
||||
widget->hide();
|
||||
widget->setMinimumWidth( 200 );
|
||||
|
||||
ToolTip::add( btn, _sbw->title() );
|
||||
ToolTip::add( button, widget->title() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SideBar::toggleButton( QAbstractButton * _btn )
|
||||
void SideBar::toggleButton( QAbstractButton * button )
|
||||
{
|
||||
QToolButton * toolButton = NULL;
|
||||
QWidget * activeWidget = NULL;
|
||||
for( ButtonMap::Iterator it = m_widgets.begin();
|
||||
it != m_widgets.end(); ++it )
|
||||
QToolButton *toolButton = NULL;
|
||||
QWidget *activeWidget = NULL;
|
||||
|
||||
for( auto it = m_widgets.begin(); it != m_widgets.end(); ++it )
|
||||
{
|
||||
QToolButton * curBtn = it.key();
|
||||
if( curBtn != _btn )
|
||||
QToolButton *curBtn = it.key();
|
||||
QWidget *curWidget = it.value();
|
||||
|
||||
if( curBtn == button )
|
||||
{
|
||||
toolButton = curBtn;
|
||||
activeWidget = curWidget;
|
||||
}
|
||||
else
|
||||
{
|
||||
curBtn->setChecked( false );
|
||||
curBtn->setToolButtonStyle( Qt::ToolButtonIconOnly );
|
||||
}
|
||||
else
|
||||
|
||||
if( curWidget )
|
||||
{
|
||||
toolButton = it.key();
|
||||
activeWidget = it.value();
|
||||
}
|
||||
if( it.value() )
|
||||
{
|
||||
it.value()->hide();
|
||||
curWidget->hide();
|
||||
}
|
||||
}
|
||||
|
||||
if( toolButton && activeWidget )
|
||||
{
|
||||
activeWidget->setVisible( _btn->isChecked() );
|
||||
toolButton->setToolButtonStyle( _btn->isChecked() ?
|
||||
activeWidget->setVisible( button->isChecked() );
|
||||
toolButton->setToolButtonStyle( button->isChecked() ?
|
||||
Qt::ToolButtonTextBesideIcon : Qt::ToolButtonIconOnly );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,12 +36,14 @@
|
||||
#include <QMessageBox>
|
||||
#include <QMdiSubWindow>
|
||||
#include <QPainter>
|
||||
#include <QWidget>
|
||||
|
||||
#include "FileDialog.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "AudioPort.h"
|
||||
#include "AutomationPattern.h"
|
||||
#include "BBTrack.h"
|
||||
#include "CaptionMenu.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "ControllerConnection.h"
|
||||
#include "debug.h"
|
||||
@@ -926,6 +928,7 @@ InstrumentTrackView::InstrumentTrackView( InstrumentTrack * _it, TrackContainerV
|
||||
connect( m_activityIndicator, SIGNAL( released() ),
|
||||
this, SLOT( activityIndicatorReleased() ) );
|
||||
_it->setIndicator( m_activityIndicator );
|
||||
connect( &_it->m_mutedModel, SIGNAL( dataChanged() ), this, SLOT( muteChanged() ) );
|
||||
|
||||
setModel( _it );
|
||||
}
|
||||
@@ -962,6 +965,30 @@ InstrumentTrackWindow * InstrumentTrackView::topLevelInstrumentTrackWindow()
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Create and assign a new FX Channel for this track */
|
||||
void InstrumentTrackView::createFxLine()
|
||||
{
|
||||
int channelIndex = gui->fxMixerView()->addNewChannel();
|
||||
|
||||
Engine::fxMixer()->effectChannel( channelIndex )->m_name = getTrack()->name();
|
||||
|
||||
assignFxLine(channelIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Assign a specific FX Channel for this track */
|
||||
void InstrumentTrackView::assignFxLine(int channelIndex)
|
||||
{
|
||||
model()->effectChannelModel()->setValue( channelIndex );
|
||||
|
||||
gui->fxMixerView()->setCurrentFxLine( channelIndex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: Add windows to free list on freeInstrumentTrackWindow.
|
||||
// But, don't NULL m_window or disconnect signals. This will allow windows
|
||||
// that are being show/hidden frequently to stay connected.
|
||||
@@ -1130,6 +1157,59 @@ void InstrumentTrackView::midiConfigChanged()
|
||||
|
||||
|
||||
|
||||
void InstrumentTrackView::muteChanged()
|
||||
{
|
||||
if(model()->m_mutedModel.value() )
|
||||
{
|
||||
m_activityIndicator->setActiveColor( QApplication::palette().color( QPalette::Active,
|
||||
QPalette::Highlight ) );
|
||||
} else
|
||||
{
|
||||
m_activityIndicator->setActiveColor( QApplication::palette().color( QPalette::Active,
|
||||
QPalette::BrightText ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QMenu * InstrumentTrackView::createFxMenu(QString title, QString newFxLabel)
|
||||
{
|
||||
int channelIndex = model()->effectChannelModel()->value();
|
||||
|
||||
FxChannel *fxChannel = Engine::fxMixer()->effectChannel( channelIndex );
|
||||
|
||||
// If title allows interpolation, pass channel index and name
|
||||
if ( title.contains( "%2" ) )
|
||||
{
|
||||
title = title.arg( channelIndex ).arg( fxChannel->m_name );
|
||||
}
|
||||
|
||||
QMenu *fxMenu = new QMenu( title );
|
||||
|
||||
QSignalMapper * fxMenuSignalMapper = new QSignalMapper(fxMenu);
|
||||
|
||||
fxMenu->addAction( newFxLabel, this, SLOT( createFxLine() ) );
|
||||
fxMenu->addSeparator();
|
||||
|
||||
for (int i = 0; i < Engine::fxMixer()->fxChannels().size(); ++i)
|
||||
{
|
||||
FxChannel * currentChannel = Engine::fxMixer()->fxChannels()[i];
|
||||
|
||||
if ( currentChannel != fxChannel )
|
||||
{
|
||||
QString label = tr( "FX %1: %2" ).arg( currentChannel->m_channelIndex ).arg( currentChannel->m_name );
|
||||
QAction * action = fxMenu->addAction( label, fxMenuSignalMapper, SLOT( map() ) );
|
||||
fxMenuSignalMapper->setMapping(action, currentChannel->m_channelIndex);
|
||||
}
|
||||
}
|
||||
|
||||
connect(fxMenuSignalMapper, SIGNAL(mapped(int)), this, SLOT(assignFxLine(int)));
|
||||
|
||||
return fxMenu;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class fxLineLcdSpinBox : public LcdSpinBox
|
||||
@@ -1148,6 +1228,30 @@ class fxLineLcdSpinBox : public LcdSpinBox
|
||||
gui->fxMixerView()->setFocus();// set focus to fxMixer window
|
||||
//engine::getFxMixerView()->raise();
|
||||
}
|
||||
|
||||
virtual void contextMenuEvent( QContextMenuEvent* event )
|
||||
{
|
||||
// for the case, the user clicked right while pressing left mouse-
|
||||
// button, the context-menu appears while mouse-cursor is still hidden
|
||||
// and it isn't shown again until user does something which causes
|
||||
// an QApplication::restoreOverrideCursor()-call...
|
||||
mouseReleaseEvent( NULL );
|
||||
|
||||
QPointer<CaptionMenu> contextMenu = new CaptionMenu( model()->displayName(), this );
|
||||
|
||||
// This condition is here just as a safety check, fxLineLcdSpinBox is aways
|
||||
// created inside a TabWidget inside an InstrumentTrackWindow
|
||||
if ( InstrumentTrackWindow* window = dynamic_cast<InstrumentTrackWindow*>( (QWidget *)this->parent()->parent() ) )
|
||||
{
|
||||
QMenu *fxMenu = window->instrumentTrackView()->createFxMenu( tr( "Assign to:" ), tr( "New FX Channel" ) );
|
||||
contextMenu->addMenu( fxMenu );
|
||||
|
||||
contextMenu->addSeparator();
|
||||
}
|
||||
addDefaultActions( contextMenu );
|
||||
contextMenu->exec( QCursor::pos() );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -761,12 +761,16 @@ void PatternView::constructContextMenu( QMenu * _cm )
|
||||
_cm->addAction( embed::getIconPixmap( "edit_rename" ),
|
||||
tr( "Change name" ),
|
||||
this, SLOT( changeName() ) );
|
||||
_cm->addSeparator();
|
||||
|
||||
_cm->addAction( embed::getIconPixmap( "step_btn_add" ),
|
||||
tr( "Add steps" ), m_pat, SLOT( addSteps() ) );
|
||||
_cm->addAction( embed::getIconPixmap( "step_btn_remove" ),
|
||||
tr( "Remove steps" ), m_pat, SLOT( removeSteps() ) );
|
||||
if ( m_pat->type() == Pattern::BeatPattern )
|
||||
{
|
||||
_cm->addSeparator();
|
||||
|
||||
_cm->addAction( embed::getIconPixmap( "step_btn_add" ),
|
||||
tr( "Add steps" ), m_pat, SLOT( addSteps() ) );
|
||||
_cm->addAction( embed::getIconPixmap( "step_btn_remove" ),
|
||||
tr( "Remove steps" ), m_pat, SLOT( removeSteps() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -834,6 +838,7 @@ void PatternView::mousePressEvent( QMouseEvent * _me )
|
||||
}
|
||||
else // note at step found
|
||||
{
|
||||
m_pat->addJournalCheckPoint();
|
||||
if( n->length() < 0 )
|
||||
{
|
||||
n->setLength( 0 ); // set note as enabled beat note
|
||||
|
||||
Reference in New Issue
Block a user