Merge branch 'master' into cpp20

This commit is contained in:
Dalton Messmer
2024-11-07 00:19:20 -05:00
24 changed files with 167 additions and 377 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,8 @@
#include "HydrogenImport.h"
#include <QDomDocument>
#include "LocalFileMng.h"
#include "HydrogenImport.h"
#include "Song.h"
#include "Engine.h"
#include "Instrument.h"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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