Merge pull request #1 from teeberg/coding

This commit is contained in:
Alexandre Almeida
2015-02-10 17:38:18 -02:00
78 changed files with 1007 additions and 751 deletions

View File

@@ -1 +1 @@
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ..
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DUSE_WERROR=ON ..

View File

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

View File

@@ -1 +1,2 @@
export CMAKE_OPTS="-DUSE_WERROR=ON"
../build_mingw32 || ../build_mingw32

View File

@@ -1 +1,2 @@
export CMAKE_OPTS="-DUSE_WERROR=ON"
../build_mingw64 || ../build_mingw64

View File

@@ -1 +1 @@
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ..
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. -DUSE_WERROR=OFF

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -27,7 +27,7 @@
#define BB_TRACK_CONTAINER_H
#include "TrackContainer.h"
#include "ComboBox.h"
#include "ComboBoxModel.h"
class EXPORT BBTrackContainer : public TrackContainer

View File

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

View File

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

View File

@@ -29,7 +29,6 @@
#include <QtCore/QPair>
#include "AutomatableModel.h"
#include "templates.h"
class PixmapLoader;

View File

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

View File

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

View File

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

View File

@@ -39,6 +39,7 @@ public:
_activated_color, QWidget * _parent );
virtual ~FadeButton();
void setActiveColor( const QColor & activated_color );
public slots:

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,8 +25,8 @@
#ifndef MODEL_H
#define MODEL_H
#include <QtCore/QString>
#include <QtCore/QObject>
#include <QtCore/QPointer>
#include "export.h"

View File

@@ -25,6 +25,7 @@
#ifndef MODEL_VIEW_H
#define MODEL_VIEW_H
#include <QtCore/QPointer>
#include "Model.h"

View File

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

View File

@@ -36,8 +36,6 @@
#include "SampleBuffer.h"
#include "lmms_constants.h"
class SampleBuffer;
class IntModel;

View File

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

View File

@@ -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();
}

View File

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

View File

@@ -391,8 +391,6 @@ private slots:
void recordingOn();
void recordingOff();
void clearTrack();
void assignFxLine( int channelIndex );
void createFxLine();
private:
static QPixmap * s_grip;

View File

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

View File

@@ -26,7 +26,6 @@
#ifndef FFT_HELPERS_H
#define FFT_HELPERS_H
#include "lmmsconfig.h"
#include "export.h"
#include <fftw3.h>

View File

@@ -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();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -26,7 +26,6 @@
#include "InstrumentTrack.h"
#include "DummyInstrument.h"
#include "NotePlayHandle.h"
#include "embed.h"
#include "Engine.h"

View File

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

View File

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

View File

@@ -26,6 +26,7 @@
#include "MemoryManager.h"
#include <QtGlobal>
#include <QReadWriteLock>
#include <stdint.h>

View File

@@ -22,8 +22,8 @@
*
*/
#include "lmms_math.h"
#include "MixHelpers.h"
#include "lmms_math.h"
#include "ValueBuffer.h"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -116,7 +116,7 @@ Song::Song() :
/* connect( &m_masterPitchModel, SIGNAL( dataChanged() ),
this, SLOT( masterPitchChanged() ) );*/
qRegisterMetaType<Note>( "note" );
qRegisterMetaType<Note>( "Note" );
setType( SongContainer );
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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();
}

View File

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

View File

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

View File

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

View File

@@ -55,6 +55,11 @@ FadeButton::~FadeButton()
{
}
void FadeButton::setActiveColor( const QColor & activated_color )
{
m_activatedColor = activated_color;
}

View File

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

View File

@@ -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() );
}
};

View File

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