Merge branch 'master' into feature/recording-stage-one
This commit is contained in:
276
include/AudioBufferView.h
Normal file
276
include/AudioBufferView.h
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* AudioBufferView.h - Non-owning views for interleaved and
|
||||
* non-interleaved (planar) buffers
|
||||
*
|
||||
* Copyright (c) 2025 Dalton Messmer <messmer.dalton/at/gmail.com>
|
||||
*
|
||||
* 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_AUDIO_BUFFER_VIEW_H
|
||||
#define LMMS_AUDIO_BUFFER_VIEW_H
|
||||
|
||||
#include <cassert>
|
||||
#include <span>
|
||||
#include <type_traits>
|
||||
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
//! Use when the number of channels is not known at compile time
|
||||
inline constexpr auto DynamicChannelCount = static_cast<proc_ch_t>(-1);
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
// For static channel count
|
||||
template<typename SampleT, proc_ch_t channelCount>
|
||||
class BufferViewData
|
||||
{
|
||||
public:
|
||||
constexpr BufferViewData() = default;
|
||||
constexpr BufferViewData(const BufferViewData&) = default;
|
||||
|
||||
constexpr BufferViewData(SampleT* data, proc_ch_t channels, f_cnt_t frames) noexcept
|
||||
: m_data{data}
|
||||
, m_frames{frames}
|
||||
{
|
||||
assert(channels == channelCount);
|
||||
}
|
||||
|
||||
constexpr BufferViewData(SampleT* data, f_cnt_t frames) noexcept
|
||||
: m_data{data}
|
||||
, m_frames{frames}
|
||||
{
|
||||
}
|
||||
|
||||
constexpr auto data() const noexcept -> SampleT* { return m_data; }
|
||||
constexpr auto channels() const noexcept -> proc_ch_t { return channelCount; }
|
||||
constexpr auto frames() const noexcept -> f_cnt_t { return m_frames; }
|
||||
|
||||
protected:
|
||||
SampleT* m_data = nullptr;
|
||||
f_cnt_t m_frames = 0;
|
||||
};
|
||||
|
||||
// For dynamic channel count
|
||||
template<typename SampleT>
|
||||
class BufferViewData<SampleT, DynamicChannelCount>
|
||||
{
|
||||
public:
|
||||
constexpr BufferViewData() = default;
|
||||
constexpr BufferViewData(const BufferViewData&) = default;
|
||||
|
||||
constexpr BufferViewData(SampleT* data, proc_ch_t channels, f_cnt_t frames) noexcept
|
||||
: m_data{data}
|
||||
, m_channels{channels}
|
||||
, m_frames{frames}
|
||||
{
|
||||
assert(channels != DynamicChannelCount);
|
||||
}
|
||||
|
||||
constexpr auto data() const noexcept -> SampleT* { return m_data; }
|
||||
constexpr auto channels() const noexcept -> proc_ch_t { return m_channels; }
|
||||
constexpr auto frames() const noexcept -> f_cnt_t { return m_frames; }
|
||||
|
||||
protected:
|
||||
SampleT* m_data = nullptr;
|
||||
proc_ch_t m_channels = 0;
|
||||
f_cnt_t m_frames = 0;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
/**
|
||||
* Non-owning view for multi-channel interleaved audio data
|
||||
*
|
||||
* TODO C++23: Use std::mdspan?
|
||||
*/
|
||||
template<typename SampleT, proc_ch_t channelCount = DynamicChannelCount>
|
||||
class InterleavedBufferView : public detail::BufferViewData<SampleT, channelCount>
|
||||
{
|
||||
using Base = detail::BufferViewData<SampleT, channelCount>;
|
||||
|
||||
public:
|
||||
using Base::Base;
|
||||
|
||||
//! Contruct const from mutable (static channel count)
|
||||
template<typename T = SampleT> requires (std::is_const_v<T> && channelCount != DynamicChannelCount)
|
||||
constexpr InterleavedBufferView(InterleavedBufferView<std::remove_const_t<T>, channelCount> other) noexcept
|
||||
: Base{other.data(), other.frames()}
|
||||
{
|
||||
}
|
||||
|
||||
//! Contruct const from mutable (dynamic channel count)
|
||||
template<typename T = SampleT> requires (std::is_const_v<T> && channelCount == DynamicChannelCount)
|
||||
constexpr InterleavedBufferView(InterleavedBufferView<std::remove_const_t<T>, channelCount> other) noexcept
|
||||
: Base{other.data(), other.channels(), other.frames()}
|
||||
{
|
||||
}
|
||||
|
||||
//! Construct dynamic channel count from static
|
||||
template<proc_ch_t otherChannels>
|
||||
requires (channelCount == DynamicChannelCount && otherChannels != DynamicChannelCount)
|
||||
constexpr InterleavedBufferView(InterleavedBufferView<SampleT, otherChannels> other) noexcept
|
||||
: Base{other.data(), otherChannels, other.frames()}
|
||||
{
|
||||
}
|
||||
|
||||
constexpr auto empty() const noexcept -> bool
|
||||
{
|
||||
return !this->m_data || this->channels() == 0 || this->m_frames == 0;
|
||||
}
|
||||
|
||||
//! @return the frame at the given index
|
||||
constexpr auto frame(f_cnt_t index) const noexcept
|
||||
{
|
||||
if constexpr (channelCount == DynamicChannelCount)
|
||||
{
|
||||
return std::span<SampleT>{framePtr(index), this->channels()};
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::span<SampleT, channelCount>{framePtr(index), this->channels()};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pointer to the frame at the given index.
|
||||
* The size of the frame is `channels()`.
|
||||
*/
|
||||
constexpr auto framePtr(f_cnt_t index) const noexcept -> SampleT*
|
||||
{
|
||||
assert(index < this->m_frames);
|
||||
return this->m_data + index * this->channels();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pointer to the frame at the given index.
|
||||
* The size of the frame is `channels()`.
|
||||
*/
|
||||
constexpr auto operator[](f_cnt_t index) const noexcept -> SampleT*
|
||||
{
|
||||
return framePtr(index);
|
||||
}
|
||||
};
|
||||
|
||||
// Check that the std::span-like space optimization works
|
||||
static_assert(sizeof(InterleavedBufferView<float>) > sizeof(InterleavedBufferView<float, 2>));
|
||||
static_assert(sizeof(InterleavedBufferView<float, 2>) == sizeof(void*) + sizeof(f_cnt_t));
|
||||
|
||||
|
||||
/**
|
||||
* Non-owning view for multi-channel non-interleaved audio data
|
||||
*
|
||||
* The data type is `SampleT* const*` which is a 2D array accessed as data[channel][frame index]
|
||||
* where each channel's buffer contains `frames()` frames.
|
||||
*
|
||||
* TODO C++23: Use std::mdspan?
|
||||
*/
|
||||
template<typename SampleT, proc_ch_t channelCount = DynamicChannelCount>
|
||||
class PlanarBufferView : public detail::BufferViewData<SampleT* const, channelCount>
|
||||
{
|
||||
using Base = detail::BufferViewData<SampleT* const, channelCount>;
|
||||
|
||||
public:
|
||||
using Base::Base;
|
||||
|
||||
//! Contruct const from mutable (static channel count)
|
||||
template<typename T = SampleT> requires (std::is_const_v<T> && channelCount != DynamicChannelCount)
|
||||
constexpr PlanarBufferView(PlanarBufferView<std::remove_const_t<T>, channelCount> other) noexcept
|
||||
: Base{other.data(), other.frames()}
|
||||
{
|
||||
}
|
||||
|
||||
//! Contruct const from mutable (dynamic channel count)
|
||||
template<typename T = SampleT> requires (std::is_const_v<T> && channelCount == DynamicChannelCount)
|
||||
constexpr PlanarBufferView(PlanarBufferView<std::remove_const_t<T>, channelCount> other) noexcept
|
||||
: Base{other.data(), other.channels(), other.frames()}
|
||||
{
|
||||
}
|
||||
|
||||
//! Construct dynamic channel count from static
|
||||
template<proc_ch_t otherChannels>
|
||||
requires (channelCount == DynamicChannelCount && otherChannels != DynamicChannelCount)
|
||||
constexpr PlanarBufferView(PlanarBufferView<SampleT, otherChannels> other) noexcept
|
||||
: Base{other.data(), otherChannels, other.frames()}
|
||||
{
|
||||
}
|
||||
|
||||
constexpr auto empty() const noexcept -> bool
|
||||
{
|
||||
return !this->m_data || this->channels() == 0 || this->m_frames == 0;
|
||||
}
|
||||
|
||||
//! @return the buffer of the given channel
|
||||
constexpr auto buffer(proc_ch_t channel) const noexcept -> std::span<SampleT>
|
||||
{
|
||||
return {bufferPtr(channel), this->m_frames};
|
||||
}
|
||||
|
||||
//! @return the buffer of the given channel
|
||||
template<proc_ch_t channel> requires (channelCount != DynamicChannelCount)
|
||||
constexpr auto buffer() const noexcept -> std::span<SampleT>
|
||||
{
|
||||
return {bufferPtr<channel>(), this->m_frames};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pointer to the buffer of the given channel.
|
||||
* The size of the buffer is `frames()`.
|
||||
*/
|
||||
constexpr auto bufferPtr(proc_ch_t channel) const noexcept -> SampleT*
|
||||
{
|
||||
assert(channel < this->channels());
|
||||
assert(this->m_data != nullptr);
|
||||
return this->m_data[channel];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pointer to the buffer of the given channel.
|
||||
* The size of the buffer is `frames()`.
|
||||
*/
|
||||
template<proc_ch_t channel> requires (channelCount != DynamicChannelCount)
|
||||
constexpr auto bufferPtr() const noexcept -> SampleT*
|
||||
{
|
||||
static_assert(channel < channelCount);
|
||||
assert(this->m_data != nullptr);
|
||||
return this->m_data[channel];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pointer to the buffer of a given channel.
|
||||
* The size of the buffer is `frames()`.
|
||||
*/
|
||||
constexpr auto operator[](proc_ch_t channel) const noexcept -> SampleT*
|
||||
{
|
||||
return bufferPtr(channel);
|
||||
}
|
||||
};
|
||||
|
||||
// Check that the std::span-like space optimization works
|
||||
static_assert(sizeof(PlanarBufferView<float>) > sizeof(PlanarBufferView<float, 2>));
|
||||
static_assert(sizeof(PlanarBufferView<float, 2>) == sizeof(void**) + sizeof(f_cnt_t));
|
||||
|
||||
} // namespace lmms
|
||||
|
||||
#endif // LMMS_AUDIO_BUFFER_VIEW_H
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <QMutex>
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
class QThread;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "AudioDevice.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "SampleFrame.h"
|
||||
#include "LocklessList.h"
|
||||
#include "FifoBuffer.h"
|
||||
@@ -50,7 +50,6 @@ class MidiClient;
|
||||
class AudioBusHandle;
|
||||
class AudioEngineWorkerThread;
|
||||
|
||||
|
||||
constexpr fpp_t MINIMUM_BUFFER_SIZE = 32;
|
||||
constexpr fpp_t DEFAULT_BUFFER_SIZE = 256;
|
||||
constexpr fpp_t MAXIMUM_BUFFER_SIZE = 4096;
|
||||
@@ -61,6 +60,8 @@ constexpr int BYTES_PER_FRAME = sizeof(SampleFrame);
|
||||
|
||||
constexpr float OUTPUT_SAMPLE_MULTIPLIER = 32767.0f;
|
||||
|
||||
constexpr auto SUPPORTED_SAMPLERATES = std::array{44100, 48000, 88200, 96000, 192000};
|
||||
|
||||
class LMMS_EXPORT AudioEngine : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <atomic>
|
||||
#include <QFile>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "MicroTimer.h"
|
||||
|
||||
namespace lmms
|
||||
|
||||
@@ -53,11 +53,6 @@ namespace lmms
|
||||
|
||||
class MidiJack;
|
||||
|
||||
namespace gui
|
||||
{
|
||||
class LcdSpinBox;
|
||||
}
|
||||
|
||||
|
||||
class AudioJack : public QObject, public AudioDevice
|
||||
{
|
||||
@@ -82,13 +77,10 @@ public:
|
||||
{
|
||||
public:
|
||||
setupWidget(QWidget* parent);
|
||||
~setupWidget() override;
|
||||
|
||||
void saveSettings() override;
|
||||
|
||||
private:
|
||||
QLineEdit* m_clientName;
|
||||
gui::LcdSpinBox* m_channels;
|
||||
};
|
||||
|
||||
private slots:
|
||||
@@ -96,6 +88,7 @@ private slots:
|
||||
|
||||
private:
|
||||
bool initJackClient();
|
||||
void resizeInputBuffer(jack_nframes_t nframes);
|
||||
|
||||
void startProcessing() override;
|
||||
void stopProcessing() override;
|
||||
@@ -116,7 +109,9 @@ private:
|
||||
|
||||
std::atomic<MidiJack*> m_midiClient;
|
||||
std::vector<jack_port_t*> m_outputPorts;
|
||||
std::vector<jack_port_t*> m_inputPorts;
|
||||
jack_default_audio_sample_t** m_tempOutBufs;
|
||||
std::vector<SampleFrame> m_inputFrameBuffer;
|
||||
SampleFrame* m_outBuf;
|
||||
|
||||
f_cnt_t m_framesDoneInCurBuf;
|
||||
|
||||
@@ -68,7 +68,6 @@ public:
|
||||
using TimemapIterator = timeMap::const_iterator;
|
||||
|
||||
AutomationClip( AutomationTrack * _auto_track );
|
||||
AutomationClip( const AutomationClip & _clip_to_copy );
|
||||
~AutomationClip() override = default;
|
||||
|
||||
bool addObject( AutomatableModel * _obj, bool _search_dup = true );
|
||||
@@ -90,7 +89,7 @@ public:
|
||||
void setTension( QString _new_tension );
|
||||
|
||||
TimePos timeMapLength() const;
|
||||
void updateLength();
|
||||
void updateLength() override;
|
||||
|
||||
TimePos putValue(
|
||||
const TimePos & time,
|
||||
@@ -196,12 +195,22 @@ public:
|
||||
static int quantization() { return s_quantization; }
|
||||
static void setQuantization(int q) { s_quantization = q; }
|
||||
|
||||
AutomationClip* clone() override
|
||||
{
|
||||
return new AutomationClip(*this);
|
||||
}
|
||||
|
||||
void clearObjects() { m_objects.clear(); }
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
void objectDestroyed( lmms::jo_id_t );
|
||||
void flipY( int min, int max );
|
||||
void flipY();
|
||||
void flipX( int length = -1 );
|
||||
void flipX(int start = -1, int end = -1);
|
||||
|
||||
protected:
|
||||
AutomationClip( const AutomationClip & _clip_to_copy );
|
||||
|
||||
private:
|
||||
void cleanObjects();
|
||||
|
||||
@@ -75,6 +75,8 @@ private:
|
||||
|
||||
QStaticText m_staticTextName;
|
||||
void scaleTimemapToFit( float oldMin, float oldMax );
|
||||
|
||||
bool isResizableBeforeStart() override { return false; }
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "MidiClip.h"
|
||||
#include "SampleClip.h"
|
||||
#include "TimePos.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "SampleThumbnail.h"
|
||||
|
||||
class QPainter;
|
||||
@@ -74,6 +74,7 @@ class AutomationEditor : public QWidget, public JournallingObject
|
||||
Q_PROPERTY(QColor ghostNoteColor MEMBER m_ghostNoteColor)
|
||||
Q_PROPERTY(QColor detuningNoteColor MEMBER m_detuningNoteColor)
|
||||
Q_PROPERTY(QColor ghostSampleColor MEMBER m_ghostSampleColor)
|
||||
Q_PROPERTY(QColor outOfBoundsShade MEMBER m_outOfBoundsShade)
|
||||
public:
|
||||
void setCurrentClip(AutomationClip * new_clip);
|
||||
void setGhostMidiClip(MidiClip* newMidiClip);
|
||||
@@ -291,6 +292,7 @@ private:
|
||||
QColor m_ghostNoteColor;
|
||||
QColor m_detuningNoteColor;
|
||||
QColor m_ghostSampleColor;
|
||||
QColor m_outOfBoundsShade;
|
||||
|
||||
SampleThumbnail m_sampleThumbnail;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class QString;
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "interpolation.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "lmms_math.h"
|
||||
#include "Engine.h"
|
||||
#include "AudioEngine.h"
|
||||
|
||||
@@ -36,7 +36,9 @@
|
||||
#include <cmath>
|
||||
#include <numbers>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "lmms_constants.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
@@ -207,7 +209,7 @@ public:
|
||||
|
||||
inline float update( float s, ch_cnt_t ch )
|
||||
{
|
||||
if (std::abs(s) < 1.0e-10f && std::abs(m_z1[ch]) < 1.0e-10f) { return 0.0f; }
|
||||
if (std::abs(s) < F_EPSILON && std::abs(m_z1[ch]) < F_EPSILON) { return 0.0f; }
|
||||
return m_z1[ch] = s * m_a0 + m_z1[ch] * m_b1;
|
||||
}
|
||||
|
||||
@@ -593,7 +595,7 @@ public:
|
||||
case FilterType::Formantfilter:
|
||||
case FilterType::FastFormant:
|
||||
{
|
||||
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
|
||||
if (std::abs(_in0) < F_EPSILON && std::abs(m_vflast[0][_chnl]) < F_EPSILON) { return 0.0f; } // performance hack - skip processing when the numbers get too small
|
||||
|
||||
const int os = m_type == FilterType::FastFormant ? 1 : 4; // no oversampling for fast formant
|
||||
for( int o = 0; o < os; ++o )
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#define LMMS_BUFFER_MANAGER_H
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <QPixmap>
|
||||
#include <QWidget>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
|
||||
namespace lmms::gui
|
||||
|
||||
@@ -100,12 +100,28 @@ public:
|
||||
* resized by clicking and dragging its edge.
|
||||
*
|
||||
*/
|
||||
inline void setAutoResize( const bool r )
|
||||
inline void setResizable( const bool r )
|
||||
{
|
||||
m_resizable = r;
|
||||
}
|
||||
|
||||
inline const bool getResizable() const
|
||||
{
|
||||
return m_resizable;
|
||||
}
|
||||
|
||||
/*! \brief Set whether a clip has been resized yet by the user or the knife tool.
|
||||
*
|
||||
* If a clip has been resized previously, it will not automatically
|
||||
* resize when editing it.
|
||||
*
|
||||
*/
|
||||
void setAutoResize(const bool r)
|
||||
{
|
||||
m_autoResize = r;
|
||||
}
|
||||
|
||||
inline const bool getAutoResize() const
|
||||
bool getAutoResize() const
|
||||
{
|
||||
return m_autoResize;
|
||||
}
|
||||
@@ -115,6 +131,7 @@ public:
|
||||
|
||||
virtual void movePosition( const TimePos & pos );
|
||||
virtual void changeLength( const TimePos & length );
|
||||
virtual void updateLength() {};
|
||||
|
||||
virtual gui::ClipView * createView( gui::TrackView * tv ) = 0;
|
||||
|
||||
@@ -137,6 +154,12 @@ public:
|
||||
// Will copy the state of a clip to another clip
|
||||
static void copyStateTo( Clip *src, Clip *dst );
|
||||
|
||||
/**
|
||||
* Creates a copy of this clip
|
||||
* @return pointer to the new clip object
|
||||
*/
|
||||
virtual Clip* clone() = 0;
|
||||
|
||||
public slots:
|
||||
void toggleMute();
|
||||
|
||||
@@ -147,6 +170,8 @@ signals:
|
||||
void destroyedClip();
|
||||
void colorChanged();
|
||||
|
||||
protected:
|
||||
Clip(const Clip& other);
|
||||
|
||||
private:
|
||||
Track * m_track;
|
||||
@@ -158,7 +183,8 @@ private:
|
||||
|
||||
BoolModel m_mutedModel;
|
||||
BoolModel m_soloModel;
|
||||
bool m_autoResize;
|
||||
bool m_resizable = true;
|
||||
bool m_autoResize = true;
|
||||
|
||||
bool m_selectViewOnCreate;
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ class ClipView : public selectableObject, public ModelView
|
||||
Q_PROPERTY( QColor textShadowColor READ textShadowColor WRITE setTextShadowColor )
|
||||
Q_PROPERTY( QColor patternClipBackground READ patternClipBackground WRITE setPatternClipBackground )
|
||||
Q_PROPERTY( bool gradient READ gradient WRITE setGradient )
|
||||
Q_PROPERTY(QColor markerColor READ markerColor WRITE setMarkerColor)
|
||||
// We have to use a QSize here because using QPoint isn't supported.
|
||||
// width -> x, height -> y
|
||||
Q_PROPERTY( QSize mouseHotspotHand MEMBER m_mouseHotspotHand )
|
||||
@@ -94,6 +95,7 @@ public:
|
||||
QColor textBackgroundColor() const;
|
||||
QColor textShadowColor() const;
|
||||
QColor patternClipBackground() const;
|
||||
QColor markerColor() const;
|
||||
bool gradient() const;
|
||||
void setMutedColor( const QColor & c );
|
||||
void setMutedBackgroundColor( const QColor & c );
|
||||
@@ -103,6 +105,7 @@ public:
|
||||
void setTextShadowColor( const QColor & c );
|
||||
void setPatternClipBackground(const QColor& c);
|
||||
void setGradient( const bool & b );
|
||||
void setMarkerColor(const QColor& c);
|
||||
|
||||
// access needsUpdate member variable
|
||||
bool needsUpdate();
|
||||
@@ -121,10 +124,8 @@ public:
|
||||
// some metadata to be written to the clipboard.
|
||||
static void remove( QVector<ClipView *> clipvs );
|
||||
static void toggleMute( QVector<ClipView *> clipvs );
|
||||
static void mergeClips(QVector<ClipView*> clipvs);
|
||||
|
||||
// Returns true if selection can be merged and false if not
|
||||
static bool canMergeSelection(QVector<ClipView*> clipvs);
|
||||
void toggleSelectedAutoResize();
|
||||
|
||||
QColor getColorForDisplay( QColor );
|
||||
|
||||
@@ -147,8 +148,7 @@ protected:
|
||||
Cut,
|
||||
Copy,
|
||||
Paste,
|
||||
Mute,
|
||||
Merge
|
||||
Mute
|
||||
};
|
||||
|
||||
TrackView * m_trackView;
|
||||
@@ -176,7 +176,7 @@ protected:
|
||||
}
|
||||
|
||||
bool unquantizedModHeld( QMouseEvent * me );
|
||||
TimePos quantizeSplitPos( TimePos, bool shiftMode );
|
||||
TimePos quantizeSplitPos(TimePos);
|
||||
|
||||
float pixelsPerBar();
|
||||
|
||||
@@ -224,6 +224,7 @@ private:
|
||||
QColor m_textShadowColor;
|
||||
QColor m_patternClipBackground;
|
||||
bool m_gradient;
|
||||
QColor m_markerColor;
|
||||
QSize m_mouseHotspotHand; // QSize must be used because QPoint
|
||||
QSize m_mouseHotspotKnife; // isn't supported by property system
|
||||
QCursor m_cursorHand;
|
||||
@@ -244,8 +245,24 @@ private:
|
||||
TimePos draggedClipPos( QMouseEvent * me );
|
||||
int knifeMarkerPos( QMouseEvent * me );
|
||||
void setColor(const std::optional<QColor>& color);
|
||||
//! Return true iff the clip could be split. Currently only implemented for samples
|
||||
virtual bool splitClip( const TimePos pos ){ return false; };
|
||||
|
||||
//! Returns whether the user can left-resize this clip so that the start of the clip bounds is before the start of the clip content.
|
||||
virtual bool isResizableBeforeStart() { return true; };
|
||||
/**
|
||||
* Split this Clip into two clips
|
||||
* @param pos the position of the split, relative to the start of the clip
|
||||
* @return true if the clip could be split
|
||||
*/
|
||||
bool splitClip(const TimePos pos);
|
||||
/**
|
||||
* Destructively split this Clip into two clips. If the clip type does not implement this feature, it will default to normal splitting.
|
||||
* @param pos the position of the split, relative to the start of the clip
|
||||
* @return true if the clip could be split
|
||||
*/
|
||||
virtual bool destructiveSplitClip(const TimePos pos)
|
||||
{
|
||||
return splitClip(pos);
|
||||
}
|
||||
void updateCursor(QMouseEvent * me);
|
||||
} ;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
bool isDefaultConstructed = false ) :
|
||||
IntModel( 0, 0, 0, parent, displayName, isDefaultConstructed )
|
||||
{
|
||||
setJournalling(false);
|
||||
}
|
||||
|
||||
void addItem( QString item, std::unique_ptr<PixmapLoader> loader = nullptr );
|
||||
|
||||
@@ -214,6 +214,8 @@ public:
|
||||
return m_recentlyOpenedProjects;
|
||||
}
|
||||
|
||||
const QStringList& favoriteItems() { return m_favoriteItems; }
|
||||
|
||||
QString localeDir() const
|
||||
{
|
||||
return m_dataDir + LOCALE_PATH;
|
||||
@@ -240,6 +242,10 @@ public:
|
||||
|
||||
void addRecentlyOpenedProject(const QString & _file);
|
||||
|
||||
void addFavoriteItem(const QString& item);
|
||||
void removeFavoriteItem(const QString& item);
|
||||
bool isFavoriteItem(const QString& item);
|
||||
|
||||
QString value(const QString& cls, const QString& attribute, const QString& defaultVal = "") const;
|
||||
|
||||
void setValue(const QString & cls, const QString & attribute,
|
||||
@@ -265,6 +271,7 @@ public:
|
||||
|
||||
signals:
|
||||
void valueChanged( QString cls, QString attribute, QString value );
|
||||
void favoritesChanged();
|
||||
|
||||
private:
|
||||
static ConfigManager * s_instanceOfMe;
|
||||
@@ -299,6 +306,7 @@ private:
|
||||
QString m_version;
|
||||
unsigned int m_configVersion;
|
||||
QStringList m_recentlyOpenedProjects;
|
||||
QStringList m_favoriteItems;
|
||||
|
||||
using stringPairVector = std::vector<QPair<QString, QString>>;
|
||||
using settingsMap = QMap<QString, stringPairVector>;
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <QCloseEvent>
|
||||
|
||||
#include "SerializingObject.h"
|
||||
#include "lmms_basics.h"
|
||||
|
||||
|
||||
class QPushButton;
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
FloatModel* model() override;
|
||||
AutomatableModelView* modelView() override;
|
||||
|
||||
KnobControl(QWidget* parent = nullptr);
|
||||
KnobControl(const QString& text, QWidget* parent = nullptr);
|
||||
~KnobControl() override = default;
|
||||
};
|
||||
|
||||
|
||||
@@ -36,9 +36,7 @@ class LMMS_EXPORT CustomTextKnob : public Knob
|
||||
protected:
|
||||
inline void setHintText( const QString & _txt_before, const QString & _txt_after ) {} // inaccessible
|
||||
public:
|
||||
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
|
||||
CustomTextKnob( KnobType _knob_num, const QString& label, QWidget * _parent = nullptr, const QString & _name = QString(), const QString & _value_text = QString() );
|
||||
|
||||
CustomTextKnob( const Knob& other ) = delete;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -39,6 +39,10 @@ public:
|
||||
InlineAutomation()
|
||||
{
|
||||
}
|
||||
DetuningHelper(const DetuningHelper& _copy) :
|
||||
InlineAutomation(_copy)
|
||||
{
|
||||
}
|
||||
|
||||
~DetuningHelper() override = default;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
class QString;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <numbers>
|
||||
|
||||
#include "lmms_math.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "SampleFrame.h"
|
||||
|
||||
namespace lmms::DspEffectLibrary
|
||||
|
||||
@@ -57,6 +57,13 @@ protected:
|
||||
DropToolBar * addDropToolBar(QWidget * parent, Qt::ToolBarArea whereToAdd, QString const & windowTitle);
|
||||
|
||||
void closeEvent(QCloseEvent * event) override;
|
||||
void keyPressEvent(QKeyEvent *ke) override;
|
||||
public slots:
|
||||
//! Called by pressing the space key. Plays or stops.
|
||||
void togglePlayStop();
|
||||
//! Called by pressing shift+space. Toggles pause state.
|
||||
void togglePause();
|
||||
|
||||
protected slots:
|
||||
virtual void play() {}
|
||||
virtual void record() {}
|
||||
@@ -65,12 +72,6 @@ protected slots:
|
||||
virtual void stop() {}
|
||||
|
||||
private slots:
|
||||
/// Called by pressing the space key. Plays or stops.
|
||||
void togglePlayStop();
|
||||
|
||||
/// Called by pressing shift+space. Toggles pause state.
|
||||
void togglePause();
|
||||
|
||||
void toggleMaximize();
|
||||
|
||||
signals:
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
#include "EffectChain.h"
|
||||
#include "ModelView.h"
|
||||
#include "lmms_basics.h"
|
||||
|
||||
class QScrollArea;
|
||||
class QVBoxLayout;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
#include "lmms_export.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "AutomatableModel.h"
|
||||
#include "SampleBuffer.h"
|
||||
#include "TempoSyncKnobModel.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -171,6 +171,7 @@ private:
|
||||
QElapsedTimer m_lastPeakTimer_R;
|
||||
|
||||
QPixmap m_knob {embed::getIconPixmap("fader_knob")};
|
||||
QSize m_knobSize;
|
||||
|
||||
/**
|
||||
* @brief Stores the offset to the knob center when the user drags the fader knob
|
||||
|
||||
@@ -61,19 +61,22 @@ class FileBrowser : public SideBarWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
Normal,
|
||||
Favorites
|
||||
};
|
||||
|
||||
/**
|
||||
Create a file browser side bar widget
|
||||
@param directories '*'-separated list of directories to search for.
|
||||
If a directory of factory files should be in the list it
|
||||
must be the last one (for the factory files delimiter to work)
|
||||
@param filter Filter as used in QDir::match
|
||||
@param recurse *to be documented*
|
||||
*/
|
||||
FileBrowser( const QString & directories, const QString & filter,
|
||||
const QString & title, const QPixmap & pm,
|
||||
QWidget * parent, bool dirs_as_items = false,
|
||||
const QString& userDir = "",
|
||||
const QString& factoryDir = "");
|
||||
Create a file browser side bar widget
|
||||
@param directories '*'-separated list of directories to search for.
|
||||
If a directory of factory files should be in the list it
|
||||
must be the last one (for the factory files delimiter to work)
|
||||
@param filter Filter as used in QDir::match
|
||||
@param recurse *to be documented*
|
||||
*/
|
||||
FileBrowser(Type type, const QString& directories, const QString& filter, const QString& title, const QPixmap& pm,
|
||||
QWidget* parent, bool dirs_as_items = false, const QString& userDir = "", const QString& factoryDir = "");
|
||||
|
||||
~FileBrowser() override = default;
|
||||
|
||||
@@ -90,6 +93,7 @@ public:
|
||||
};
|
||||
return s_excludedPaths;
|
||||
}
|
||||
|
||||
static QDir::Filters dirFilters() { return QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden; }
|
||||
static QDir::SortFlags sortFlags() { return QDir::LocaleAware | QDir::DirsFirst | QDir::Name | QDir::IgnoreCase; }
|
||||
|
||||
@@ -101,7 +105,7 @@ private slots:
|
||||
private:
|
||||
void keyPressEvent( QKeyEvent * ke ) override;
|
||||
|
||||
void addItems( const QString & path );
|
||||
void addItems(const QString & path);
|
||||
|
||||
void saveDirectoriesStates();
|
||||
void restoreDirectoriesStates();
|
||||
@@ -117,6 +121,7 @@ private:
|
||||
FileBrowserTreeWidget * m_searchTreeWidget;
|
||||
|
||||
QLineEdit * m_filterEdit;
|
||||
Type m_type;
|
||||
|
||||
std::shared_ptr<FileSearch> m_currentSearch;
|
||||
QProgressBar* m_searchIndicator = nullptr;
|
||||
@@ -216,8 +221,7 @@ public:
|
||||
{
|
||||
path += QDir::separator();
|
||||
}
|
||||
return( QDir::cleanPath( path + text( 0 ) ) +
|
||||
QDir::separator() );
|
||||
return QDir::cleanPath(path + text(0));
|
||||
}
|
||||
|
||||
inline void addDirectory( const QString & dir )
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LMMS_FILE_REVEALER_H
|
||||
#define LMMS_FILE_REVEALER_H
|
||||
#ifndef LMMS_GUI_FILE_REVEALER_H
|
||||
#define LMMS_GUI_FILE_REVEALER_H
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace lmms {
|
||||
namespace lmms::gui {
|
||||
|
||||
/**
|
||||
* @class FileRevealer
|
||||
@@ -73,5 +73,6 @@ protected:
|
||||
static bool supportsArg(const QString& command, const QString& arg);
|
||||
};
|
||||
|
||||
} // namespace lmms
|
||||
#endif // LMMS_FILE_REVEALER_H
|
||||
} // namespace lmms::gui
|
||||
|
||||
#endif // LMMS_GUI_FILE_REVEALER_H
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LMMS_FONT_HELPER_H
|
||||
#define LMMS_FONT_HELPER_H
|
||||
#ifndef LMMS_GUI_FONT_HELPER_H
|
||||
#define LMMS_GUI_FONT_HELPER_H
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFont>
|
||||
@@ -44,4 +44,4 @@ inline QFont adjustedToPixelSize(QFont font, int size)
|
||||
|
||||
} // namespace lmms::gui
|
||||
|
||||
#endif // LMMS_FONT_HELPER_H
|
||||
#endif // LMMS_GUI_FONT_HELPER_H
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#include "Model.h"
|
||||
#include "ModelView.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define LMMS_GUI_GUI_APPLICATION_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSocketNotifier>
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "lmmsconfig.h"
|
||||
@@ -53,10 +54,14 @@ public:
|
||||
~GuiApplication() override;
|
||||
|
||||
static GuiApplication* instance();
|
||||
static void sigintHandler(int);
|
||||
static bool isWayland();
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
static QFont getWin32SystemFont();
|
||||
#endif
|
||||
|
||||
void createSocketNotifier();
|
||||
|
||||
MainWindow* mainWindow() { return m_mainWindow; }
|
||||
MixerView* mixerView() { return m_mixerView; }
|
||||
SongEditorWindow* songEditor() { return m_songEditor; }
|
||||
@@ -67,11 +72,15 @@ public:
|
||||
AutomationEditorWindow* automationEditor() { return m_automationEditor; }
|
||||
ControllerRackView* getControllerRackView() { return m_controllerRackView; }
|
||||
|
||||
//! File descriptors for unix socketpair, used to receive SIGINT
|
||||
static inline int s_sigintFd[2];
|
||||
|
||||
public slots:
|
||||
void displayInitProgress(const QString &msg);
|
||||
|
||||
private slots:
|
||||
void childDestroyed(QObject *obj);
|
||||
void sigintOccurred();
|
||||
|
||||
private:
|
||||
static GuiApplication* s_instance;
|
||||
@@ -86,6 +95,7 @@ private:
|
||||
MicrotunerConfig* m_microtunerConfig;
|
||||
ControllerRackView* m_controllerRackView;
|
||||
QLabel* m_loadingProgressLabel;
|
||||
QSocketNotifier* m_sigintNotifier;
|
||||
};
|
||||
|
||||
// Short-hand function
|
||||
|
||||
@@ -27,27 +27,28 @@
|
||||
|
||||
#include "AutomationNode.h"
|
||||
#include "AutomationClip.h"
|
||||
#include "shared_object.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
class InlineAutomation : public FloatModel, public sharedObject
|
||||
class InlineAutomation : public FloatModel
|
||||
{
|
||||
public:
|
||||
InlineAutomation() :
|
||||
FloatModel(),
|
||||
sharedObject(),
|
||||
m_autoClip( nullptr )
|
||||
FloatModel()
|
||||
{
|
||||
}
|
||||
|
||||
InlineAutomation(const InlineAutomation& _copy) :
|
||||
FloatModel(_copy.value(), _copy.minValue(), _copy.maxValue(), _copy.step<float>()),
|
||||
m_autoClip(_copy.m_autoClip->clone())
|
||||
{
|
||||
m_autoClip->clearObjects();
|
||||
m_autoClip->addObject(this);
|
||||
}
|
||||
|
||||
~InlineAutomation() override
|
||||
{
|
||||
if( m_autoClip )
|
||||
{
|
||||
delete m_autoClip;
|
||||
}
|
||||
}
|
||||
|
||||
virtual float defaultValue() const = 0;
|
||||
@@ -81,10 +82,10 @@ public:
|
||||
{
|
||||
if( m_autoClip == nullptr )
|
||||
{
|
||||
m_autoClip = new AutomationClip( nullptr );
|
||||
m_autoClip = std::make_unique<AutomationClip>(nullptr);
|
||||
m_autoClip->addObject( this );
|
||||
}
|
||||
return m_autoClip;
|
||||
return m_autoClip.get();
|
||||
}
|
||||
|
||||
void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
|
||||
@@ -92,7 +93,7 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
AutomationClip * m_autoClip;
|
||||
std::unique_ptr<AutomationClip> m_autoClip;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#include "Flags.h"
|
||||
#include "lmms_export.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "Plugin.h"
|
||||
#include "TimePos.h"
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "AutomatableButton.h"
|
||||
#include "ModelView.h"
|
||||
#include "PixmapButton.h"
|
||||
#include "SerializingObject.h"
|
||||
#include "PluginView.h"
|
||||
|
||||
@@ -148,8 +148,8 @@ private:
|
||||
Knob * m_volumeKnob;
|
||||
Knob * m_panningKnob;
|
||||
Knob * m_pitchKnob;
|
||||
PixmapButton *m_muteBtn;
|
||||
PixmapButton *m_soloBtn;
|
||||
AutomatableButton* m_muteBtn;
|
||||
AutomatableButton* m_soloBtn;
|
||||
QLabel * m_pitchLabel;
|
||||
LcdSpinBox* m_pitchRangeSpinBox;
|
||||
QLabel * m_pitchRangeLabel;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <QStack>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "SerializingObject.h"
|
||||
|
||||
namespace lmms
|
||||
|
||||
@@ -77,11 +77,65 @@ class LMMS_EXPORT Knob : public FloatModelEditorBase
|
||||
void onKnobNumUpdated(); //!< to be called when you updated @a m_knobNum
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Determines how the label of the knob is rendered.
|
||||
*
|
||||
* Labels can be rendered using the font that is set for the knob or using a
|
||||
* font with a fixed size which is determined by SMALL_FONT_SIZE.
|
||||
*/
|
||||
enum class LabelRendering
|
||||
{
|
||||
/**
|
||||
* @brief Renders the label using the font that is set for the widget.
|
||||
*
|
||||
* The space that's needed for the label is determined using the font metrics of the knob's font.
|
||||
*/
|
||||
WidgetFont,
|
||||
|
||||
/**
|
||||
* @brief Renders the labels in legacy mode. This uses a fixed font size and does not adhere
|
||||
* to the font size that's set for the widget's font.
|
||||
*
|
||||
* @deprecated Do not use this mode in new code as it is considered deprecated and might be removed in the future.
|
||||
*/
|
||||
LegacyFixedFontSize
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Construct a Knob with the given style and no label.
|
||||
*
|
||||
* @param _knob_num Style of the knob
|
||||
* @param _parent Parent widget
|
||||
* @param _name Object name of the widget
|
||||
*/
|
||||
Knob( KnobType _knob_num, QWidget * _parent = nullptr, const QString & _name = QString() );
|
||||
|
||||
/**
|
||||
* @brief Construct a Knob with the given style and label text.
|
||||
*
|
||||
* @param knobNum Style of the knob
|
||||
* @param labelText Text for the label
|
||||
* @param parent Parent widget
|
||||
* @param labelRendering Determines if the label uses the widget font or a font with a fixed size of 12 pixels (LegacyFixedFontSize). The default is to use the widget font.
|
||||
* @param name Object name of the widget
|
||||
*/
|
||||
Knob(KnobType knobNum, const QString& labelText, QWidget* parent = nullptr, LabelRendering labelRendering = LabelRendering::WidgetFont, const QString& name = QString());
|
||||
|
||||
/**
|
||||
* @brief Constructs a knob with a label font in the pixel size.
|
||||
*
|
||||
* @param knobNum Style of the knob
|
||||
* @param labelText Text for the label
|
||||
* @param labelPixelSize Pixel size for the label
|
||||
* @param parent Parent widget
|
||||
* @param name Object name of the widget
|
||||
*/
|
||||
Knob(KnobType knobNum, const QString& labelText, int labelPixelSize, QWidget* parent, const QString& name = QString());
|
||||
|
||||
Knob( QWidget * _parent = nullptr, const QString & _name = QString() ); //!< default ctor
|
||||
|
||||
Knob( const Knob& other ) = delete;
|
||||
|
||||
void setLabel( const QString & txt );
|
||||
void setHtmlLabel( const QString &htmltxt );
|
||||
|
||||
void setTotalAngle( float angle );
|
||||
@@ -113,15 +167,44 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
void paintEvent( QPaintEvent * _me ) override;
|
||||
void setLabel(const QString& txt);
|
||||
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
|
||||
void changeEvent(QEvent * ev) override;
|
||||
|
||||
/*!
|
||||
* Affects how the label of the knob is rendered.
|
||||
*
|
||||
* The default mode returns false. The height of the label text is taken into account when a new fixed
|
||||
* size is computed for the Knob. When the label text is painted the descent of the font is used to
|
||||
* compute the base line. The default mode returns false.
|
||||
*
|
||||
* Enabling fixed font size rendering mode leads to the following behavior:
|
||||
* * The height of the label is not taken into account when the new fixed height of the Knob is computed.
|
||||
* Instead a fixed size of 10 is added for the label.
|
||||
* * When the knob is painted the baseline of the font is always set to 2 pixels away from the lower side
|
||||
* of the Knob's rectangle.
|
||||
* * The label is always rendered with a size of SMALL_FONT_SIZE.
|
||||
*/
|
||||
bool fixedFontSizeLabelRendering() const { return m_fixedFontSizeLabelRendering; }
|
||||
|
||||
/*!
|
||||
* Set the button to legacy rendering mode which uses a fixed font size and that does not take the size
|
||||
* of the widget's font into account.
|
||||
*
|
||||
* This can be thought of as a legacy mode which reinstates the old behavior of the knob.
|
||||
*
|
||||
* @see fixedFontSizeLabelRendering().
|
||||
*/
|
||||
void setFixedFontSizeLabelRendering();
|
||||
|
||||
private:
|
||||
QLineF calculateLine( const QPointF & _mid, float _radius,
|
||||
float _innerRadius = 1) const;
|
||||
|
||||
void drawKnob( QPainter * _p );
|
||||
void drawLabel(QPainter& p);
|
||||
bool updateAngle();
|
||||
|
||||
int angleFromValue( float value, float minValue, float maxValue, float totalAngle ) const
|
||||
@@ -129,7 +212,10 @@ private:
|
||||
return static_cast<int>( ( value - 0.5 * ( minValue + maxValue ) ) / ( maxValue - minValue ) * m_totalAngle ) % 360;
|
||||
}
|
||||
|
||||
void updateFixedSize();
|
||||
|
||||
QString m_label;
|
||||
bool m_fixedFontSizeLabelRendering = false;
|
||||
bool m_isHtmlLabel;
|
||||
QTextDocument* m_tdRenderer;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
|
||||
namespace lmms
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
#include "AutomatableModel.h"
|
||||
#include "Controller.h"
|
||||
#include "ControllerDialog.h"
|
||||
#include "SampleBuffer.h"
|
||||
#include "TempoSyncKnobModel.h"
|
||||
#include "Oscillator.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* debug.h - header file to be included for debugging purposes
|
||||
*
|
||||
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* LmmsCommonMacros.h - defines some common macros used in the codebase
|
||||
*
|
||||
* Copyright (c) 2025 Roshan M R (Ross Maxx) <mrroshan127/at/gmail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -22,20 +22,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LMMS_DEBUG_H
|
||||
#define LMMS_DEBUG_H
|
||||
#ifndef LMMS_COMMON_MACROS_H
|
||||
#define LMMS_COMMON_MACROS_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
// Define standard macro NDEBUG when building without debug flag to make sure asserts become no-ops.
|
||||
#ifndef LMMS_DEBUG
|
||||
#ifndef NDEBUG
|
||||
#define NDEBUG
|
||||
#endif
|
||||
#endif // LMMS_DEBUG
|
||||
#define LMMS_STRINGIFY(s) LMMS_STR(s) // a macro used to stringify the plugin name
|
||||
#define LMMS_STR(PN) #PN
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
} // namespace lmms
|
||||
|
||||
|
||||
#endif // LMMS_DEBUG_H
|
||||
#endif // LMMS_COMMON_MACROS_H
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* lmms_basics.h - typedefs for common types that are used in the whole app
|
||||
* LmmsTypes.h - typedefs for common types that are used in the whole app
|
||||
*
|
||||
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -26,48 +26,31 @@
|
||||
#define LMMS_TYPES_H
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
using bar_t = int32_t;
|
||||
using tick_t = int32_t;
|
||||
using volume_t = uint8_t;
|
||||
using panning_t = int8_t;
|
||||
using bar_t = std::int32_t;
|
||||
using tick_t = std::int32_t;
|
||||
using volume_t = std::uint8_t;
|
||||
using panning_t = std::int8_t;
|
||||
|
||||
using sample_t = float; // standard sample-type
|
||||
using int_sample_t = int16_t; // 16-bit-int-sample
|
||||
using sample_t = float; // standard sample-type
|
||||
using int_sample_t = std::int16_t; // 16-bit-int-sample
|
||||
|
||||
using sample_rate_t = uint32_t; // sample-rate
|
||||
using fpp_t = size_t; // frames per period (0-16384)
|
||||
using f_cnt_t = size_t; // standard frame-count
|
||||
using ch_cnt_t = uint8_t; // channel-count (0-DEFAULT_CHANNELS)
|
||||
using bpm_t = uint16_t; // tempo (MIN_BPM to MAX_BPM)
|
||||
using bitrate_t = uint16_t; // bitrate in kbps
|
||||
using mix_ch_t = uint16_t; // Mixer-channel (0 to MAX_CHANNEL)
|
||||
using sample_rate_t = std::uint32_t; // sample-rate
|
||||
using fpp_t = std::size_t; // frames per period (0-16384)
|
||||
using f_cnt_t = std::size_t; // standard frame-count
|
||||
using ch_cnt_t = std::uint8_t; // channel-count (0-DEFAULT_CHANNELS)
|
||||
using bpm_t = std::uint16_t; // tempo (MIN_BPM to MAX_BPM)
|
||||
using bitrate_t = std::uint16_t; // bitrate in kbps
|
||||
using mix_ch_t = std::uint16_t; // Mixer-channel (0 to MAX_CHANNEL)
|
||||
using track_ch_t = std::uint16_t; // track channel index/count (0-256)
|
||||
using proc_ch_t = std::uint16_t; // audio processor channel index/count
|
||||
|
||||
using jo_id_t = uint32_t; // (unique) ID of a journalling object
|
||||
|
||||
|
||||
constexpr ch_cnt_t DEFAULT_CHANNELS = 2;
|
||||
|
||||
constexpr char LADSPA_PATH_SEPERATOR =
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
';';
|
||||
#else
|
||||
':';
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define LMMS_STRINGIFY(s) LMMS_STR(s)
|
||||
#define LMMS_STR(PN) #PN
|
||||
using jo_id_t = std::uint32_t; // (unique) ID of a journalling object
|
||||
|
||||
} // namespace lmms
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#include <ringbuffer/ringbuffer.h>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Flags.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "PluginIssue.h"
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ class ConfigManager;
|
||||
namespace gui
|
||||
{
|
||||
|
||||
class FileBrowser;
|
||||
class PluginView;
|
||||
class SubWindow;
|
||||
class ToolButton;
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#ifndef LMMS_MIDI_H
|
||||
#define LMMS_MIDI_H
|
||||
|
||||
#include "lmms_basics.h"
|
||||
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -53,12 +53,11 @@ public:
|
||||
} ;
|
||||
|
||||
MidiClip( InstrumentTrack* instrumentTrack );
|
||||
MidiClip( const MidiClip& other );
|
||||
~MidiClip() override;
|
||||
|
||||
void init();
|
||||
|
||||
void updateLength();
|
||||
void updateLength() override;
|
||||
|
||||
// note management
|
||||
Note * addNote( const Note & _new_note, const bool _quant_pos = true );
|
||||
@@ -79,6 +78,9 @@ public:
|
||||
Note * addStepNote( int step );
|
||||
void setStep( int step, bool enabled );
|
||||
|
||||
//! Horizontally flip the positions of the given notes.
|
||||
void reverseNotes(const NoteVector& notes);
|
||||
|
||||
// Split the list of notes on the given position
|
||||
void splitNotes(const NoteVector& notes, TimePos pos);
|
||||
|
||||
@@ -114,6 +116,11 @@ public:
|
||||
|
||||
gui::ClipView * createView( gui::TrackView * _tv ) override;
|
||||
|
||||
MidiClip* clone() override
|
||||
{
|
||||
return new MidiClip(*this);
|
||||
}
|
||||
|
||||
|
||||
using Model::dataChanged;
|
||||
|
||||
@@ -124,6 +131,7 @@ public slots:
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
MidiClip( const MidiClip& other );
|
||||
void updatePatternTrack();
|
||||
|
||||
protected slots:
|
||||
|
||||
@@ -63,6 +63,11 @@ public:
|
||||
QColor const & getMutedNoteBorderColor() const { return m_mutedNoteBorderColor; }
|
||||
void setMutedNoteBorderColor(QColor const & color) { m_mutedNoteBorderColor = color; }
|
||||
|
||||
// Returns true if selection can be merged and false if not
|
||||
static bool canMergeSelection(QVector<ClipView*> clipvs);
|
||||
static void mergeClips(QVector<ClipView*> clipvs);
|
||||
static void bulkClearNotesOutOfBounds(QVector<ClipView*> clipvs);
|
||||
|
||||
public slots:
|
||||
lmms::MidiClip* getMidiClip();
|
||||
void update() override;
|
||||
@@ -76,6 +81,7 @@ protected slots:
|
||||
void resetName();
|
||||
void changeName();
|
||||
void transposeSelection();
|
||||
void clearNotesOutOfBounds();
|
||||
|
||||
|
||||
protected:
|
||||
@@ -103,6 +109,10 @@ private:
|
||||
QStaticText m_staticTextName;
|
||||
|
||||
bool m_legacySEPattern;
|
||||
|
||||
bool isResizableBeforeStart() override { return false; }
|
||||
|
||||
bool destructiveSplitClip(const TimePos pos) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef LMMS_MIX_HELPERS_H
|
||||
#define LMMS_MIX_HELPERS_H
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
void contextMenuEvent(QContextMenuEvent*) override;
|
||||
void mousePressEvent(QMouseEvent*) override;
|
||||
void mouseDoubleClickEvent(QMouseEvent*) override;
|
||||
bool eventFilter(QObject* dist, QEvent* event) override;
|
||||
void keyPressEvent(QKeyEvent* ke) override;
|
||||
|
||||
void reset();
|
||||
int channelIndex() const { return m_channelIndex; }
|
||||
@@ -115,8 +115,8 @@ private:
|
||||
QLineEdit* m_renameLineEdit;
|
||||
QGraphicsView* m_renameLineEditView;
|
||||
QLabel* m_sendArrow;
|
||||
PixmapButton* m_muteButton;
|
||||
PixmapButton* m_soloButton;
|
||||
AutomatableButton* m_muteButton;
|
||||
AutomatableButton* m_soloButton;
|
||||
PeakIndicator* m_peakIndicator = nullptr;
|
||||
Fader* m_fader;
|
||||
EffectRackView* m_effectRackView;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#ifndef LMMS_NOTE_H
|
||||
#define LMMS_NOTE_H
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
@@ -103,10 +104,15 @@ public:
|
||||
int key = DefaultKey,
|
||||
volume_t volume = DefaultVolume,
|
||||
panning_t panning = DefaultPanning,
|
||||
DetuningHelper * detuning = nullptr );
|
||||
std::shared_ptr<DetuningHelper> detuning = nullptr);
|
||||
Note( const Note & note );
|
||||
~Note() override;
|
||||
|
||||
Note& operator=(const Note& note);
|
||||
|
||||
//! Performs a deep copy and returns an owning raw pointer
|
||||
Note* clone() const;
|
||||
|
||||
// Note types
|
||||
enum class Type
|
||||
{
|
||||
@@ -234,10 +240,8 @@ public:
|
||||
|
||||
static TimePos quantized( const TimePos & m, const int qGrid );
|
||||
|
||||
DetuningHelper * detuning() const
|
||||
{
|
||||
return m_detuning;
|
||||
}
|
||||
const std::shared_ptr<DetuningHelper>& detuning() const { return m_detuning; }
|
||||
|
||||
bool hasDetuningInfo() const;
|
||||
bool withinRange(int tickStart, int tickEnd) const;
|
||||
|
||||
@@ -262,7 +266,7 @@ private:
|
||||
panning_t m_panning;
|
||||
TimePos m_length;
|
||||
TimePos m_pos;
|
||||
DetuningHelper * m_detuning;
|
||||
std::shared_ptr<DetuningHelper> m_detuning;
|
||||
|
||||
Type m_type = Type::Regular;
|
||||
};
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
#include "Engine.h"
|
||||
#include "lmms_math.h"
|
||||
#include "lmmsconfig.h"
|
||||
#include "AudioEngine.h"
|
||||
#include "OscillatorConstants.h"
|
||||
#include "SampleBuffer.h"
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms::OscillatorConstants
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <QWidget>
|
||||
#include <QPixmap>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef LMMS_OUTPUT_SETTINGS_H
|
||||
#define LMMS_OUTPUT_SETTINGS_H
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
|
||||
namespace lmms::PathUtil
|
||||
{
|
||||
enum class Base { Absolute, ProjectDir, FactorySample, UserSample, UserVST, Preset,
|
||||
UserLADSPA, DefaultLADSPA, UserSoundfont, DefaultSoundfont, UserGIG, DefaultGIG,
|
||||
enum class Base { Absolute, ProjectDir, FactoryProjects, FactorySample, UserSample, UserVST, Preset,
|
||||
FactoryPresets, UserLADSPA, DefaultLADSPA, UserSoundfont, DefaultSoundfont, UserGIG, DefaultGIG,
|
||||
LocalDir };
|
||||
|
||||
//! Return the directory associated with a given base as a QString
|
||||
|
||||
@@ -51,6 +51,11 @@ public:
|
||||
|
||||
gui::ClipView * createView( gui::TrackView * _tv ) override;
|
||||
|
||||
PatternClip* clone() override
|
||||
{
|
||||
return new PatternClip(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class PatternClipView;
|
||||
} ;
|
||||
|
||||
@@ -78,7 +78,8 @@ private:
|
||||
static int m_loadCount;
|
||||
static bool m_buggedFile;
|
||||
|
||||
float m_coeff;
|
||||
float m_attackCoeff;
|
||||
float m_decayCoeff;
|
||||
bool m_coeffNeedsUpdate;
|
||||
} ;
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "ComboBoxModel.h"
|
||||
#include "SerializingObject.h"
|
||||
#include "Note.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "Song.h"
|
||||
#include "StepRecorder.h"
|
||||
#include "StepRecorderWidget.h"
|
||||
@@ -90,6 +90,7 @@ class PianoRoll : public QWidget
|
||||
Q_PROPERTY(int ghostNoteOpacity MEMBER m_ghostNoteOpacity)
|
||||
Q_PROPERTY(bool ghostNoteBorders MEMBER m_ghostNoteBorders)
|
||||
Q_PROPERTY(QColor backgroundShade MEMBER m_backgroundShade)
|
||||
Q_PROPERTY(QColor outOfBoundsShade MEMBER m_outOfBoundsShade)
|
||||
|
||||
/* white key properties */
|
||||
Q_PROPERTY(int whiteKeyWidth MEMBER m_whiteKeyWidth)
|
||||
@@ -112,7 +113,8 @@ public:
|
||||
Erase,
|
||||
Select,
|
||||
Detuning,
|
||||
Knife
|
||||
Knife,
|
||||
Strum
|
||||
};
|
||||
|
||||
/*! \brief Resets settings to default when e.g. creating a new project */
|
||||
@@ -247,6 +249,7 @@ protected slots:
|
||||
void clearGhostClip();
|
||||
void glueNotes();
|
||||
void fitNoteLengths(bool fill);
|
||||
void reverseNotes();
|
||||
void constrainNoteLengths(bool constrainMax);
|
||||
|
||||
void changeSnapMode();
|
||||
@@ -268,7 +271,8 @@ private:
|
||||
SelectNotes,
|
||||
ChangeNoteProperty,
|
||||
ResizeNoteEditArea,
|
||||
Knife
|
||||
Knife,
|
||||
Strum
|
||||
};
|
||||
|
||||
enum class NoteEditMode
|
||||
@@ -324,6 +328,9 @@ private:
|
||||
void setKnifeAction();
|
||||
void cancelKnifeAction();
|
||||
|
||||
void setStrumAction();
|
||||
void cancelStrumAction();
|
||||
|
||||
void updateScrollbars();
|
||||
void updatePositionLineHeight();
|
||||
|
||||
@@ -347,6 +354,7 @@ private:
|
||||
QPixmap m_toolMove = embed::getIconPixmap("edit_move");
|
||||
QPixmap m_toolOpen = embed::getIconPixmap("automation");
|
||||
QPixmap m_toolKnife = embed::getIconPixmap("edit_knife");
|
||||
QPixmap m_toolStrum = embed::getIconPixmap("arp_free");
|
||||
|
||||
static std::array<KeyType, 12> prKeyOrder;
|
||||
|
||||
@@ -437,6 +445,7 @@ private:
|
||||
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
|
||||
EditMode m_strumMode; //< mode they where in before entering strum mode
|
||||
|
||||
bool m_mouseDownRight; //true if right click is being held down
|
||||
|
||||
@@ -465,6 +474,21 @@ private:
|
||||
|
||||
void updateKnifePos(QMouseEvent* me, bool initial);
|
||||
|
||||
//! Stores the chords for the strum tool
|
||||
std::vector<NoteVector> m_selectedChords;
|
||||
//! Computes which notes belong to which chords from the selection
|
||||
void setupSelectedChords();
|
||||
|
||||
TimePos m_strumStartTime;
|
||||
TimePos m_strumCurrentTime;
|
||||
int m_strumStartVertical = 0;
|
||||
int m_strumCurrentVertical = 0;
|
||||
float m_strumHeightRatio = 0.0f;
|
||||
bool m_strumEnabled = false;
|
||||
//! Handles updating all of the note positions when performing a strum
|
||||
void updateStrumPos(QMouseEvent* me, bool initial, bool warp);
|
||||
|
||||
|
||||
friend class PianoRollWindow;
|
||||
|
||||
StepRecorderWidget m_stepRecorderWidget;
|
||||
@@ -493,6 +517,7 @@ private:
|
||||
bool m_noteBorders;
|
||||
bool m_ghostNoteBorders;
|
||||
QColor m_backgroundShade;
|
||||
QColor m_outOfBoundsShade;
|
||||
/* white key properties */
|
||||
int m_whiteKeyWidth;
|
||||
QColor m_whiteKeyActiveTextColor;
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#include "Flags.h"
|
||||
#include "ThreadableJob.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
class QThread;
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "Song.h"
|
||||
|
||||
namespace lmms::gui
|
||||
{
|
||||
|
||||
@@ -37,7 +39,7 @@ class PositionLine : public QWidget
|
||||
Q_PROPERTY(bool tailGradient MEMBER m_hasTailGradient)
|
||||
Q_PROPERTY(QColor lineColor MEMBER m_lineColor)
|
||||
public:
|
||||
PositionLine(QWidget* parent);
|
||||
PositionLine(QWidget* parent, Song::PlayMode playMode);
|
||||
|
||||
public slots:
|
||||
void zoomChange(float zoom);
|
||||
@@ -45,6 +47,8 @@ public slots:
|
||||
private:
|
||||
void paintEvent(QPaintEvent* pe) override;
|
||||
|
||||
Song::PlayMode m_playMode;
|
||||
|
||||
bool m_hasTailGradient;
|
||||
QColor m_lineColor;
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <QHash>
|
||||
#include <QStack>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "DataFile.h"
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#define LMMS_PROJECT_RENDERER_H
|
||||
|
||||
#include "AudioFileDevice.h"
|
||||
#include "lmmsconfig.h"
|
||||
#include "AudioEngine.h"
|
||||
#include "OutputSettings.h"
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "MidiEvent.h"
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <QObject>
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "lmms_export.h"
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#include "AudioEngine.h"
|
||||
#include "Engine.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "lmms_export.h"
|
||||
|
||||
namespace lmms {
|
||||
|
||||
@@ -49,13 +49,11 @@ class SampleClip : public Clip
|
||||
public:
|
||||
SampleClip(Track* track, Sample sample, bool isPlaying);
|
||||
SampleClip(Track* track);
|
||||
SampleClip( const SampleClip& orig );
|
||||
~SampleClip() override;
|
||||
|
||||
SampleClip& operator=( const SampleClip& that ) = delete;
|
||||
|
||||
void changeLength( const TimePos & _length ) override;
|
||||
void changeLengthToSampleLength();
|
||||
const QString& sampleFile() const;
|
||||
bool hasSampleFileLoaded(const QString & filename) const;
|
||||
|
||||
@@ -81,6 +79,11 @@ public:
|
||||
void setIsPlaying(bool isPlaying);
|
||||
void setSampleBuffer(std::shared_ptr<const SampleBuffer> sb);
|
||||
|
||||
SampleClip* clone() override
|
||||
{
|
||||
return new SampleClip(*this);
|
||||
}
|
||||
|
||||
public slots:
|
||||
void setSampleFile(const QString& sf);
|
||||
void updateLength();
|
||||
@@ -88,6 +91,8 @@ public slots:
|
||||
void playbackPositionChanged();
|
||||
void updateTrackClips();
|
||||
|
||||
protected:
|
||||
SampleClip( const SampleClip& orig );
|
||||
|
||||
private:
|
||||
Sample m_sample;
|
||||
|
||||
@@ -68,7 +68,7 @@ private:
|
||||
SampleClip * m_clip;
|
||||
SampleThumbnail m_sampleThumbnail;
|
||||
QPixmap m_paintPixmap;
|
||||
bool splitClip( const TimePos pos ) override;
|
||||
long m_paintPixmapXPosition;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "SampleFrame.h"
|
||||
|
||||
namespace lmms {
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
#ifndef LMMS_SAMPLEFRAME_H
|
||||
#define LMMS_SAMPLEFRAME_H
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "lmms_constants.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
@@ -54,10 +54,8 @@ public:
|
||||
{
|
||||
QRect sampleRect; //!< A rectangle that covers the entire range of samples.
|
||||
|
||||
QRect drawRect; //!< Specifies the location in `sampleRect` where the waveform will be drawn. Equals
|
||||
//!< `sampleRect` when null.
|
||||
|
||||
QRect viewportRect; //!< Clips `drawRect`. Equals `drawRect` when null.
|
||||
QRect viewportRect; //!< Specifies the location in `sampleRect` where the waveform will be drawn. Equals
|
||||
//!< `sampleRect` when null.
|
||||
|
||||
float amplification = 1.0f; //!< The amount of amplification to apply to the waveform.
|
||||
|
||||
@@ -95,8 +93,8 @@ private:
|
||||
Peak operator+(const Peak& other) const { return Peak(std::min(min, other.min), std::max(max, other.max)); }
|
||||
Peak operator+(const SampleFrame& frame) const { return *this + Peak{frame}; }
|
||||
|
||||
float min = std::numeric_limits<float>::max();
|
||||
float max = std::numeric_limits<float>::min();
|
||||
float min = std::numeric_limits<float>::infinity();
|
||||
float max = -std::numeric_limits<float>::infinity();
|
||||
};
|
||||
|
||||
Thumbnail() = default;
|
||||
@@ -105,6 +103,7 @@ private:
|
||||
|
||||
Thumbnail zoomOut(float factor) const;
|
||||
|
||||
Peak* data() { return m_peaks.data(); }
|
||||
Peak& operator[](size_t index) { return m_peaks[index]; }
|
||||
const Peak& operator[](size_t index) const { return m_peaks[index]; }
|
||||
|
||||
@@ -134,7 +133,7 @@ private:
|
||||
|
||||
using ThumbnailCache = std::vector<Thumbnail>;
|
||||
std::shared_ptr<ThumbnailCache> m_thumbnailCache = std::make_shared<ThumbnailCache>();
|
||||
|
||||
std::shared_ptr<const SampleBuffer> m_buffer = SampleBuffer::emptyBuffer();
|
||||
inline static std::unordered_map<SampleThumbnailEntry, std::shared_ptr<ThumbnailCache>, Hash> s_sampleThumbnailCacheMap;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
#include <QWidget>
|
||||
|
||||
#include "ModelView.h"
|
||||
#include "PixmapButton.h"
|
||||
#include "SampleTrack.h"
|
||||
#include "SerializingObject.h"
|
||||
#include "AutomatableButton.h"
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
@@ -91,8 +91,8 @@ private:
|
||||
QLineEdit * m_nameLineEdit;
|
||||
Knob * m_volumeKnob;
|
||||
Knob * m_panningKnob;
|
||||
PixmapButton *m_muteBtn;
|
||||
PixmapButton *m_soloBtn;
|
||||
AutomatableButton* m_muteBtn;
|
||||
AutomatableButton* m_soloBtn;
|
||||
MixerChannelLcdSpinBox * m_mixerChannelNumber;
|
||||
|
||||
EffectRackView * m_effectRack;
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
#include "AudioDevice.h"
|
||||
#include "AudioDeviceSetupWidget.h"
|
||||
#include "lmmsconfig.h"
|
||||
#include "MidiClient.h"
|
||||
#include "MidiSetupWidget.h"
|
||||
|
||||
@@ -183,6 +182,8 @@ private:
|
||||
QSlider * m_bufferSizeSlider;
|
||||
QLabel * m_bufferSizeLbl;
|
||||
QLabel * m_bufferSizeWarnLbl;
|
||||
int m_sampleRate;
|
||||
QSlider* m_sampleRateSlider;
|
||||
|
||||
// MIDI settings widgets.
|
||||
QComboBox * m_midiInterfaces;
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SIMPLE_TEXT_FLOAT_H
|
||||
#define SIMPLE_TEXT_FLOAT_H
|
||||
#ifndef LMMS_GUI_SIMPLE_TEXT_FLOAT_H
|
||||
#define LMMS_GUI_SIMPLE_TEXT_FLOAT_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
@@ -47,7 +47,10 @@ public:
|
||||
|
||||
void showWithDelay(int msecBeforeDisplay, int msecDisplayTime);
|
||||
|
||||
void setVisibilityTimeOut(int msecs);
|
||||
void showWithTimeout(int msec)
|
||||
{
|
||||
showWithDelay(0, msec);
|
||||
}
|
||||
|
||||
void moveGlobal(QWidget * w, const QPoint & offset)
|
||||
{
|
||||
@@ -64,4 +67,4 @@ private:
|
||||
|
||||
} // namespace lmms::gui
|
||||
|
||||
#endif
|
||||
#endif // LMMS_GUI_SIMPLE_TEXT_FLOAT_H
|
||||
|
||||
@@ -257,6 +257,7 @@ public:
|
||||
return m_playMode;
|
||||
}
|
||||
|
||||
PlayMode lastPlayMode() const { return m_lastPlayMode; }
|
||||
inline PlayPos & getPlayPos( PlayMode pm )
|
||||
{
|
||||
return m_playPos[static_cast<std::size_t>(pm)];
|
||||
@@ -492,6 +493,7 @@ private:
|
||||
std::array<Timeline, PlayModeCount> m_timelines;
|
||||
|
||||
PlayMode m_playMode;
|
||||
PlayMode m_lastPlayMode;
|
||||
PlayPos m_playPos[PlayModeCount];
|
||||
bar_t m_length;
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* SweepOscillator.h - sweeping oscillator
|
||||
*
|
||||
* Copyright (c) 2006-2014 Tobias Doerffel <tobydox/at/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 LMMS_SWEEP_OSCILLATOR_H
|
||||
#define LMMS_SWEEP_OSCILLATOR_H
|
||||
|
||||
#include "Oscillator.h"
|
||||
#include "DspEffectLibrary.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
template<class FX = DspEffectLibrary::StereoBypass>
|
||||
class SweepOscillator
|
||||
{
|
||||
public:
|
||||
SweepOscillator( const FX & _fx = FX() ) :
|
||||
m_phase( 0.0f ),
|
||||
m_FX( _fx )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SweepOscillator() = default;
|
||||
|
||||
void update( SampleFrame* buf, const fpp_t frames, const float freq1, const float freq2, const float sampleRate )
|
||||
{
|
||||
const float df = freq2 - freq1;
|
||||
for( fpp_t frame = 0; frame < frames; ++frame )
|
||||
{
|
||||
const sample_t s = Oscillator::sinSample( m_phase );
|
||||
buf[frame][0] = s;
|
||||
buf[frame][1] = s;
|
||||
m_FX.nextSample( buf[frame][0], buf[frame][1] );
|
||||
m_phase += ( freq1 + ( frame * df / frames ) ) / sampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
float m_phase;
|
||||
FX m_FX;
|
||||
|
||||
// inline sample_t getSample( const float _sample );
|
||||
// inline void recalcPhase();
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
} // namespace lmms
|
||||
|
||||
#endif // LMMS_SWEEP_OSCILLATOR_H
|
||||
@@ -42,6 +42,29 @@ class LMMS_EXPORT TempoSyncKnob : public Knob
|
||||
Q_OBJECT
|
||||
public:
|
||||
TempoSyncKnob( KnobType knobNum, QWidget* parent = nullptr, const QString& name = QString() );
|
||||
|
||||
/**
|
||||
* @brief Construct a TempoSyncKnob with the given style and label text.
|
||||
*
|
||||
* @param knobNum Style of the knob
|
||||
* @param labelText Text for the label
|
||||
* @param parent Parent widget
|
||||
* @param labelRendering Determines if the label uses the widget font or a font with a fixed size of 12 pixels (LegacyFixedFontSize). The default is to use the widget font.
|
||||
* @param name Object name of the widget
|
||||
*/
|
||||
TempoSyncKnob(KnobType knobNum, const QString& labelText, QWidget* parent = nullptr, LabelRendering labelRendering = LabelRendering::WidgetFont, const QString& name = QString());
|
||||
|
||||
/**
|
||||
* @brief Constructs a tempo sync knob with a label font in the pixel size.
|
||||
*
|
||||
* @param knobNum Style of the knob
|
||||
* @param labelText Text for the label
|
||||
* @param labelPixelSize Pixel size for the label
|
||||
* @param parent Parent widget
|
||||
* @param name Object name of the widget
|
||||
*/
|
||||
TempoSyncKnob(KnobType knobNum, const QString& labelText, int labelPixelSize, QWidget* parent, const QString& name = QString());
|
||||
|
||||
~TempoSyncKnob() override;
|
||||
|
||||
const QString & syncDescription();
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef LMMS_THREADABLE_JOB_H
|
||||
#define LMMS_THREADABLE_JOB_H
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include "lmms_export.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
TimePos( const bar_t bar, const tick_t ticks );
|
||||
TimePos( const tick_t ticks = 0 );
|
||||
|
||||
TimePos quantize(float) const;
|
||||
TimePos quantize(float bars, bool forceRoundDown = false) const;
|
||||
TimePos toAbsoluteBar() const { return getBar() * s_ticksPerBar; }
|
||||
|
||||
TimePos& operator+=(const TimePos& time)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#include "AutomatableModel.h"
|
||||
#include "JournallingObject.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include <optional>
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define LMMS_GUI_TRACK_OPERATIONS_WIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "AutomatableButton.h"
|
||||
|
||||
class QPushButton;
|
||||
|
||||
@@ -69,8 +70,8 @@ private:
|
||||
|
||||
TrackGrip* m_trackGrip;
|
||||
QPushButton * m_trackOps;
|
||||
PixmapButton * m_muteBtn;
|
||||
PixmapButton * m_soloBtn;
|
||||
AutomatableButton* m_muteBtn;
|
||||
AutomatableButton* m_soloBtn;
|
||||
|
||||
|
||||
friend class TrackView;
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
#include <QString>
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsCommonMacros.h"
|
||||
|
||||
|
||||
namespace lmms {
|
||||
|
||||
@@ -51,6 +52,24 @@ auto LMMS_EXPORT getIconPixmap(std::string_view name,
|
||||
int width = -1, int height = -1, const char* const* xpm = nullptr) -> QPixmap;
|
||||
auto LMMS_EXPORT getText(std::string_view name) -> QString;
|
||||
|
||||
/**
|
||||
* @brief Temporary shim for QPixmap::deviceIndependentSize.
|
||||
* @param pixmap The pixmap to get the size of.
|
||||
* @return The device-independent size of the pixmap.
|
||||
*/
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
|
||||
[[deprecated("Use QPixmap::deviceIndependentSize() instead; See "
|
||||
"https://doc.qt.io/qt-6/qpixmap.html#deviceIndependentSize")]]
|
||||
#endif
|
||||
inline auto logicalSize(const QPixmap &pixmap) noexcept
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
|
||||
return pixmap.deviceIndependentSize().toSize();
|
||||
#else
|
||||
return pixmap.isNull() ? QSize() : pixmap.size() / pixmap.devicePixelRatio();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace embed
|
||||
|
||||
class PixmapLoader
|
||||
|
||||
@@ -25,10 +25,9 @@
|
||||
#ifndef LMMS_ENDIAN_HANDLING_H
|
||||
#define LMMS_ENDIAN_HANDLING_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <QSysInfo>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -25,17 +25,23 @@
|
||||
#ifndef LMMS_CONSTANTS_H
|
||||
#define LMMS_CONSTANTS_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
// Prefer using `approximatelyEqual()` from lmms_math.h rather than
|
||||
// using this directly
|
||||
inline constexpr float F_EPSILON = 1.0e-10f; // 10^-10
|
||||
|
||||
inline constexpr ch_cnt_t DEFAULT_CHANNELS = 2;
|
||||
|
||||
// Microtuner
|
||||
inline constexpr unsigned MaxScaleCount = 10; //!< number of scales per project
|
||||
inline constexpr unsigned MaxKeymapCount = 10; //!< number of keyboard mappings per project
|
||||
|
||||
|
||||
// Note: All constants below are used only in spectrum analyser
|
||||
// Frequency ranges (in Hz).
|
||||
// Arbitrary low limit for logarithmic frequency scale; >1 Hz.
|
||||
inline constexpr auto LOWEST_LOG_FREQ = 5;
|
||||
@@ -79,6 +85,15 @@ inline constexpr auto ARANGE_LOUD_END = 0;
|
||||
inline constexpr auto ARANGE_SILENT_START = -60;
|
||||
inline constexpr auto ARANGE_SILENT_END = -10;
|
||||
|
||||
|
||||
// This macro is used to handle path seperation properly in windows
|
||||
constexpr char LADSPA_PATH_SEPERATOR =
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
';';
|
||||
#else
|
||||
':';
|
||||
#endif
|
||||
|
||||
} // namespace lmms
|
||||
|
||||
#endif // LMMS_CONSTANTS_H
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <numbers>
|
||||
#include <concepts>
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
#include "lmms_constants.h"
|
||||
|
||||
namespace lmms
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef LMMS_PANNING_H
|
||||
#define LMMS_PANNING_H
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
#include "Midi.h"
|
||||
#include "volume.h"
|
||||
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* shared_object.h - class sharedObject for use among other objects
|
||||
*
|
||||
* Copyright (c) 2006-2007 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
|
||||
* Copyright (c) 2008-2014 Tobias Doerffel <tobydox/at/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 LMMS_SHARED_OBJECT_H
|
||||
#define LMMS_SHARED_OBJECT_H
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
class sharedObject
|
||||
{
|
||||
public:
|
||||
sharedObject() :
|
||||
m_referenceCount(1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sharedObject() = default;
|
||||
|
||||
template<class T>
|
||||
static T* ref( T* object )
|
||||
{
|
||||
// Incrementing an atomic reference count can be relaxed since no action
|
||||
// is ever taken as a result of increasing the count.
|
||||
// Other loads and stores can be reordered around this without consequence.
|
||||
object->m_referenceCount.fetch_add(1, std::memory_order_relaxed);
|
||||
return object;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void unref( T* object )
|
||||
{
|
||||
// When decrementing an atomic reference count, we need to provide
|
||||
// two ordering guarantees:
|
||||
// 1. All reads and writes to the referenced object occur before
|
||||
// the count reaches zero.
|
||||
// 2. Deletion occurs after the count reaches zero.
|
||||
//
|
||||
// To accomplish this, each decrement must be store-released,
|
||||
// and the final thread (which is deleting the referenced data)
|
||||
// must load-acquire those stores.
|
||||
// The simplest way to do this to give the decrement acquire-release
|
||||
// semantics.
|
||||
//
|
||||
// See https://www.boost.org/doc/libs/1_67_0/doc/html/atomic/usage_examples.html
|
||||
// for further discussion, along with a slightly more complicated
|
||||
// (but possibly more performant on weakly-ordered hardware like ARM)
|
||||
// approach.
|
||||
const bool deleteObject =
|
||||
object->m_referenceCount.fetch_sub(1, std::memory_order_acq_rel) == 1;
|
||||
|
||||
if ( deleteObject )
|
||||
{
|
||||
object->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic_int m_referenceCount;
|
||||
} ;
|
||||
|
||||
|
||||
} // namespace lmms
|
||||
|
||||
#endif // LMMS_SHARED_OBJECT_H
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef LMMS_VERSION_INFO_H
|
||||
#define LMMS_VERSION_INFO_H
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsCommonMacros.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
constexpr const char* LMMS_BUILDCONF_COMPILER_VERSION = "GCC " __VERSION__;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef LMMS_VOLUME_H
|
||||
#define LMMS_VOLUME_H
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "LmmsTypes.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user