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

basics: Change sampleFrame to use std::array #5536

Merged
merged 8 commits into from
Sep 21, 2020
Merged
64 changes: 9 additions & 55 deletions include/LocklessRingBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,79 +33,33 @@
#include "../src/3rdparty/ringbuffer/include/ringbuffer/ringbuffer.h"


//! A convenience layer for a realtime-safe and thread-safe multi-reader ring buffer library.
//! A convenience layer for a realtime-safe and thread-safe multi-reader ringbuffer
template <class T>
class LocklessRingBufferBase
class LocklessRingBuffer
{
template<class _T>
friend class LocklessRingBufferReader;
public:
LocklessRingBufferBase(std::size_t sz) : m_buffer(sz)
LocklessRingBuffer(std::size_t sz) : m_buffer(sz)
{
m_buffer.touch(); // reserve storage space before realtime operation starts
}
~LocklessRingBufferBase() {};
~LocklessRingBuffer() {};

std::size_t capacity() const {return m_buffer.maximum_eventual_write_space();}
std::size_t free() const {return m_buffer.write_space();}
void wakeAll() {m_notifier.wakeAll();}

protected:
ringbuffer_t<T> m_buffer;
QWaitCondition m_notifier;
};


// The SampleFrameCopier is required because sampleFrame is just a two-element
// array and therefore does not have a copy constructor needed by std::copy.
class SampleFrameCopier
{
const sampleFrame* m_src;
public:
SampleFrameCopier(const sampleFrame* src) : m_src(src) {}
void operator()(std::size_t src_offset, std::size_t count, sampleFrame* dest)
{
for (std::size_t i = src_offset; i < src_offset + count; i++, dest++)
{
(*dest)[0] = m_src[i][0];
(*dest)[1] = m_src[i][1];
}
}
};


//! Standard ring buffer template for data types with copy constructor.
template <class T>
class LocklessRingBuffer : public LocklessRingBufferBase<T>
{
public:
LocklessRingBuffer(std::size_t sz) : LocklessRingBufferBase<T>(sz) {};

std::size_t write(const sampleFrame *src, std::size_t cnt, bool notify = false)
{
std::size_t written = LocklessRingBufferBase<T>::m_buffer.write(src, cnt);
std::size_t written = LocklessRingBuffer<T>::m_buffer.write(src, cnt);
// Let all waiting readers know new data are available.
if (notify) {LocklessRingBufferBase<T>::m_notifier.wakeAll();}
if (notify) {LocklessRingBuffer<T>::m_notifier.wakeAll();}
return written;
}
};


//! Specialized ring buffer template with write function modified to support sampleFrame.
template <>
class LocklessRingBuffer<sampleFrame> : public LocklessRingBufferBase<sampleFrame>
{
public:
LocklessRingBuffer(std::size_t sz) : LocklessRingBufferBase<sampleFrame>(sz) {};

std::size_t write(const sampleFrame *src, std::size_t cnt, bool notify = false)
{
SampleFrameCopier copier(src);
std::size_t written = LocklessRingBufferBase<sampleFrame>::m_buffer.write_func<SampleFrameCopier>(copier, cnt);
// Let all waiting readers know new data are available.
if (notify) {LocklessRingBufferBase<sampleFrame>::m_notifier.wakeAll();}
return written;
}
protected:
ringbuffer_t<T> m_buffer;
QWaitCondition m_notifier;
};


Expand Down
10 changes: 4 additions & 6 deletions include/lmms_basics.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@

#ifdef LMMS_HAVE_STDINT_H
#include <cstdint>
#include <array>
#endif


typedef int32_t bar_t;
typedef int32_t tick_t;
typedef uint8_t volume_t;
Expand Down Expand Up @@ -127,12 +127,10 @@ const ch_cnt_t SURROUND_CHANNELS =



typedef sample_t sampleFrame[DEFAULT_CHANNELS];
typedef sample_t surroundSampleFrame[SURROUND_CHANNELS];
typedef std::array<sample_t, DEFAULT_CHANNELS> sampleFrame;

typedef std::array<sample_t, SURROUND_CHANNELS> surroundSampleFrame;
#define ALIGN_SIZE 16
#if __GNUC__
typedef sample_t sampleFrameA[DEFAULT_CHANNELS] __attribute__((__aligned__(ALIGN_SIZE)));
#endif


#define STRINGIFY(s) STR(s)
Expand Down
2 changes: 1 addition & 1 deletion plugins/Delay/StereoDelay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ StereoDelay::~StereoDelay()



void StereoDelay::tick( sampleFrame frame )
void StereoDelay::tick( sampleFrame& frame )
{
m_writeIndex = ( m_writeIndex + 1 ) % ( int )m_maxLength;
int readIndex = m_writeIndex - m_length;
Expand Down
2 changes: 1 addition & 1 deletion plugins/Delay/StereoDelay.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class StereoDelay
m_feedback = feedback;
}

void tick( sampleFrame frame );
void tick( sampleFrame& frame );
void setSampleRate( int sampleRate );

private:
Expand Down
4 changes: 2 additions & 2 deletions src/core/Effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ void Effect::resample( int _i, const sampleFrame * _src_buf,
}
m_srcData[_i].input_frames = _frames;
m_srcData[_i].output_frames = Engine::mixer()->framesPerPeriod();
m_srcData[_i].data_in = (float *) _src_buf[0];
m_srcData[_i].data_out = _dst_buf[0];
m_srcData[_i].data_in = (float *) _src_buf[0].data ();
m_srcData[_i].data_out = _dst_buf[0].data ();
m_srcData[_i].src_ratio = (double) _dst_sr / _src_sr;
m_srcData[_i].end_of_input = 0;
int error;
Expand Down
10 changes: 5 additions & 5 deletions src/core/SampleBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,8 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state,
// Generate output
src_data.data_in =
getSampleFragment( play_frame, fragment_size, _loopmode, &tmp, &is_backwards,
loopStartFrame, loopEndFrame, endFrame )[0];
src_data.data_out = _ab[0];
loopStartFrame, loopEndFrame, endFrame )->data ();
src_data.data_out = _ab->data ();
src_data.input_frames = fragment_size;
src_data.output_frames = _frames;
src_data.src_ratio = 1.0 / freq_factor;
Expand Down Expand Up @@ -1196,9 +1196,9 @@ SampleBuffer * SampleBuffer::resample( const sample_rate_t _src_sr,
{
SRC_DATA src_data;
src_data.end_of_input = 1;
src_data.data_in = data[0];
src_data.data_out = dst_buf[0];
src_data.input_frames = frames;
src_data.data_in = data->data ();
src_data.data_out = dst_buf->data (); // @recording => !!!
src_data.input_frames = frames; // @recording => !!!
src_data.output_frames = dst_frames;
src_data.src_ratio = (double) _dst_sr / _src_sr;
if( ( error = src_process( state, &src_data ) ) )
Expand Down
4 changes: 2 additions & 2 deletions src/core/audio/AudioDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ fpp_t AudioDevice::resample( const surroundSampleFrame * _src,
}
m_srcData.input_frames = _frames;
m_srcData.output_frames = _frames;
m_srcData.data_in = (float *) _src[0];
m_srcData.data_out = _dst[0];
m_srcData.data_in = (float *) _src[0].data ();
m_srcData.data_out = _dst[0].data ();
m_srcData.src_ratio = (double) _dst_sr / _src_sr;
m_srcData.end_of_input = 0;
int error;
Expand Down