Merge remote-tracking branch 'upstream/master' into 2510-SetupDialogWithLayouts-MasterMerge

Merge master to integrate the changes of:
* f10277715f: Classier enums
* 7aca8ae726: SetupDialog: Warn of unusual buffersizes
* 8fb9c3e6a2: Fix warnings in Clang build (#6893)

Solved conflicts in:
* src/gui/modals/SetupDialog.cpp
This commit is contained in:
Michael Gregorius
2023-10-01 09:40:42 +02:00
434 changed files with 8335 additions and 5370 deletions

388
include/ArrayVector.h Normal file
View File

@@ -0,0 +1,388 @@
/*
* ArrayVector.h
*
* Copyright (c) 2023 Dominic Clark
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef LMMS_ARRAY_VECTOR_H
#define LMMS_ARRAY_VECTOR_H
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iterator>
#include <memory>
#include <new>
#include <stdexcept>
#include <utility>
#include <type_traits>
namespace lmms {
namespace detail {
template<typename T, typename = void>
constexpr bool is_input_iterator_v = false;
template<typename T>
constexpr bool is_input_iterator_v<T, std::void_t<typename std::iterator_traits<T>::iterator_category>> =
std::is_convertible_v<typename std::iterator_traits<T>::iterator_category, std::input_iterator_tag>;
} // namespace detail
/**
* A container that stores up to a maximum of `N` elements of type `T` directly
* within itself, rather than separately on the heap. Useful when a dynamically
* resizeable container is needed for use in real-time code. Can be thought of
* as a hybrid between `std::array` and `std::vector`. The interface follows
* that of `std::vector` - see standard C++ documentation.
*/
template<typename T, std::size_t N>
class ArrayVector
{
public:
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using value_type = T;
using reference = T&;
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
using iterator = pointer;
using const_iterator = const_pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
ArrayVector() = default;
ArrayVector(const ArrayVector& other) noexcept(std::is_nothrow_copy_constructible_v<T>) :
m_size{other.m_size}
{
std::uninitialized_copy(other.begin(), other.end(), begin());
}
ArrayVector(ArrayVector&& other) noexcept(std::is_nothrow_move_constructible_v<T>) :
m_size{other.m_size}
{
std::uninitialized_move(other.begin(), other.end(), begin());
other.clear();
}
ArrayVector(size_type count, const T& value) noexcept(std::is_nothrow_copy_constructible_v<T>) :
m_size{count}
{
assert(count <= N);
std::uninitialized_fill_n(begin(), count, value);
}
explicit ArrayVector(size_type count) noexcept(std::is_nothrow_default_constructible_v<T>) :
m_size{count}
{
assert(count <= N);
std::uninitialized_value_construct_n(begin(), count);
}
template<typename It, std::enable_if_t<detail::is_input_iterator_v<It>, int> = 0>
ArrayVector(It first, It last)
{
// Can't check the size first as the iterator may not be multipass
const auto end = std::uninitialized_copy(first, last, begin());
m_size = end - begin();
assert(m_size <= N);
}
ArrayVector(std::initializer_list<T> il) noexcept(std::is_nothrow_copy_constructible_v<T>) :
m_size{il.size()}
{
assert(il.size() <= N);
std::uninitialized_copy(il.begin(), il.end(), begin());
}
~ArrayVector() { std::destroy(begin(), end()); }
ArrayVector& operator=(const ArrayVector& other)
noexcept(std::is_nothrow_copy_assignable_v<T> && std::is_nothrow_copy_constructible_v<T>)
{
if (this != &other) {
const auto toAssign = std::min(other.size(), size());
const auto assignedFromEnd = other.begin() + toAssign;
const auto assignedToEnd = std::copy(other.begin(), other.begin() + toAssign, begin());
std::destroy(assignedToEnd, end());
std::uninitialized_copy(assignedFromEnd, other.end(), end());
m_size = other.size();
}
return *this;
}
ArrayVector& operator=(ArrayVector&& other)
noexcept(std::is_nothrow_move_assignable_v<T> && std::is_nothrow_move_constructible_v<T>)
{
if (this != &other) {
const auto toAssign = std::min(other.size(), size());
const auto assignedFromEnd = other.begin() + toAssign;
const auto assignedToEnd = std::move(other.begin(), other.begin() + toAssign, begin());
std::destroy(assignedToEnd, end());
std::uninitialized_move(assignedFromEnd, other.end(), end());
m_size = other.size();
other.clear();
}
return *this;
}
ArrayVector& operator=(std::initializer_list<T> il)
noexcept(std::is_nothrow_copy_assignable_v<T> && std::is_nothrow_copy_constructible_v<T>)
{
assert(il.size() <= N);
const auto toAssign = std::min(il.size(), size());
const auto assignedFromEnd = il.begin() + toAssign;
const auto assignedToEnd = std::copy(il.begin(), assignedFromEnd, begin());
std::destroy(assignedToEnd, end());
std::uninitialized_copy(assignedFromEnd, il.end(), end());
m_size = il.size();
return *this;
}
void assign(size_type count, const T& value)
noexcept(std::is_nothrow_copy_assignable_v<T> && std::is_nothrow_copy_constructible_v<T>)
{
assert(count <= N);
const auto temp = value;
const auto toAssign = std::min(count, size());
const auto toConstruct = count - toAssign;
const auto assignedToEnd = std::fill_n(begin(), toAssign, temp);
std::destroy(assignedToEnd, end());
std::uninitialized_fill_n(assignedToEnd, toConstruct, temp);
m_size = count;
}
template<typename It, std::enable_if_t<detail::is_input_iterator_v<It>, int> = 0>
void assign(It first, It last)
{
// Can't check the size first as the iterator may not be multipass
auto pos = begin();
for (; first != last && pos != end(); ++pos, ++first) {
*pos = *first;
}
std::destroy(pos, end());
pos = std::uninitialized_copy(first, last, pos);
m_size = pos - begin();
assert(m_size <= N);
}
reference at(size_type index)
{
if (index >= m_size) { throw std::out_of_range{"index out of range"}; }
return data()[index];
}
const_reference at(size_type index) const
{
if (index >= m_size) { throw std::out_of_range{"index out of range"}; }
return data()[index];
}
reference operator[](size_type index) noexcept
{
assert(index < m_size);
return data()[index];
}
const_reference operator[](size_type index) const noexcept
{
assert(index < m_size);
return data()[index];
}
reference front() noexcept { return operator[](0); }
const_reference front() const noexcept { return operator[](0); }
reference back() noexcept { return operator[](m_size - 1); }
const_reference back() const noexcept { return operator[](m_size - 1); }
pointer data() noexcept { return *std::launder(reinterpret_cast<T(*)[N]>(m_data)); }
const_pointer data() const noexcept { return *std::launder(reinterpret_cast<const T(*)[N]>(m_data)); }
iterator begin() noexcept { return data(); }
const_iterator begin() const noexcept { return data(); }
const_iterator cbegin() const noexcept { return data(); }
iterator end() noexcept { return data() + m_size; }
const_iterator end() const noexcept { return data() + m_size; }
const_iterator cend() const noexcept { return data() + m_size; }
reverse_iterator rbegin() noexcept { return std::reverse_iterator{end()}; }
const_reverse_iterator rbegin() const noexcept { return std::reverse_iterator{end()}; }
const_reverse_iterator crbegin() const noexcept { return std::reverse_iterator{cend()}; }
reverse_iterator rend() noexcept { return std::reverse_iterator{begin()}; }
const_reverse_iterator rend() const noexcept { return std::reverse_iterator{begin()}; }
const_reverse_iterator crend() const noexcept { return std::reverse_iterator{cbegin()}; }
bool empty() const noexcept { return m_size == 0; }
bool full() const noexcept { return m_size == N; }
size_type size() const noexcept { return m_size; }
size_type max_size() const noexcept { return N; }
size_type capacity() const noexcept { return N; }
void clear() noexcept
{
std::destroy(begin(), end());
m_size = 0;
}
iterator insert(const_iterator pos, const T& value) { return emplace(pos, value); }
iterator insert(const_iterator pos, T&& value) { return emplace(pos, std::move(value)); }
iterator insert(const_iterator pos, size_type count, const T& value)
{
assert(m_size + count <= N);
assert(cbegin() <= pos && pos <= cend());
const auto mutPos = begin() + (pos - cbegin());
const auto newEnd = std::uninitialized_fill_n(end(), count, value);
std::rotate(mutPos, end(), newEnd);
m_size += count;
return mutPos;
}
template<typename It, std::enable_if_t<detail::is_input_iterator_v<It>, int> = 0>
iterator insert(const_iterator pos, It first, It last)
{
// Can't check the size first as the iterator may not be multipass
assert(cbegin() <= pos && pos <= cend());
const auto mutPos = begin() + (pos - cbegin());
const auto newEnd = std::uninitialized_copy(first, last, end());
std::rotate(mutPos, end(), newEnd);
m_size = newEnd - begin();
assert(m_size <= N);
return mutPos;
}
iterator insert(const_iterator pos, std::initializer_list<T> il) { return insert(pos, il.begin(), il.end()); }
template<typename... Args>
iterator emplace(const_iterator pos, Args&&... args)
{
assert(cbegin() <= pos && pos <= cend());
const auto mutPos = begin() + (pos - cbegin());
emplace_back(std::forward<Args>(args)...);
std::rotate(mutPos, end() - 1, end());
return mutPos;
}
iterator erase(const_iterator pos) { return erase(pos, pos + 1); }
iterator erase(const_iterator first, const_iterator last)
{
assert(cbegin() <= first && first <= last && last <= cend());
const auto mutFirst = begin() + (first - cbegin());
const auto mutLast = begin() + (last - cbegin());
const auto newEnd = std::move(mutLast, end(), mutFirst);
std::destroy(newEnd, end());
m_size = newEnd - begin();
return mutFirst;
}
void push_back(const T& value) { emplace_back(value); }
void push_back(T&& value) { emplace_back(std::move(value)); }
template<typename... Args>
reference emplace_back(Args&&... args)
{
assert(!full());
// TODO C++20: Use std::construct_at
const auto result = new(static_cast<void*>(end())) T(std::forward<Args>(args)...);
++m_size;
return *result;
}
void pop_back()
{
assert(!empty());
--m_size;
std::destroy_at(end());
}
void resize(size_type size)
{
if (size > N) { throw std::length_error{"size exceeds maximum size"}; }
if (size < m_size) {
std::destroy(begin() + size, end());
} else {
std::uninitialized_value_construct(end(), begin() + size);
}
m_size = size;
}
void resize(size_type size, const value_type& value)
{
if (size > N) { throw std::length_error{"size exceeds maximum size"}; }
if (size < m_size) {
std::destroy(begin() + size, end());
} else {
std::uninitialized_fill(end(), begin() + size, value);
}
m_size = size;
}
void swap(ArrayVector& other)
noexcept(std::is_nothrow_swappable_v<T> && std::is_nothrow_move_constructible_v<T>)
{
using std::swap;
swap(*this, other);
}
friend void swap(ArrayVector& a, ArrayVector& b)
noexcept(std::is_nothrow_swappable_v<T> && std::is_nothrow_move_constructible_v<T>)
{
const auto toSwap = std::min(a.size(), b.size());
const auto aSwapEnd = a.begin() + toSwap;
const auto bSwapEnd = b.begin() + toSwap;
std::swap_ranges(a.begin(), aSwapEnd, b.begin());
std::uninitialized_move(aSwapEnd, a.end(), bSwapEnd);
std::uninitialized_move(bSwapEnd, b.end(), aSwapEnd);
std::destroy(aSwapEnd, a.end());
std::destroy(bSwapEnd, b.end());
std::swap(a.m_size, b.m_size);
}
// TODO C++20: Replace with operator<=>
friend bool operator<(const ArrayVector& l, const ArrayVector& r)
{
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
}
friend bool operator<=(const ArrayVector& l, const ArrayVector& r) { return !(r < l); }
friend bool operator>(const ArrayVector& l, const ArrayVector& r) { return r < l; }
friend bool operator>=(const ArrayVector& l, const ArrayVector& r) { return !(l < r); }
friend bool operator==(const ArrayVector& l, const ArrayVector& r)
{
return std::equal(l.begin(), l.end(), r.begin(), r.end());
}
// TODO C++20: Remove
friend bool operator!=(const ArrayVector& l, const ArrayVector& r) { return !(l == r); }
private:
alignas(T) std::byte m_data[std::max(N * sizeof(T), std::size_t{1})]; // Intentionally a raw array
size_type m_size = 0;
};
} // namespace lmms
#endif // LMMS_ARRAY_VECTOR_H

View File

@@ -32,10 +32,10 @@
#endif
#include <QThread>
#include <QVector>
#include <QWaitCondition>
#include <samplerate.h>
#include <vector>
#include "lmms_basics.h"
#include "LocklessList.h"
@@ -109,27 +109,27 @@ public:
struct qualitySettings
{
enum Mode
enum class Mode
{
Mode_Draft,
Mode_HighQuality,
Mode_FinalMix
Draft,
HighQuality,
FinalMix
} ;
enum Interpolation
enum class Interpolation
{
Interpolation_Linear,
Interpolation_SincFastest,
Interpolation_SincMedium,
Interpolation_SincBest
Linear,
SincFastest,
SincMedium,
SincBest
} ;
enum Oversampling
enum class Oversampling
{
Oversampling_None,
Oversampling_2x,
Oversampling_4x,
Oversampling_8x
None,
X2,
X4,
X8
} ;
Interpolation interpolation;
@@ -139,18 +139,18 @@ public:
{
switch (m)
{
case Mode_Draft:
interpolation = Interpolation_Linear;
oversampling = Oversampling_None;
case Mode::Draft:
interpolation = Interpolation::Linear;
oversampling = Oversampling::None;
break;
case Mode_HighQuality:
case Mode::HighQuality:
interpolation =
Interpolation_SincFastest;
oversampling = Oversampling_2x;
Interpolation::SincFastest;
oversampling = Oversampling::X2;
break;
case Mode_FinalMix:
interpolation = Interpolation_SincBest;
oversampling = Oversampling_8x;
case Mode::FinalMix:
interpolation = Interpolation::SincBest;
oversampling = Oversampling::X8;
break;
}
}
@@ -165,10 +165,10 @@ public:
{
switch( oversampling )
{
case Oversampling_None: return 1;
case Oversampling_2x: return 2;
case Oversampling_4x: return 4;
case Oversampling_8x: return 8;
case Oversampling::None: return 1;
case Oversampling::X2: return 2;
case Oversampling::X4: return 4;
case Oversampling::X8: return 8;
}
return 1;
}
@@ -177,13 +177,13 @@ public:
{
switch( interpolation )
{
case Interpolation_Linear:
case Interpolation::Linear:
return SRC_ZERO_ORDER_HOLD;
case Interpolation_SincFastest:
case Interpolation::SincFastest:
return SRC_SINC_FASTEST;
case Interpolation_SincMedium:
case Interpolation::SincMedium:
return SRC_SINC_MEDIUM_QUALITY;
case Interpolation_SincBest:
case Interpolation::SincBest:
return SRC_SINC_BEST_QUALITY;
}
return SRC_LINEAR;
@@ -197,6 +197,7 @@ public:
// audio-device-stuff
bool renderOnly() const { return m_renderOnly; }
// Returns the current audio device's name. This is not necessarily
// the user's preferred audio device, in case you were thinking that.
inline const QString & audioDevName() const
@@ -255,7 +256,7 @@ public:
return m_playHandles;
}
void removePlayHandlesOfTypes(Track * track, const quint8 types);
void removePlayHandlesOfTypes(Track * track, PlayHandle::Types types);
// methods providing information for other classes
@@ -275,6 +276,11 @@ public:
return m_profiler.cpuLoad();
}
int detailLoad(const AudioEngineProfiler::DetailType type) const
{
return m_profiler.detailLoad(type);
}
const qualitySettings & currentQualitySettings() const
{
return m_qualitySettings;
@@ -401,6 +407,10 @@ private:
AudioDevice * tryAudioDevices();
MidiClient * tryMidiClients();
void renderStageNoteSetup();
void renderStageInstruments();
void renderStageEffects();
void renderStageMix();
const surroundSampleFrame * renderNextBuffer();
@@ -416,7 +426,7 @@ private:
bool m_renderOnly;
QVector<AudioPort *> m_audioPorts;
std::vector<AudioPort *> m_audioPorts;
fpp_t m_framesPerPeriod;
@@ -430,7 +440,7 @@ private:
surroundSampleFrame * m_outputBufferWrite;
// worker thread stuff
QVector<AudioEngineWorkerThread *> m_workers;
std::vector<AudioEngineWorkerThread *> m_workers;
int m_numWorkers;
// playhandle stuff

View File

@@ -25,6 +25,8 @@
#ifndef LMMS_AUDIO_ENGINE_PROFILER_H
#define LMMS_AUDIO_ENGINE_PROFILER_H
#include <array>
#include <atomic>
#include <QFile>
#include "lmms_basics.h"
@@ -53,11 +55,55 @@ public:
void setOutputFile( const QString& outputFile );
enum class DetailType {
NoteSetup,
Instruments,
Effects,
Mixing,
Count
};
constexpr static auto DetailCount = static_cast<std::size_t>(DetailType::Count);
int detailLoad(const DetailType type) const
{
return m_detailLoad[static_cast<std::size_t>(type)].load(std::memory_order_relaxed);
}
class Probe
{
public:
Probe(AudioEngineProfiler& profiler, AudioEngineProfiler::DetailType type)
: m_profiler(profiler)
, m_type(type)
{
profiler.startDetail(type);
}
~Probe() { m_profiler.finishDetail(m_type); }
Probe& operator=(const Probe&) = delete;
Probe(const Probe&) = delete;
Probe(Probe&&) = delete;
private:
AudioEngineProfiler &m_profiler;
const AudioEngineProfiler::DetailType m_type;
};
private:
void startDetail(const DetailType type) { m_detailTimer[static_cast<std::size_t>(type)].reset(); }
void finishDetail(const DetailType type)
{
m_detailTime[static_cast<std::size_t>(type)] = m_detailTimer[static_cast<std::size_t>(type)].elapsed();
}
MicroTimer m_periodTimer;
int m_cpuLoad;
std::atomic<float> m_cpuLoad;
QFile m_outputFile;
// Use arrays to avoid dynamic allocations in realtime code
std::array<MicroTimer, DetailCount> m_detailTimer;
std::array<int, DetailCount> m_detailTime{0};
std::array<std::atomic<float>, DetailCount> m_detailLoad{0};
};
} // namespace lmms

View File

@@ -45,7 +45,7 @@ public:
class JobQueue
{
public:
enum OperationMode
enum class OperationMode
{
Static, // no jobs added while processing queue
Dynamic // jobs can be added while processing queue
@@ -57,7 +57,7 @@ public:
m_items(),
m_writeIndex( 0 ),
m_itemsDone( 0 ),
m_opMode( Static )
m_opMode( OperationMode::Static )
{
std::fill(m_items, m_items + JOB_QUEUE_SIZE, nullptr);
}
@@ -83,7 +83,7 @@ public:
virtual void quit();
static void resetJobQueue( JobQueue::OperationMode _opMode =
JobQueue::Static )
JobQueue::OperationMode::Static )
{
globalJobQueue.reset( _opMode );
}
@@ -97,12 +97,12 @@ public:
// to ThreadableJob objects
template<typename T>
static void fillJobQueue( const T & _vec,
JobQueue::OperationMode _opMode = JobQueue::Static )
JobQueue::OperationMode _opMode = JobQueue::OperationMode::Static )
{
resetJobQueue( _opMode );
for( typename T::ConstIterator it = _vec.begin(); it != _vec.end(); ++it )
for (const auto& job : _vec)
{
addJob( *it );
addJob(job);
}
}

View File

@@ -35,7 +35,7 @@
#endif
#include <atomic>
#include <QVector>
#include <vector>
#include "AudioDevice.h"
#include "AudioDeviceSetupWidget.h"
@@ -117,7 +117,7 @@ private:
std::atomic<bool> m_stopped;
std::atomic<MidiJack *> m_midiClient;
QVector<jack_port_t *> m_outputPorts;
std::vector<jack_port_t *> m_outputPorts;
jack_default_audio_sample_t * * m_tempOutBufs;
surroundSampleFrame * m_outBuf;

View File

@@ -27,6 +27,7 @@
#include <QMap>
#include <QMutex>
#include <cmath>
#include "JournallingObject.h"
#include "Model.h"
@@ -78,9 +79,9 @@ class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject
Q_OBJECT
MM_OPERATORS
public:
using AutoModelVector = QVector<AutomatableModel*>;
using AutoModelVector = std::vector<AutomatableModel*>;
enum ScaleType
enum class ScaleType
{
Linear,
Logarithmic,
@@ -144,7 +145,7 @@ public:
template<bool>
static bool castValue( const float v )
{
return ( qRound( v ) != 0 );
return (std::round(v) != 0);
}
@@ -231,11 +232,11 @@ public:
}
void setScaleLogarithmic( bool setToTrue = true )
{
setScaleType( setToTrue ? Logarithmic : Linear );
setScaleType( setToTrue ? ScaleType::Logarithmic : ScaleType::Linear );
}
bool isScaleLogarithmic() const
{
return m_scaleType == Logarithmic;
return m_scaleType == ScaleType::Logarithmic;
}
void setStep( const float step );

View File

@@ -54,15 +54,15 @@ class LMMS_EXPORT AutomationClip : public Clip
{
Q_OBJECT
public:
enum ProgressionTypes
enum class ProgressionType
{
DiscreteProgression,
LinearProgression,
CubicHermiteProgression
Discrete,
Linear,
CubicHermite
} ;
using timeMap = QMap<int, AutomationNode>;
using objectVector = QVector<QPointer<AutomatableModel>>;
using objectVector = std::vector<QPointer<AutomatableModel>>;
using TimemapIterator = timeMap::const_iterator;
@@ -76,11 +76,11 @@ public:
const objectVector& objects() const;
// progression-type stuff
inline ProgressionTypes progressionType() const
inline ProgressionType progressionType() const
{
return m_progressionType;
}
void setProgressionType( ProgressionTypes _new_progression_type );
void setProgressionType( ProgressionType _new_progression_type );
inline float getTension() const
{
@@ -167,7 +167,7 @@ public:
static bool isAutomated( const AutomatableModel * _m );
static QVector<AutomationClip *> clipsForModel( const AutomatableModel * _m );
static std::vector<AutomationClip*> clipsForModel(const AutomatableModel* _m);
static AutomationClip * globalAutomationClip( AutomatableModel * _m );
static void resolveAllIDs();
@@ -190,6 +190,15 @@ private:
void generateTangents(timeMap::iterator it, int numToGenerate);
float valueAt( timeMap::const_iterator v, int offset ) const;
/**
* @brief
* This function combines the song tracks, pattern store tracks,
* and the global automation track all in one vector.
*
* @return std::vector<Track*>
*/
static std::vector<Track*> combineAllTracks();
// Mutex to make methods involving automation clips thread safe
// Mutable so we can lock it from const objects
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
@@ -199,13 +208,13 @@ private:
#endif
AutomationTrack * m_autoTrack;
QVector<jo_id_t> m_idsToResolve;
std::vector<jo_id_t> m_idsToResolve;
objectVector m_objects;
timeMap m_timeMap; // actual values
timeMap m_oldTimeMap; // old values for storing the values before setDragValue() is called.
float m_tension;
bool m_hasAutomation;
ProgressionTypes m_progressionType;
ProgressionType m_progressionType;
bool m_dragging;
bool m_dragKeepOutValue; // Should we keep the current dragged node's outValue?

View File

@@ -27,6 +27,7 @@
#define LMMS_GUI_AUTOMATION_EDITOR_H
#include <QWidget>
#include <array>
#include "Editor.h"
@@ -86,11 +87,11 @@ public:
return "automationeditor";
}
enum EditModes
enum class EditMode
{
DRAW,
ERASE,
DRAW_OUTVALUES
Draw,
Erase,
DrawOutValues
};
public slots:
@@ -128,10 +129,10 @@ protected slots:
void horScrolled( int new_pos );
void verScrolled( int new_pos );
void setEditMode(AutomationEditor::EditModes mode);
void setEditMode(AutomationEditor::EditMode mode);
void setEditMode(int mode);
void setProgressionType(AutomationClip::ProgressionTypes type);
void setProgressionType(AutomationClip::ProgressionType type);
void setProgressionType(int type);
void setTension();
@@ -145,14 +146,14 @@ protected slots:
private:
enum Actions
enum class Action
{
NONE,
MOVE_VALUE,
ERASE_VALUES,
MOVE_OUTVALUE,
RESET_OUTVALUES,
DRAW_LINE
None,
MoveValue,
EraseValues,
MoveOutValue,
ResetOutValues,
DrawLine
} ;
// some constants...
@@ -180,7 +181,7 @@ private:
ComboBoxModel m_zoomingYModel;
ComboBoxModel m_quantizeModel;
static const QVector<float> m_zoomXLevels;
static const std::array<float, 7> m_zoomXLevels;
FloatModel * m_tensionModel;
@@ -200,7 +201,7 @@ private:
TimePos m_currentPosition;
Actions m_action;
Action m_action;
int m_moveXOffset;
@@ -214,7 +215,7 @@ private:
// Time position (key) of automation node whose outValue is being dragged
int m_draggedOutValueKey;
EditModes m_editMode;
EditMode m_editMode;
bool m_mouseDownLeft;
bool m_mouseDownRight; //true if right click is being held down

View File

@@ -89,14 +89,15 @@ QDataStream& operator>> ( QDataStream &in, WaveMipMap &waveMipMap );
class LMMS_EXPORT BandLimitedWave
{
public:
enum Waveforms
enum class Waveform
{
BLSaw,
BLSquare,
BLTriangle,
BLMoog,
NumBLWaveforms
Count
};
constexpr static auto NumWaveforms = static_cast<std::size_t>(Waveform::Count);
BandLimitedWave() = default;
virtual ~BandLimitedWave() = default;
@@ -127,7 +128,7 @@ public:
* \param _wavelen The wavelength (length of one cycle, ie. the inverse of frequency) of the wanted oscillation, measured in sample frames
* \param _wave The wanted waveform. Options currently are saw, triangle, square and moog saw.
*/
static inline sample_t oscillate( float _ph, float _wavelen, Waveforms _wave )
static inline sample_t oscillate( float _ph, float _wavelen, Waveform _wave )
{
// get the next higher tlen
int t = 0;
@@ -139,12 +140,12 @@ public:
int lookup = static_cast<int>( lookupf );
const float ip = fraction( lookupf );
const sample_t s1 = s_waveforms[ _wave ].sampleAt( t, lookup );
const sample_t s2 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 1 ) % tlen );
const sample_t s1 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, lookup );
const sample_t s2 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, ( lookup + 1 ) % tlen );
const int lm = lookup == 0 ? tlen - 1 : lookup - 1;
const sample_t s0 = s_waveforms[ _wave ].sampleAt( t, lm );
const sample_t s3 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 2 ) % tlen );
const sample_t s0 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, lm );
const sample_t s3 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, ( lookup + 2 ) % tlen );
const sample_t sr = optimal4pInterpolate( s0, s1, s2, s3, ip );
return sr;
@@ -153,8 +154,8 @@ public:
lookup = lookup << 1;
tlen = tlen << 1;
t += 1;
const sample_t s3 = s_waveforms[ _wave ].sampleAt( t, lookup );
const sample_t s4 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 1 ) % tlen );
const sample_t s3 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, lookup );
const sample_t s4 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, ( lookup + 1 ) % tlen );
const sample_t s34 = linearInterpolate( s3, s4, ip );
const float ip2 = ( ( tlen - _wavelen ) / tlen - 0.5 ) * 2.0;
@@ -168,7 +169,7 @@ public:
static bool s_wavesGenerated;
static std::array<WaveMipMap, NumBLWaveforms> s_waveforms;
static std::array<WaveMipMap, NumWaveforms> s_waveforms;
static QString s_wavetableDir;
};

View File

