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:
388
include/ArrayVector.h
Normal file
388
include/ArrayVector.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -164,13 +164,6 @@ signals:
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
NoAction,
|
||||
Move,
|
||||
Resize
|
||||
} ;
|
||||
|
||||
Track * m_track;
|
||||
QString m_name;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ),
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
using EffectList = QVector<Effect*>;
|
||||
using EffectList = std::vector<Effect*>;
|
||||
EffectList m_effects;
|
||||
|
||||
BoolModel m_enabledModel;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
} ;
|
||||
|
||||
|
||||
@@ -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
83
include/Flags.h
Normal 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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
} ;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
} ;
|
||||
|
||||
@@ -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
93
include/LmmsSemaphore.h
Normal 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
|
||||
@@ -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 ];
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
93
include/Lv2Worker.h
Normal 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
|
||||
|
||||
@@ -113,7 +113,7 @@ public:
|
||||
return m_autoSaveTimer.interval();
|
||||
}
|
||||
|
||||
enum SessionState
|
||||
enum class SessionState
|
||||
{
|
||||
Normal,
|
||||
Recover
|
||||
|
||||
@@ -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;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -48,6 +48,7 @@ class MidiController : public Controller, public MidiEventProcessor
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static constexpr int NONE = -1;
|
||||
MidiController( Model * _parent );
|
||||
~MidiController() override = default;
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace lmms
|
||||
|
||||
class PeakControllerEffect;
|
||||
|
||||
using PeakControllerEffectVector = QVector<PeakControllerEffect*>;
|
||||
using PeakControllerEffectVector = std::vector<PeakControllerEffect*>;
|
||||
|
||||
class LMMS_EXPORT PeakController : public Controller
|
||||
{
|
||||
|
||||
@@ -38,10 +38,10 @@ class MidiEventProcessor;
|
||||
class Piano final : public Model
|
||||
{
|
||||
public:
|
||||
enum KeyTypes
|
||||
enum class KeyType
|
||||
{
|
||||
WhiteKey,
|
||||
BlackKey
|
||||
White,
|
||||
Black
|
||||
} ;
|
||||
|
||||
Piano(InstrumentTrack* track);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -51,13 +51,11 @@ private slots:
|
||||
|
||||
|
||||
private:
|
||||
enum DisplayModes
|
||||
enum class DisplayMode
|
||||
{
|
||||
MinutesSeconds,
|
||||
BarsTicks,
|
||||
DisplayModeCount
|
||||
BarsTicks
|
||||
};
|
||||
using DisplayMode = DisplayModes;
|
||||
|
||||
void setDisplayMode( DisplayMode displayMode );
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -174,12 +174,6 @@ protected:
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
AddTrack,
|
||||
RemoveTrack
|
||||
} ;
|
||||
|
||||
class scrollArea : public QScrollArea
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -95,7 +95,7 @@ public slots:
|
||||
void changePosition( const lmms::TimePos & newPos = TimePos( -1 ) );
|
||||
|
||||
protected:
|
||||
enum ContextMenuAction
|
||||
enum class ContextMenuAction
|
||||
{
|
||||
Paste
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user