Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor SampleBuffer #6610

Merged
merged 170 commits into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from 134 commits
Commits
Show all changes
170 commits
Select commit Hold shift + click to select a range
49e8852
Add refactored SampleBuffer
sakertooth Aug 27, 2023
aeef0f8
Add Sample
sakertooth Aug 27, 2023
51bd371
Add SampleLoader
sakertooth Aug 27, 2023
e01b1fc
Integrate changes into AudioSampleRecorder
sakertooth Aug 27, 2023
7245b1a
Integrate changes into Oscillator
sakertooth Aug 27, 2023
d3ecea3
Integrate changes into SampleClip/SamplePlayHandle
sakertooth Aug 28, 2023
253ce15
Integrate changes into Graph
sakertooth Aug 28, 2023
6bf4483
Remove SampleBuffer include from SampleClipView
sakertooth Aug 28, 2023
25bb7ab
Integrate changes into Patman
sakertooth Aug 28, 2023
aca875b
Reduce indirection to sample buffer from Sample
sakertooth Aug 28, 2023
0017f66
Integrate changes into AudioFileProcessor
sakertooth Aug 28, 2023
53728ce
Remove old SampleBuffer
sakertooth Aug 28, 2023
12fe2b9
Include memory header in TripleOscillator
sakertooth Aug 28, 2023
2b37874
Include memory header in Oscillator
sakertooth Aug 28, 2023
6a53a10
Use atomic_load within SampleClip::sample
sakertooth Aug 28, 2023
3688073
Include memory header in EnvelopeAndLfoParameters
sakertooth Aug 28, 2023
d16b77e
Use std::atomic_load for most calls to Oscillator::userWaveSample
sakertooth Aug 28, 2023
dbf3214
Revert accidental change on SamplePlayHandle L.111
sakertooth Aug 28, 2023
d7f9f59
Check if audio file is empty before loading
sakertooth Aug 28, 2023
622405e
Add asserts to Sample
sakertooth Aug 28, 2023
cb42f0a
Add cassert include within Sample
sakertooth Aug 28, 2023
9583fcf
Adjust assert expressions in Sample
sakertooth Aug 29, 2023
1d45233
Remove use of shared ownership for Sample
sakertooth Aug 31, 2023
8c834aa
Merge remote-tracking branch 'upstream/master' into refactor-samplebu…
sakertooth Aug 31, 2023
48b545b
Use ArrayVector in Sample
sakertooth Aug 31, 2023
2b6166f
Enforce std::atomic_load for users of std::shared_ptr<const SampleBuf…
sakertooth Aug 31, 2023
6f79621
Use requestChangesGuard in ClipView::remove
sakertooth Aug 31, 2023
d68bd6f
Revert only formatting changes
sakertooth Aug 31, 2023
b1516ea
Update ClipView::remove comment
sakertooth Aug 31, 2023
5ac9159
Revert "Remove use of shared ownership for Sample"
sakertooth Sep 1, 2023
98c73b3
Merge remote-tracking branch 'upstream/master' into refactor-samplebu…
sakertooth Sep 4, 2023
d5bf069
Merge remote-tracking branch 'upstream/master' into refactor-samplebu…
sakertooth Sep 8, 2023
f5615b4
Fix heap-use-after-free in Track::loadSettings
sakertooth Sep 8, 2023
a5a01cf
Remove m_buffer asserts
sakertooth Sep 25, 2023
1f932d3
Refactor play functionality (again)
sakertooth Sep 26, 2023
e890aac
Merge remote-tracking branch 'upstream/master' into refactor-samplebu…
sakertooth Sep 26, 2023
8d18010
Merge branch 'master' into refactor-samplebuffer
sakertooth Sep 26, 2023
7025194
Change copyright
sakertooth Sep 26, 2023
700b7c7
Cast processingSampleRate to float
sakertooth Sep 26, 2023
5fa3dab
Update include/SampleLoader.h
sakertooth Sep 26, 2023
db77259
Update include/SampleLoader.h
sakertooth Sep 26, 2023
d4756de
Format SampleLoader.h
sakertooth Sep 26, 2023
f0ff0f9
Remove SampleBuffer.h include in SampleRecordHandle.h
sakertooth Sep 26, 2023
44c5bb5
Update src/core/Oscillator.cpp
sakertooth Sep 26, 2023
ee19205
Use typeInfo<float> for float equality comparison
sakertooth Sep 26, 2023
42086bb
Use std::min in Sample::visualize
sakertooth Sep 26, 2023
d6e6c1c
Move in result to m_data
sakertooth Sep 26, 2023
1e0c75c
Use if block in playSampleRange
sakertooth Sep 26, 2023
6900a2b
Pass in unique_ptr to SampleClip::setSampleBuffer
sakertooth Sep 26, 2023
4470454
Return const QString& from SampleBuffer::audioFile
sakertooth Sep 26, 2023
b324577
Do not pass in unique_ptr by r-value reference
sakertooth Sep 26, 2023
8e41e4c
Use isEmpty() within SampleClipView::updateSample
sakertooth Sep 26, 2023
7d87637
Remove use of atomic_store and atomic_load
sakertooth Sep 26, 2023
0600ced
Remove ArrayVector comment
sakertooth Sep 26, 2023
99e628a
Use array specialization for unique_ptr when managing DrumSynth data
sakertooth Sep 27, 2023
c5f7ccb
Don't manually delete Clip if it has a Track
sakertooth Sep 27, 2023
73da2e1
Clean up generateAntiAliasUserWaveTable function
sakertooth Sep 27, 2023
d41d02a
Set user wave, even when value is empty
sakertooth Sep 27, 2023
7c8804b
Remove whitespace in EnvelopeAndLfoParameters.cpp L#121
sakertooth Sep 27, 2023
8689a68
Fix error in c5f7ccba492dd867524156afa652c4eff99f9b40
sakertooth Sep 27, 2023
900e52c
Convert std::shared_ptr<Sample> to Sample
sakertooth Sep 27, 2023
1769ed5
Fix segfault when closing LMMS
sakertooth Sep 28, 2023
dcedcca
Construct buffer through SampleLoader in FileBrowser's previewFileIte…
sakertooth Oct 5, 2023
fb6c7b5
Move guard out of removeClip and deleteClips
sakertooth Oct 5, 2023
2792fcb
Simplify the switch in play function for loopMode
sakertooth Oct 5, 2023
8036289
Merge branch 'master' into refactor-samplebuffer
sakertooth Oct 5, 2023
46170b5
Add SampleDecoder
sakertooth Oct 6, 2023
f08c94a
Add LMMS_HAVE_OGGVORBIS comment
sakertooth Oct 6, 2023
432fafb
Fix unused variable error
sakertooth Oct 6, 2023
47af4f7
Include unordered_map
sakertooth Oct 6, 2023
5af5961
Simplify SampleDecoder
sakertooth Oct 7, 2023
6301022
Merge remote-tracking branch 'upstream/master' into refactor-samplebu…
sakertooth Oct 7, 2023
0e03a38
Attempt to fix Mac builds
sakertooth Oct 7, 2023
6b0b131
Attempt to fix Mac builds take 2
sakertooth Oct 7, 2023
afefc5b
Add vector include to SampleDecoder
sakertooth Oct 7, 2023
42e337b
Add TODO comment about shared ownership with clips
sakertooth Oct 7, 2023
b4ab016
Adjust TODO comment
sakertooth Oct 7, 2023
215f476
Remove Sample::playbackSize
sakertooth Oct 7, 2023
bccc685
Fix issues involving length of Sample's
sakertooth Oct 7, 2023
33783bf
Simplify if condition in src/gui/FileBrowser.cpp
sakertooth Oct 8, 2023
6c98654
Simplify if condition in src/core/SampleBuffer.cpp
sakertooth Oct 8, 2023
12464bc
Update style in include/Oscillator.h
sakertooth Oct 8, 2023
dcc5265
Format src/core/SampleDecoder.cpp
sakertooth Oct 11, 2023
c2a9dee
Set the sample rate to be that of the AudioEngine by default
sakertooth Oct 11, 2023
9046fc5
Set single-argument constructors in Sample and SampleBuffer to be exp…
sakertooth Oct 11, 2023
b617441
Do not make a copy when reading result from the decoder
sakertooth Oct 11, 2023
2025c98
Add constructor to pass in vector of sampleFrame's directly
sakertooth Oct 11, 2023
503561a
Do a pass by value and move in SampleBuffer.cpp
sakertooth Oct 11, 2023
6793a74
Pass vector by value in SampleBuffer.h
sakertooth Oct 11, 2023
4372eef
Make Sample(std::shared_ptr) constructor explicit
sakertooth Oct 12, 2023
37d05d0
Properly draw sample waveform when reversed
sakertooth Oct 12, 2023
3580999
Collect sample not found errors when loading project
sakertooth Oct 15, 2023
65d7803
Merge remote-tracking branch 'upstream/master' into refactor-samplebu…
sakertooth Oct 15, 2023
df980ab
Use std::make_unique<SampleBuffer> in SampleLoader
sakertooth Oct 15, 2023
037e007
Merge remote-tracking branch 'upstream/master' into refactor-samplebu…
sakertooth Oct 21, 2023
bcce57b
Fix loop modes
sakertooth Oct 26, 2023
ea91765
Limit sample duration to [start, end] and not the entire buffer
sakertooth Oct 26, 2023
d0c6f35
Use structured binding to access buffer
sakertooth Oct 26, 2023
fef9f8f
Check if GUI exists before displaying error
sakertooth Oct 26, 2023
971e832
Make Base64 constructor pass in the string instead
sakertooth Oct 27, 2023
aa760dc
Remove use of QByteArray::fromBase64Encoding
sakertooth Oct 27, 2023
2957647
Merge remote-tracking branch 'upstream/master' into refactor-samplebu…
sakertooth Nov 4, 2023
cf0d3a6
Inline simple functions in SampleBuffer
sakertooth Nov 8, 2023
be86cc3
Dynamically include supported audio file types
sakertooth Nov 10, 2023
686dc3c
Remove redundant inline specifier
sakertooth Nov 11, 2023
4ab1ebe
Translate file types
sakertooth Nov 11, 2023
0cb43f3
Cache calls to SampleDecoder::supportedAudioTypes
sakertooth Nov 11, 2023
6baecfa
Fix translations in SampleLoader (again)
sakertooth Nov 11, 2023
c863923
Store static local variable for supported audio types instead of in t…
sakertooth Nov 11, 2023
10c23c3
Clamp frame index depending on loop mode
sakertooth Nov 18, 2023
d5c6c63
Inline member functions of PlaybackState
sakertooth Nov 19, 2023
b0ace22
Merge remote-tracking branch 'upstream/master' into refactor-samplebu…
sakertooth Nov 19, 2023
1cb0bef
Do not collect errors in SampleLoader when loading projects
sakertooth Nov 19, 2023
74533d2
Default construct shared pointers to SampleBuffer
sakertooth Nov 19, 2023
4db9a17
Merge remote-tracking branch 'upstream/master' into refactor-samplebu…
sakertooth Nov 19, 2023
7678c41
Simplify and optimize Sample::visulaize()
DanielKauss Nov 19, 2023
0151ee1
Remove redundant gui:: prefix
sakertooth Nov 19, 2023
9fbfc08
Merge remote-tracking branch 'DanielKauss/refactor-samplebuffer' into…
sakertooth Nov 19, 2023
a215574
Rearrange Sample::visualize after optimizations by DanielKauss
sakertooth Nov 20, 2023
0dbbf1b
Apply amplification when visualizing sample waveforms
sakertooth Nov 20, 2023
6a45528
Set default min and max values to 1 and -1
sakertooth Nov 21, 2023
43cdfb2
Treat waveform as mono signal when visualizing
sakertooth Nov 22, 2023
e68fde3
Ensure visualization works when framesPerPixel < 1
sakertooth Nov 22, 2023
dd997f1
Simplify Sample::visualize a bit more
sakertooth Nov 22, 2023
e2a7b67
Fix CPU lag in Sample by using atomics (with relaxed ordering)
sakertooth Nov 23, 2023
77a5fe0
Merge remote-tracking branch 'upstream/master' into refactor-samplebu…
sakertooth Nov 28, 2023
e85f339
Fix errors from merge
sakertooth Nov 28, 2023
8ebd3a2
Fix broken LFO controller functionality
sakertooth Nov 30, 2023
a008316
Remove TODO
sakertooth Nov 30, 2023
d2daa2d
Update EnvelopeAndLfoView.cpp
sakertooth Dec 4, 2023
5f5dee5
Update src/gui/clips/SampleClipView.cpp
sakertooth Dec 4, 2023
27f4438
Update plugins/SlicerT/SlicerT.cpp
sakertooth Dec 4, 2023
0f5c27a
Update plugins/SlicerT/SlicerT.cpp
sakertooth Dec 4, 2023
807da3b
Store shortest relative path in SampleBuffer
sakertooth Dec 13, 2023
c971d1b
Tie up a few loose ends
sakertooth Dec 16, 2023
46e5cca
Use sample_rate_t when storing sample rate in SampleBuffer
sakertooth Dec 23, 2023
c7ce788
Add missing named requirement functions and aliases
sakertooth Dec 23, 2023
0a38244
Use sampledata attribute when loading from Base64 in AFP
sakertooth Dec 23, 2023
5b51686
Remove initializer for m_userWave in the constructor
sakertooth Dec 23, 2023
e7da94d
Do not use trailing return syntax when return is void
sakertooth Dec 23, 2023
9054a9f
Move decoder functionality into unnamed namespace
sakertooth Dec 23, 2023
70ec50d
Remove redundant gui:: prefix
sakertooth Dec 23, 2023
1bfb4bb
Use PathUtil::toAbsolute to simplify code in SampleLoader::openAudioFile
sakertooth Dec 24, 2023
97cdfdb
Fix translations in SampleLoader::openAudioFile
sakertooth Dec 24, 2023
1d098d3
Fix formatting for ternary operator
sakertooth Dec 24, 2023
6cca49c
Remove redundant inlines
sakertooth Dec 24, 2023
429e889
Resolve UB when decoding from Base64 data in SampleBuffer
sakertooth Dec 24, 2023
9ac9c09
Fix up SampleClip constructors
sakertooth Dec 24, 2023
8f6d986
Add AudioResampler, a wrapper class around libsamplerate
sakertooth Dec 24, 2023
c6e7417
Move buffer when moving and simplify assignment functions in Sample
sakertooth Dec 24, 2023
b84b383
Move Sample::visualize out of Sample and into the GUI namespace
sakertooth Dec 24, 2023
6bb3e01
Initialize supportedAudioTypes in static lambda
sakertooth Dec 24, 2023
e50ac67
Return shared pointer from SampleLoader
sakertooth Dec 24, 2023
0217c28
Create and use static empty SampleBuffer by default
sakertooth Dec 24, 2023
d7bcf2f
Fix header guard in SampleWaveform.h
sakertooth Dec 24, 2023
a735c03
Remove use of src_clone
sakertooth Dec 24, 2023
09e336b
Include memory header in SampleBuffer.h
sakertooth Dec 24, 2023
f444281
Remove mutex and shared_mutex includes in Sample.h
sakertooth Dec 24, 2023
2b553f2
Attempt to fix string operand error within AudioResampler
sakertooth Dec 24, 2023
2c58bb6
Include string header in AudioResampler.cpp
sakertooth Dec 24, 2023
9ffba98
Add LMMS_EXPORT for SampleWaveform class declaration
sakertooth Dec 24, 2023
5b9a847
Add LMMS_EXPORT for AudioResampler class declaration
sakertooth Dec 24, 2023
a45802f
Enforce returning std::shared_ptr<const SampleBuffer>
sakertooth Dec 25, 2023
8cdb1e2
Restrict the size of the memcpy to the destination size, not the sour…
sakertooth Dec 25, 2023
b6480a2
Do not make resample const
sakertooth Dec 25, 2023
d56083d
Initialize data.end_of_input
sakertooth Dec 25, 2023
bf4b9c7
Add trailing new lines
sakertooth Dec 25, 2023
c12e7de
Simplify AudioResampler interface
sakertooth Dec 25, 2023
c81d838
Fix header guard prefix to LMMS_GUI instead of LMMS
sakertooth Dec 25, 2023
5a45282
Remove Sample::resampleSampleRange
sakertooth Dec 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/AudioSampleRecorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <QList>
#include <QPair>
#include <memory>

