forked from LMMS/lmms
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement sample caching (LMMS#6390)
This implements a framework for the caching/sharing of samples. Reintegration still needs to occur, so not everything is complete. This is just to simplify the changes. SampleBufferV2 is where samples and any pertaining data to that sample is stored. From there, Sample's use that buffer but do not change it. They do that by storing a std::shared_ptr<const SampleBufferV2>, which gives read-only access to the buffer. SampleBufferCache tracks the samples used in a project from a file or from Base64. If something needs a certain sample that is tracked by this cache, it will just create a std::shared_ptr from that tracked sample. The tracking is done with std::weak_ptr's within the SampleBufferCache.
- Loading branch information
1 parent
3964c53
commit 3b74f03
Showing
18 changed files
with
1,322 additions
and
387 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/* | ||
* Sample.h - a SampleBuffer with its own characteristics | ||
* | ||
* Copyright (c) 2022 sakertooth <sakertooth@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 SAMPLE_H | ||
#define SAMPLE_H | ||
|
||
#include <QObject> | ||
#include <QPainter> | ||
#include <QRect> | ||
#include <QString> | ||
#include <memory> | ||
#include <samplerate.h> | ||
|
||
#include "Note.h" | ||
#include "SampleBufferCache.h" | ||
#include "SampleBufferV2.h" | ||
#include "lmms_basics.h" | ||
|
||
class Sample | ||
{ | ||
public: | ||
enum class PlaybackType | ||
{ | ||
Regular, | ||
LoopPoints, | ||
PingPong | ||
}; | ||
|
||
Sample() = default; | ||
Sample(const QString& strData, SampleBufferV2::StrDataType dataType); | ||
Sample(const sampleFrame* data, const f_cnt_t numFrames); | ||
explicit Sample(const SampleBufferV2* buffer); | ||
explicit Sample(const f_cnt_t numFrames); | ||
|
||
Sample(const Sample& other); | ||
Sample& operator=(const Sample& other); | ||
|
||
Sample(Sample&& other); | ||
Sample& operator=(Sample&& other); | ||
|
||
bool play(sampleFrame* dst, const fpp_t numFrames, const float freq); | ||
void visualize(QPainter& painter, const QRect& drawingRect, f_cnt_t fromFrame = 0, f_cnt_t toFrame = 0); | ||
|
||
QString sampleFile() const; | ||
std::shared_ptr<const SampleBufferV2> sampleBuffer() const; | ||
sample_rate_t sampleRate() const; | ||
float amplification() const; | ||
float frequency() const; | ||
bool reversed() const; | ||
bool varyingPitch() const; | ||
int interpolationMode() const; | ||
f_cnt_t startFrame() const; | ||
f_cnt_t endFrame() const; | ||
f_cnt_t loopStartFrame() const; | ||
f_cnt_t loopEndFrame() const; | ||
f_cnt_t frameIndex() const; | ||
f_cnt_t numFrames() const; | ||
PlaybackType playback() const; | ||
|
||
void setSampleData(const QString& str, SampleBufferV2::StrDataType dataType); | ||
void setSampleBuffer(const SampleBufferV2* buffer); | ||
void setAmplification(float amplification); | ||
void setFrequency(float frequency); | ||
void setReversed(bool reversed); | ||
void setVaryingPitch(bool varyingPitch); | ||
void setInterpolationMode(int interpolationMode); | ||
void setStartFrame(f_cnt_t start); | ||
void setEndFrame(f_cnt_t end); | ||
void setLoopStartFrame(f_cnt_t loopStart); | ||
void setLoopEndFrame(f_cnt_t loopEnd); | ||
void setFrameIndex(f_cnt_t frameIndex); | ||
void setPlayback(PlaybackType playback); | ||
|
||
void loadAudioFile(const QString& audioFile); | ||
void loadBase64(const QString& base64); | ||
|
||
void resetMarkers(); | ||
int calculateTickLength() const; | ||
QString openSample(); | ||
|
||
private: | ||
std::shared_ptr<const SampleBufferV2> m_sampleBuffer = nullptr; | ||
float m_amplification = 1.0f; | ||
float m_frequency = DefaultBaseFreq; | ||
bool m_reversed = false; | ||
bool m_varyingPitch = false; | ||
bool m_pingPongBackwards = false; | ||
int m_interpolationMode = SRC_LINEAR; | ||
f_cnt_t m_startFrame = 0; | ||
f_cnt_t m_endFrame = 0; | ||
f_cnt_t m_loopStartFrame = 0; | ||
f_cnt_t m_loopEndFrame = 0; | ||
f_cnt_t m_frameIndex = 0; | ||
PlaybackType m_playback = PlaybackType::Regular; | ||
SRC_STATE* resampleState = nullptr; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* SampleBufferCache.h - Used to cache sample buffers | ||
* | ||
* Copyright (c) 2022 sakertooth <sakertooth@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 SAMPLE_BUFFER_CACHE_H | ||
#define SAMPLE_BUFFER_CACHE_H | ||
|
||
#include <QHash> | ||
#include <QString> | ||
#include <memory> | ||
|
||
#include "SampleBufferV2.h" | ||
|
||
class SampleBufferCache | ||
{ | ||
public: | ||
std::shared_ptr<const SampleBufferV2> get(const QString& id); | ||
std::shared_ptr<const SampleBufferV2> add(const QString& id, const SampleBufferV2* buffer); | ||
|
||
private: | ||
QHash<QString, std::weak_ptr<const SampleBufferV2>> m_hash; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* SampleBufferV2.h - container class for immutable sample data | ||
* | ||
* Copyright (c) 2022 sakertooth <sakertooth@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 SAMPLE_BUFFER_V2_H | ||
#define SAMPLE_BUFFER_V2_H | ||
|
||
#include "Engine.h" | ||
#include "AudioEngine.h" | ||
#include "lmms_basics.h" | ||
|
||
#include <QObject> | ||
#include <QString> | ||
#include <memory> | ||
#include <vector> | ||
|
||
|
||
class SampleBufferV2 | ||
{ | ||
public: | ||
enum class StrDataType | ||
{ | ||
AudioFile, | ||
Base64 | ||
}; | ||
|
||
SampleBufferV2(const QString& strData, StrDataType dataType); | ||
SampleBufferV2(const sampleFrame* data, const f_cnt_t numFrames); | ||
explicit SampleBufferV2(const f_cnt_t numFrames); | ||
|
||
SampleBufferV2(const SampleBufferV2& other) = delete; | ||
SampleBufferV2& operator=(const SampleBufferV2& other) = delete; | ||
|
||
SampleBufferV2(SampleBufferV2&& other); | ||
SampleBufferV2& operator=(SampleBufferV2&& other); | ||
|
||
const std::vector<sampleFrame>& sampleData() const; | ||
sample_rate_t originalSampleRate() const; | ||
f_cnt_t numFrames() const; | ||
|
||
const QString& filePath() const; | ||
bool hasFilePath() const; | ||
|
||
QString toBase64() const; | ||
|
||
private: | ||
void loadFromAudioFile(const QString& audioFilePath); | ||
void loadFromDrumSynthFile(const QString& drumSynthFilePath); | ||
void loadFromBase64(const QString& str); | ||
void resample(const sample_rate_t oldSampleRate, const sample_rate_t newSampleRate); | ||
|
||
private: | ||
std::vector<sampleFrame> m_sampleData; | ||
sample_rate_t m_originalSampleRate; | ||
QString m_filePath; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.