@@ -209,7 +209,7 @@ public:
inline float update( float s, ch_cnt_t ch )
{
if( qAbs( s ) < 1.0e-10f && qAbs( m_z1[ch] ) < 1.0e-10f ) return 0.0f;
if (std::abs(s) < 1.0e-10f && std::abs(m_z1[ch]) < 1.0e-10f) return 0.0f;
return m_z1[ch] = s * m_a0 + m_z1[ch] * m_b1;
}
@@ -224,7 +224,7 @@ class BasicFilters
{
MM_OPERATORS
public:
enum FilterTypes
enum class FilterType
{
LowPass,
HiPass,
@@ -247,8 +247,7 @@ public:
Highpass_SV,
Notch_SV,
FastFormant,
Tripole,
NumFilters
Tripole
};
static inline float minFreq()
@@ -261,20 +260,20 @@ public:
return( 0.01f );
}
inline void setFilterType( const int _idx )
inline void setFilterType( const FilterType _idx )
{
m_doubleFilter = _idx == DoubleLowPass || _idx == DoubleMoog;
m_doubleFilter = _idx == FilterType::DoubleLowPass || _idx == FilterType::DoubleMoog;
if( !m_doubleFilter )
{
m_type = static_cast<FilterTypes>( _idx );
m_type = _idx;
return;
}
// Double lowpass mode, backwards-compat for the goofy
// Add-NumFilters to signify doubleFilter stuff
m_type = _idx == DoubleLowPass
? LowPass
: Moog;
m_type = _idx == FilterType::DoubleLowPass
? FilterType::LowPass
: FilterType::Moog;
if( m_subFilter == nullptr )
{
m_subFilter = new BasicFilters<CHANNELS>(
@@ -334,28 +333,24 @@ public:
sample_t out;
switch( m_type )
{
case Moog:
case FilterType::Moog:
{
sample_t x = _in0 - m_r*m_y4[_chnl];
// four cascaded onepole filters
// (bilinear transform)
m_y1[_chnl] = qBound( -10.0f,
( x + m_oldx[_chnl] ) * m_p
- m_k * m_y1[_chnl],
10.0f );
m_y2[_chnl] = qBound( -10.0f,
( m_y1[_chnl] + m_oldy1[_chnl] ) * m_p
- m_k * m_y2[_chnl],
10.0f );
m_y3[_chnl] = qBound( -10.0f,
( m_y2[_chnl] + m_oldy2[_chnl] ) * m_p
- m_k * m_y3[_chnl],
10.0f );
m_y4[_chnl] = qBound( -10.0f,
( m_y3[_chnl] + m_oldy3[_chnl] ) * m_p
- m_k * m_y4[_chnl],
m_y1[_chnl] = std::clamp((x + m_oldx[_chnl]) * m_p
- m_k * m_y1[_chnl], -10.0f,
10.0f);
m_y2[_chnl] = std::clamp((m_y1[_chnl] + m_oldy1[_chnl]) * m_p
- m_k * m_y2[_chnl], -10.0f,
10.0f);
m_y3[_chnl] = std::clamp((m_y2[_chnl] + m_oldy2[_chnl]) * m_p
- m_k * m_y3[_chnl], -10.0f,
10.0f );
m_y4[_chnl] = std::clamp((m_y3[_chnl] + m_oldy3[_chnl]) * m_p
- m_k * m_y4[_chnl], -10.0f,
10.0f);
m_oldx[_chnl] = x;
m_oldy1[_chnl] = m_y1[_chnl];
@@ -368,7 +363,7 @@ public:
// 3x onepole filters with 4x oversampling and interpolation of oversampled signal:
// input signal is linear-interpolated after oversampling, output signal is averaged from oversampled outputs
case Tripole:
case FilterType::Tripole:
{
out = 0.0f;
float ip = 0.0f;
@@ -377,18 +372,15 @@ public:
ip += 0.25f;
sample_t x = linearInterpolate( m_last[_chnl], _in0, ip ) - m_r * m_y3[_chnl];
m_y1[_chnl] = qBound( -10.0f,
( x + m_oldx[_chnl] ) * m_p
- m_k * m_y1[_chnl],
10.0f );
m_y2[_chnl] = qBound( -10.0f,
( m_y1[_chnl] + m_oldy1[_chnl] ) * m_p
- m_k * m_y2[_chnl],
10.0f );
m_y3[_chnl] = qBound( -10.0f,
( m_y2[_chnl] + m_oldy2[_chnl] ) * m_p
- m_k * m_y3[_chnl],
10.0f );
m_y1[_chnl] = std::clamp((x + m_oldx[_chnl]) * m_p
- m_k * m_y1[_chnl], -10.0f,
10.0f);
m_y2[_chnl] = std::clamp((m_y1[_chnl] + m_oldy1[_chnl]) * m_p
- m_k * m_y2[_chnl], -10.0f,
10.0f);
m_y3[_chnl] = std::clamp((m_y2[_chnl] + m_oldy2[_chnl]) * m_p
- m_k * m_y3[_chnl], -10.0f,
10.0f);
m_oldx[_chnl] = x;
m_oldy1[_chnl] = m_y1[_chnl];
m_oldy2[_chnl] = m_y2[_chnl];
@@ -404,8 +396,8 @@ public:
// and extended to other SV filter types
// /* Hal Chamberlin's state variable filter */
case Lowpass_SV:
case Bandpass_SV:
case FilterType::Lowpass_SV:
case FilterType::Bandpass_SV:
{
float highpass;
@@ -421,12 +413,12 @@ public:
}
/* mix filter output into output buffer */
return m_type == Lowpass_SV
return m_type == FilterType::Lowpass_SV
? m_delay4[_chnl]
: m_delay3[_chnl];
}
case Highpass_SV:
case FilterType::Highpass_SV:
{
float hp;
@@ -440,7 +432,7 @@ public:
return hp;
}
case Notch_SV:
case FilterType::Notch_SV:
{
float hp1, hp2;
@@ -465,22 +457,22 @@ public:
// can be driven up to self-oscillation (BTW: do not remove the limits!!!).
// (C) 1998 ... 2009 S.Fendt. Released under the GPL v2.0 or any later version.
case Lowpass_RC12:
case FilterType::Lowpass_RC12:
{
sample_t lp, bp, hp, in;
for( int n = 4; n != 0; --n )
{
in = _in0 + m_rcbp0[_chnl] * m_rcq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f);
lp = in * m_rcb + m_rclp0[_chnl] * m_rca;
lp = qBound( -1.0f, lp, 1.0f );
lp = std::clamp(lp, -1.0f, 1.0f);
hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast0[_chnl] = in;
m_rclp0[_chnl] = lp;
@@ -489,45 +481,45 @@ public:
}
return lp;
}
case Highpass_RC12:
case Bandpass_RC12:
case FilterType::Highpass_RC12:
case FilterType::Bandpass_RC12:
{
sample_t hp, bp, in;
for( int n = 4; n != 0; --n )
{
in = _in0 + m_rcbp0[_chnl] * m_rcq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f);
hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast0[_chnl] = in;
m_rchp0[_chnl] = hp;
m_rcbp0[_chnl] = bp;
}
return m_type == Highpass_RC12 ? hp : bp;
return m_type == FilterType::Highpass_RC12 ? hp : bp;
}
case Lowpass_RC24:
case FilterType::Lowpass_RC24:
{
sample_t lp, bp, hp, in;
for( int n = 4; n != 0; --n )
{
// first stage is as for the 12dB case...
in = _in0 + m_rcbp0[_chnl] * m_rcq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f);
lp = in * m_rcb + m_rclp0[_chnl] * m_rca;
lp = qBound( -1.0f, lp, 1.0f );
lp = std::clamp(lp, -1.0f, 1.0f);
hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast0[_chnl] = in;
m_rclp0[_chnl] = lp;
@@ -536,16 +528,16 @@ public:
// second stage gets the output of the first stage as input...
in = lp + m_rcbp1[_chnl] * m_rcq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f );
lp = in * m_rcb + m_rclp1[_chnl] * m_rca;
lp = qBound( -1.0f, lp, 1.0f );
lp = std::clamp(lp, -1.0f, 1.0f);
hp = m_rcc * ( m_rchp1[_chnl] + in - m_rclast1[_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_rcb + m_rcbp1[_chnl] * m_rca;
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast1[_chnl] = in;
m_rclp1[_chnl] = lp;
@@ -554,91 +546,91 @@ public:
}
return lp;
}
case Highpass_RC24:
case Bandpass_RC24:
case FilterType::Highpass_RC24:
case FilterType::Bandpass_RC24:
{
sample_t hp, bp, in;
for( int n = 4; n != 0; --n )
{
// first stage is as for the 12dB case...
in = _in0 + m_rcbp0[_chnl] * m_rcq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f);
hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast0[_chnl] = in;
m_rchp0[_chnl] = hp;
m_rcbp0[_chnl] = bp;
// second stage gets the output of the first stage as input...
in = m_type == Highpass_RC24
in = m_type == FilterType::Highpass_RC24
? hp + m_rcbp1[_chnl] * m_rcq
: bp + m_rcbp1[_chnl] * m_rcq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f);
hp = m_rcc * ( m_rchp1[_chnl] + in - m_rclast1[_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_rcb + m_rcbp1[_chnl] * m_rca;
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast1[_chnl] = in;
m_rchp1[_chnl] = hp;
m_rcbp1[_chnl] = bp;
}
return m_type == Highpass_RC24 ? hp : bp;
return m_type == FilterType::Highpass_RC24 ? hp : bp;
}
case Formantfilter:
case FastFormant:
case FilterType::Formantfilter:
case FilterType::FastFormant:
{
if( qAbs( _in0 ) < 1.0e-10f && qAbs( m_vflast[0][_chnl] ) < 1.0e-10f ) { return 0.0f; } // performance hack - skip processing when the numbers get too small
if (std::abs(_in0) < 1.0e-10f && std::abs(m_vflast[0][_chnl]) < 1.0e-10f) { return 0.0f; } // performance hack - skip processing when the numbers get too small
sample_t hp, bp, in;
out = 0;
const int os = m_type == FastFormant ? 1 : 4; // no oversampling for fast formant
const int os = m_type == FilterType::FastFormant ? 1 : 4; // no oversampling for fast formant
for( int o = 0; o < os; ++o )
{
// first formant
in = _in0 + m_vfbp[0][_chnl] * m_vfq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f);
hp = m_vfc[0] * ( m_vfhp[0][_chnl] + in - m_vflast[0][_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_vfb[0] + m_vfbp[0][_chnl] * m_vfa[0];
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[0][_chnl] = in;
m_vfhp[0][_chnl] = hp;
m_vfbp[0][_chnl] = bp;
in = bp + m_vfbp[2][_chnl] * m_vfq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f);
hp = m_vfc[0] * ( m_vfhp[2][_chnl] + in - m_vflast[2][_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_vfb[0] + m_vfbp[2][_chnl] * m_vfa[0];
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[2][_chnl] = in;
m_vfhp[2][_chnl] = hp;
m_vfbp[2][_chnl] = bp;
in = bp + m_vfbp[4][_chnl] * m_vfq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f);
hp = m_vfc[0] * ( m_vfhp[4][_chnl] + in - m_vflast[4][_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_vfb[0] + m_vfbp[4][_chnl] * m_vfa[0];
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[4][_chnl] = in;
m_vfhp[4][_chnl] = hp;
@@ -648,39 +640,39 @@ public:
// second formant
in = _in0 + m_vfbp[0][_chnl] * m_vfq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f);
hp = m_vfc[1] * ( m_vfhp[1][_chnl] + in - m_vflast[1][_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_vfb[1] + m_vfbp[1][_chnl] * m_vfa[1];
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[1][_chnl] = in;
m_vfhp[1][_chnl] = hp;
m_vfbp[1][_chnl] = bp;
in = bp + m_vfbp[3][_chnl] * m_vfq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f);
hp = m_vfc[1] * ( m_vfhp[3][_chnl] + in - m_vflast[3][_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_vfb[1] + m_vfbp[3][_chnl] * m_vfa[1];
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[3][_chnl] = in;
m_vfhp[3][_chnl] = hp;
m_vfbp[3][_chnl] = bp;
in = bp + m_vfbp[5][_chnl] * m_vfq;
in = qBound( -1.0f, in, 1.0f );
in = std::clamp(in, -1.0f, 1.0f);
hp = m_vfc[1] * ( m_vfhp[5][_chnl] + in - m_vflast[5][_chnl] );
hp = qBound( -1.0f, hp, 1.0f );
hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_vfb[1] + m_vfbp[5][_chnl] * m_vfa[1];
bp = qBound( -1.0f, bp, 1.0f );
bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[5][_chnl] = in;
m_vfhp[5][_chnl] = hp;
@@ -688,7 +680,7 @@ public:
out += bp;
}
return m_type == FastFormant ? out * 2.0f : out * 0.5f;
return m_type == FilterType::FastFormant ? out * 2.0f : out * 0.5f;
}
default:
@@ -709,16 +701,16 @@ public:
inline void calcFilterCoeffs( float _freq, float _q )
{
// temp coef vars
_q = qMax( _q, minQ() );
_q = std::max(_q, minQ());
if( m_type == Lowpass_RC12 ||
m_type == Bandpass_RC12 ||
m_type == Highpass_RC12 ||
m_type == Lowpass_RC24 ||
m_type == Bandpass_RC24 ||
m_type == Highpass_RC24 )
if( m_type == FilterType::Lowpass_RC12 ||
m_type == FilterType::Bandpass_RC12 ||
m_type == FilterType::Highpass_RC12 ||
m_type == FilterType::Lowpass_RC24 ||
m_type == FilterType::Bandpass_RC24 ||
m_type == FilterType::Highpass_RC24 )
{
_freq = qBound( 50.0f, _freq, 20000.0f );
_freq = std::clamp(_freq, 50.0f, 20000.0f);
const float sr = m_sampleRatio * 0.25f;
const float f = 1.0f / ( _freq * F_2PI );
@@ -731,10 +723,10 @@ public:
return;
}
if( m_type == Formantfilter ||
m_type == FastFormant )
if( m_type == FilterType::Formantfilter ||
m_type == FilterType::FastFormant )
{
_freq = qBound( minFreq(), _freq, 20000.0f ); // limit freq and q for not getting bad noise out of the filter...
_freq = std::clamp(_freq, minFreq(), 20000.0f); // limit freq and q for not getting bad noise out of the filter...
// formats for a, e, i, o, u, a
static const float _f[6][2] = { { 1000, 1400 }, { 500, 2300 },
@@ -757,7 +749,7 @@ public:
const float f1 = 1.0f / ( linearInterpolate( _f[vowel+0][1], _f[vowel+1][1], fract ) * F_2PI );
// samplerate coeff: depends on oversampling
const float sr = m_type == FastFormant ? m_sampleRatio : m_sampleRatio * 0.25f;
const float sr = m_type == FilterType::FastFormant ? m_sampleRatio : m_sampleRatio * 0.25f;
m_vfa[0] = 1.0f - sr / ( f0 + sr );
m_vfb[0] = 1.0f - m_vfa[0];
@@ -768,11 +760,11 @@ public:
return;
}
if( m_type == Moog ||
m_type == DoubleMoog )
if( m_type == FilterType::Moog ||
m_type == FilterType::DoubleMoog )
{
// [ 0 - 0.5 ]
const float f = qBound( minFreq(), _freq, 20000.0f ) * m_sampleRatio;
const float f = std::clamp(_freq, minFreq(), 20000.0f) * m_sampleRatio;
// (Empirical tunning)
m_p = ( 3.6f - 3.2f * f ) * f;
m_k = 2.0f * m_p - 1;
@@ -787,9 +779,9 @@ public:
return;
}
if( m_type == Tripole )
if( m_type == FilterType::Tripole )
{
const float f = qBound( 20.0f, _freq, 20000.0f ) * m_sampleRatio * 0.25f;
const float f = std::clamp(_freq, 20.0f, 20000.0f) * m_sampleRatio * 0.25f;
m_p = ( 3.6f - 3.2f * f ) * f;
m_k = 2.0f * m_p - 1.0f;
@@ -798,20 +790,20 @@ public:
return;
}
if( m_type == Lowpass_SV ||
m_type == Bandpass_SV ||
m_type == Highpass_SV ||
m_type == Notch_SV )
if( m_type == FilterType::Lowpass_SV ||
m_type == FilterType::Bandpass_SV ||
m_type == FilterType::Highpass_SV ||
m_type == FilterType::Notch_SV )
{
const float f = sinf( qMax( minFreq(), _freq ) * m_sampleRatio * F_PI );
m_svf1 = qMin( f, 0.825f );
m_svf2 = qMin( f * 2.0f, 0.825f );
m_svq = qMax( 0.0001f, 2.0f - ( _q * 0.1995f ) );
const float f = sinf(std::max(minFreq(), _freq) * m_sampleRatio * F_PI);
m_svf1 = std::min(f, 0.825f);
m_svf2 = std::min(f * 2.0f, 0.825f);
m_svq = std::max(0.0001f, 2.0f - (_q * 0.1995f));
return;
}
// other filters
_freq = qBound( minFreq(), _freq, 20000.0f );
_freq = std::clamp(_freq, minFreq(), 20000.0f);
const float omega = F_2PI * _freq * m_sampleRatio;
const float tsin = sinf( omega ) * 0.5f;
const float tcos = cosf( omega );
@@ -825,38 +817,38 @@ public:
switch( m_type )
{
case LowPass:
case FilterType::LowPass:
{
const float b1 = ( 1.0f - tcos ) * a0;
const float b0 = b1 * 0.5f;
m_biQuad.setCoeffs( a1, a2, b0, b1, b0 );
break;
}
case HiPass:
case FilterType::HiPass:
{
const float b1 = ( -1.0f - tcos ) * a0;
const float b0 = b1 * -0.5f;
m_biQuad.setCoeffs( a1, a2, b0, b1, b0 );
break;
}
case BandPass_CSG:
case FilterType::BandPass_CSG:
{
const float b0 = tsin * a0;
m_biQuad.setCoeffs( a1, a2, b0, 0.0f, -b0 );
break;
}
case BandPass_CZPG:
case FilterType::BandPass_CZPG:
{
const float b0 = alpha * a0;
m_biQuad.setCoeffs( a1, a2, b0, 0.0f, -b0 );
break;
}
case Notch:
case FilterType::Notch:
{
m_biQuad.setCoeffs( a1, a2, a0, a1, a0 );
break;
}
case AllPass:
case FilterType::AllPass:
{
m_biQuad.setCoeffs( a1, a2, a2, a1, 1.0f );
break;
@@ -905,7 +897,7 @@ private:
// in/out history for Lowpass_SV (state-variant lowpass)
frame m_delay1, m_delay2, m_delay3, m_delay4;
FilterTypes m_type;
FilterType m_type;
bool m_doubleFilter;
float m_sampleRate;

View File

@@ -26,6 +26,7 @@
#ifndef LMMS_GUI_CPU_LOAD_WIDGET_H
#define LMMS_GUI_CPU_LOAD_WIDGET_H
#include <algorithm>
#include <QTimer>
#include <QPixmap>
#include <QWidget>
@@ -40,6 +41,7 @@ namespace lmms::gui
class CPULoadWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(int stepSize MEMBER m_stepSize)
public:
CPULoadWidget( QWidget * _parent );
~CPULoadWidget() override = default;
@@ -54,6 +56,8 @@ protected slots:
private:
int stepSize() const { return std::max(1, m_stepSize); }
int m_currentLoad;
QPixmap m_temp;
@@ -64,6 +68,8 @@ private:
QTimer m_updateTimer;
int m_stepSize;
} ;

View File

@@ -164,13 +164,6 @@ signals:
private:
enum Actions
{
NoAction,
Move,
Resize
} ;
Track * m_track;
QString m_name;

View File

@@ -140,7 +140,7 @@ public slots:
void resetColor();
protected:
enum ContextMenuAction
enum class ContextMenuAction
{
Remove,
Cut,
@@ -191,9 +191,9 @@ protected slots:
private:
enum Actions
enum class Action
{
NoAction,
None,
Move,
MoveSelection,
Resize,
@@ -206,7 +206,7 @@ private:
static TextFloat * s_textFloat;
Clip * m_clip;
Actions m_action;
Action m_action;
QPoint m_initialMousePos;
QPoint m_initialMouseGlobalPos;
QVector<TimePos> m_initialOffsets;

View File

@@ -72,12 +72,12 @@ public:
const QString & itemText( int i ) const
{
return m_items[qBound<int>( minValue(), i, maxValue() )].first;
return m_items[std::clamp(i, minValue(), maxValue())].first;
}
const PixmapLoader* itemPixmap( int i ) const
{
return m_items[qBound<int>( minValue(), i, maxValue() )].second.get();
return m_items[std::clamp(i, minValue(), maxValue())].second.get();
}
int size() const

View File

@@ -30,9 +30,9 @@
#include <QMap>
#include <QPair>
#include <QStringList>
#include <QVector>
#include <QObject>
#include <vector>
#include "lmms_export.h"
@@ -239,11 +239,8 @@ public:
void addRecentlyOpenedProject(const QString & _file);
const QString & value(const QString & cls,
const QString & attribute) const;
const QString & value(const QString & cls,
const QString & attribute,
const QString & defaultVal) const;
QString value(const QString& cls, const QString& attribute, const QString& defaultVal = "") const;
void setValue(const QString & cls, const QString & attribute,
const QString & value);
void deleteValue(const QString & cls, const QString & attribute);
@@ -302,7 +299,7 @@ private:
unsigned int m_configVersion;
QStringList m_recentlyOpenedProjects;
using stringPairVector = QVector<QPair<QString, QString>>;
using stringPairVector = std::vector<QPair<QString, QString>>;
using settingsMap = QMap<QString, stringPairVector>;
settingsMap m_settings;

View File

@@ -45,26 +45,25 @@ class ControllerDialog;
} // namespace gui
using ControllerVector = QVector<Controller*>;
using ControllerVector = std::vector<Controller*>;
class LMMS_EXPORT Controller : public Model, public JournallingObject
{
Q_OBJECT
public:
enum ControllerTypes
enum class ControllerType
{
DummyController,
LfoController,
MidiController,
PeakController,
Dummy,
Lfo,
Midi,
Peak,
/*
XYController,
EquationController
XY,
Equation
*/
NumControllerTypes
} ;
Controller( ControllerTypes _type, Model * _parent,
Controller( ControllerType _type, Model * _parent,
const QString & _display_name );
~Controller() override;
@@ -83,7 +82,7 @@ public:
m_sampleExact = _exact;
}
inline ControllerTypes type() const
inline ControllerType type() const
{
return( m_type );
}
@@ -94,8 +93,8 @@ public:
{
switch( m_type )
{
case LfoController: return( true );
case PeakController: return( true );
case ControllerType::Lfo: return( true );
case ControllerType::Peak: return( true );
default:
break;
}
@@ -112,13 +111,13 @@ public:
void loadSettings( const QDomElement & _this ) override;
QString nodeName() const override;
static Controller * create( ControllerTypes _tt, Model * _parent );
static Controller * create( ControllerType _tt, Model * _parent );
static Controller * create( const QDomElement & _this,
Model * _parent );
inline static float fittedValue( float _val )
{
return qBound<float>( 0.0f, _val, 1.0f );
return std::clamp(_val, 0.0f, 1.0f);
}
static long runningPeriods()
@@ -165,7 +164,7 @@ protected:
int m_connectionCount;
QString m_name;
ControllerTypes m_type;
ControllerType m_type;
static ControllerVector s_controllers;

View File

@@ -30,12 +30,13 @@
#define LMMS_CONTROLLER_CONNECTION_H
#include <QObject>
#include <QVector>
#include "Controller.h"
#include "JournallingObject.h"
#include "ValueBuffer.h"
#include <vector>
namespace lmms
{
@@ -46,7 +47,7 @@ namespace gui
class ControllerConnectionDialog;
}
using ControllerConnectionVector = QVector<ControllerConnection*>;
using ControllerConnectionVector = std::vector<ControllerConnection*>;
class LMMS_EXPORT ControllerConnection : public QObject, public JournallingObject
{

View File

@@ -36,7 +36,7 @@ class LMMS_EXPORT CustomTextKnob : public Knob
protected:
inline void setHintText( const QString & _txt_before, const QString & _txt_after ) {} // inaccessible
public:
CustomTextKnob( knobTypes _knob_num, QWidget * _parent = nullptr, const QString & _name = QString(), const QString & _value_text = QString() );
CustomTextKnob( KnobType _knob_num, QWidget * _parent = nullptr, const QString & _name = QString(), const QString & _value_text = QString() );
CustomTextKnob( QWidget * _parent = nullptr, const QString & _name = QString(), const QString & _value_text = QString() ); //!< default ctor

View File

@@ -47,9 +47,9 @@ class LMMS_EXPORT DataFile : public QDomDocument
using UpgradeMethod = void(DataFile::*)();
public:
enum Types
enum class Type
{
UnknownType,
Unknown,
SongProject,
SongProjectTemplate,
InstrumentTrackSettings,
@@ -57,10 +57,8 @@ public:
ClipboardData,
JournalData,
EffectSettings,
MidiClip,
TypeCount
MidiClip
} ;
using Type = Types;
DataFile( const QString& fileName );
DataFile( const QByteArray& data );
@@ -128,6 +126,8 @@ private:
void upgrade_defaultTripleOscillatorHQ();
void upgrade_mixerRename();
void upgrade_bbTcoRename();
void upgrade_sampleAndHold();
void upgrade_midiCCIndexing();
// List of all upgrade methods
static const std::vector<UpgradeMethod> UPGRADE_METHODS;

View File

@@ -187,7 +187,7 @@ namespace lmms::DspEffectLibrary
template<typename sample_t>
inline sample_t saturate( sample_t x )
{
return qMin<sample_t>( qMax<sample_t>( -1.0f, x ), 1.0f );
return std::min<sample_t>(std::max<sample_t>(-1.0f, x), 1.0f);
}
@@ -198,7 +198,7 @@ namespace lmms::DspEffectLibrary
const sample_t _gain,
const sample_t _ratio,
const FastBassBoost & _orig = FastBassBoost() ) :
m_frequency( qMax<sample_t>( _frequency, 10.0 ) ),
m_frequency(std::max<sample_t>(_frequency, 10.0)),
m_gain1( 1.0 / ( m_frequency + 1.0 ) ),
m_gain2( _gain ),
m_ratio( _ratio ),

View File

@@ -69,7 +69,7 @@ public:
private:
using EffectList = QVector<Effect*>;
using EffectList = std::vector<Effect*>;
EffectList m_effects;
BoolModel m_enabledModel;

View File

@@ -25,7 +25,7 @@
#ifndef LMMS_ENVELOPE_AND_LFO_PARAMETERS_H
#define LMMS_ENVELOPE_AND_LFO_PARAMETERS_H
#include <QVector>
#include <vector>
#include "JournallingObject.h"
#include "AutomatableModel.h"
@@ -169,7 +169,7 @@ private:
bool m_bad_lfoShapeData;
SampleBuffer m_userWave;
enum LfoShapes
enum class LfoShape
{
SineWave,
TriangleWave,
@@ -177,8 +177,9 @@ private:
SquareWave,
UserDefinedWave,
RandomWave,
NumLfoShapes
Count
} ;
constexpr static auto NumLfoShapes = static_cast<std::size_t>(LfoShape::Count);
sample_t lfoShapeSample( fpp_t _frame_offset );
void updateLfoShapeData();

View File

@@ -62,7 +62,7 @@ private:
QString m_fileExtension;
bool m_multiExport;
ProjectRenderer::ExportFileFormats m_ft;
ProjectRenderer::ExportFileFormat m_ft;
std::unique_ptr<RenderManager> m_renderManager;
} ;

View File

@@ -75,8 +75,7 @@ public:
private slots:
void reloadTree();
void expandItems( QTreeWidgetItem * item=nullptr, QList<QString> expandedDirs = QList<QString>() );
// call with item=NULL to filter the entire tree
bool filterItems( const QString & filter, QTreeWidgetItem * item=nullptr );
bool filterAndExpandItems(const QString & filter, QTreeWidgetItem * item = nullptr);
void giveFocusToFilter();
private:
@@ -84,6 +83,9 @@ private:
void addItems( const QString & path );
void saveDirectoriesStates();
void restoreDirectoriesStates();
FileBrowserTreeWidget * m_fileBrowserTreeWidget;
QLineEdit * m_filterEdit;
@@ -99,6 +101,8 @@ private:
QCheckBox* m_showFactoryContent = nullptr;
QString m_userDir;
QString m_factoryDir;
QList<QString> m_savedExpandedDirs;
QString m_previousFilterValue;
} ;
@@ -115,7 +119,6 @@ public:
//! that are expanded in the tree.
QList<QString> expandedDirs( QTreeWidgetItem * item = nullptr ) const;
protected:
void contextMenuEvent( QContextMenuEvent * e ) override;
void mousePressEvent( QMouseEvent * me ) override;
@@ -223,20 +226,19 @@ private:
class FileItem : public QTreeWidgetItem
{
public:
enum FileTypes
enum class FileType
{
ProjectFile,
PresetFile,
SampleFile,
SoundFontFile,
PatchFile,
MidiFile,
VstPluginFile,
UnknownFile,
NumFileTypes
Project,
Preset,
Sample,
SoundFont,
Patch,
Midi,
VstPlugin,
Unknown
} ;
enum FileHandling
enum class FileHandling
{
NotSupported,
LoadAsProject,
@@ -255,7 +257,7 @@ public:
return QFileInfo(m_path, text(0)).absoluteFilePath();
}
inline FileTypes type() const
inline FileType type() const
{
return( m_type );
}
@@ -267,7 +269,7 @@ public:
inline bool isTrack() const
{
return m_handling == LoadAsPreset || m_handling == LoadByPlugin;
return m_handling == FileHandling::LoadAsPreset || m_handling == FileHandling::LoadByPlugin;
}
QString extension();
@@ -287,7 +289,7 @@ private:
static QPixmap * s_unknownFilePixmap;
QString m_path;
FileTypes m_type;
FileType m_type;
FileHandling m_handling;
} ;

83
include/Flags.h Normal file
View File

@@ -0,0 +1,83 @@
/*
* Flags.h - class to make flags from enums
*
* Copyright (c) 2023 Dominic Clark
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef LMMS_FLAGS_H
#define LMMS_FLAGS_H
#include <type_traits>
namespace lmms {
template<typename T>
class Flags
{
static_assert(std::is_enum_v<T>, "lmms::Flags can only be used with enum types");
public:
using EnumType = T;
using UnderlyingType = std::underlying_type_t<T>;
constexpr Flags() = default;
constexpr Flags(T value) : // Intentionally not explicit
m_value{static_cast<UnderlyingType>(value)}
{}
constexpr explicit Flags(UnderlyingType value) :
m_value{value}
{}
constexpr auto testAll(Flags flags) const -> bool { return (*this & flags) == flags; }
constexpr auto testAny(Flags flags) const -> bool { return (*this & flags) != Flags{}; }
constexpr auto testFlag(EnumType flag) const -> bool { return static_cast<bool>(*this & flag); }
constexpr auto operator~() const -> Flags { return Flags{~m_value}; }
friend constexpr auto operator&(Flags l, Flags r) -> Flags { return Flags{l.m_value & r.m_value}; }
friend constexpr auto operator|(Flags l, Flags r) -> Flags { return Flags{l.m_value | r.m_value}; }
friend constexpr auto operator^(Flags l, Flags r) -> Flags { return Flags{l.m_value ^ r.m_value}; }
friend constexpr auto operator+(Flags l, Flags r) -> Flags { return Flags{l.m_value | r.m_value}; }
friend constexpr auto operator-(Flags l, Flags r) -> Flags { return Flags{l.m_value & ~r.m_value}; }
constexpr auto operator&=(Flags f) -> Flags& { m_value &= f.m_value; return *this; }
constexpr auto operator|=(Flags f) -> Flags& { m_value |= f.m_value; return *this; }
constexpr auto operator^=(Flags f) -> Flags& { m_value ^= f.m_value; return *this; }
constexpr auto operator+=(Flags f) -> Flags& { m_value |= f.m_value; return *this; }
constexpr auto operator-=(Flags f) -> Flags& { m_value &= ~f.m_value; return *this; }
constexpr explicit operator UnderlyingType() const { return m_value; } // TODO C++23: explicit(std::is_scoped_enum<T>)
constexpr explicit operator bool() const { return m_value != 0; }
friend constexpr auto operator==(Flags l, Flags r) -> bool { return l.m_value == r.m_value; } // TODO C++20: = default
friend constexpr auto operator!=(Flags l, Flags r) -> bool { return l.m_value != r.m_value; } // TODO C++20: Remove
private:
UnderlyingType m_value = 0;
};
#define LMMS_DECLARE_OPERATORS_FOR_FLAGS(type) \
constexpr inline auto operator|(type l, type r) -> ::lmms::Flags<type> { return ::lmms::Flags{l} | ::lmms::Flags{r}; }
} // namespace lmms
#endif // LMMS_FLAGS_H

View File

@@ -48,13 +48,12 @@ class LMMS_EXPORT Graph : public QWidget, public ModelView
{
Q_OBJECT
public:
enum graphStyle
enum class Style
{
NearestStyle, //!< draw as stairs
LinearStyle, //!< connect each 2 samples with a line, with wrapping
LinearNonCyclicStyle, //!< LinearStyle without wrapping
BarStyle, //!< draw thick bars
NumGraphStyles
Nearest, //!< draw as stairs
Linear, //!< connect each 2 samples with a line, with wrapping
LinearNonCyclic, //!< Linear without wrapping
Bar, //!< draw thick bars
};
/**
@@ -62,7 +61,7 @@ public:
* @param _width Pixel width of widget
* @param _height Pixel height of widget
*/
Graph( QWidget * _parent, graphStyle _style = Graph::LinearStyle,
Graph( QWidget * _parent, Style _style = Style::Linear,
int _width = 132,
int _height = 104
);
@@ -78,13 +77,13 @@ public:
return castModel<graphModel>();
}
inline graphStyle getGraphStyle()
inline Style getGraphStyle()
{
return m_graphStyle;
}
inline void setGraphStyle( graphStyle _s )
inline void setGraphStyle( Style _s )
{
m_graphStyle = _s;
update();
@@ -114,7 +113,7 @@ private:
QPixmap m_foreground;
QColor m_graphColor;
graphStyle m_graphStyle;
Style m_graphStyle;
bool m_mouseDown;
int m_lastCursorX;

View File

@@ -27,6 +27,8 @@
#define LMMS_INSTRUMENT_H
#include <QString>
#include "Flags.h"
#include "lmms_export.h"
#include "lmms_basics.h"
#include "MemoryManager.h"
@@ -47,7 +49,7 @@ class LMMS_EXPORT Instrument : public Plugin
{
MM_OPERATORS
public:
enum Flag
enum class Flag
{
NoFlags = 0x00,
IsSingleStreamed = 0x01, /*! Instrument provides a single audio stream for all notes */
@@ -55,7 +57,7 @@ public:
IsNotBendable = 0x04, /*! Instrument can't react to pitch bend changes */
};
Q_DECLARE_FLAGS(Flags, Flag);
using Flags = lmms::Flags<Flag>;
Instrument(InstrumentTrack * _instrument_track,
const Descriptor * _descriptor,
@@ -102,7 +104,7 @@ public:
virtual Flags flags() const
{
return NoFlags;
return Flag::NoFlags;
}
// sub-classes can re-implement this for receiving all incoming
@@ -149,7 +151,7 @@ private:
} ;
Q_DECLARE_OPERATORS_FOR_FLAGS(Instrument::Flags)
LMMS_DECLARE_OPERATORS_FOR_FLAGS(Instrument::Flag)
} // namespace lmms

View File

@@ -119,7 +119,7 @@ public:
};
struct ChordTable : public QVector<Chord>
struct ChordTable
{
private:
ChordTable();
@@ -131,6 +131,7 @@ public:
};
static std::array<Init, NUM_CHORD_TABLES> s_initTable;
std::vector<Chord> m_chords;
public:
static const ChordTable & getInstance()
@@ -150,6 +151,11 @@ public:
{
return getByName( name, false );
}
const std::vector<Chord>& chords() const
{
return m_chords;
}
};
@@ -170,14 +176,13 @@ class InstrumentFunctionArpeggio : public Model, public JournallingObject
{
Q_OBJECT
public:
enum ArpDirections
enum class ArpDirection
{
ArpDirUp,
ArpDirDown,
ArpDirUpAndDown,
ArpDirDownAndUp,
ArpDirRandom,
NumArpDirections
Up,
Down,
UpAndDown,
DownAndUp,
Random
} ;
InstrumentFunctionArpeggio( Model * _parent );
@@ -196,11 +201,11 @@ public:
private:
enum ArpModes
enum class ArpMode
{
FreeMode,
SortMode,
SyncMode
Free,
Sort,
Sync
} ;
BoolModel m_arpEnabledModel;

View File

@@ -26,62 +26,33 @@
#define LMMS_INSTRUMENT_PLAY_HANDLE_H
#include "PlayHandle.h"
#include "Instrument.h"
#include "NotePlayHandle.h"
#include "lmms_export.h"
namespace lmms
{
class Instrument;
class InstrumentTrack;
class LMMS_EXPORT InstrumentPlayHandle : public PlayHandle
{
public:
InstrumentPlayHandle( Instrument * instrument, InstrumentTrack* instrumentTrack );
InstrumentPlayHandle(Instrument * instrument, InstrumentTrack* instrumentTrack);
~InstrumentPlayHandle() override = default;
void play( sampleFrame * _working_buffer ) override
{
// ensure that all our nph's have been processed first
ConstNotePlayHandleList nphv = NotePlayHandle::nphsOfInstrumentTrack( m_instrument->instrumentTrack(), true );
bool nphsLeft;
do
{
nphsLeft = false;
for( const NotePlayHandle * constNotePlayHandle : nphv )
{
NotePlayHandle * notePlayHandle = const_cast<NotePlayHandle *>( constNotePlayHandle );
if( notePlayHandle->state() != ThreadableJob::ProcessingState::Done &&
!notePlayHandle->isFinished())
{
nphsLeft = true;
notePlayHandle->process();
}
}
}
while( nphsLeft );
m_instrument->play( _working_buffer );
}
void play(sampleFrame * working_buffer) override;
bool isFinished() const override
{
return false;
}
bool isFromTrack( const Track* _track ) const override
{
return m_instrument->isFromTrack( _track );
}
bool isFromTrack(const Track* track) const override;
private:
Instrument* m_instrument;
} ;
};
} // namespace lmms

View File

@@ -51,13 +51,14 @@ public:
void processAudioBuffer( sampleFrame * _ab, const fpp_t _frames,
NotePlayHandle * _n );
enum Targets
enum class Target
{
Volume,
Cut,
Resonance,
NumTargets
Count
} ;
constexpr static auto NumTargets = static_cast<std::size_t>(Target::Count);
f_cnt_t envFrames( const bool _only_vol = false ) const;
f_cnt_t releaseFrames() const;
@@ -82,7 +83,7 @@ private:
FloatModel m_filterCutModel;
FloatModel m_filterResModel;
static const char *const targetNames[InstrumentSoundShaping::NumTargets][3];
static const char *const targetNames[NumTargets][3];
friend class gui::InstrumentSoundShapingView;

View File

@@ -51,7 +51,7 @@ namespace gui
class InstrumentTrackView;
class InstrumentTrackWindow;
class InstrumentMiscView;
class InstrumentTuningView;
class MidiCCRackView;
} // namespace gui
@@ -315,7 +315,7 @@ private:
friend class gui::InstrumentTrackView;
friend class gui::InstrumentTrackWindow;
friend class NotePlayHandle;
friend class gui::InstrumentMiscView;
friend class gui::InstrumentTuningView;
friend class gui::MidiCCRackView;
} ;

View File

@@ -25,6 +25,7 @@
#ifndef LMMS_GUI_INSTRUMENT_TRACK_VIEW_H
#define LMMS_GUI_INSTRUMENT_TRACK_VIEW_H
#include "MixerLineLcdSpinBox.h"
#include "TrackView.h"
#include "InstrumentTrack.h"
@@ -72,6 +73,7 @@ public:
protected:
void modelChanged() override;
void dragEnterEvent( QDragEnterEvent * _dee ) override;
void dropEvent( QDropEvent * _de ) override;
@@ -97,6 +99,7 @@ private:
// widgets in track-settings-widget
TrackLabelButton * m_tlb;
MixerLineLcdSpinBox* m_mixerChannelNumber;
Knob * m_volumeKnob;
Knob * m_panningKnob;
FadeButton * m_activityIndicator;

View File

@@ -47,7 +47,7 @@ class MixerLineLcdSpinBox;
class InstrumentFunctionArpeggioView;
class InstrumentFunctionNoteStackingView;
class InstrumentMidiIOView;
class InstrumentMiscView;
class InstrumentTuningView;
class InstrumentSoundShapingView;
class InstrumentTrackShapingView;
class InstrumentTrackView;
@@ -154,7 +154,7 @@ private:
InstrumentFunctionArpeggioView* m_arpeggioView;
InstrumentMidiIOView * m_midiView;
EffectRackView * m_effectView;
InstrumentMiscView *m_miscView;
InstrumentTuningView *m_tuningView;
// test-piano at the bottom of every instrument-settings-window

View File

@@ -1,9 +1,9 @@
/*
* InstrumentMiscView.h - widget in instrument-track-window for setting up
* miscellaneous options not covered by other tabs
* InstrumentTuningView.h - widget in instrument-track-window for setting up
* tuning and transposition options
*
* Copyright (c) 2005-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2020 Martin Pavelek <he29.HS/at/gmail.com>
* Copyright (c) 2020-2022 Martin Pavelek <he29.HS/at/gmail.com>
*
* This file is part of LMMS - https://lmms.io
*
@@ -24,11 +24,13 @@
*
*/
#ifndef LMMS_GUI_INSTRUMENT_MISC_VIEW_H
#define LMMS_GUI_INSTRUMENT_MISC_VIEW_H
#ifndef LMMS_GUI_INSTRUMENT_TUNING_VIEW_H
#define LMMS_GUI_INSTRUMENT_TUNING_VIEW_H
#include <QWidget>
class QLabel;
namespace lmms
{
@@ -42,15 +44,17 @@ class GroupBox;
class LedCheckBox;
class InstrumentMiscView : public QWidget
class InstrumentTuningView : public QWidget
{
Q_OBJECT
public:
InstrumentMiscView(InstrumentTrack *it, QWidget *parent);
InstrumentTuningView(InstrumentTrack *it, QWidget *parent);
GroupBox *pitchGroupBox() {return m_pitchGroupBox;}
GroupBox *microtunerGroupBox() {return m_microtunerGroupBox;}
QLabel *microtunerNotSupportedLabel() {return m_microtunerNotSupportedLabel;}
ComboBox *scaleCombo() {return m_scaleCombo;}
ComboBox *keymapCombo() {return m_keymapCombo;}
@@ -60,6 +64,8 @@ private:
GroupBox *m_pitchGroupBox;
GroupBox *m_microtunerGroupBox;
QLabel *m_microtunerNotSupportedLabel;
ComboBox *m_scaleCombo;
ComboBox *m_keymapCombo;
@@ -71,4 +77,4 @@ private:
} // namespace lmms
#endif // LMMS_GUI_INSTRUMENT_MISC_VIEW_H
#endif // LMMS_GUI_INSTRUMENT_TUNING_VIEW_H

View File

@@ -42,9 +42,9 @@ namespace lmms::gui
class SimpleTextFloat;
enum knobTypes
enum class KnobType
{
knobDark_28, knobBright_26, knobSmall_17, knobVintage_32, knobStyled
Dark28, Bright26, Small17, Vintage32, Styled
} ;
@@ -53,7 +53,7 @@ void convertPixmapToGrayScale(QPixmap &pixMap);
class LMMS_EXPORT Knob : public QWidget, public FloatModelView
{
Q_OBJECT
Q_ENUMS( knobTypes )
Q_ENUMS( KnobType )
Q_PROPERTY(float innerRadius READ innerRadius WRITE setInnerRadius)
Q_PROPERTY(float outerRadius READ outerRadius WRITE setOuterRadius)
@@ -75,7 +75,7 @@ class LMMS_EXPORT Knob : public QWidget, public FloatModelView
mapPropertyFromModel(bool,isVolumeKnob,setVolumeKnob,m_volumeKnob);
mapPropertyFromModel(float,volumeRatio,setVolumeRatio,m_volumeRatio);
Q_PROPERTY(knobTypes knobNum READ knobNum WRITE setknobNum)
Q_PROPERTY(KnobType knobNum READ knobNum WRITE setknobNum)
Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
@@ -83,7 +83,7 @@ class LMMS_EXPORT Knob : public QWidget, public FloatModelView
void onKnobNumUpdated(); //!< to be called when you updated @a m_knobNum
public:
Knob( knobTypes _knob_num, QWidget * _parent = nullptr, const QString & _name = QString() );
Knob( KnobType _knob_num, QWidget * _parent = nullptr, const QString & _name = QString() );
Knob( QWidget * _parent = nullptr, const QString & _name = QString() ); //!< default ctor
Knob( const Knob& other ) = delete;
@@ -106,8 +106,8 @@ public:
float outerRadius() const;
void setOuterRadius( float r );
knobTypes knobNum() const;
void setknobNum( knobTypes k );
KnobType knobNum() const;
void setknobNum( KnobType k );
QPointF centerPoint() const;
float centerPointX() const;
@@ -144,6 +144,9 @@ protected:
void wheelEvent( QWheelEvent * _me ) override;
void changeEvent(QEvent * ev) override;
void enterEvent(QEvent *event) override;
void leaveEvent(QEvent *event) override;
virtual float getValue( const QPoint & _p );
private slots:
@@ -160,6 +163,7 @@ private:
float _innerRadius = 1) const;
void drawKnob( QPainter * _p );
void showTextFloat(int msecBeforeDisplay, int msecDisplayTime);
void setPosition( const QPoint & _p );
bool updateAngle();
@@ -206,7 +210,7 @@ private:
QColor m_textColor;
knobTypes m_knobNum;
KnobType m_knobNum;
} ;

View File

@@ -35,16 +35,16 @@ namespace lmms
class LadspaControl;
enum buffer_rate_t {
CHANNEL_IN,
CHANNEL_OUT,
AUDIO_RATE_INPUT,
AUDIO_RATE_OUTPUT,
CONTROL_RATE_INPUT,
CONTROL_RATE_OUTPUT
enum class BufferRate {
ChannelIn,
ChannelOut,
AudioRateInput,
AudioRateOutput,
ControlRateInput,
ControlRateOutput
};
enum buffer_data_t { TOGGLED, ENUM, INTEGER, FLOATING, TIME, NONE };
enum class BufferDataType { Toggled, Enum, Integer, Floating, Time, None };
//! This struct is used to hold port descriptions internally
//! which where received from the ladspa plugin
@@ -54,8 +54,8 @@ struct port_desc_t
ch_cnt_t proc;
uint16_t port_id;
uint16_t control_id;
buffer_rate_t rate;
buffer_data_t data_type;
BufferRate rate;
BufferDataType data_type;
float scale;
LADSPA_Data max;
LADSPA_Data min;

View File

@@ -62,14 +62,14 @@ calls using:
as the plug-in key. */
enum LadspaPluginType
enum class LadspaPluginType
{
SOURCE,
TRANSFER,
VALID,
INVALID,
SINK,
OTHER
Source,
Transfer,
Valid,
Invalid,
Sink,
Other
};
struct LadspaManagerDescription

View File

@@ -38,20 +38,19 @@ class LMMS_EXPORT LedCheckBox : public AutomatableButton
{
Q_OBJECT
public:
enum LedColors
enum class LedColor
{
Yellow,
Green,
Red,
NumColors
Red
} ;
LedCheckBox( const QString & _txt, QWidget * _parent,
const QString & _name = QString(),
LedColors _color = Yellow );
LedColor _color = LedColor::Yellow );
LedCheckBox( QWidget * _parent,
const QString & _name = QString(),
LedColors _color = Yellow );
LedColor _color = LedColor::Yellow );
~LedCheckBox() override;
@@ -75,7 +74,7 @@ private:
QString m_text;
void initUi( LedColors _color ); //!< to be called by ctors
void initUi( LedColor _color ); //!< to be called by ctors
void onTextUpdated(); //!< to be called when you updated @a m_text
} ;

View File

@@ -86,6 +86,7 @@ protected:
sample_t (*m_sampleFunction)( const float );
private:
float m_heldSample;
SampleBuffer * m_userDefSampleBuffer;
protected slots:

93
include/LmmsSemaphore.h Normal file
View File

@@ -0,0 +1,93 @@
/*
* Semaphore.h - Semaphore declaration
*
* Copyright (c) 2022-2022 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
/*
* This code has been copied and adapted from https://github.com/drobilla/jalv
* File src/zix/sem.h
*/
#ifndef LMMS_SEMAPHORE_H
#define LMMS_SEMAPHORE_H
#include "lmmsconfig.h"
#ifdef LMMS_BUILD_APPLE
# include <mach/mach.h>
#elif defined(LMMS_BUILD_WIN32)
# include <windows.h>
#else
# include <semaphore.h>
#endif
#include <system_error>
namespace lmms {
/**
A counting semaphore.
This is an integer that is always positive, and has two main operations:
increment (post) and decrement (wait). If a decrement can not be performed
(i.e. the value is 0) the caller will be blocked until another thread posts
and the operation can succeed.
Semaphores can be created with any starting value, but typically this will
be 0 so the semaphore can be used as a simple signal where each post
corresponds to one wait.
Semaphores are very efficient (much moreso than a mutex/cond pair). In
particular, at least on Linux, post is async-signal-safe, which means it
does not block and will not be interrupted. If you need to signal from
a realtime thread, this is the most appropriate primitive to use.
@note Likely outdated with C++20's std::counting_semaphore
(though we have to check that this will be RT conforming on all platforms)
*/
class Semaphore
{
public:
Semaphore(unsigned initial);
Semaphore(const Semaphore&) = delete;
Semaphore& operator=(const Semaphore&) = delete;
Semaphore(Semaphore&&) = delete;
Semaphore& operator=(Semaphore&&) = delete;
~Semaphore();
void post();
void wait();
bool tryWait();
private:
#ifdef LMMS_BUILD_APPLE
semaphore_t m_sem;
#elif defined(LMMS_BUILD_WIN32)
HANDLE m_sem;
#else
sem_t m_sem;
#endif
};
} // namespace lmms
#endif // LMMS_SEMAPHORE_H

View File

@@ -36,34 +36,6 @@ namespace lmms::gui
class LmmsStyle : public QProxyStyle
{
public:
enum ColorRole
{
AutomationBarFill,
AutomationBarValue,
AutomationSelectedBarFill,
AutomationCrosshair,
PianoRollStepNote,
PianoRollSelectedNote,
PianoRollDefaultNote,
PianoRollFrozenNote,
PianoRollMutedNote,
PianoRollEditHandle,
PianoRollVolumeLevel,
PianoRollPanningLevel,
PianoRollSelectedLevel,
TimelineForecolor,
StandardGraphLine,
StandardGraphHandle,
StandardGraphHandleBorder,
StandardGraphCrosshair,
TextFloatForecolor,
TextFloatFill,
VisualizationLevelLow,
VisualizationLevelMid,
VisualizationLevelPeak,
NumColorRoles
};
LmmsStyle();
~LmmsStyle() override = default;
@@ -88,8 +60,6 @@ public:
private:
QImage colorizeXpm( const char * const * xpm, const QBrush& fill ) const;
void hoverColors( bool sunken, bool hover, bool active, QColor& color, QColor& blend ) const;
QColor m_colors[ LmmsStyle::NumColorRoles ];
};

View File

@@ -51,13 +51,14 @@ public:
std::size_t capacity() const {return m_buffer.maximum_eventual_write_space();}
std::size_t free() const {return m_buffer.write_space();}
void wakeAll() {m_notifier.wakeAll();}
std::size_t write(const sampleFrame *src, std::size_t cnt, bool notify = false)
std::size_t write(const T *src, std::size_t cnt, bool notify = false)
{
std::size_t written = LocklessRingBuffer<T>::m_buffer.write(src, cnt);
// Let all waiting readers know new data are available.
if (notify) {LocklessRingBuffer<T>::m_notifier.wakeAll();}
return written;
}
void mlock() { m_buffer.mlock(); }
protected:
ringbuffer_t<T> m_buffer;

View File

@@ -47,8 +47,14 @@ struct LilvNodesDeleter
void operator()(LilvNodes* n) { lilv_nodes_free(n); }
};
struct LilvScalePointsDeleter
{
void operator()(LilvScalePoints* s) { lilv_scale_points_free(s); }
};
using AutoLilvNode = std::unique_ptr<LilvNode, LilvNodeDeleter>;
using AutoLilvNodes = std::unique_ptr<LilvNodes, LilvNodesDeleter>;
using AutoLilvScalePoints = std::unique_ptr<LilvScalePoints, LilvScalePointsDeleter>;
/**
Return QString from a plugin's node, everything will be freed automatically

View File

@@ -74,7 +74,7 @@ class PluginIssue;
class LMMS_EXPORT Lv2ControlBase : public LinkedModelGroups
{
public:
static Plugin::PluginTypes check(const LilvPlugin* m_plugin,
static Plugin::Type check(const LilvPlugin* m_plugin,
std::vector<PluginIssue> &issues);
void shutdown();

View File

@@ -30,6 +30,7 @@
#ifdef LMMS_HAVE_LV2
#include <map>
#include <string_view>
#include <vector>
#include "Lv2Manager.h"
@@ -78,7 +79,7 @@ private:
//! pointers to m_features, required for lilv_plugin_instantiate
std::vector<const LV2_Feature*> m_featurePointers;
//! features + data, ordered by URI
std::map<const char*, void*, Lv2Manager::CmpStr> m_featureByUri;
std::map<std::string_view, void*> m_featureByUri;
};

View File

@@ -31,6 +31,7 @@
#include <map>
#include <set>
#include <string_view>
#include <lilv/lilv.h>
#include "Lv2Basics.h"
@@ -95,18 +96,18 @@ public:
//! use only for std::map internals
Lv2Info() : m_plugin(nullptr) {}
//! ctor used inside Lv2Manager
Lv2Info(const LilvPlugin* plug, Plugin::PluginTypes type, bool valid) :
Lv2Info(const LilvPlugin* plug, Plugin::Type type, bool valid) :
m_plugin(plug), m_type(type), m_valid(valid) {}
Lv2Info(Lv2Info&& other) = default;
Lv2Info& operator=(Lv2Info&& other) = default;
const LilvPlugin* plugin() const { return m_plugin; }
Plugin::PluginTypes type() const { return m_type; }
Plugin::Type type() const { return m_type; }
bool isValid() const { return m_valid; }
private:
const LilvPlugin* m_plugin;
Plugin::PluginTypes m_type;
Plugin::Type m_type;
bool m_valid = false;
};
@@ -120,15 +121,9 @@ public:
Iterator begin() { return m_lv2InfoMap.begin(); }
Iterator end() { return m_lv2InfoMap.end(); }
//! strcmp based key comparator for std::set and std::map
struct CmpStr
{
bool operator()(char const *a, char const *b) const;
};
UridMap& uridMap() { return m_uridMap; }
const Lv2UridCache& uridCache() const { return m_uridCache; }
const std::set<const char*, CmpStr>& supportedFeatureURIs() const
const std::set<std::string_view>& supportedFeatureURIs() const
{
return m_supportedFeatureURIs;
}
@@ -136,17 +131,21 @@ public:
AutoLilvNodes findNodes(const LilvNode *subject,
const LilvNode *predicate, const LilvNode *object);
static const std::set<const char*, Lv2Manager::CmpStr>& getPluginBlacklist()
static const std::set<std::string_view>& getPluginBlacklist()
{
return pluginBlacklist;
}
static const std::set<std::string_view>& getPluginBlacklistBuffersizeLessThan32()
{
return pluginBlacklistBuffersizeLessThan32;
}
private:
// general data
bool m_debug; //!< if set, debug output will be printed
LilvWorld* m_world;
Lv2InfoMap m_lv2InfoMap;
std::set<const char*, CmpStr> m_supportedFeatureURIs;
std::set<std::string_view> m_supportedFeatureURIs;
// feature data that are common for all Lv2Proc
UridMap m_uridMap;
@@ -155,7 +154,8 @@ private:
Lv2UridCache m_uridCache;
// static
static const std::set<const char*, Lv2Manager::CmpStr> pluginBlacklist;
static const std::set<std::string_view>
pluginBlacklist, pluginBlacklistBuffersizeLessThan32;
// functions
bool isSubclassOf(const LilvPluginClass *clvss, const char *uriStr);

View File

@@ -33,6 +33,7 @@
#include <memory>
#include <vector>
#include "Flags.h"
#include "lmms_basics.h"
#include "PluginIssue.h"
@@ -210,12 +211,12 @@ private:
struct AtomSeq : public VisitablePort<AtomSeq, PortBase>
{
enum FlagType
enum class FlagType
{
None = 0,
Midi = 1
};
unsigned flags = FlagType::None;
Flags<FlagType> flags = FlagType::None;
struct Lv2EvbufDeleter
{

View File

@@ -1,7 +1,7 @@
/*
* Lv2Proc.h - Lv2 processor class
*
* Copyright (c) 2019-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
* Copyright (c) 2019-2022 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
*
* This file is part of LMMS - https://lmms.io
*
@@ -31,11 +31,14 @@
#include <lilv/lilv.h>
#include <memory>
#include <optional>
#include "LinkedModelGroups.h"
#include "LmmsSemaphore.h"
#include "Lv2Basics.h"
#include "Lv2Features.h"
#include "Lv2Options.h"
#include "LinkedModelGroups.h"
#include "Lv2Worker.h"
#include "Plugin.h"
#include "../src/3rdparty/ringbuffer/include/ringbuffer/ringbuffer.h"
#include "TimePos.h"
@@ -64,7 +67,7 @@ namespace Lv2Ports
class Lv2Proc : public LinkedModelGroup
{
public:
static Plugin::PluginTypes check(const LilvPlugin* plugin,
static Plugin::Type check(const LilvPlugin* plugin,
std::vector<PluginIssue> &issues);
/*
@@ -174,8 +177,14 @@ private:
const LilvPlugin* m_plugin;
LilvInstance* m_instance;
Lv2Features m_features;
// options
Lv2Options m_options;
// worker
std::optional<Lv2Worker> m_worker;
Semaphore m_workLock; // this must be shared by different workers
// full list of ports
std::vector<std::unique_ptr<Lv2Ports::PortBase>> m_ports;
// quick reference to specific, unique ports

View File

@@ -47,7 +47,7 @@ private:
static QString pluginName(const LilvPlugin *plug);
public:
Lv2SubPluginFeatures(Plugin::PluginTypes type);
Lv2SubPluginFeatures(Plugin::Type type);
void fillDescriptionWidget(
QWidget *parent, const Key *k) const override;

View File

@@ -55,8 +55,6 @@ class UridMap
LV2_URID_Map m_mapFeature;
LV2_URID_Unmap m_unmapFeature;
LV2_URID m_lastUrid = 0;
public:
//! constructor; will set up the features
UridMap();

View File

@@ -56,7 +56,7 @@ class Lv2ViewProc : public LinkedModelGroupView
{
public:
//! @param colNum numbers of columns for the controls
Lv2ViewProc(QWidget *parent, Lv2Proc *ctrlBase, int colNum);
Lv2ViewProc(QWidget *parent, Lv2Proc *proc, int colNum);
~Lv2ViewProc() override = default;
private:

93
include/Lv2Worker.h Normal file
View File

@@ -0,0 +1,93 @@
/*
* Lv2Worker.h - Lv2Worker class
*
* Copyright (c) 2022-2022 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef LV2WORKER_H
#define LV2WORKER_H
#include "lmmsconfig.h"
#ifdef LMMS_HAVE_LV2
#include <lilv/lilv.h>
#include <lv2/lv2plug.in/ns/ext/worker/worker.h>
#include <thread>
#include <vector>
#include "LocklessRingBuffer.h"
#include "LmmsSemaphore.h"
namespace lmms
{
/**
Worker container
*/
class Lv2Worker
{
public:
// CTOR/DTOR/feature access
Lv2Worker(const LV2_Worker_Interface* iface, Semaphore* common_work_lock, bool threaded);
~Lv2Worker();
void setHandle(LV2_Handle handle) { m_handle = handle; }
LV2_Worker_Schedule* feature() { return &m_scheduleFeature; }
// public API
void emitResponses();
void notifyPluginThatRunFinished()
{
if(m_iface->end_run) { m_iface->end_run(m_scheduleFeature.handle); }
}
// to be called only by static functions
LV2_Worker_Status scheduleWork(uint32_t size, const void* data);
LV2_Worker_Status respond(uint32_t size, const void* data);
private:
// functions
void workerFunc();
std::size_t bufferSize() const; //!< size of internal buffers
// parameters
const LV2_Worker_Interface* m_iface;
bool m_threaded;
LV2_Handle m_handle;
LV2_Worker_Schedule m_scheduleFeature;
// threading/synchronization
std::thread m_thread;
std::vector<char> m_response; //!< buffer where single requests from m_requests are unpacked
LocklessRingBuffer<char> m_requests, m_responses; //!< ringbuffer to queue multiple requests
LocklessRingBufferReader<char> m_requestsReader, m_responsesReader;
std::atomic<bool> m_exit = false; //!< Whether the worker function should keep looping
Semaphore m_sem;
Semaphore* m_workLock;
};
} // namespace lmms
#endif // LMMS_HAVE_LV2
#endif // LV2WORKER_H

View File

@@ -113,7 +113,7 @@ public:
return m_autoSaveTimer.interval();
}
enum SessionState
enum class SessionState
{
Normal,
Recover

View File

@@ -26,7 +26,7 @@
#define LMMS_MIDI_CLIENT_H
#include <QStringList>
#include <QVector>
#include <vector>
#include "MidiEvent.h"
@@ -111,7 +111,7 @@ public:
static MidiClient * openMidiClient();
protected:
QVector<MidiPort *> m_midiPorts;
std::vector<MidiPort *> m_midiPorts;
} ;

View File

@@ -46,7 +46,7 @@ class LMMS_EXPORT MidiClip : public Clip
{
Q_OBJECT
public:
enum MidiClipTypes
enum class Type
{
BeatClip,
MelodyClip
@@ -79,10 +79,10 @@ public:
void setStep( int step, bool enabled );
// Split the list of notes on the given position
void splitNotes(NoteVector notes, TimePos pos);
void splitNotes(const NoteVector& notes, TimePos pos);
// clip-type stuff
inline MidiClipTypes type() const
inline Type type() const
{
return m_clipType;
}
@@ -129,14 +129,14 @@ protected slots:
private:
TimePos beatClipLength() const;
void setType( MidiClipTypes _new_clip_type );
void setType( Type _new_clip_type );
void checkType();
void resizeToFirstTrack();
InstrumentTrack * m_instrumentTrack;
MidiClipTypes m_clipType;
Type m_clipType;
// data-stuff
NoteVector m_notes;

View File

@@ -48,6 +48,7 @@ class MidiController : public Controller, public MidiEventProcessor
{
Q_OBJECT
public:
static constexpr int NONE = -1;
MidiController( Model * _parent );
~MidiController() override = default;

View File

@@ -212,7 +212,7 @@ private:
int32_t m_sysExDataLen; // len of m_sysExData
} m_data;
const char* m_sysExData;
[[maybe_unused]] const char* m_sysExData;
const void* m_sourcePort;
// Stores the source of the MidiEvent: Internal or External (hardware controllers).

View File

@@ -69,20 +69,19 @@ class MidiPort : public Model, public SerializingObject
public:
using Map = QMap<QString, bool>;
enum Modes
enum class Mode
{
Disabled, // don't route any MIDI-events (default)
Input, // from MIDI-client to MIDI-event-processor
Output, // from MIDI-event-processor to MIDI-client
Duplex // both directions
} ;
using Mode = Modes;
MidiPort( const QString& name,
MidiClient* client,
MidiEventProcessor* eventProcessor,
Model* parent = nullptr,
Mode mode = Disabled );
Mode mode = Mode::Disabled );
~MidiPort() override;
void setName( const QString& name );
@@ -96,12 +95,12 @@ public:
bool isInputEnabled() const
{
return mode() == Input || mode() == Duplex;
return mode() == Mode::Input || mode() == Mode::Duplex;
}
bool isOutputEnabled() const
{
return mode() == Output || mode() == Duplex;
return mode() == Mode::Output || mode() == Mode::Duplex;
}
int realOutputChannel() const

View File

@@ -40,7 +40,7 @@ class MidiPortMenu : public QMenu, public ModelView
{
Q_OBJECT
public:
MidiPortMenu( MidiPort::Modes _mode );
MidiPortMenu( MidiPort::Mode _mode );
~MidiPortMenu() override = default;
@@ -55,7 +55,7 @@ protected slots:
private:
void modelChanged() override;
MidiPort::Modes m_mode;
MidiPort::Mode m_mode;
} ;

View File

@@ -39,7 +39,7 @@ namespace lmms
class MixerRoute;
using MixerRouteVector = QVector<MixerRoute*>;
using MixerRouteVector = std::vector<MixerRoute*>;
class MixerChannel : public ThreadableJob
{
@@ -219,7 +219,7 @@ public:
private:
// the mixer channels in the mixer. index 0 is always master.
QVector<MixerChannel *> m_mixerChannels;
std::vector<MixerChannel*> m_mixerChannels;
// make sure we have at least num channels
void allocateChannelsTo(int num);

View File

@@ -27,7 +27,7 @@
#define LMMS_NOTE_H
#include <optional>
#include <QVector>
#include <vector>
#include "volume.h"
#include "panning.h"
@@ -42,50 +42,56 @@ namespace lmms
class DetuningHelper;
enum Keys
enum class Key : int
{
Key_C = 0,
Key_CIS = 1, Key_DES = 1,
Key_D = 2,
Key_DIS = 3, Key_ES = 3,
Key_E = 4, Key_FES = 4,
Key_F = 5,
Key_FIS = 6, Key_GES = 6,
Key_G = 7,
Key_GIS = 8, Key_AS = 8,
Key_A = 9,
Key_AIS = 10, Key_B = 10,
Key_H = 11
C = 0,
Cis = 1, Des = 1,
D = 2,
Dis = 3, Es = 3,
E = 4, Fes = 4,
F = 5,
Fis = 6, Ges = 6,
G = 7,
Gis = 8, As = 8,
A = 9,
Ais = 10, B = 10,
H = 11
} ;
enum Octaves
enum class Octave : int
{
Octave_m1, // MIDI standard starts at C-1
Octave_0,
Octave_1,
Octave_2,
Octave_3,
Octave_4, DefaultOctave = Octave_4,
Octave_4,
Octave_5,
Octave_6,
Octave_7,
Octave_8,
Octave_9, // incomplete octave, MIDI only goes up to G9
NumOctaves
};
const int FirstOctave = -1;
const int KeysPerOctave = 12;
const int DefaultKey = DefaultOctave * KeysPerOctave + Key_A;
constexpr inline auto operator+(Octave octave, Key key) -> int
{
return static_cast<int>(octave) * KeysPerOctave + static_cast<int>(key);
}
constexpr auto DefaultOctave = Octave::Octave_4;
const int DefaultKey = DefaultOctave + Key::A;
//! Number of physical keys, limited to MIDI range (valid for both MIDI 1.0 and 2.0)
const int NumKeys = 128;
const int DefaultMiddleKey = Octave_4 * KeysPerOctave + Key_C;
const int DefaultBaseKey = Octave_4 * KeysPerOctave + Key_A;
const int DefaultMiddleKey = Octave::Octave_4 + Key::C;
const int DefaultBaseKey = Octave::Octave_4 + Key::A;
const float DefaultBaseFreq = 440.f;
const float MaxDetuning = 4 * 12.0f;
const float MaxDetuning = 5 * 12.0f;
@@ -198,7 +204,7 @@ public:
int midiVelocity( int midiBaseVelocity ) const
{
return qMin( MidiMaxVelocity, getVolume() * midiBaseVelocity / DefaultVolume );
return std::min(MidiMaxVelocity, getVolume() * midiBaseVelocity / DefaultVolume);
}
inline panning_t getPanning() const
@@ -249,7 +255,7 @@ private:
DetuningHelper * m_detuning;
};
using NoteVector = QVector<Note*>;
using NoteVector = std::vector<Note*>;
struct NoteBounds
{

View File

@@ -56,15 +56,13 @@ public:
fpp_t m_fadeInLength;
// specifies origin of NotePlayHandle
enum Origins
enum class Origin
{
OriginMidiClip, /*! playback of a note from a MIDI clip */
OriginMidiInput, /*! playback of a MIDI note input event */
OriginNoteStacking, /*! created by note stacking instrument function */
OriginArpeggio, /*! created by arpeggio instrument function */
OriginCount
MidiClip, /*! playback of a note from a MIDI clip */
MidiInput, /*! playback of a MIDI note input event */
NoteStacking, /*! created by note stacking instrument function */
Arpeggio, /*! created by arpeggio instrument function */
};
using Origin = Origins;
NotePlayHandle( InstrumentTrack* instrumentTrack,
const f_cnt_t offset,
@@ -72,7 +70,7 @@ public:
const Note& noteToPlay,
NotePlayHandle* parent = nullptr,
int midiEventChannel = -1,
Origin origin = OriginMidiClip );
Origin origin = Origin::MidiClip );
~NotePlayHandle() override;
void * operator new ( size_t size, void * p )
@@ -110,6 +108,9 @@ public:
return m_unpitchedFrequency;
}
//! Get the current per-note detuning for this note
float currentDetuning() const { return m_baseDetuning->value(); }
/*! Renders one chunk using the attached instrument into the buffer */
void play( sampleFrame* buffer ) override;
@@ -247,7 +248,7 @@ public:
}
/*! Process note detuning automation */
void processTimePos( const TimePos& time );
void processTimePos(const TimePos& time, float pitchValue, bool isRecording);
/*! Updates total length (m_frames) depending on a new tempo */
void resize( const bpm_t newTempo );
@@ -349,7 +350,7 @@ public:
const Note& noteToPlay,
NotePlayHandle* parent = nullptr,
int midiEventChannel = -1,
NotePlayHandle::Origin origin = NotePlayHandle::OriginMidiClip );
NotePlayHandle::Origin origin = NotePlayHandle::Origin::MidiClip );
static void release( NotePlayHandle * nph );
static void extend( int i );
static void free();

View File

@@ -48,31 +48,34 @@ class LMMS_EXPORT Oscillator
{
MM_OPERATORS
public:
enum WaveShapes
enum class WaveShape
{
SineWave,
TriangleWave,
SawWave,
SquareWave,
MoogSawWave,
ExponentialWave,
Sine,
Triangle,
Saw,
Square,
MoogSaw,
Exponential,
WhiteNoise,
UserDefinedWave,
NumWaveShapes, //!< Number of all available wave shapes
FirstWaveShapeTable = TriangleWave, //!< First wave shape that has a pre-generated table
NumWaveShapeTables = WhiteNoise - FirstWaveShapeTable, //!< Number of band-limited wave shapes to be generated
UserDefined,
Count //!< Number of all available wave shapes
};
constexpr static auto NumWaveShapes = static_cast<std::size_t>(WaveShape::Count);
//! First wave shape that has a pre-generated table
constexpr static auto FirstWaveShapeTable = static_cast<std::size_t>(WaveShape::Triangle);
//! Number of band-limited wave shapes to be generated
constexpr static auto NumWaveShapeTables = static_cast<std::size_t>(WaveShape::WhiteNoise) - FirstWaveShapeTable;
enum ModulationAlgos
enum class ModulationAlgo
{
PhaseModulation,
AmplitudeModulation,
SignalMix,
SynchronizedBySubOsc,
FrequencyModulation,
NumModulationAlgos
Count
} ;
constexpr static auto NumModulationAlgos = static_cast<std::size_t>(ModulationAlgo::Count);
Oscillator( const IntModel *wave_shape_model,
const IntModel *mod_algo_model,
@@ -251,7 +254,7 @@ private:
bool m_isModulator;
/* Multiband WaveTable */
static sample_t s_waveTables[WaveShapes::NumWaveShapeTables][OscillatorConstants::WAVE_TABLES_PER_WAVEFORM_COUNT][OscillatorConstants::WAVETABLE_LENGTH];
static sample_t s_waveTables[NumWaveShapeTables][OscillatorConstants::WAVE_TABLES_PER_WAVEFORM_COUNT][OscillatorConstants::WAVETABLE_LENGTH];
static fftwf_plan s_fftPlan;
static fftwf_plan s_ifftPlan;
static fftwf_complex * s_specBuf;
@@ -284,26 +287,26 @@ private:
const ch_cnt_t _chnl );
inline bool syncOk( float _osc_coeff );
template<WaveShapes W>
template<WaveShape W>
void updateNoSub( sampleFrame * _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShapes W>
template<WaveShape W>
void updatePM( sampleFrame * _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShapes W>
template<WaveShape W>
void updateAM( sampleFrame * _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShapes W>
template<WaveShape W>
void updateMix( sampleFrame * _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShapes W>
template<WaveShape W>
void updateSync( sampleFrame * _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShapes W>
template<WaveShape W>
void updateFM( sampleFrame * _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShapes W>
template<WaveShape W>
inline sample_t getSample( const float _sample );
inline void recalcPhase();

View File

@@ -35,19 +35,18 @@ namespace lmms
class OutputSettings
{
public:
enum BitDepth
enum class BitDepth
{
Depth_16Bit,
Depth_24Bit,
Depth_32Bit,
NumDepths
Depth16Bit,
Depth24Bit,
Depth32Bit
};
enum StereoMode
enum class StereoMode
{
StereoMode_Stereo,
StereoMode_JointStereo,
StereoMode_Mono
Stereo,
JointStereo,
Mono
};
class BitRateSettings
@@ -85,7 +84,7 @@ public:
OutputSettings( sample_rate_t sampleRate,
BitRateSettings const & bitRateSettings,
BitDepth bitDepth ) :
OutputSettings(sampleRate, bitRateSettings, bitDepth, StereoMode_Stereo )
OutputSettings(sampleRate, bitRateSettings, bitDepth, StereoMode::Stereo )
{
}

View File

@@ -36,7 +36,7 @@ namespace lmms
class PeakControllerEffect;
using PeakControllerEffectVector = QVector<PeakControllerEffect*>;
using PeakControllerEffectVector = std::vector<PeakControllerEffect*>;
class LMMS_EXPORT PeakController : public Controller
{

View File

@@ -38,10 +38,10 @@ class MidiEventProcessor;
class Piano final : public Model
{
public:
enum KeyTypes
enum class KeyType
{
WhiteKey,
BlackKey
White,
Black
} ;
Piano(InstrumentTrack* track);

View File

@@ -27,9 +27,10 @@
#ifndef LMMS_GUI_PIANO_ROLL_H
#define LMMS_GUI_PIANO_ROLL_H
#include <QVector>
#include <QWidget>
#include <vector>
#include "Editor.h"
#include "ComboBoxModel.h"
#include "SerializingObject.h"
@@ -103,13 +104,13 @@ class PianoRoll : public QWidget
Q_PROPERTY(QBrush blackKeyActiveBackground MEMBER m_blackKeyActiveBackground)
Q_PROPERTY(QBrush blackKeyDisabledBackground MEMBER m_blackKeyDisabledBackground)
public:
enum EditModes
enum class EditMode
{
ModeDraw,
ModeErase,
ModeSelect,
ModeEditDetuning,
ModeEditKnife
Draw,
Erase,
Select,
Detuning,
Knife
};
/*! \brief Resets settings to default when e.g. creating a new project */
@@ -152,16 +153,26 @@ public:
int trackOctaveSize() const;
Song::PlayModes desiredPlayModeForAccompany() const;
Song::PlayMode desiredPlayModeForAccompany() const;
int quantization() const;
protected:
enum QuantizeActions
enum class QuantizeAction
{
QuantizeBoth,
QuantizePos,
QuantizeLength
Both,
Pos,
Length
};
enum class SemiToneMarkerAction
{
UnmarkAll,
MarkCurrentSemiTone,
MarkAllOctaveSemiTones,
MarkCurrentScale,
MarkCurrentChord,
CopyAllNotesOnKey
};
void keyPressEvent( QKeyEvent * ke ) override;
@@ -220,12 +231,12 @@ protected slots:
void quantizeChanged();
void noteLengthChanged();
void keyChanged();
void quantizeNotes(lmms::gui::PianoRoll::QuantizeActions mode = QuantizeBoth);
void quantizeNotes(QuantizeAction mode = QuantizeAction::Both);
void updateSemiToneMarkerMenu();
void changeNoteEditMode( int i );
void markSemiTone(int i, bool fromMenu = true);
void markSemiTone(SemiToneMarkerAction i, bool fromMenu = true);
void hideMidiClip( lmms::MidiClip* clip );
@@ -247,51 +258,41 @@ signals:
private:
enum Actions
enum class Action
{
ActionNone,
ActionMoveNote,
ActionResizeNote,
ActionSelectNotes,
ActionChangeNoteProperty,
ActionResizeNoteEditArea,
ActionKnife
None,
MoveNote,
ResizeNote,
SelectNotes,
ChangeNoteProperty,
ResizeNoteEditArea,
Knife
};
enum NoteEditMode
enum class NoteEditMode
{
NoteEditVolume,
NoteEditPanning,
NoteEditCount // make sure this one is always last
Volume,
Panning,
Count // make sure this one is always last
};
enum SemiToneMarkerAction
enum class KeyType
{
stmaUnmarkAll,
stmaMarkCurrentSemiTone,
stmaMarkAllOctaveSemiTones,
stmaMarkCurrentScale,
stmaMarkCurrentChord,
stmaCopyAllNotesOnKey
WhiteSmall,
WhiteBig,
Black
};
enum PianoRollKeyTypes
enum class GridMode
{
PR_WHITE_KEY_SMALL,
PR_WHITE_KEY_BIG,
PR_BLACK_KEY
};
enum GridMode
{
gridNudge,
gridSnap
// gridFree
Nudge,
Snap
// Free
};
PositionLine * m_positionLine;
QVector<QString> m_nemStr; // gui names of each edit mode
std::vector<QString> m_nemStr; // gui names of each edit mode
QMenu * m_noteEditMenu; // when you right click below the key area
QList<int> m_markedSemiTones;
@@ -307,9 +308,9 @@ private:
TimePos newNoteLen() const;
void shiftPos(int amount);
void shiftPos(NoteVector notes, int amount);
void shiftPos(const NoteVector& notes, int amount);
void shiftSemiTone(int amount);
void shiftSemiTone(NoteVector notes, int amount);
void shiftSemiTone(const NoteVector& notes, int amount);
bool isSelection() const;
int selectionCount() const;
void testPlayNote( Note * n );
@@ -345,7 +346,7 @@ private:
static QPixmap * s_toolOpen;
static QPixmap* s_toolKnife;
static std::array<PianoRollKeyTypes, 12> prKeyOrder;
static std::array<KeyType, 12> prKeyOrder;
static SimpleTextFloat * s_textFloat;
@@ -358,8 +359,8 @@ private:
ComboBoxModel m_chordModel;
ComboBoxModel m_snapModel;
static const QVector<float> m_zoomLevels;
static const QVector<float> m_zoomYLevels;
static const std::vector<float> m_zoomLevels;
static const std::vector<float> m_zoomYLevels;
MidiClip* m_midiClip;
NoteVector m_ghostNotes;
@@ -377,7 +378,7 @@ private:
QList<Note> m_recordingNotes;
Note * m_currentNote;
Actions m_action;
Action m_action;
NoteEditMode m_noteEditMode;
GridMode m_gridMode;
@@ -428,9 +429,9 @@ private:
int m_startKey; // first key when drawing
int m_lastKey;
EditModes m_editMode;
EditModes m_ctrlMode; // mode they were in before they hit ctrl
EditModes m_knifeMode; // mode they where in before entering knife mode
EditMode m_editMode;
EditMode m_ctrlMode; // mode they were in before they hit ctrl
EditMode m_knifeMode; // mode they where in before entering knife mode
bool m_mouseDownRight; //true if right click is being held down

View File

@@ -30,7 +30,7 @@
#include "lmms_export.h"
#include "Flags.h"
#include "ThreadableJob.h"
#include "lmms_basics.h"
@@ -45,19 +45,16 @@ class AudioPort;
class LMMS_EXPORT PlayHandle : public ThreadableJob
{
public:
enum Types
enum class Type
{
TypeNotePlayHandle = 0x01,
TypeInstrumentPlayHandle = 0x02,
TypeSamplePlayHandle = 0x04,
TypePresetPreviewHandle = 0x08
NotePlayHandle = 0x01,
InstrumentPlayHandle = 0x02,
SamplePlayHandle = 0x04,
PresetPreviewHandle = 0x08
} ;
using Type = Types;
using Types = Flags<Type>;
enum
{
MaxNumber = 1024
} ;
constexpr static std::size_t MaxNumber = 1024;
PlayHandle( const Type type, f_cnt_t offset = 0 );
@@ -164,6 +161,8 @@ private:
using PlayHandleList = QList<PlayHandle*>;
using ConstPlayHandleList = QList<const PlayHandle*>;
LMMS_DECLARE_OPERATORS_FOR_FLAGS(PlayHandle::Type)
} // namespace lmms
#endif // LMMS_PLAY_HANDLE_H

View File

@@ -74,7 +74,7 @@ class LMMS_EXPORT Plugin : public Model, public JournallingObject
MM_OPERATORS
Q_OBJECT
public:
enum PluginTypes
enum class Type
{
Instrument, // instrument being used in channel-track
Effect, // effect-plugin for effect-board
@@ -97,7 +97,7 @@ public:
const char * description;
const char * author;
int version;
PluginTypes type;
Type type;
const PixmapLoader * logo;
const char * supportedFileTypes; //!< csv list of extensions
@@ -181,7 +181,7 @@ public:
using KeyList = QList<Key>;
SubPluginFeatures( Plugin::PluginTypes type ) :
SubPluginFeatures( Plugin::Type type ) :
m_type( type )
{
}
@@ -227,7 +227,7 @@ public:
}
protected:
const Plugin::PluginTypes m_type;
const Plugin::Type m_type;
} ;
SubPluginFeatures * subPluginFeatures;
@@ -250,7 +250,7 @@ public:
const PixmapLoader *logo() const;
//! Return plugin type
inline PluginTypes type() const
inline Type type() const
{
return m_descriptor->type;
}

View File

@@ -27,12 +27,12 @@
#include <memory>
#include <string>
#include <vector>
#include <QFileInfo>
#include <QHash>
#include <QList>
#include <QString>
#include <QVector>
#include "lmms_export.h"
#include "Plugin.h"
@@ -55,7 +55,7 @@ public:
bool isNull() const {return ! library;}
};
using PluginInfoList = QList<PluginInfo>;
using DescriptorMap = QMultiMap<Plugin::PluginTypes, Plugin::Descriptor*>;
using DescriptorMap = QMultiMap<Plugin::Type, Plugin::Descriptor*>;
PluginFactory();
~PluginFactory() = default;
@@ -68,7 +68,7 @@ public:
/// Returns a list of all found plugins' descriptors.
Plugin::DescriptorList descriptors() const;
Plugin::DescriptorList descriptors(Plugin::PluginTypes type) const;
Plugin::DescriptorList descriptors(Plugin::Type type) const;
struct PluginInfoAndKey
{
@@ -99,7 +99,7 @@ private:
PluginInfoList m_pluginInfos;
QMap<QString, PluginInfoAndKey> m_pluginByExt;
QVector<std::string> m_garbage; //!< cleaned up at destruction
std::vector<std::string> m_garbage; //!< cleaned up at destruction
QHash<QString, QString> m_errors;

View File

@@ -33,32 +33,32 @@ namespace lmms
//! Types of issues that can cause LMMS to not load a plugin
//! LMMS Plugins should use this to indicate errors
enum PluginIssueType
enum class PluginIssueType
{
// port flow & type
unknownPortFlow,
unknownPortType,
UnknownPortFlow,
UnknownPortType,
// channel count
tooManyInputChannels,
tooManyOutputChannels,
tooManyMidiInputChannels,
tooManyMidiOutputChannels,
noOutputChannel,
TooManyInputChannels,
TooManyOutputChannels,
TooManyMidiInputChannels,
TooManyMidiOutputChannels,
NoOutputChannel,
// port metadata
portHasNoDef,
portHasNoMin,
portHasNoMax,
minGreaterMax,
defaultValueNotInRange,
logScaleMinMissing,
logScaleMaxMissing,
logScaleMinMaxDifferentSigns,
PortHasNoDef,
PortHasNoMin,
PortHasNoMax,
MinGreaterMax,
DefaultValueNotInRange,
LogScaleMinMissing,
LogScaleMaxMissing,
LogScaleMinMaxDifferentSigns,
// features
featureNotSupported, //!< plugin requires functionality LMMS can't offer
FeatureNotSupported, //!< plugin requires functionality LMMS can't offer
// misc
badPortType, //!< port type not supported
blacklisted,
noIssue
BadPortType, //!< port type not supported
Blacklisted,
NoIssue
};
//! Issue type bundled with informational string

View File

@@ -104,7 +104,7 @@ private:
struct CheckPoint
{
CheckPoint( jo_id_t initID = 0, const DataFile& initData = DataFile( DataFile::JournalData ) ) :
CheckPoint( jo_id_t initID = 0, const DataFile& initData = DataFile( DataFile::Type::JournalData ) ) :
joID( initID ),
data( initData )
{

View File

@@ -40,20 +40,21 @@ class LMMS_EXPORT ProjectRenderer : public QThread
{
Q_OBJECT
public:
enum ExportFileFormats: int
enum class ExportFileFormat : int
{
WaveFile,
FlacFile,
OggFile,
MP3File,
NumFileFormats
Wave,
Flac,
Ogg,
MP3,
Count
} ;
constexpr static auto NumFileFormats = static_cast<std::size_t>(ExportFileFormat::Count);
struct FileEncodeDevice
{
bool isAvailable() const { return m_getDevInst != nullptr; }
ExportFileFormats m_fileFormat;
ExportFileFormat m_fileFormat;
const char * m_description;
const char * m_extension;
AudioFileDeviceInstantiaton m_getDevInst;
@@ -62,7 +63,7 @@ public:
ProjectRenderer( const AudioEngine::qualitySettings & _qs,
const OutputSettings & _os,
ExportFileFormats _file_format,
ExportFileFormat _file_format,
const QString & _out_file );
~ProjectRenderer() override = default;
@@ -71,10 +72,10 @@ public:
return m_fileDev != nullptr;
}
static ExportFileFormats getFileFormatFromExtension(
static ExportFileFormat getFileFormatFromExtension(
const QString & _ext );
static QString getFileExtensionFromFormat( ExportFileFormats fmt );
static QString getFileExtensionFromFormat( ExportFileFormat fmt );
static const std::array<FileEncodeDevice, 5> fileEncodeDevices;

View File

@@ -42,11 +42,11 @@ namespace lmms
class ProjectVersion
{
public:
enum CompareType : int { None = 0, Major=1, Minor=2, Release=3, Stage=4, Build=5, All = std::numeric_limits<int>::max() };
enum class CompareType : int { None = 0, Major=1, Minor=2, Release=3, Stage=4, Build=5, All = std::numeric_limits<int>::max() };
ProjectVersion(QString version, CompareType c = All);
ProjectVersion(const char * version, CompareType c = All);
ProjectVersion(QString version, CompareType c = CompareType::All);
ProjectVersion(const char * version, CompareType c = CompareType::All);
const QString& getVersion() const { return m_version; }
int getMajor() const { return m_major; }

View File

@@ -43,7 +43,7 @@ public:
RenderManager(
const AudioEngine::qualitySettings & qualitySettings,
const OutputSettings & outputSettings,
ProjectRenderer::ExportFileFormats fmt,
ProjectRenderer::ExportFileFormat fmt,
QString outputPath);
~RenderManager() override;
@@ -73,13 +73,13 @@ private:
const AudioEngine::qualitySettings m_qualitySettings;
const AudioEngine::qualitySettings m_oldQualitySettings;
const OutputSettings m_outputSettings;
ProjectRenderer::ExportFileFormats m_format;
ProjectRenderer::ExportFileFormat m_format;
QString m_outputPath;
std::unique_ptr<ProjectRenderer> m_activeRenderer;
QVector<Track*> m_tracksToRender;
QVector<Track*> m_unmuted;
std::vector<Track*> m_tracksToRender;
std::vector<Track*> m_unmuted;
} ;

View File

@@ -57,10 +57,10 @@ class LMMS_EXPORT SampleBuffer : public QObject, public sharedObject
Q_OBJECT
MM_OPERATORS
public:
enum LoopMode {
LoopOff = 0,
LoopOn,
LoopPingPong
enum class LoopMode {
Off = 0,
On,
PingPong
};
class LMMS_EXPORT handleState
{
@@ -125,7 +125,7 @@ public:
handleState * state,
const fpp_t frames,
const float freq,
const LoopMode loopMode = LoopOff
const LoopMode loopMode = LoopMode::Off
);
void visualize(

View File

@@ -77,7 +77,7 @@ public:
public slots:
void setSampleBuffer( lmms::SampleBuffer* sb );
void setSampleFile( const QString & _sf );
void setSampleFile( const QString & sf );
void updateLength();
void toggleRecord();
void playbackPositionChanged();

View File

@@ -40,7 +40,7 @@ class Track;
class AudioPort;
class SamplePlayHandle : public PlayHandle
class LMMS_EXPORT SamplePlayHandle : public PlayHandle
{
public:
SamplePlayHandle( SampleBuffer* sampleBuffer , bool ownAudioPort = true );

View File

@@ -26,6 +26,7 @@
#define LMMS_GUI_SAMPLE_TRACK_VIEW_H
#include "MixerLineLcdSpinBox.h"
#include "TrackView.h"
namespace lmms
@@ -90,6 +91,7 @@ private slots:
private:
SampleTrackWindow * m_window;
MixerLineLcdSpinBox* m_mixerChannelNumber;
Knob * m_volumeKnob;
Knob * m_panningKnob;
FadeButton * m_activityIndicator;

View File

@@ -53,7 +53,7 @@ class SetupDialog : public QDialog
Q_OBJECT
public:
enum ConfigTabs
enum class ConfigTab
{
GeneralSettings,
PerformanceSettings,
@@ -62,7 +62,7 @@ public:
PathsSettings
};
SetupDialog(ConfigTabs tab_to_open = GeneralSettings);
SetupDialog(ConfigTab tab_to_open = ConfigTab::GeneralSettings);
~SetupDialog() override;
@@ -102,6 +102,7 @@ private slots:
// Audio settings widget.
void audioInterfaceChanged(const QString & driver);
void toggleHQAudioDev(bool enabled);
void updateBufferSizeWarning(int value);
void setBufferSize(int value);
void resetBufferSize();
@@ -179,6 +180,7 @@ private:
int m_bufferSize;
QSlider * m_bufferSizeSlider;
QLabel * m_bufferSizeLbl;
QLabel * m_bufferSizeWarnLbl;
// MIDI settings widgets.
QComboBox * m_midiInterfaces;

View File

@@ -31,6 +31,7 @@
#include "lmms_export.h"
class QLabel;
class QTimer;
namespace lmms::gui
{
@@ -44,6 +45,8 @@ public:
void setText(const QString & text);
void showWithDelay(int msecBeforeDisplay, int msecDisplayTime);
void setVisibilityTimeOut(int msecs);
void moveGlobal(QWidget * w, const QPoint & offset)
@@ -51,11 +54,14 @@ public:
move(w->mapToGlobal(QPoint(0, 0)) + offset);
}
void hide();
private:
QLabel * m_textLabel;
QTimer * m_showTimer;
QTimer * m_hideTimer;
};
} // namespace lmms::gui
#endif

View File

@@ -68,15 +68,16 @@ class LMMS_EXPORT Song : public TrackContainer
mapPropertyFromModel( int,masterPitch,setMasterPitch,m_masterPitchModel );
mapPropertyFromModel( int,masterVolume,setMasterVolume, m_masterVolumeModel );
public:
enum PlayModes
enum class PlayMode
{
Mode_None,
Mode_PlaySong,
Mode_PlayPattern,
Mode_PlayMidiClip,
Mode_PlayAutomationClip,
Mode_Count
None,
Song,
Pattern,
MidiClip,
AutomationClip,
Count
} ;
constexpr static auto PlayModeCount = static_cast<std::size_t>(PlayMode::Count);
struct SaveOptions {
/**
@@ -141,36 +142,34 @@ public:
inline int getMilliseconds() const
{
return m_elapsedMilliSeconds[m_playMode];
return getMilliseconds(m_playMode);
}
inline int getMilliseconds(PlayModes playMode) const
inline int getMilliseconds(PlayMode playMode) const
{
return m_elapsedMilliSeconds[playMode];
return m_elapsedMilliSeconds[static_cast<std::size_t>(playMode)];
}
inline void setToTime(TimePos const & pos)
{
m_elapsedMilliSeconds[m_playMode] = pos.getTimeInMilliseconds(getTempo());
m_playPos[m_playMode].setTicks(pos.getTicks());
setToTime(pos, m_playMode);
}
inline void setToTime(TimePos const & pos, PlayModes playMode)
inline void setToTime(TimePos const & pos, PlayMode playMode)
{
m_elapsedMilliSeconds[playMode] = pos.getTimeInMilliseconds(getTempo());
m_playPos[playMode].setTicks(pos.getTicks());
m_elapsedMilliSeconds[static_cast<std::size_t>(playMode)] = pos.getTimeInMilliseconds(getTempo());
getPlayPos(playMode).setTicks(pos.getTicks());
}
inline void setToTimeByTicks(tick_t ticks)
{
m_elapsedMilliSeconds[m_playMode] = TimePos::ticksToMilliseconds(ticks, getTempo());
m_playPos[m_playMode].setTicks(ticks);
setToTimeByTicks(ticks, m_playMode);
}
inline void setToTimeByTicks(tick_t ticks, PlayModes playMode)
inline void setToTimeByTicks(tick_t ticks, PlayMode playMode)
{
m_elapsedMilliSeconds[playMode] = TimePos::ticksToMilliseconds(ticks, getTempo());
m_playPos[playMode].setTicks(ticks);
m_elapsedMilliSeconds[static_cast<std::size_t>(playMode)] = TimePos::ticksToMilliseconds(ticks, getTempo());
getPlayPos(playMode).setTicks(ticks);
}
inline int getBars() const
@@ -253,18 +252,18 @@ public:
m_renderBetweenMarkers = renderBetweenMarkers;
}
inline PlayModes playMode() const
inline PlayMode playMode() const
{
return m_playMode;
}
inline PlayPos & getPlayPos( PlayModes pm )
inline PlayPos & getPlayPos( PlayMode pm )
{
return m_playPos[pm];
return m_playPos[static_cast<std::size_t>(pm)];
}
inline const PlayPos & getPlayPos( PlayModes pm ) const
inline const PlayPos & getPlayPos( PlayMode pm ) const
{
return m_playPos[pm];
return m_playPos[static_cast<std::size_t>(pm)];
}
inline PlayPos & getPlayPos()
{
@@ -417,21 +416,21 @@ private:
inline bar_t currentBar() const
{
return m_playPos[m_playMode].getBar();
return getPlayPos(m_playMode).getBar();
}
inline tick_t currentTick() const
{
return m_playPos[m_playMode].getTicks();
return getPlayPos(m_playMode).getTicks();
}
inline f_cnt_t currentFrame() const
{
return m_playPos[m_playMode].getTicks() * Engine::framesPerTick() +
m_playPos[m_playMode].currentFrame();
return getPlayPos(m_playMode).getTicks() * Engine::framesPerTick() +
getPlayPos(m_playMode).currentFrame();
}
void setPlayPos( tick_t ticks, PlayModes playMode );
void setPlayPos( tick_t ticks, PlayMode playMode );
void saveControllerStates( QDomDocument & doc, QDomElement & element );
void restoreControllerStates( const QDomElement & element );
@@ -482,14 +481,14 @@ private:
QHash<QString, int> m_errors;
PlayModes m_playMode;
PlayPos m_playPos[Mode_Count];
PlayMode m_playMode;
PlayPos m_playPos[PlayModeCount];
bar_t m_length;
const MidiClip* m_midiClipToPlay;
bool m_loopMidiClip;
double m_elapsedMilliSeconds[Mode_Count];
double m_elapsedMilliSeconds[PlayModeCount];
tick_t m_elapsedTicks;
bar_t m_elapsedBars;

View File

@@ -26,6 +26,7 @@
#ifndef LMMS_GUI_SONG_EDITOR_H
#define LMMS_GUI_SONG_EDITOR_H
#include "AutomatableModel.h"
#include "Editor.h"
#include "TrackContainerView.h"
@@ -56,11 +57,11 @@ class SongEditor : public TrackContainerView
{
Q_OBJECT
public:
enum EditMode
enum class EditMode
{
DrawMode,
KnifeMode,
SelectMode
Draw,
Knife,
Select
};
SongEditor( Song * song );
@@ -69,7 +70,6 @@ public:
void saveSettings( QDomDocument& doc, QDomElement& element ) override;
void loadSettings( const QDomElement& element ) override;
ComboBoxModel *zoomingModel() const;
ComboBoxModel *snappingModel() const;
float getSnapSize() const;
QString getSnapSizeString() const;
@@ -120,10 +120,12 @@ private:
bool allowRubberband() const override;
bool knifeMode() const override;
int calculatePixelsPerBar() const;
int calculateZoomSliderValue(int pixelsPerBar) const;
int trackIndexFromSelectionPoint(int yPos);
int indexOfTrackView(const TrackView* tv);
Song * m_song;
QScrollBar * m_leftRightScroll;
@@ -141,12 +143,10 @@ private:
PositionLine * m_positionLine;
ComboBoxModel* m_zoomingModel;
IntModel* m_zoomingModel;
ComboBoxModel* m_snappingModel;
bool m_proportionalSnap;
static const QVector<float> m_zoomLevels;
bool m_scrollBack;
bool m_smoothScroll;
@@ -158,14 +158,14 @@ private:
QPoint m_mousePos;
int m_rubberBandStartTrackview;
TimePos m_rubberbandStartTimePos;
int m_currentZoomingValue;
int m_rubberbandPixelsPerBar; //!< pixels per bar when selection starts
int m_trackHeadWidth;
bool m_selectRegion;
friend class SongEditorWindow;
signals:
void zoomingValueChanged( float );
void pixelsPerBarChanged(float);
} ;
@@ -213,7 +213,7 @@ private:
QAction* m_selectModeAction;
QAction* m_crtlAction;
ComboBox * m_zoomingComboBox;
AutomatableSlider * m_zoomingSlider;
ComboBox * m_snappingComboBox;
QLabel* m_snapSizeLabel;
@@ -221,7 +221,6 @@ private:
QAction* m_removeBarAction;
};
} // namespace gui
} // namespace lmms

View File

@@ -59,7 +59,7 @@ class StepRecorder : public QObject
void setCurrentMidiClip(MidiClip* newMidiClip);
void setStepsLength(const TimePos& newLength);
QVector<Note*> getCurStepNotes();
std::vector<Note*> getCurStepNotes();
bool isRecording() const
{
@@ -142,7 +142,7 @@ class StepRecorder : public QObject
QElapsedTimer releasedTimer;
} ;
QVector<StepNote*> m_curStepNotes; // contains the current recorded step notes (i.e. while user still press the notes; before they are applied to the clip)
std::vector<StepNote*> m_curStepNotes; // contains the current recorded step notes (i.e. while user still press the notes; before they are applied to the clip)
StepNote* findCurStepNote(const int key);

View File

@@ -41,7 +41,7 @@ class LMMS_EXPORT TempoSyncKnob : public Knob
{
Q_OBJECT
public:
TempoSyncKnob( knobTypes knobNum, QWidget* parent = nullptr, const QString& name = QString() );
TempoSyncKnob( KnobType knobNum, QWidget* parent = nullptr, const QString& name = QString() );
~TempoSyncKnob() override;
const QString & syncDescription();

View File

@@ -46,17 +46,17 @@ class LMMS_EXPORT TempoSyncKnobModel : public FloatModel
Q_OBJECT
MODEL_IS_VISITABLE
public:
enum TempoSyncMode
enum class SyncMode
{
SyncNone,
SyncDoubleWholeNote,
SyncWholeNote,
SyncHalfNote,
SyncQuarterNote,
SyncEighthNote,
SyncSixteenthNote,
SyncThirtysecondNote,
SyncCustom
None,
DoubleWholeNote,
WholeNote,
HalfNote,
QuarterNote,
EighthNote,
SixteenthNote,
ThirtysecondNote,
Custom
} ;
TempoSyncKnobModel( const float _val, const float _min,
@@ -68,12 +68,12 @@ public:
void saveSettings( QDomDocument & _doc, QDomElement & _this, const QString& name ) override;
void loadSettings( const QDomElement & _this, const QString& name ) override;
TempoSyncMode syncMode() const
SyncMode syncMode() const
{
return m_tempoSyncMode;
}
void setSyncMode( TempoSyncMode _new_mode );
void setSyncMode( SyncMode _new_mode );
float scale() const
{
@@ -83,16 +83,16 @@ public:
void setScale( float _new_scale );
signals:
void syncModeChanged( lmms::TempoSyncKnobModel::TempoSyncMode _new_mode );
void syncModeChanged( lmms::TempoSyncKnobModel::SyncMode _new_mode );
void scaleChanged( float _new_scale );
public slots:
inline void disableSync()
{
setTempoSync( SyncNone );
setTempoSync( SyncMode::None );
}
void setTempoSync( int _note_type );
void setTempoSync( SyncMode _note_type );
void setTempoSync( QAction * _item );
@@ -102,8 +102,8 @@ protected slots:
private:
TempoSyncMode m_tempoSyncMode;
TempoSyncMode m_tempoLastSyncMode;
SyncMode m_tempoSyncMode;
SyncMode m_tempoLastSyncMode;
float m_scale;
MeterModel m_custom;

View File

@@ -51,13 +51,11 @@ private slots:
private:
enum DisplayModes
enum class DisplayMode
{
MinutesSeconds,
BarsTicks,
DisplayModeCount
BarsTicks
};
using DisplayMode = DisplayModes;
void setDisplayMode( DisplayMode displayMode );

View File

@@ -55,19 +55,19 @@ public:
Q_PROPERTY( QColor activeLoopInnerColor READ getActiveLoopInnerColor WRITE setActiveLoopInnerColor )
Q_PROPERTY( int loopRectangleVerticalPadding READ getLoopRectangleVerticalPadding WRITE setLoopRectangleVerticalPadding )
enum AutoScrollStates
enum class AutoScrollState
{
AutoScrollEnabled,
AutoScrollDisabled
Enabled,
Disabled
} ;
enum LoopPointStates
enum class LoopPointState
{
LoopPointsDisabled,
LoopPointsEnabled
Disabled,
Enabled
} ;
enum BehaviourAtStopStates
enum class BehaviourAtStopState
{
BackToZero,
BackToStart,
@@ -76,7 +76,7 @@ public:
TimeLineWidget(int xoff, int yoff, float ppb, Song::PlayPos & pos,
const TimePos & begin, Song::PlayModes mode, QWidget * parent);
const TimePos & begin, Song::PlayMode mode, QWidget * parent);
~TimeLineWidget() override;
inline QColor const & getBarLineColor() const { return m_barLineColor; }
@@ -111,12 +111,12 @@ public:
return( m_pos );
}
AutoScrollStates autoScroll() const
AutoScrollState autoScroll() const
{
return m_autoScroll;
}
BehaviourAtStopStates behaviourAtStop() const
BehaviourAtStopState behaviourAtStop() const
{
return m_behaviourAtStop;
}
@@ -128,7 +128,7 @@ public:
bool loopPointsEnabled() const
{
return m_loopPoints == LoopPointsEnabled;
return m_loopPoints == LoopPointState::Enabled;
}
inline const TimePos & loopBegin() const
@@ -220,9 +220,9 @@ private:
QColor m_barLineColor;
QColor m_barNumberColor;
AutoScrollStates m_autoScroll;
LoopPointStates m_loopPoints;
BehaviourAtStopStates m_behaviourAtStop;
AutoScrollState m_autoScroll;
LoopPointState m_loopPoints;
BehaviourAtStopState m_behaviourAtStop;
bool m_changedPosition;
@@ -232,7 +232,7 @@ private:
float m_snapSize;
Song::PlayPos & m_pos;
const TimePos & m_begin;
const Song::PlayModes m_mode;
const Song::PlayMode m_mode;
TimePos m_loopPos[2];
TimePos m_savedPos;
@@ -242,7 +242,7 @@ private:
int m_initalXSelect;
enum actions
enum class Action
{
NoAction,
MovePositionMarker,

View File

@@ -25,7 +25,8 @@
#ifndef LMMS_TRACK_H
#define LMMS_TRACK_H
#include <QVector>
#include <vector>
#include <QColor>
#include "AutomatableModel.h"
@@ -69,31 +70,31 @@ class LMMS_EXPORT Track : public Model, public JournallingObject
mapPropertyFromModel(bool,isMuted,setMuted,m_mutedModel);
mapPropertyFromModel(bool,isSolo,setSolo,m_soloModel);
public:
using clipVector = QVector<Clip*>;
using clipVector = std::vector<Clip*>;
enum TrackTypes
enum class Type
{
InstrumentTrack,
PatternTrack,
SampleTrack,
EventTrack,
VideoTrack,
AutomationTrack,
HiddenAutomationTrack,
NumTrackTypes
Instrument,
Pattern,
Sample,
Event,
Video,
Automation,
HiddenAutomation,
Count
} ;
Track( TrackTypes type, TrackContainer * tc );
Track( Type type, TrackContainer * tc );
~Track() override;
static Track * create( TrackTypes tt, TrackContainer * tc );
static Track * create( Type tt, TrackContainer * tc );
static Track * create( const QDomElement & element,
TrackContainer * tc );
Track * clone();
// pure virtual functions
TrackTypes type() const
Type type() const
{
return m_type;
}
@@ -223,7 +224,7 @@ public slots:
private:
TrackContainer* m_trackContainer;
TrackTypes m_type;
Type m_type;
QString m_name;
int m_height;

View File

@@ -49,11 +49,11 @@ class LMMS_EXPORT TrackContainer : public Model, public JournallingObject
{
Q_OBJECT
public:
using TrackList = QVector<Track*>;
enum TrackContainerTypes
using TrackList = std::vector<Track*>;
enum class Type
{
PatternContainer,
SongContainer
Pattern,
Song
} ;
TrackContainer();
@@ -63,7 +63,7 @@ public:
void loadSettings( const QDomElement & _this ) override;
int countTracks( Track::TrackTypes _tt = Track::NumTrackTypes ) const;
int countTracks( Track::Type _tt = Track::Type::Count ) const;
void addTrack( Track * _track );
@@ -85,12 +85,12 @@ public:
return "trackcontainer";
}
inline void setType( TrackContainerTypes newType )
inline void setType( Type newType )
{
m_TrackContainerType = newType;
}
inline TrackContainerTypes type() const
inline Type type() const
{
return m_TrackContainerType;
}
@@ -108,7 +108,7 @@ protected:
private:
TrackList m_tracks;
TrackContainerTypes m_TrackContainerType;
Type m_TrackContainerType;
friend class gui::TrackContainerView;

View File

@@ -174,12 +174,6 @@ protected:
private:
enum Actions
{
AddTrack,
RemoveTrack
} ;
class scrollArea : public QScrollArea
{
public:

View File

@@ -95,7 +95,7 @@ public slots:
void changePosition( const lmms::TimePos & newPos = TimePos( -1 ) );
protected:
enum ContextMenuAction
enum class ContextMenuAction
{
Paste
};

View File

@@ -48,11 +48,11 @@ class FadeButton;
class TrackContainerView;
const int DEFAULT_SETTINGS_WIDGET_WIDTH = 224;
const int DEFAULT_SETTINGS_WIDGET_WIDTH = 256;
const int TRACK_OP_WIDTH = 78;
// This shaves 150-ish pixels off track buttons,
// ruled from config: ui.compacttrackbuttons
const int DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT = 96;
const int DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT = 128;
const int TRACK_OP_WIDTH_COMPACT = 62;
@@ -95,7 +95,7 @@ public:
bool isMovingTrack() const
{
return m_action == MoveTrack;
return m_action == Action::Move;
}
virtual void update();
@@ -139,11 +139,11 @@ protected:
private:
enum Actions
enum class Action
{
NoAction,
MoveTrack,
ResizeTrack
None,
Move,
Resize
} ;
Track * m_track;
@@ -153,7 +153,7 @@ private:
QWidget m_trackSettingsWidget;
TrackContentWidget m_trackContentWidget;
Actions m_action;
Action m_action;
virtual FadeButton * getActivityIndicator()
{

View File

@@ -44,12 +44,12 @@ const unsigned int FFT_BUFFER_SIZE = 2048;
const std::vector<unsigned int> FFT_BLOCK_SIZES = {256, 512, 1024, 2048, 4096, 8192, 16384};
// List of FFT window functions supported by precomputeWindow()
enum FFT_WINDOWS
enum class FFTWindow
{
RECTANGULAR = 0,
BLACKMAN_HARRIS,
HAMMING,
HANNING
Rectangular = 0,
BlackmanHarris,
Hamming,
Hanning
};
@@ -83,7 +83,7 @@ int LMMS_EXPORT notEmpty(const std::vector<float> &spectrum);
*
* @return -1 on error
*/
int LMMS_EXPORT precomputeWindow(float *window, unsigned int length, FFT_WINDOWS type, bool normalized = true);
int LMMS_EXPORT precomputeWindow(float *window, unsigned int length, FFTWindow type, bool normalized = true);
/** Compute absolute values of complex_buffer, save to absspec_buffer.

View File

@@ -62,13 +62,13 @@ constexpr unsigned int MaxKeymapCount = 10; //!< number of keyboard mappings per
constexpr int LOWEST_LOG_FREQ = 5;
// Full range is defined by LOWEST_LOG_FREQ and current sample rate.
enum FREQUENCY_RANGES
enum class FrequencyRange
{
FRANGE_FULL = 0,
FRANGE_AUDIBLE,
FRANGE_BASS,
FRANGE_MIDS,
FRANGE_HIGH
Full = 0,
Audible,
Bass,
Mids,
High
};
constexpr int FRANGE_AUDIBLE_START = 20;
@@ -83,12 +83,12 @@ constexpr int FRANGE_HIGH_END = 20000;
// Amplitude ranges (in dBFS).
// Reference: full scale sine wave (-1.0 to 1.0) is 0 dB.
// Doubling or halving the amplitude produces 3 dB difference.
enum AMPLITUDE_RANGES
enum class AmplitudeRange
{
ARANGE_EXTENDED = 0,
ARANGE_AUDIBLE,
ARANGE_LOUD,
ARANGE_SILENT
Extended = 0,
Audible,
Loud,
Silent
};
constexpr int ARANGE_EXTENDED_START = -80;

View File

@@ -214,7 +214,7 @@ static inline float logToLinearScale( float min, float max, float value )
{
if( min < 0 )
{
const float mmax = qMax( qAbs( min ), qAbs( max ) );
const float mmax = std::max(std::abs(min), std::abs(max));
const float val = value * ( max - min ) + min;
float result = signedPowf( val / mmax, F_E ) * mmax;
return std::isnan( result ) ? 0 : result;
@@ -228,11 +228,11 @@ static inline float logToLinearScale( float min, float max, float value )
static inline float linearToLogScale( float min, float max, float value )
{
static const float EXP = 1.0f / F_E;
const float valueLimited = qBound( min, value, max);
const float valueLimited = std::clamp(value, min, max);
const float val = ( valueLimited - min ) / ( max - min );
if( min < 0 )
{
const float mmax = qMax( qAbs( min ), qAbs( max ) );
const float mmax = std::max(std::abs(min), std::abs(max));
float result = signedPowf( valueLimited / mmax, EXP ) * mmax;
return std::isnan( result ) ? 0 : result;
}
@@ -315,14 +315,40 @@ static inline float fastSqrt( float n )
template<class T>
static inline T absMax( T a, T b )
{
return qAbs<T>(a) > qAbs<T>(b) ? a : b;
return std::abs(a) > std::abs(b) ? a : b;
}
//! returns value nearest to zero
template<class T>
static inline T absMin( T a, T b )
{
return qAbs<T>(a) < qAbs<T>(b) ? a : b;
return std::abs(a) < std::abs(b) ? a : b;
}
// @brief Calculate number of digits which LcdSpinBox would show for a given number
// @note Once we upgrade to C++20, we could probably use std::formatted_size
static inline int numDigitsAsInt(float f)
{
// use rounding:
// LcdSpinBox sometimes uses roundf(), sometimes cast rounding
// we use rounding to be on the "safe side"
const float rounded = roundf(f);
int asInt = static_cast<int>(rounded);
int digits = 1; // always at least 1
if(asInt < 0)
{
++digits;
asInt = -asInt;
}
// "asInt" is positive from now
int32_t power = 1;
for(int32_t i = 1; i<10; ++i)
{
power *= 10;
if(static_cast<int32_t>(asInt) >= power) { ++digits; } // 2 digits for >=10, 3 for >=100
else { break; }
}
return digits;
}

View File

@@ -31,6 +31,8 @@
#include "Midi.h"
#include "volume.h"
#include <cmath>
namespace lmms
{
@@ -40,7 +42,7 @@ inline StereoVolumeVector panningToVolumeVector( panning_t _p,
{
StereoVolumeVector v = { { _scale, _scale } };
const float pf = _p / 100.0f;
v.vol[_p >= PanningCenter ? 0 : 1] *= 1.0f - qAbs<float>( pf );
v.vol[_p >= PanningCenter ? 0 : 1] *= 1.0f - std::abs(pf);
return v;
}

View File

@@ -3,15 +3,17 @@
#include "lmms_basics.h"
#ifdef __GNUC__
#if defined(__GNUC__)
constexpr const char* LMMS_BUILDCONF_COMPILER_VERSION = "GCC " __VERSION__;
#elif defined(__clang__)
constexpr const char* LMMS_BUILDCONF_COMPILER_VERSION = "Clang " __clang_version__;
#elif defined(_MSC_VER)
constexpr const char* LMMS_BUILDCONF_COMPILER_VERSION = "MSVC " LMMS_STRINGIFY(_MSC_FULL_VER);
#else
constexpr const char* LMMS_BUILDCONF_COMPILER_VERSION = "unknown compiler";
#endif
#ifdef LMMS_HOST_X86
#if defined(LMMS_HOST_X86)
constexpr const char* LMMS_BUILDCONF_MACHINE = "i386";
#elif defined(LMMS_HOST_X86_64)
constexpr const char* LMMS_BUILDCONF_MACHINE = "x86_64";
@@ -23,32 +25,28 @@ constexpr const char* LMMS_BUILDCONF_MACHINE = "arm64";
constexpr const char* LMMS_BUILDCONF_MACHINE = "riscv32";
#elif defined(LMMS_HOST_RISCV64)
constexpr const char* LMMS_BUILDCONF_MACHINE = "riscv64";
#elif defined(LMMS_HOST_PPC32)
constexpr const char* LMMS_BUILDCONF_MACHINE = "ppc";
#elif defined(LMMS_HOST_PPC64)
constexpr const char* LMMS_BUILDCONF_MACHINE = "ppc64";
#else
constexpr const char* LMMS_BUILDCONF_MACHINE = "unknown processor";
#endif
#ifdef LMMS_BUILD_LINUX
#if defined(LMMS_BUILD_LINUX)
constexpr const char* LMMS_BUILDCONF_PLATFORM = "Linux";
#endif
#ifdef LMMS_BUILD_APPLE
#elif defined(LMMS_BUILD_APPLE)
constexpr const char* LMMS_BUILDCONF_PLATFORM = "OS X";
#endif
#ifdef LMMS_BUILD_OPENBSD
#elif defined(LMMS_BUILD_OPENBSD)
constexpr const char* LMMS_BUILDCONF_PLATFORM = "OpenBSD";
#endif
#ifdef LMMS_BUILD_FREEBSD
#elif defined(LMMS_BUILD_FREEBSD)
constexpr const char* LMMS_BUILDCONF_PLATFORM = "FreeBSD";
#endif
#ifdef LMMS_BUILD_WIN32
#elif defined(LMMS_BUILD_WIN32)
constexpr const char* LMMS_BUILDCONF_PLATFORM = "win32";
#endif
#ifdef LMMS_BUILD_HAIKU
#elif defined(LMMS_BUILD_HAIKU)
constexpr const char* LMMS_BUILDCONF_PLATFORM = "Haiku";
#else
constexpr const char* LMMS_BUILDCONF_PLATFORM = "unknown platform";
#endif
#endif // LMMS_VERSION_INFO_H