#include "AudioDevice.h"

Expand All @@ -44,8 +45,7 @@ class AudioSampleRecorder : public AudioDevice
~AudioSampleRecorder() override;

f_cnt_t framesRecorded() const;
void createSampleBuffer( SampleBuffer** sampleBuffer );

std::unique_ptr<SampleBuffer> createSampleBuffer();

private:
void writeBuffer( const surroundSampleFrame * _ab,
Expand Down
3 changes: 2 additions & 1 deletion include/EnvelopeAndLfoParameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#ifndef LMMS_ENVELOPE_AND_LFO_PARAMETERS_H
#define LMMS_ENVELOPE_AND_LFO_PARAMETERS_H

#include <memory>
#include <vector>

#include "JournallingObject.h"
Expand Down Expand Up @@ -167,7 +168,7 @@ public slots:
sample_t * m_lfoShapeData;
sample_t m_random;
bool m_bad_lfoShapeData;
SampleBuffer m_userWave;
std::shared_ptr<const SampleBuffer> m_userWave = std::make_shared<SampleBuffer>();
sakertooth marked this conversation as resolved.
Show resolved Hide resolved

enum class LfoShape
{
Expand Down
2 changes: 1 addition & 1 deletion include/LfoController.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public slots:

private:
float m_heldSample;
SampleBuffer * m_userDefSampleBuffer;
std::shared_ptr<const SampleBuffer> m_userDefSampleBuffer = std::make_shared<SampleBuffer>();

protected slots:
void updatePhase();
Expand Down
30 changes: 23 additions & 7 deletions include/Oscillator.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@

#include <cassert>
#include <fftw3.h>
#include <memory>
#include <cstdlib>
#include "interpolation.h"

#include "Engine.h"
#include "lmms_constants.h"
Expand All @@ -46,7 +48,6 @@ class IntModel;

class LMMS_EXPORT Oscillator
{
MM_OPERATORS
public:
enum class WaveShape
{
Expand Down Expand Up @@ -91,18 +92,23 @@ class LMMS_EXPORT Oscillator

static void waveTableInit();
static void destroyFFTPlans();
static void generateAntiAliasUserWaveTable(SampleBuffer* sampleBuffer);
static std::unique_ptr<OscillatorConstants::waveform_t> generateAntiAliasUserWaveTable(const SampleBuffer* sampleBuffer);

inline void setUseWaveTable(bool n)
{
m_useWaveTable = n;
}

inline void setUserWave( const SampleBuffer * _wave )
inline void setUserWave(std::shared_ptr<const SampleBuffer> _wave)
{
m_userWave = _wave;
}

inline void setUserAntiAliasWaveTable(std::shared_ptr<const OscillatorConstants::waveform_t> waveform)
sakertooth marked this conversation as resolved.
Show resolved Hide resolved
{
m_userAntiAliasWaveTable = waveform;
}

void update(sampleFrame* ab, const fpp_t frames, const ch_cnt_t chnl, bool modulator = false);

// now follow the wave-shape-routines...
Expand Down Expand Up @@ -164,9 +170,18 @@ class LMMS_EXPORT Oscillator
return 1.0f - fast_rand() * 2.0f / FAST_RAND_MAX;
}

inline sample_t userWaveSample( const float _sample ) const
static inline sample_t userWaveSample(const SampleBuffer* buffer, const float sample)
{
return m_userWave->userWaveSample( _sample );
if (buffer == nullptr || buffer->size() == 0) { return 0; }
const auto frames = buffer->size();
const auto frame = sample * frames;
auto f1 = static_cast<f_cnt_t>(frame) % frames;
if (f1 < 0)
{
f1 += frames;
}

return linearInterpolate(buffer->data()[f1][0], buffer->data()[(f1 + 1) % frames][0], fraction(frame));
}

struct wtSampleControl {
Expand Down Expand Up @@ -203,7 +218,7 @@ class LMMS_EXPORT Oscillator
table[control.band][control.f2], fraction(control.frame));
}

inline sample_t wtSample(const std::unique_ptr<OscillatorConstants::waveform_t>& table, const float sample) const
inline sample_t wtSample(const OscillatorConstants::waveform_t* table, const float sample) const
{
assert(table != nullptr);
wtSampleControl control = getWtSampleControl(sample);
Expand Down Expand Up @@ -247,7 +262,8 @@ class LMMS_EXPORT Oscillator
Oscillator * m_subOsc;
float m_phaseOffset;
float m_phase;
const SampleBuffer * m_userWave;
std::shared_ptr<const SampleBuffer> m_userWave = std::make_shared<SampleBuffer>();
std::shared_ptr<const OscillatorConstants::waveform_t> m_userAntiAliasWaveTable;
bool m_useWaveTable;
// There are many update*() variants; the modulator flag is stored as a member variable to avoid
// adding more explicit parameters to all of them. Can be converted to a parameter if needed.
Expand Down
158 changes: 158 additions & 0 deletions include/Sample.h
sakertooth marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* Sample.h - State for container-class SampleBuffer
*
* Copyright (c) 2023 saker <[email protected]>
*
* 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_SAMPLE_H
#define LMMS_SAMPLE_H

#include <cmath>
#include <memory>

#include "Note.h"
#include "SampleBuffer.h"
#include "lmms_export.h"

#ifdef __MINGW32__
#include <mingw.mutex.h>
#include <mingw.shared_mutex.h>
#else
#include <mutex>
#include <shared_mutex>
#endif

class QPainter;
class QRect;

namespace lmms {
messmerd marked this conversation as resolved.
Show resolved Hide resolved
class LMMS_EXPORT Sample
{
public:
// values for buffer margins, used for various libsamplerate interpolation modes
// the array positions correspond to the converter_type parameter values in libsamplerate
// if there appears problems with playback on some interpolation mode, then the value for that mode
// may need to be higher - conversely, to optimize, some may work with lower values
static constexpr auto s_interpolationMargins = std::array<int, 5>{64, 64, 64, 4, 4};

enum class Loop
{
Off,
On,
PingPong
};

class LMMS_EXPORT PlaybackState
{
public:
PlaybackState(bool varyingPitch = false, int interpolationMode = SRC_LINEAR)
: m_varyingPitch(varyingPitch)
, m_interpolationMode(interpolationMode)
{
auto error = 0;
m_resampleState = src_new(m_interpolationMode, DEFAULT_CHANNELS, &error);
if (error != 0)
{
throw std::runtime_error{"Error creating resample state: " + std::string{src_strerror(error)}};
}
}

~PlaybackState() noexcept { src_delete(m_resampleState); }
sakertooth marked this conversation as resolved.
Show resolved Hide resolved

auto frameIndex() const -> f_cnt_t { return m_frameIndex; }
auto varyingPitch() const -> bool { return m_varyingPitch; }
auto backwards() const -> bool { return m_backwards; }
auto interpolationMode() const -> int { return m_interpolationMode; }

auto setFrameIndex(f_cnt_t frameIndex) -> void { m_frameIndex = frameIndex; }
sakertooth marked this conversation as resolved.
Show resolved Hide resolved
auto setVaryingPitch(bool varyingPitch) -> void { m_varyingPitch = varyingPitch; }
auto setBackwards(bool backwards) -> void { m_backwards = backwards; }

private:
f_cnt_t m_frameIndex = 0;
bool m_varyingPitch = false;
bool m_backwards = false;
SRC_STATE* m_resampleState = nullptr;
int m_interpolationMode = SRC_LINEAR;
friend class Sample;
};

Sample() = default;
Sample(const QByteArray& base64, int sampleRate = Engine::audioEngine()->processingSampleRate());
Sample(const sampleFrame* data, int numFrames, int sampleRate = Engine::audioEngine()->processingSampleRate());
Sample(const Sample& other);
Sample(Sample&& other);
explicit Sample(const QString& audioFile);
explicit Sample(std::shared_ptr<const SampleBuffer> buffer);

auto operator=(const Sample&) -> Sample&;
auto operator=(Sample&&) -> Sample&;

auto play(sampleFrame* dst, PlaybackState* state, int numFrames, float desiredFrequency = DefaultBaseFreq,
Loop loopMode = Loop::Off) const -> bool;
auto visualize(QPainter& p, const QRect& dr, int fromFrame = 0, int toFrame = 0) const -> void;
sakertooth marked this conversation as resolved.
Show resolved Hide resolved

auto sampleDuration() const -> std::chrono::milliseconds;
auto sampleFile() const -> const QString& { return m_buffer->audioFile(); }
auto sampleRate() const -> int { return m_buffer->sampleRate(); }
auto sampleSize() const -> int { return m_buffer->size(); }

auto toBase64() const -> QString { return m_buffer->toBase64(); }

auto data() -> const sampleFrame* { return m_buffer->data(); }
auto buffer() const -> std::shared_ptr<const SampleBuffer> { return m_buffer; }
auto startFrame() const -> int { return m_startFrame.load(std::memory_order_relaxed); }
auto endFrame() const -> int { return m_endFrame.load(std::memory_order_relaxed); }
auto loopStartFrame() const -> int { return m_loopStartFrame.load(std::memory_order_relaxed); }
auto loopEndFrame() const -> int { return m_loopEndFrame.load(std::memory_order_relaxed); }
auto amplification() const -> float { return m_amplification.load(std::memory_order_relaxed); }
auto frequency() const -> float { return m_frequency.load(std::memory_order_relaxed); }
auto reversed() const -> bool { return m_reversed.load(std::memory_order_relaxed); }

auto setStartFrame(int startFrame) -> void { m_startFrame.store(startFrame, std::memory_order_relaxed); }
auto setEndFrame(int endFrame) -> void { m_endFrame.store(endFrame, std::memory_order_relaxed); }
auto setLoopStartFrame(int loopStartFrame) -> void { m_loopStartFrame.store(loopStartFrame, std::memory_order_relaxed); }
auto setLoopEndFrame(int loopEndFrame) -> void { m_loopEndFrame.store(loopEndFrame, std::memory_order_relaxed); }
auto setAllPointFrames(int startFrame, int endFrame, int loopStartFrame, int loopEndFrame) -> void;
auto setAmplification(float amplification) -> void { m_amplification.store(amplification, std::memory_order_relaxed); }
auto setFrequency(float frequency) -> void { m_frequency.store(frequency, std::memory_order_relaxed); }
auto setReversed(bool reversed) -> void { m_reversed.store(reversed, std::memory_order_relaxed); }

private:
auto playSampleRange(PlaybackState* state, sampleFrame* dst, size_t numFrames) const -> void;
auto resampleSampleRange(SRC_STATE* state, sampleFrame* src, sampleFrame* dst, size_t numInputFrames,
size_t numOutputFrames, double ratio) const -> SRC_DATA;
auto amplifySampleRange(sampleFrame* src, int numFrames) const -> void;
auto copyBufferForward(sampleFrame* dst, int initialPosition, int advanceAmount) const -> void;
auto copyBufferBackward(sampleFrame* dst, int initialPosition, int advanceAmount) const -> void;

private:
std::shared_ptr<const SampleBuffer> m_buffer = std::make_shared<SampleBuffer>();
std::atomic<int> m_startFrame = 0;
std::atomic<int> m_endFrame = 0;
std::atomic<int> m_loopStartFrame = 0;
std::atomic<int> m_loopEndFrame = 0;
std::atomic<float> m_amplification = 1.0f;
std::atomic<float> m_frequency = DefaultBaseFreq;
std::atomic<bool> m_reversed = false;
};
} // namespace lmms
#endif
sakertooth marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading