Convert std::shared_ptr<Sample> to Sample

This conversion does not apply to Patman as there seems to be issues
with it causing heap-use-after-free issues, such as with
PatmanInstrument::unloadCurrentPatch
This commit is contained in:
sakertooth
2023-09-27 17:20:59 -04:00
parent 8689a68ad5
commit 900e52cc1a
8 changed files with 53 additions and 54 deletions

View File

@@ -63,7 +63,7 @@ public:
return "sampleclip";
}
std::shared_ptr<Sample> sample()
const Sample& sample()
{
return m_sample;
}
@@ -87,7 +87,7 @@ public slots:
private:
std::shared_ptr<Sample> m_sample = std::make_shared<Sample>();
Sample m_sample;
BoolModel m_recordModel;
bool m_isPlaying;

View File

@@ -44,7 +44,7 @@ class AudioPort;
class LMMS_EXPORT SamplePlayHandle : public PlayHandle
{
public:
SamplePlayHandle(std::shared_ptr<const Sample> sampleBuffer , bool ownAudioPort = true);
SamplePlayHandle(const Sample* sample, bool ownAudioPort = true);
SamplePlayHandle( const QString& sampleFile );
SamplePlayHandle( SampleClip* clip );
~SamplePlayHandle() override;
@@ -82,7 +82,7 @@ public:
private:
std::shared_ptr<const Sample> m_sample;
const Sample* m_sample;
bool m_doneMayReturnTrue;
f_cnt_t m_frame;

View File

@@ -77,7 +77,6 @@ Plugin::Descriptor PLUGIN_EXPORT audiofileprocessor_plugin_descriptor =
AudioFileProcessor::AudioFileProcessor( InstrumentTrack * _instrument_track ) :
Instrument( _instrument_track, &audiofileprocessor_plugin_descriptor ),
m_sample(std::make_shared<Sample>()),
m_ampModel( 100, 0, 500, 1, this, tr( "Amplify" ) ),
m_startPointModel( 0, 0, 1, 0.0000001f, this, tr( "Start of sample" ) ),
m_endPointModel( 1, 0, 1, 0.0000001f, this, tr( "End of sample" ) ),
@@ -125,18 +124,18 @@ void AudioFileProcessor::playNote( NotePlayHandle * _n,
// played.
if( m_stutterModel.value() == true && _n->frequency() < 20.0 )
{
m_nextPlayStartPoint = m_sample->startFrame();
m_nextPlayStartPoint = m_sample.startFrame();
m_nextPlayBackwards = false;
return;
}
if( !_n->m_pluginData )
{
if (m_stutterModel.value() == true && m_nextPlayStartPoint >= m_sample->endFrame())
if (m_stutterModel.value() == true && m_nextPlayStartPoint >= m_sample.endFrame())
{
// Restart playing the note if in stutter mode, not in loop mode,
// and we're at the end of the sample.
m_nextPlayStartPoint = m_sample->startFrame();
m_nextPlayStartPoint = m_sample.startFrame();
m_nextPlayBackwards = false;
}
// set interpolation mode for libsamplerate
@@ -165,7 +164,7 @@ void AudioFileProcessor::playNote( NotePlayHandle * _n,
if( ! _n->isFinished() )
{
if (m_sample->play(_working_buffer + offset,
if (m_sample.play(_working_buffer + offset,
static_cast<Sample::PlaybackState*>(_n->m_pluginData),
frames, _n->frequency(),
static_cast<Sample::Loop>(m_loopModel.value())))
@@ -203,10 +202,10 @@ void AudioFileProcessor::deleteNotePluginData( NotePlayHandle * _n )
void AudioFileProcessor::saveSettings(QDomDocument& doc, QDomElement& elem)
{
elem.setAttribute("src", m_sample->sampleFile());
if (m_sample->sampleFile().isEmpty())
elem.setAttribute("src", m_sample.sampleFile());
if (m_sample.sampleFile().isEmpty())
{
elem.setAttribute("sampledata", m_sample->toBase64());
elem.setAttribute("sampledata", m_sample.toBase64());
}
m_reverseModel.saveSettings(doc, elem, "reversed");
m_loopModel.saveSettings(doc, elem, "looped");
@@ -227,16 +226,16 @@ void AudioFileProcessor::loadSettings(const QDomElement& elem)
{
setAudioFile(elem.attribute("src"), false);
QString absolutePath = PathUtil::toAbsolute(m_sample->sampleFile());
QString absolutePath = PathUtil::toAbsolute(m_sample.sampleFile());
if (!QFileInfo(absolutePath).exists())
{
QString message = tr("Sample not found: %1").arg(m_sample->sampleFile());
QString message = tr("Sample not found: %1").arg(m_sample.sampleFile());
Engine::getSong()->collectError(message);
}
}
else if (!elem.attribute("sampledata").isEmpty())
{
m_sample = std::make_shared<Sample>(gui::SampleLoader::createBufferFromBase64(elem.attribute("srcdata")));
m_sample = Sample(gui::SampleLoader::createBufferFromBase64(elem.attribute("srcdata")));
}
m_loopModel.loadSettings(elem, "looped");
@@ -295,7 +294,7 @@ int AudioFileProcessor::getBeatLen( NotePlayHandle * _n ) const
const float freq_factor = baseFreq / _n->frequency() *
Engine::audioEngine()->processingSampleRate() / Engine::audioEngine()->baseSampleRate();
return static_cast<int>(floorf((m_sample->endFrame() - m_sample->startFrame()) * freq_factor));
return static_cast<int>(floorf((m_sample.endFrame() - m_sample.startFrame()) * freq_factor));
}
@@ -316,15 +315,15 @@ void AudioFileProcessor::setAudioFile( const QString & _audio_file,
// is current channel-name equal to previous-filename??
if( _rename &&
( instrumentTrack()->name() ==
QFileInfo(m_sample->sampleFile()).fileName() ||
m_sample->sampleFile().isEmpty()))
QFileInfo(m_sample.sampleFile()).fileName() ||
m_sample.sampleFile().isEmpty()))
{
// then set it to new one
instrumentTrack()->setName( PathUtil::cleanName( _audio_file ) );
}
// else we don't touch the track-name, because the user named it self
m_sample = std::make_shared<Sample>(gui::SampleLoader::createBufferFromFile(_audio_file));
m_sample = Sample(gui::SampleLoader::createBufferFromFile(_audio_file));
loopPointChanged();
emit sampleUpdated();
}
@@ -334,8 +333,8 @@ void AudioFileProcessor::setAudioFile( const QString & _audio_file,
void AudioFileProcessor::reverseModelChanged()
{
m_sample->setReversed(m_reverseModel.value());
m_nextPlayStartPoint = m_sample->startFrame();
m_sample.setReversed(m_reverseModel.value());
m_nextPlayStartPoint = m_sample.startFrame();
m_nextPlayBackwards = false;
emit sampleUpdated();
}
@@ -345,14 +344,14 @@ void AudioFileProcessor::reverseModelChanged()
void AudioFileProcessor::ampModelChanged()
{
m_sample->setAmplification(m_ampModel.value() / 100.0f);
m_sample.setAmplification(m_ampModel.value() / 100.0f);
emit sampleUpdated();
}
void AudioFileProcessor::stutterModelChanged()
{
m_nextPlayStartPoint = m_sample->startFrame();
m_nextPlayStartPoint = m_sample.startFrame();
m_nextPlayBackwards = false;
}
@@ -421,14 +420,14 @@ void AudioFileProcessor::loopPointChanged()
void AudioFileProcessor::pointChanged()
{
const auto f_start = static_cast<f_cnt_t>(m_startPointModel.value() * m_sample->sampleSize());
const auto f_end = static_cast<f_cnt_t>(m_endPointModel.value() * m_sample->sampleSize());
const auto f_loop = static_cast<f_cnt_t>(m_loopPointModel.value() * m_sample->sampleSize());
const auto f_start = static_cast<f_cnt_t>(m_startPointModel.value() * m_sample.sampleSize());
const auto f_end = static_cast<f_cnt_t>(m_endPointModel.value() * m_sample.sampleSize());
const auto f_loop = static_cast<f_cnt_t>(m_loopPointModel.value() * m_sample.sampleSize());
m_nextPlayStartPoint = f_start;
m_nextPlayBackwards = false;
m_sample->setAllPointFrames(f_start, f_end, f_loop, f_end);
m_sample.setAllPointFrames(f_start, f_end, f_loop, f_end);
emit dataChanged();
}
@@ -596,7 +595,7 @@ void AudioFileProcessorView::newWaveView()
delete m_waveView;
m_waveView = 0;
}
m_waveView = new AudioFileProcessorWaveView(this, 245, 75, castModel<AudioFileProcessor>()->m_sample.get());
m_waveView = new AudioFileProcessorWaveView(this, 245, 75, &castModel<AudioFileProcessor>()->m_sample);
m_waveView->move( 2, 172 );
m_waveView->setKnobs(
dynamic_cast<AudioFileProcessorWaveView::knob *>( m_startKnob ),
@@ -643,7 +642,7 @@ void AudioFileProcessorView::paintEvent( QPaintEvent * )
QString file_name = "";
int idx = a->m_sample->sampleFile().length();
int idx = a->m_sample.sampleFile().length();
p.setFont( pointSize<8>( font() ) );
@@ -654,7 +653,7 @@ void AudioFileProcessorView::paintEvent( QPaintEvent * )
while( idx > 0 &&
fm.size( Qt::TextSingleLine, file_name + "..." ).width() < 210 )
{
file_name = a->m_sample->sampleFile()[--idx] + file_name;
file_name = a->m_sample.sampleFile()[--idx] + file_name;
}
if( idx > 0 )
@@ -671,7 +670,6 @@ void AudioFileProcessorView::paintEvent( QPaintEvent * )
void AudioFileProcessorView::sampleUpdated()
{
m_waveView->m_sample = castModel<AudioFileProcessor>()->m_sample.get();
m_waveView->updateSampleRange();
m_waveView->update();
update();

View File

@@ -97,7 +97,7 @@ signals:
void sampleUpdated();
private:
std::shared_ptr<Sample> m_sample;
Sample m_sample;
FloatModel m_ampModel;
FloatModel m_startPointModel;

View File

@@ -119,12 +119,12 @@ void SampleClip::changeLength( const TimePos & _length )
const QString& SampleClip::sampleFile() const
{
return m_sample->sampleFile();
return m_sample.sampleFile();
}
void SampleClip::setSampleBuffer(std::unique_ptr<SampleBuffer> sb)
{
m_sample = std::make_shared<Sample>(std::shared_ptr<const SampleBuffer>(std::move(sb)));
m_sample = Sample(std::move(sb));
updateLength();
emit sampleChanged();
@@ -139,7 +139,7 @@ void SampleClip::setSampleFile(const QString & sf)
if (!sf.isEmpty())
{
//Otherwise set it to the sample's length
m_sample = std::make_shared<Sample>(gui::SampleLoader::createBufferFromFile(sf));
m_sample = Sample(gui::SampleLoader::createBufferFromFile(sf));
length = sampleLength();
}
@@ -218,7 +218,7 @@ void SampleClip::updateLength()
TimePos SampleClip::sampleLength() const
{
return static_cast<int>(m_sample->playbackSize() / Engine::framesPerTick());
return static_cast<int>(m_sample.playbackSize() / Engine::framesPerTick());
}
@@ -226,7 +226,7 @@ TimePos SampleClip::sampleLength() const
void SampleClip::setSampleStartFrame(f_cnt_t startFrame)
{
m_sample->setStartFrame(startFrame);
m_sample.setStartFrame(startFrame);
}
@@ -234,7 +234,7 @@ void SampleClip::setSampleStartFrame(f_cnt_t startFrame)
void SampleClip::setSamplePlayLength(f_cnt_t length)
{
m_sample->setEndFrame(length);
m_sample.setEndFrame(length);
}
@@ -257,15 +257,15 @@ void SampleClip::saveSettings( QDomDocument & _doc, QDomElement & _this )
if( sampleFile() == "" )
{
QString s;
_this.setAttribute("data", m_sample->toBase64());
_this.setAttribute("data", m_sample.toBase64());
}
_this.setAttribute("sample_rate", m_sample->sampleRate());
_this.setAttribute("sample_rate", m_sample.sampleRate());
if( usesCustomClipColor() )
{
_this.setAttribute( "color", color().name() );
}
if (m_sample->reversed())
if (m_sample.reversed())
{
_this.setAttribute("reversed", "true");
}
@@ -288,7 +288,7 @@ void SampleClip::loadSettings( const QDomElement & _this )
Engine::audioEngine()->processingSampleRate();
auto buffer = gui::SampleLoader::createBufferFromBase64(_this.attribute("data"), sampleRate);
m_sample = std::make_shared<Sample>(std::move(buffer));
m_sample = Sample(std::move(buffer));
}
changeLength( _this.attribute( "len" ).toInt() );
setMuted( _this.attribute( "muted" ).toInt() );
@@ -306,7 +306,7 @@ void SampleClip::loadSettings( const QDomElement & _this )
if(_this.hasAttribute("reversed"))
{
m_sample->setReversed(true);
m_sample.setReversed(true);
emit wasReversed(); // tell SampleClipView to update the view
}
}

View File

@@ -35,7 +35,7 @@ namespace lmms
{
SamplePlayHandle::SamplePlayHandle(std::shared_ptr<const Sample> sample, bool ownAudioPort) :
SamplePlayHandle::SamplePlayHandle(const Sample* sample, bool ownAudioPort) :
PlayHandle( Type::SamplePlayHandle ),
m_sample(sample),
m_doneMayReturnTrue( true ),
@@ -56,7 +56,7 @@ SamplePlayHandle::SamplePlayHandle(std::shared_ptr<const Sample> sample, bool ow
SamplePlayHandle::SamplePlayHandle( const QString& sampleFile ) :
SamplePlayHandle(std::make_shared<const Sample>(sampleFile), true)
SamplePlayHandle(new const Sample(sampleFile), true)
{
}
@@ -64,7 +64,7 @@ SamplePlayHandle::SamplePlayHandle( const QString& sampleFile ) :
SamplePlayHandle::SamplePlayHandle( SampleClip* clip ) :
SamplePlayHandle(clip->sample(), false)
SamplePlayHandle(&clip->sample(), false)
{
m_track = clip->getTrack();
setAudioPort( ( (SampleTrack *)clip->getTrack() )->audioPort() );
@@ -78,6 +78,7 @@ SamplePlayHandle::~SamplePlayHandle()
if( m_ownAudioPort )
{
delete audioPort();
delete m_sample;
}
}

View File

@@ -60,7 +60,7 @@ void SampleClipView::updateSample()
update();
// set tooltip to filename so that user can see what sample this
// sample-clip contains
setToolTip(!m_clip->m_sample->sampleFile().isEmpty() ? PathUtil::toAbsolute(m_clip->m_sample->sampleFile())
setToolTip(!m_clip->m_sample.sampleFile().isEmpty() ? PathUtil::toAbsolute(m_clip->m_sample.sampleFile())
: tr("Double-click to open sample"));
}
@@ -172,9 +172,9 @@ void SampleClipView::mouseDoubleClickEvent( QMouseEvent * )
QString af = gui::SampleLoader::openAudioFile();
if ( af.isEmpty() ) {} //Don't do anything if no file is loaded
else if (af == m_clip->m_sample->sampleFile())
else if (af == m_clip->m_sample.sampleFile())
{ //Instead of reloading the existing file, just reset the size
int length = static_cast<int>(m_clip->m_sample->sampleSize() / Engine::framesPerTick());
int length = static_cast<int>(m_clip->m_sample.sampleSize() / Engine::framesPerTick());
m_clip->changeLength(length);
}
else
@@ -261,9 +261,9 @@ void SampleClipView::paintEvent( QPaintEvent * pe )
float offset = m_clip->startTimeOffset() / ticksPerBar * pixelsPerBar();
QRect r = QRect( offset, spacing,
qMax( static_cast<int>( m_clip->sampleLength() * ppb / ticksPerBar ), 1 ), rect().bottom() - 2 * spacing );
m_clip->m_sample->visualize(p, r);
m_clip->m_sample.visualize(p, r);
QString name = PathUtil::cleanName(m_clip->m_sample->sampleFile());
QString name = PathUtil::cleanName(m_clip->m_sample.sampleFile());
paintTextLabel(name, p);
// disable antialiasing for borders, since its not needed
@@ -316,7 +316,7 @@ void SampleClipView::paintEvent( QPaintEvent * pe )
void SampleClipView::reverseSample()
{
m_clip->sample()->setReversed(!m_clip->sample()->reversed());
m_clip->m_sample.setReversed(!m_clip->m_sample.reversed());
Engine::getSong()->setModified();
update();
}

View File

@@ -108,10 +108,10 @@ bool SampleTrack::play( const TimePos & _start, const fpp_t _frames,
{
if( sClip->isPlaying() == false && _start >= (sClip->startPosition() + sClip->startTimeOffset()) )
{
auto bufferFramesPerTick = Engine::framesPerTick(sClip->sample()->sampleRate());
auto bufferFramesPerTick = Engine::framesPerTick(sClip->sample().sampleRate());
f_cnt_t sampleStart = bufferFramesPerTick * ( _start - sClip->startPosition() - sClip->startTimeOffset() );
f_cnt_t clipFrameLength = bufferFramesPerTick * ( sClip->endPosition() - sClip->startPosition() - sClip->startTimeOffset() );
f_cnt_t sampleBufferLength = sClip->sample()->sampleSize();
f_cnt_t sampleBufferLength = sClip->sample().sampleSize();
//if the Clip smaller than the sample length we play only until Clip end
//else we play the sample to the end but nothing more
f_cnt_t samplePlayLength = clipFrameLength > sampleBufferLength ? sampleBufferLength : clipFrameLength;