Merge branch 'master' into cpp20
This commit is contained in:
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -72,11 +72,11 @@ jobs:
|
||||
arch: [ x86_64, arm64 ]
|
||||
include:
|
||||
- arch: x86_64
|
||||
os: macos-12
|
||||
xcode: "13.1"
|
||||
os: macos-13
|
||||
xcode: "15.2"
|
||||
- arch: arm64
|
||||
os: macos-14
|
||||
xcode: "14.3.1"
|
||||
xcode: "15.4"
|
||||
name: macos-${{ matrix.arch }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "AudioDevice.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "SampleFrame.h"
|
||||
#include "LocklessList.h"
|
||||
@@ -235,9 +236,20 @@ public:
|
||||
}
|
||||
|
||||
|
||||
sample_rate_t baseSampleRate() const;
|
||||
sample_rate_t outputSampleRate() const;
|
||||
sample_rate_t inputSampleRate() const;
|
||||
sample_rate_t baseSampleRate() const { return m_baseSampleRate; }
|
||||
|
||||
|
||||
sample_rate_t outputSampleRate() const
|
||||
{
|
||||
return m_audioDev != nullptr ? m_audioDev->sampleRate() : m_baseSampleRate;
|
||||
}
|
||||
|
||||
|
||||
sample_rate_t inputSampleRate() const
|
||||
{
|
||||
return m_audioDev != nullptr ? m_audioDev->sampleRate() : m_baseSampleRate;
|
||||
}
|
||||
|
||||
|
||||
inline float masterGain() const
|
||||
{
|
||||
@@ -361,6 +373,7 @@ private:
|
||||
SampleFrame* m_inputBuffer[2];
|
||||
f_cnt_t m_inputBufferFrames[2];
|
||||
f_cnt_t m_inputBufferSize[2];
|
||||
sample_rate_t m_baseSampleRate;
|
||||
int m_inputBufferRead;
|
||||
int m_inputBufferWrite;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MixerChannelView.h - the mixer channel view
|
||||
* MixerChannelView.h
|
||||
*
|
||||
* Copyright (c) 2022 saker <sakertooth@gmail.com>
|
||||
* Copyright (c) 2024 saker
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
@@ -22,8 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MIXER_CHANNEL_VIEW_H
|
||||
#define MIXER_CHANNEL_VIEW_H
|
||||
#ifndef LMMS_GUI_MIXER_CHANNEL_VIEW_H
|
||||
#define LMMS_GUI_MIXER_CHANNEL_VIEW_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include <QLabel>
|
||||
@@ -46,8 +46,6 @@ class MixerChannel;
|
||||
namespace lmms::gui {
|
||||
class PeakIndicator;
|
||||
|
||||
constexpr int MIXER_CHANNEL_INNER_BORDER_SIZE = 3;
|
||||
constexpr int MIXER_CHANNEL_OUTER_BORDER_SIZE = 1;
|
||||
|
||||
class MixerChannelView : public QWidget
|
||||
{
|
||||
@@ -65,25 +63,24 @@ public:
|
||||
void mouseDoubleClickEvent(QMouseEvent*) override;
|
||||
bool eventFilter(QObject* dist, QEvent* event) override;
|
||||
|
||||
int channelIndex() const;
|
||||
void reset();
|
||||
int channelIndex() const { return m_channelIndex; }
|
||||
void setChannelIndex(int index);
|
||||
|
||||
QBrush backgroundActive() const;
|
||||
void setBackgroundActive(const QBrush& c);
|
||||
QBrush backgroundActive() const { return m_backgroundActive; }
|
||||
void setBackgroundActive(const QBrush& c) { m_backgroundActive = c; }
|
||||
|
||||
QColor strokeOuterActive() const;
|
||||
void setStrokeOuterActive(const QColor& c);
|
||||
QColor strokeOuterActive() const { return m_strokeOuterActive; }
|
||||
void setStrokeOuterActive(const QColor& c) { m_strokeOuterActive = c; }
|
||||
|
||||
QColor strokeOuterInactive() const;
|
||||
void setStrokeOuterInactive(const QColor& c);
|
||||
QColor strokeOuterInactive() const { return m_strokeOuterInactive; }
|
||||
void setStrokeOuterInactive(const QColor& c) { m_strokeOuterInactive = c; }
|
||||
|
||||
QColor strokeInnerActive() const;
|
||||
void setStrokeInnerActive(const QColor& c);
|
||||
QColor strokeInnerActive() const { return m_strokeInnerActive; }
|
||||
void setStrokeInnerActive(const QColor& c) { m_strokeInnerActive = c; }
|
||||
|
||||
QColor strokeInnerInactive() const;
|
||||
void setStrokeInnerInactive(const QColor& c);
|
||||
|
||||
void reset();
|
||||
QColor strokeInnerInactive() const { return m_strokeInnerInactive; }
|
||||
void setStrokeInnerInactive(const QColor& c) { m_strokeInnerInactive = c; }
|
||||
|
||||
public slots:
|
||||
void renameChannel();
|
||||
@@ -135,4 +132,4 @@ private:
|
||||
};
|
||||
} // namespace lmms::gui
|
||||
|
||||
#endif // MIXER_CHANNEL_VIEW_H
|
||||
#endif // LMMS_GUI_MIXER_CHANNEL_VIEW_H
|
||||
|
||||
@@ -78,8 +78,7 @@ private:
|
||||
static int m_loadCount;
|
||||
static bool m_buggedFile;
|
||||
|
||||
float m_attackCoeff;
|
||||
float m_decayCoeff;
|
||||
float m_coeff;
|
||||
bool m_coeffNeedsUpdate;
|
||||
} ;
|
||||
|
||||
|
||||
@@ -398,7 +398,7 @@ public:
|
||||
message & addInt( int _i )
|
||||
{
|
||||
char buf[32];
|
||||
sprintf( buf, "%d", _i );
|
||||
std::snprintf(buf, 32, "%d", _i);
|
||||
data.emplace_back( buf );
|
||||
return *this;
|
||||
}
|
||||
@@ -406,7 +406,7 @@ public:
|
||||
message & addFloat( float _f )
|
||||
{
|
||||
char buf[32];
|
||||
sprintf( buf, "%f", _f );
|
||||
std::snprintf(buf, 32, "%f", _f);
|
||||
data.emplace_back( buf );
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ bool RemotePluginClient::processMessage( const message & _m )
|
||||
default:
|
||||
{
|
||||
char buf[64];
|
||||
sprintf( buf, "undefined message: %d\n", (int) _m.id );
|
||||
std::snprintf(buf, 64, "undefined message: %d\n", _m.id);
|
||||
debugMessage( buf );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#ifndef LMMS_TIME_POS_H
|
||||
#define LMMS_TIME_POS_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include "lmms_export.h"
|
||||
#include "lmms_basics.h"
|
||||
|
||||
@@ -51,8 +53,8 @@ class LMMS_EXPORT TimeSig
|
||||
public:
|
||||
TimeSig( int num, int denom );
|
||||
TimeSig( const MeterModel &model );
|
||||
int numerator() const;
|
||||
int denominator() const;
|
||||
int numerator() const { return m_num; }
|
||||
int denominator() const { return m_denom; }
|
||||
private:
|
||||
int m_num;
|
||||
int m_denom;
|
||||
@@ -69,42 +71,72 @@ public:
|
||||
TimePos( const tick_t ticks = 0 );
|
||||
|
||||
TimePos quantize(float) const;
|
||||
TimePos toAbsoluteBar() const;
|
||||
TimePos toAbsoluteBar() const { return getBar() * s_ticksPerBar; }
|
||||
|
||||
TimePos& operator+=( const TimePos& time );
|
||||
TimePos& operator-=( const TimePos& time );
|
||||
TimePos& operator+=(const TimePos& time)
|
||||
{
|
||||
m_ticks += time.m_ticks;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TimePos& operator-=(const TimePos& time)
|
||||
{
|
||||
m_ticks -= time.m_ticks;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// return the bar, rounded down and 0-based
|
||||
bar_t getBar() const;
|
||||
bar_t getBar() const { return m_ticks / s_ticksPerBar; }
|
||||
|
||||
// return the bar, rounded up and 0-based
|
||||
bar_t nextFullBar() const;
|
||||
bar_t nextFullBar() const { return (m_ticks + (s_ticksPerBar - 1)) / s_ticksPerBar; }
|
||||
|
||||
void setTicks( tick_t ticks );
|
||||
tick_t getTicks() const;
|
||||
void setTicks(tick_t ticks) { m_ticks = ticks; }
|
||||
tick_t getTicks() const { return m_ticks; }
|
||||
|
||||
operator int() const;
|
||||
operator int() const { return m_ticks; }
|
||||
|
||||
tick_t ticksPerBeat(const TimeSig& sig) const { return ticksPerBar(sig) / sig.numerator(); }
|
||||
|
||||
tick_t ticksPerBeat( const TimeSig &sig ) const;
|
||||
// Remainder ticks after bar is removed
|
||||
tick_t getTickWithinBar( const TimeSig &sig ) const;
|
||||
tick_t getTickWithinBar(const TimeSig& sig) const { return m_ticks % ticksPerBar(sig); }
|
||||
|
||||
// Returns the beat position inside the bar, 0-based
|
||||
tick_t getBeatWithinBar( const TimeSig &sig ) const;
|
||||
tick_t getBeatWithinBar(const TimeSig& sig) const { return getTickWithinBar(sig) / ticksPerBeat(sig); }
|
||||
|
||||
// Remainder ticks after bar and beat are removed
|
||||
tick_t getTickWithinBeat( const TimeSig &sig ) const;
|
||||
tick_t getTickWithinBeat(const TimeSig& sig) const { return getTickWithinBar(sig) % ticksPerBeat(sig); }
|
||||
|
||||
// calculate number of frame that are needed this time
|
||||
f_cnt_t frames( const float framesPerTick ) const;
|
||||
f_cnt_t frames(const float framesPerTick) const
|
||||
{
|
||||
// Before, step notes used to have negative length. This
|
||||
// assert is a safeguard against negative length being
|
||||
// introduced again (now using Note Types instead #5902)
|
||||
assert(m_ticks >= 0);
|
||||
return static_cast<f_cnt_t>(m_ticks * framesPerTick);
|
||||
}
|
||||
|
||||
double getTimeInMilliseconds( bpm_t beatsPerMinute ) const;
|
||||
double getTimeInMilliseconds(bpm_t beatsPerMinute) const { return ticksToMilliseconds(getTicks(), beatsPerMinute); }
|
||||
|
||||
static TimePos fromFrames( const f_cnt_t frames, const float framesPerTick );
|
||||
static tick_t ticksPerBar();
|
||||
static tick_t ticksPerBar( const TimeSig &sig );
|
||||
static int stepsPerBar();
|
||||
static void setTicksPerBar( tick_t tpt );
|
||||
static TimePos stepPosition( int step );
|
||||
static double ticksToMilliseconds( tick_t ticks, bpm_t beatsPerMinute );
|
||||
static double ticksToMilliseconds( double ticks, bpm_t beatsPerMinute );
|
||||
static TimePos fromFrames(const f_cnt_t frames, const float framesPerTick)
|
||||
{
|
||||
return TimePos(static_cast<int>(frames / framesPerTick));
|
||||
}
|
||||
|
||||
static tick_t ticksPerBar() { return s_ticksPerBar; }
|
||||
static tick_t ticksPerBar(const TimeSig& sig) { return DefaultTicksPerBar * sig.numerator() / sig.denominator(); }
|
||||
|
||||
static int stepsPerBar() { return std::max(1, ticksPerBar() / DefaultBeatsPerBar); }
|
||||
static void setTicksPerBar(tick_t ticks) { s_ticksPerBar = ticks; }
|
||||
static TimePos stepPosition(int step) { return step * ticksPerBar() / stepsPerBar(); }
|
||||
|
||||
static double ticksToMilliseconds(tick_t ticks, bpm_t beatsPerMinute)
|
||||
{
|
||||
return ticksToMilliseconds(static_cast<double>(ticks), beatsPerMinute);
|
||||
}
|
||||
|
||||
static double ticksToMilliseconds(double ticks, bpm_t beatsPerMinute) { return (ticks * 1250) / beatsPerMinute; }
|
||||
|
||||
private:
|
||||
tick_t m_ticks;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
INCLUDE(BuildPlugin)
|
||||
|
||||
BUILD_PLUGIN(hydrogenimport HydrogenImport.cpp HydrogenImport.h local_file_mgr.cpp LocalFileMng.h)
|
||||
BUILD_PLUGIN(hydrogenimport HydrogenImport.cpp HydrogenImport.h LocalFileMng.cpp LocalFileMng.h)
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "HydrogenImport.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
|
||||
#include "LocalFileMng.h"
|
||||
#include "HydrogenImport.h"
|
||||
#include "Song.h"
|
||||
#include "Engine.h"
|
||||
#include "Instrument.h"
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
#include <sys/stat.h>
|
||||
#include "LocalFileMng.h"
|
||||
|
||||
#include <cctype>
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QFile>
|
||||
#include <QLocale>
|
||||
#include <QTextCodec>
|
||||
|
||||
#include "LocalFileMng.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
@@ -197,10 +196,7 @@ QDomDocument LocalFileMng::openXmlDocument( const QString& filename )
|
||||
return QDomDocument();
|
||||
|
||||
if( TinyXMLCompat ) {
|
||||
QString enc = QTextCodec::codecForLocale()->name();
|
||||
if( enc == QString("System") ) {
|
||||
enc = "UTF-8";
|
||||
}
|
||||
const QString enc = "UTF-8"; // unknown encoding, so assume utf-8 and call it a day
|
||||
QByteArray line;
|
||||
QByteArray buf = QString("<?xml version='1.0' encoding='%1' ?>\n")
|
||||
.arg( enc )
|
||||
@@ -14,12 +14,6 @@ namespace lmms
|
||||
class LocalFileMng
|
||||
{
|
||||
public:
|
||||
LocalFileMng();
|
||||
~LocalFileMng();
|
||||
std::vector<QString> getallPatternList(){
|
||||
return m_allPatternList;
|
||||
}
|
||||
|
||||
static QString readXmlString( QDomNode , const QString& nodeName, const QString& defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false);
|
||||
static float readXmlFloat( QDomNode , const QString& nodeName, float defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false);
|
||||
static int readXmlInt( QDomNode , const QString& nodeName, int defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false);
|
||||
@@ -27,7 +21,6 @@ public:
|
||||
static void convertFromTinyXMLString( QByteArray* str );
|
||||
static bool checkTinyXMLCompatMode( const QString& filename );
|
||||
static QDomDocument openXmlDocument( const QString& filename );
|
||||
std::vector<QString> m_allPatternList;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -132,8 +132,18 @@ Effect::ProcessStatus PeakControllerEffect::processImpl(SampleFrame* buf, const
|
||||
float curRMS = sqrt_neg(sum / frames);
|
||||
const float tres = c.m_tresholdModel.value();
|
||||
const float amount = c.m_amountModel.value() * c.m_amountMultModel.value();
|
||||
const float attack = 1.0f - c.m_attackModel.value();
|
||||
const float decay = 1.0f - c.m_decayModel.value();
|
||||
|
||||
curRMS = qAbs( curRMS ) < tres ? 0.0f : curRMS;
|
||||
m_lastSample = qBound( 0.0f, c.m_baseModel.value() + amount * curRMS, 1.0f );
|
||||
float target = c.m_baseModel.value() + amount * curRMS;
|
||||
// Use decay when the volume is decreasing, attack otherwise.
|
||||
// Since direction can change as often as every sampleBuffer, it's difficult
|
||||
// to witness attack/decay working in isolation unless using large buffer sizes.
|
||||
const float t = target < m_lastSample ? decay : attack;
|
||||
// Set m_lastSample to the interpolation between itself and target.
|
||||
// When t is 1.0, m_lastSample snaps to target. When t is 0.0, m_lastSample shouldn't change.
|
||||
m_lastSample = std::clamp(m_lastSample + t * (target - m_lastSample), 0.0f, 1.0f);
|
||||
|
||||
return ProcessStatus::Continue;
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ void VestigeInstrument::loadSettings( const QDomElement & _this )
|
||||
QStringList s_dumpValues;
|
||||
for( int i = 0; i < paramCount; i++ )
|
||||
{
|
||||
sprintf(paramStr.data(), "param%d", i);
|
||||
std::snprintf(paramStr.data(), paramStr.size(), "param%d", i);
|
||||
s_dumpValues = dump[paramStr.data()].split(":");
|
||||
|
||||
knobFModel[i] = new FloatModel( 0.0f, 0.0f, 1.0f, 0.01f, this, QString::number(i) );
|
||||
@@ -290,7 +290,7 @@ void VestigeInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
for( int i = 0; i < paramCount; i++ )
|
||||
{
|
||||
if (knobFModel[i]->isAutomated() || knobFModel[i]->controllerConnection()) {
|
||||
sprintf(paramStr.data(), "param%d", i);
|
||||
std::snprintf(paramStr.data(), paramStr.size(), "param%d", i);
|
||||
knobFModel[i]->saveSettings(_doc, _this, paramStr.data());
|
||||
}
|
||||
|
||||
@@ -987,7 +987,7 @@ ManageVestigeInstrumentView::ManageVestigeInstrumentView( Instrument * _instrume
|
||||
|
||||
for( int i = 0; i < m_vi->paramCount; i++ )
|
||||
{
|
||||
sprintf(paramStr.data(), "param%d", i);
|
||||
std::snprintf(paramStr.data(), paramStr.size(), "param%d", i);
|
||||
s_dumpValues = dump[paramStr.data()].split(":");
|
||||
|
||||
vstKnobs[ i ] = new CustomTextKnob( KnobType::Bright26, this, s_dumpValues.at( 1 ) );
|
||||
@@ -996,7 +996,7 @@ ManageVestigeInstrumentView::ManageVestigeInstrumentView( Instrument * _instrume
|
||||
|
||||
if( !hasKnobModel )
|
||||
{
|
||||
sprintf(paramStr.data(), "%d", i);
|
||||
std::snprintf(paramStr.data(), paramStr.size(), "%d", i);
|
||||
m_vi->knobFModel[i] = new FloatModel(LocaleHelper::toFloat(s_dumpValues.at(2)),
|
||||
0.0f, 1.0f, 0.01f, castModel<VestigeInstrument>(), paramStr.data());
|
||||
}
|
||||
@@ -1059,8 +1059,8 @@ void ManageVestigeInstrumentView::syncPlugin( void )
|
||||
// those auto-setted values are not jurnaled, tracked for undo / redo
|
||||
if( !( m_vi->knobFModel[ i ]->isAutomated() || m_vi->knobFModel[ i ]->controllerConnection() ) )
|
||||
{
|
||||
sprintf(paramStr.data(), "param%d", i);
|
||||
s_dumpValues = dump[paramStr.data()].split(":");
|
||||
std::snprintf(paramStr.data(), paramStr.size(), "param%d", i);
|
||||
s_dumpValues = dump[paramStr.data()].split(":");
|
||||
float f_value = LocaleHelper::toFloat(s_dumpValues.at(2));
|
||||
m_vi->knobFModel[ i ]->setAutomatedValue( f_value );
|
||||
m_vi->knobFModel[ i ]->setInitValue( f_value );
|
||||
|
||||
@@ -87,7 +87,7 @@ void VstEffectControls::loadSettings( const QDomElement & _this )
|
||||
QStringList s_dumpValues;
|
||||
for( int i = 0; i < paramCount; i++ )
|
||||
{
|
||||
sprintf(paramStr.data(), "param%d", i);
|
||||
std::snprintf(paramStr.data(), paramStr.size(), "param%d", i);
|
||||
s_dumpValues = dump[paramStr.data()].split(":");
|
||||
|
||||
knobFModel[i] = new FloatModel( 0.0f, 0.0f, 1.0f, 0.01f, this, QString::number(i) );
|
||||
@@ -137,7 +137,7 @@ void VstEffectControls::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
for( int i = 0; i < paramCount; i++ )
|
||||
{
|
||||
if (knobFModel[i]->isAutomated() || knobFModel[i]->controllerConnection()) {
|
||||
sprintf(paramStr.data(), "param%d", i);
|
||||
std::snprintf(paramStr.data(), paramStr.size(), "param%d", i);
|
||||
knobFModel[i]->saveSettings(_doc, _this, paramStr.data());
|
||||
}
|
||||
}
|
||||
@@ -386,7 +386,7 @@ ManageVSTEffectView::ManageVSTEffectView( VstEffect * _eff, VstEffectControls *
|
||||
|
||||
for( int i = 0; i < m_vi->paramCount; i++ )
|
||||
{
|
||||
sprintf(paramStr.data(), "param%d", i);
|
||||
std::snprintf(paramStr.data(), paramStr.size(), "param%d", i);
|
||||
s_dumpValues = dump[paramStr.data()].split(":");
|
||||
|
||||
vstKnobs[ i ] = new CustomTextKnob( KnobType::Bright26, widget, s_dumpValues.at( 1 ) );
|
||||
@@ -395,7 +395,7 @@ ManageVSTEffectView::ManageVSTEffectView( VstEffect * _eff, VstEffectControls *
|
||||
|
||||
if( !hasKnobModel )
|
||||
{
|
||||
sprintf(paramStr.data(), "%d", i);
|
||||
std::snprintf(paramStr.data(), paramStr.size(), "%d", i);
|
||||
m_vi->knobFModel[i] = new FloatModel(LocaleHelper::toFloat(s_dumpValues.at(2)),
|
||||
0.0f, 1.0f, 0.01f, _eff, paramStr.data());
|
||||
}
|
||||
@@ -460,7 +460,7 @@ void ManageVSTEffectView::syncPlugin()
|
||||
if( !( m_vi2->knobFModel[ i ]->isAutomated() ||
|
||||
m_vi2->knobFModel[ i ]->controllerConnection() ) )
|
||||
{
|
||||
sprintf(paramStr.data(), "param%d", i);
|
||||
std::snprintf(paramStr.data(), paramStr.size(), "param%d", i);
|
||||
s_dumpValues = dump[paramStr.data()].split(":");
|
||||
float f_value = LocaleHelper::toFloat(s_dumpValues.at(2));
|
||||
m_vi2->knobFModel[ i ]->setAutomatedValue( f_value );
|
||||
|
||||
@@ -74,6 +74,7 @@ static thread_local bool s_renderingThread = false;
|
||||
AudioEngine::AudioEngine( bool renderOnly ) :
|
||||
m_renderOnly( renderOnly ),
|
||||
m_framesPerPeriod( DEFAULT_BUFFER_SIZE ),
|
||||
m_baseSampleRate(std::max(ConfigManager::inst()->value("audioengine", "samplerate").toInt(), 44100)),
|
||||
m_inputBufferRead( 0 ),
|
||||
m_inputBufferWrite( 1 ),
|
||||
m_outputBufferRead(nullptr),
|
||||
@@ -241,34 +242,6 @@ void AudioEngine::stopProcessing()
|
||||
|
||||
|
||||
|
||||
sample_rate_t AudioEngine::baseSampleRate() const
|
||||
{
|
||||
sample_rate_t sr = ConfigManager::inst()->value( "audioengine", "samplerate" ).toInt();
|
||||
if( sr < 44100 )
|
||||
{
|
||||
sr = 44100;
|
||||
}
|
||||
return sr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
sample_rate_t AudioEngine::outputSampleRate() const
|
||||
{
|
||||
return m_audioDev != nullptr ? m_audioDev->sampleRate() :
|
||||
baseSampleRate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
sample_rate_t AudioEngine::inputSampleRate() const
|
||||
{
|
||||
return m_audioDev != nullptr ? m_audioDev->sampleRate() :
|
||||
baseSampleRate();
|
||||
}
|
||||
|
||||
bool AudioEngine::criticalXRuns() const
|
||||
{
|
||||
return cpuLoad() >= 99 && Engine::getSong()->isExporting() == false;
|
||||
|
||||
@@ -29,20 +29,17 @@
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::move;
|
||||
|
||||
void ComboBoxModel::addItem( QString item, unique_ptr<PixmapLoader> loader )
|
||||
void ComboBoxModel::addItem(QString item, std::unique_ptr<PixmapLoader> loader)
|
||||
{
|
||||
m_items.emplace_back( move(item), move(loader) );
|
||||
m_items.emplace_back(std::move(item), std::move(loader));
|
||||
setRange( 0, m_items.size() - 1 );
|
||||
}
|
||||
|
||||
|
||||
void ComboBoxModel::replaceItem(std::size_t index, QString item, unique_ptr<PixmapLoader> loader)
|
||||
void ComboBoxModel::replaceItem(std::size_t index, QString item, std::unique_ptr<PixmapLoader> loader)
|
||||
{
|
||||
assert(index < m_items.size());
|
||||
m_items[index] = Item(move(item), move(loader));
|
||||
m_items[index] = Item(std::move(item), std::move(loader));
|
||||
emit propertiesChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ void Keymap::loadSettings(const QDomElement &element)
|
||||
QDomNode node = element.firstChild();
|
||||
m_map.clear();
|
||||
|
||||
for (int i = 0; !node.isNull(); i++)
|
||||
while (!node.isNull())
|
||||
{
|
||||
m_map.push_back(node.toElement().attribute("value").toInt());
|
||||
node = node.nextSibling();
|
||||
|
||||
@@ -80,9 +80,7 @@ void PeakController::updateValueBuffer()
|
||||
{
|
||||
if( m_coeffNeedsUpdate )
|
||||
{
|
||||
const float ratio = 44100.0f / Engine::audioEngine()->outputSampleRate();
|
||||
m_attackCoeff = 1.0f - powf( 2.0f, -0.3f * ( 1.0f - m_peakEffect->attackModel()->value() ) * ratio );
|
||||
m_decayCoeff = 1.0f - powf( 2.0f, -0.3f * ( 1.0f - m_peakEffect->decayModel()->value() ) * ratio );
|
||||
m_coeff = 100.0f / Engine::audioEngine()->outputSampleRate();
|
||||
m_coeffNeedsUpdate = false;
|
||||
}
|
||||
|
||||
@@ -97,14 +95,7 @@ void PeakController::updateValueBuffer()
|
||||
for( f_cnt_t f = 0; f < frames; ++f )
|
||||
{
|
||||
const float diff = ( targetSample - m_currentSample );
|
||||
if( m_currentSample < targetSample ) // going up...
|
||||
{
|
||||
m_currentSample += diff * m_attackCoeff;
|
||||
}
|
||||
else if( m_currentSample > targetSample ) // going down
|
||||
{
|
||||
m_currentSample += diff * m_decayCoeff;
|
||||
}
|
||||
m_currentSample += diff * m_coeff;
|
||||
values[f] = m_currentSample;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ void ProjectRenderer::abortProcessing()
|
||||
|
||||
void ProjectRenderer::updateConsoleProgress()
|
||||
{
|
||||
const int cols = 50;
|
||||
constexpr int cols = 50;
|
||||
static int rot = 0;
|
||||
auto buf = std::array<char, 80>{};
|
||||
auto prog = std::array<char, cols + 1>{};
|
||||
@@ -221,9 +221,9 @@ void ProjectRenderer::updateConsoleProgress()
|
||||
}
|
||||
prog[cols] = 0;
|
||||
|
||||
const auto activity = (const char*)"|/-\\";
|
||||
const auto activity = "|/-\\";
|
||||
std::fill(buf.begin(), buf.end(), 0);
|
||||
sprintf(buf.data(), "\r|%s| %3d%% %c ", prog.data(), m_progress,
|
||||
std::snprintf(buf.data(), buf.size(), "\r|%s| %3d%% %c ", prog.data(), m_progress,
|
||||
activity[rot] );
|
||||
rot = ( rot+1 ) % 4;
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ void Scale::loadSettings(const QDomElement &element)
|
||||
QDomNode node = element.firstChild();
|
||||
m_intervals.clear();
|
||||
|
||||
for (int i = 0; !node.isNull(); i++)
|
||||
while (!node.isNull())
|
||||
{
|
||||
Interval temp;
|
||||
temp.restoreState(node.toElement());
|
||||
|
||||
@@ -43,20 +43,6 @@ TimeSig::TimeSig( const MeterModel &model ) :
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int TimeSig::numerator() const
|
||||
{
|
||||
return m_num;
|
||||
}
|
||||
|
||||
int TimeSig::denominator() const
|
||||
{
|
||||
return m_denom;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
TimePos::TimePos( const bar_t bar, const tick_t ticks ) :
|
||||
m_ticks( bar * s_ticksPerBar + ticks )
|
||||
{
|
||||
@@ -86,140 +72,4 @@ TimePos TimePos::quantize(float bars) const
|
||||
return (lowPos + snapUp) * interval;
|
||||
}
|
||||
|
||||
|
||||
TimePos TimePos::toAbsoluteBar() const
|
||||
{
|
||||
return getBar() * s_ticksPerBar;
|
||||
}
|
||||
|
||||
|
||||
TimePos& TimePos::operator+=( const TimePos& time )
|
||||
{
|
||||
m_ticks += time.m_ticks;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
TimePos& TimePos::operator-=( const TimePos& time )
|
||||
{
|
||||
m_ticks -= time.m_ticks;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bar_t TimePos::getBar() const
|
||||
{
|
||||
return m_ticks / s_ticksPerBar;
|
||||
}
|
||||
|
||||
|
||||
bar_t TimePos::nextFullBar() const
|
||||
{
|
||||
return ( m_ticks + ( s_ticksPerBar - 1 ) ) / s_ticksPerBar;
|
||||
}
|
||||
|
||||
|
||||
void TimePos::setTicks( tick_t ticks )
|
||||
{
|
||||
m_ticks = ticks;
|
||||
}
|
||||
|
||||
|
||||
tick_t TimePos::getTicks() const
|
||||
{
|
||||
return m_ticks;
|
||||
}
|
||||
|
||||
|
||||
TimePos::operator int() const
|
||||
{
|
||||
return m_ticks;
|
||||
}
|
||||
|
||||
|
||||
tick_t TimePos::ticksPerBeat( const TimeSig &sig ) const
|
||||
{
|
||||
// (number of ticks per bar) divided by (number of beats per bar)
|
||||
return ticksPerBar(sig) / sig.numerator();
|
||||
}
|
||||
|
||||
|
||||
tick_t TimePos::getTickWithinBar( const TimeSig &sig ) const
|
||||
{
|
||||
return m_ticks % ticksPerBar( sig );
|
||||
}
|
||||
|
||||
tick_t TimePos::getBeatWithinBar( const TimeSig &sig ) const
|
||||
{
|
||||
return getTickWithinBar( sig ) / ticksPerBeat( sig );
|
||||
}
|
||||
|
||||
tick_t TimePos::getTickWithinBeat( const TimeSig &sig ) const
|
||||
{
|
||||
return getTickWithinBar( sig ) % ticksPerBeat( sig );
|
||||
}
|
||||
|
||||
|
||||
f_cnt_t TimePos::frames( const float framesPerTick ) const
|
||||
{
|
||||
// Before, step notes used to have negative length. This
|
||||
// assert is a safeguard against negative length being
|
||||
// introduced again (now using Note Types instead #5902)
|
||||
assert(m_ticks >= 0);
|
||||
return static_cast<f_cnt_t>(m_ticks * framesPerTick);
|
||||
}
|
||||
|
||||
double TimePos::getTimeInMilliseconds( bpm_t beatsPerMinute ) const
|
||||
{
|
||||
return ticksToMilliseconds( getTicks(), beatsPerMinute );
|
||||
}
|
||||
|
||||
TimePos TimePos::fromFrames( const f_cnt_t frames, const float framesPerTick )
|
||||
{
|
||||
return TimePos( static_cast<int>( frames / framesPerTick ) );
|
||||
}
|
||||
|
||||
|
||||
tick_t TimePos::ticksPerBar()
|
||||
{
|
||||
return s_ticksPerBar;
|
||||
}
|
||||
|
||||
|
||||
tick_t TimePos::ticksPerBar( const TimeSig &sig )
|
||||
{
|
||||
return DefaultTicksPerBar * sig.numerator() / sig.denominator();
|
||||
}
|
||||
|
||||
|
||||
int TimePos::stepsPerBar()
|
||||
{
|
||||
int steps = ticksPerBar() / DefaultBeatsPerBar;
|
||||
return std::max(1, steps);
|
||||
}
|
||||
|
||||
|
||||
void TimePos::setTicksPerBar( tick_t tpb )
|
||||
{
|
||||
s_ticksPerBar = tpb;
|
||||
}
|
||||
|
||||
|
||||
TimePos TimePos::stepPosition( int step )
|
||||
{
|
||||
return step * ticksPerBar() / stepsPerBar();
|
||||
}
|
||||
|
||||
double TimePos::ticksToMilliseconds( tick_t ticks, bpm_t beatsPerMinute )
|
||||
{
|
||||
return TimePos::ticksToMilliseconds( static_cast<double>(ticks), beatsPerMinute );
|
||||
}
|
||||
|
||||
double TimePos::ticksToMilliseconds(double ticks, bpm_t beatsPerMinute)
|
||||
{
|
||||
// 60 * 1000 / 48 = 1250
|
||||
return ( ticks * 1250 ) / beatsPerMinute;
|
||||
}
|
||||
|
||||
|
||||
} // namespace lmms
|
||||
|
||||
@@ -159,7 +159,7 @@ void MidiApple::removePort( MidiPort* port )
|
||||
|
||||
QString MidiApple::sourcePortName( const MidiEvent& event ) const
|
||||
{
|
||||
qDebug("sourcePortName return '%s'?\n", event.sourcePort());
|
||||
qDebug("sourcePortName");
|
||||
/*
|
||||
if( event.sourcePort() )
|
||||
{
|
||||
@@ -501,7 +501,7 @@ void MidiApple::openDevices()
|
||||
void MidiApple::openMidiReference( MIDIEndpointRef reference, QString refName, bool isIn )
|
||||
{
|
||||
char * registeredName = (char*) malloc(refName.length()+1);
|
||||
sprintf(registeredName, "%s",refName.toLatin1().constData());
|
||||
std::snprintf(registeredName, refName.length() + 1, "%s",refName.toLatin1().constData());
|
||||
qDebug("openMidiReference refName '%s'",refName.toLatin1().constData());
|
||||
|
||||
MIDIClientRef mClient = getMidiClientRef();
|
||||
@@ -623,7 +623,7 @@ char * MidiApple::getFullName(MIDIEndpointRef &endpoint_ref)
|
||||
size_t deviceNameLen = deviceName == nullptr ? 0 : strlen(deviceName);
|
||||
size_t endPointNameLen = endPointName == nullptr ? 0 : strlen(endPointName);
|
||||
char * fullName = (char *)malloc(deviceNameLen + endPointNameLen + 2);
|
||||
sprintf(fullName, "%s:%s", deviceName,endPointName);
|
||||
std::snprintf(fullName, deviceNameLen + endPointNameLen + 2, "%s:%s", deviceName,endPointName);
|
||||
if (deviceName != nullptr) { free(deviceName); }
|
||||
if (endPointName != nullptr) { free(endPointName); }
|
||||
return fullName;
|
||||
|
||||
@@ -186,21 +186,18 @@ void MixerChannelView::contextMenuEvent(QContextMenuEvent*)
|
||||
delete contextMenu;
|
||||
}
|
||||
|
||||
void MixerChannelView::paintEvent(QPaintEvent* event)
|
||||
void MixerChannelView::paintEvent(QPaintEvent*)
|
||||
{
|
||||
static constexpr auto innerBorderSize = 3;
|
||||
static constexpr auto outerBorderSize = 1;
|
||||
|
||||
const auto channel = mixerChannel();
|
||||
const bool muted = channel->m_muteModel.value();
|
||||
const auto name = channel->m_name;
|
||||
const auto elidedName = elideName(name);
|
||||
const auto isActive = m_mixerView->currentMixerChannel() == this;
|
||||
|
||||
if (!m_inRename && m_renameLineEdit->text() != elidedName) { m_renameLineEdit->setText(elidedName); }
|
||||
|
||||
const auto width = rect().width();
|
||||
const auto height = rect().height();
|
||||
auto painter = QPainter{this};
|
||||
|
||||
if (channel->color().has_value() && !muted)
|
||||
if (channel->color().has_value() && !channel->m_muteModel.value())
|
||||
{
|
||||
painter.fillRect(rect(), channel->color()->darker(isActive ? 120 : 150));
|
||||
}
|
||||
@@ -208,13 +205,11 @@ void MixerChannelView::paintEvent(QPaintEvent* event)
|
||||
|
||||
// inner border
|
||||
painter.setPen(isActive ? strokeInnerActive() : strokeInnerInactive());
|
||||
painter.drawRect(1, 1, width - MIXER_CHANNEL_INNER_BORDER_SIZE, height - MIXER_CHANNEL_INNER_BORDER_SIZE);
|
||||
painter.drawRect(1, 1, width - innerBorderSize, height - innerBorderSize);
|
||||
|
||||
// outer border
|
||||
painter.setPen(isActive ? strokeOuterActive() : strokeOuterInactive());
|
||||
painter.drawRect(0, 0, width - MIXER_CHANNEL_OUTER_BORDER_SIZE, height - MIXER_CHANNEL_OUTER_BORDER_SIZE);
|
||||
|
||||
QWidget::paintEvent(event);
|
||||
painter.drawRect(0, 0, width - outerBorderSize, height - outerBorderSize);
|
||||
}
|
||||
|
||||
void MixerChannelView::mousePressEvent(QMouseEvent*)
|
||||
@@ -227,7 +222,7 @@ void MixerChannelView::mouseDoubleClickEvent(QMouseEvent*)
|
||||
renameChannel();
|
||||
}
|
||||
|
||||
bool MixerChannelView::eventFilter(QObject* dist, QEvent* event)
|
||||
bool MixerChannelView::eventFilter(QObject*, QEvent* event)
|
||||
{
|
||||
// If we are in a rename, capture the enter/return events and handle them
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
@@ -246,11 +241,6 @@ bool MixerChannelView::eventFilter(QObject* dist, QEvent* event)
|
||||
return false;
|
||||
}
|
||||
|
||||
int MixerChannelView::channelIndex() const
|
||||
{
|
||||
return m_channelIndex;
|
||||
}
|
||||
|
||||
void MixerChannelView::setChannelIndex(int index)
|
||||
{
|
||||
MixerChannel* mixerChannel = Engine::mixer()->mixerChannel(index);
|
||||
@@ -259,64 +249,10 @@ void MixerChannelView::setChannelIndex(int index)
|
||||
m_soloButton->setModel(&mixerChannel->m_soloModel);
|
||||
m_effectRackView->setModel(&mixerChannel->m_fxChain);
|
||||
m_channelNumberLcd->setValue(index);
|
||||
m_renameLineEdit->setText(elideName(mixerChannel->m_name));
|
||||
m_channelIndex = index;
|
||||
}
|
||||
|
||||
QBrush MixerChannelView::backgroundActive() const
|
||||
{
|
||||
return m_backgroundActive;
|
||||
}
|
||||
|
||||
void MixerChannelView::setBackgroundActive(const QBrush& c)
|
||||
{
|
||||
m_backgroundActive = c;
|
||||
}
|
||||
|
||||
QColor MixerChannelView::strokeOuterActive() const
|
||||
{
|
||||
return m_strokeOuterActive;
|
||||
}
|
||||
|
||||
void MixerChannelView::setStrokeOuterActive(const QColor& c)
|
||||
{
|
||||
m_strokeOuterActive = c;
|
||||
}
|
||||
|
||||
QColor MixerChannelView::strokeOuterInactive() const
|
||||
{
|
||||
return m_strokeOuterInactive;
|
||||
}
|
||||
|
||||
void MixerChannelView::setStrokeOuterInactive(const QColor& c)
|
||||
{
|
||||
m_strokeOuterInactive = c;
|
||||
}
|
||||
|
||||
QColor MixerChannelView::strokeInnerActive() const
|
||||
{
|
||||
return m_strokeInnerActive;
|
||||
}
|
||||
|
||||
void MixerChannelView::setStrokeInnerActive(const QColor& c)
|
||||
{
|
||||
m_strokeInnerActive = c;
|
||||
}
|
||||
|
||||
QColor MixerChannelView::strokeInnerInactive() const
|
||||
{
|
||||
return m_strokeInnerInactive;
|
||||
}
|
||||
|
||||
void MixerChannelView::setStrokeInnerInactive(const QColor& c)
|
||||
{
|
||||
m_strokeInnerInactive = c;
|
||||
}
|
||||
|
||||
void MixerChannelView::reset()
|
||||
{
|
||||
m_peakIndicator->resetPeakToMinusInf();
|
||||
}
|
||||
|
||||
void MixerChannelView::renameChannel()
|
||||
{
|
||||
m_inRename = true;
|
||||
@@ -459,4 +395,9 @@ MixerChannel* MixerChannelView::mixerChannel() const
|
||||
return Engine::mixer()->mixerChannel(m_channelIndex);
|
||||
}
|
||||
|
||||
void MixerChannelView::reset()
|
||||
{
|
||||
m_peakIndicator->resetPeakToMinusInf();
|
||||
}
|
||||
|
||||
} // namespace lmms::gui
|
||||
|
||||
@@ -282,20 +282,17 @@ void Fader::paintEvent(QPaintEvent* ev)
|
||||
|
||||
void Fader::paintLevels(QPaintEvent* ev, QPainter& painter, bool linear)
|
||||
{
|
||||
std::function<float(float value)> mapper = [this](float value) { return ampToDbfs(qMax(0.0001f, value)); };
|
||||
const auto mapper = linear
|
||||
? +[](float value) -> float { return value; }
|
||||
: +[](float value) -> float { return ampToDbfs(qMax(0.0001f, value)); };
|
||||
|
||||
if (linear)
|
||||
{
|
||||
mapper = [this](float value) { return value; };
|
||||
}
|
||||
|
||||
const float mappedMinPeak(mapper(m_fMinPeak));
|
||||
const float mappedMaxPeak(mapper(m_fMaxPeak));
|
||||
const float mappedPeakL(mapper(m_fPeakValue_L));
|
||||
const float mappedPeakR(mapper(m_fPeakValue_R));
|
||||
const float mappedPersistentPeakL(mapper(m_persistentPeak_L));
|
||||
const float mappedPersistentPeakR(mapper(m_persistentPeak_R));
|
||||
const float mappedUnity(mapper(1.f));
|
||||
const float mappedMinPeak = mapper(m_fMinPeak);
|
||||
const float mappedMaxPeak = mapper(m_fMaxPeak);
|
||||
const float mappedPeakL = mapper(m_fPeakValue_L);
|
||||
const float mappedPeakR = mapper(m_fPeakValue_R);
|
||||
const float mappedPersistentPeakL = mapper(m_persistentPeak_L);
|
||||
const float mappedPersistentPeakR = mapper(m_persistentPeak_R);
|
||||
const float mappedUnity = mapper(1.f);
|
||||
|
||||
painter.save();
|
||||
|
||||
@@ -375,10 +372,10 @@ void Fader::paintLevels(QPaintEvent* ev, QPainter& painter, bool linear)
|
||||
// Please ensure that "clip starts" is the maximum value and that "ok ends"
|
||||
// is the minimum value and that all other values lie inbetween. Otherwise
|
||||
// there will be warnings when the gradient is defined.
|
||||
const float mappedClipStarts(mapper(dbfsToAmp(0.f)));
|
||||
const float mappedWarnEnd(mapper(dbfsToAmp(-0.01f)));
|
||||
const float mappedWarnStart(mapper(dbfsToAmp(-6.f)));
|
||||
const float mappedOkEnd(mapper(dbfsToAmp(-12.f)));
|
||||
const float mappedClipStarts = mapper(dbfsToAmp(0.f));
|
||||
const float mappedWarnEnd = mapper(dbfsToAmp(-0.01f));
|
||||
const float mappedWarnStart = mapper(dbfsToAmp(-6.f));
|
||||
const float mappedOkEnd = mapper(dbfsToAmp(-12.f));
|
||||
|
||||
// Prepare the gradient for the meters
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user