Merge branch 'master' into sample-recording

This commit is contained in:
Rossmaxx
2024-07-15 16:46:37 +05:30
274 changed files with 3020 additions and 1890 deletions

View File

@@ -37,6 +37,7 @@ namespace lmms
class AudioEngine;
class AudioPort;
class SampleFrame;
class AudioDevice
@@ -92,14 +93,14 @@ public:
protected:
// subclasses can re-implement this for being used in conjunction with
// processNextBuffer()
virtual void writeBuffer(const surroundSampleFrame* /* _buf*/, const fpp_t /*_frames*/) {}
virtual void writeBuffer(const SampleFrame* /* _buf*/, const fpp_t /*_frames*/) {}
// called by according driver for fetching new sound-data
fpp_t getNextBuffer( surroundSampleFrame * _ab );
fpp_t getNextBuffer(SampleFrame* _ab);
// convert a given audio-buffer to a buffer in signed 16-bit samples
// returns num of bytes in outbuf
int convertToS16( const surroundSampleFrame * _ab,
int convertToS16(const SampleFrame* _ab,
const fpp_t _frames,
int_sample_t * _output_buffer,
const bool _convert_endian = false );
@@ -133,7 +134,7 @@ private:
QMutex m_devMutex;
surroundSampleFrame * m_buffer;
SampleFrame* m_buffer;
};

View File

@@ -94,7 +94,7 @@ private:
while( true )
{
timer.reset();
const surroundSampleFrame* b = audioEngine()->nextBuffer();
const SampleFrame* b = audioEngine()->nextBuffer();
if( !b )
{
break;

View File

@@ -25,18 +25,16 @@
#ifndef LMMS_AUDIO_ENGINE_H
#define LMMS_AUDIO_ENGINE_H
#ifdef __MINGW32__
#include <mingw.mutex.h>
#else
#include <mutex>
#endif
#include <QThread>
#include <samplerate.h>
#include <memory>
#include <vector>
#include "lmms_basics.h"
#include "SampleFrame.h"
#include "LocklessList.h"
#include "FifoBuffer.h"
#include "AudioEngineProfiler.h"
@@ -57,8 +55,7 @@ const fpp_t DEFAULT_BUFFER_SIZE = 256;
const int BYTES_PER_SAMPLE = sizeof( sample_t );
const int BYTES_PER_INT_SAMPLE = sizeof( int_sample_t );
const int BYTES_PER_FRAME = sizeof( sampleFrame );
const int BYTES_PER_SURROUND_FRAME = sizeof( surroundSampleFrame );
const int BYTES_PER_FRAME = sizeof( SampleFrame );
const float OUTPUT_SAMPLE_MULTIPLIER = 32767.0f;
@@ -268,15 +265,6 @@ public:
}
struct StereoSample
{
StereoSample(sample_t _left, sample_t _right) : left(_left), right(_right) {}
sample_t left;
sample_t right;
};
StereoSample getPeakValues(sampleFrame * ab, const f_cnt_t _frames) const;
bool criticalXRuns() const;
inline bool hasFifoWriter() const
@@ -284,9 +272,9 @@ public:
return m_fifoWriter != nullptr;
}
void pushInputFrames( sampleFrame * _ab, const f_cnt_t _frames );
void pushInputFrames( SampleFrame* _ab, const f_cnt_t _frames );
inline const sampleFrame * inputBuffer()
inline const SampleFrame* inputBuffer()
{
return m_inputBuffer[ m_inputBufferRead ];
}
@@ -296,7 +284,7 @@ public:
return m_inputBufferFrames[ m_inputBufferRead ];
}
inline const surroundSampleFrame * nextBuffer()
inline const SampleFrame* nextBuffer()
{
return hasFifoWriter() ? m_fifo->read() : renderNextBuffer();
}
@@ -322,11 +310,11 @@ public:
signals:
void qualitySettingsChanged();
void sampleRateChanged();
void nextAudioBuffer( const lmms::surroundSampleFrame * buffer );
void nextAudioBuffer(const lmms::SampleFrame* buffer);
private:
using Fifo = FifoBuffer<surroundSampleFrame*>;
using Fifo = FifoBuffer<SampleFrame*>;
class fifoWriter : public QThread
{
@@ -343,7 +331,7 @@ private:
void run() override;
void write( surroundSampleFrame * buffer );
void write(SampleFrame* buffer);
} ;
@@ -367,7 +355,7 @@ private:
void renderStageEffects();
void renderStageMix();
const surroundSampleFrame * renderNextBuffer();
const SampleFrame* renderNextBuffer();
void swapBuffers();
@@ -381,14 +369,14 @@ private:
fpp_t m_framesPerPeriod;
sampleFrame * m_inputBuffer[2];
SampleFrame* m_inputBuffer[2];
f_cnt_t m_inputBufferFrames[2];
f_cnt_t m_inputBufferSize[2];
int m_inputBufferRead;
int m_inputBufferWrite;
surroundSampleFrame * m_outputBufferRead;
surroundSampleFrame * m_outputBufferWrite;
std::unique_ptr<SampleFrame[]> m_outputBufferRead;
std::unique_ptr<SampleFrame[]> m_outputBufferWrite;
// worker thread stuff
std::vector<AudioEngineWorkerThread *> m_workers;
@@ -425,7 +413,7 @@ private:
bool m_clearSignal;
std::mutex m_changeMutex;
std::recursive_mutex m_changeMutex;
friend class Engine;
friend class AudioEngineWorkerThread;

View File

@@ -65,7 +65,7 @@ private:
SF_INFO m_sfinfo;
SNDFILE* m_sf;
void writeBuffer(surroundSampleFrame const* _ab, fpp_t const frames) override;
void writeBuffer(const SampleFrame* _ab, fpp_t const frames) override;
bool startEncoding();
void finishEncoding();

View File

@@ -58,7 +58,7 @@ public:
}
protected:
void writeBuffer(const surroundSampleFrame* /* _buf*/, const fpp_t /*_frames*/) override;
void writeBuffer(const SampleFrame* /* _buf*/, const fpp_t /*_frames*/) override;
private:
void flushRemainingBuffers();

View File

@@ -58,7 +58,7 @@ public:
private:
void writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) override;
void writeBuffer(const SampleFrame* _ab, const fpp_t _frames) override;
bool startEncoding();
void finishEncoding();

View File

@@ -56,7 +56,7 @@ public:
private:
void writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) override;
void writeBuffer(const SampleFrame* _ab, const fpp_t _frames) override;
bool startEncoding();
void finishEncoding();

View File

@@ -111,7 +111,7 @@ private:
std::atomic<MidiJack*> m_midiClient;
std::vector<jack_port_t*> m_outputPorts;
jack_default_audio_sample_t** m_tempOutBufs;
surroundSampleFrame* m_outBuf;
SampleFrame* m_outBuf;
f_cnt_t m_framesDoneInCurBuf;
f_cnt_t m_framesToDoInCurBuf;

View File

@@ -46,7 +46,7 @@ public:
BoolModel * mutedModel = nullptr );
virtual ~AudioPort();
inline sampleFrame * buffer()
inline SampleFrame* buffer()
{
return m_portBuffer;
}
@@ -112,7 +112,7 @@ public:
private:
volatile bool m_bufferUsage;
sampleFrame * m_portBuffer;
SampleFrame* m_portBuffer;
QMutex m_portBufferLock;
bool m_extOutputEnabled;

View File

@@ -150,7 +150,7 @@ private:
bool m_wasPAInitError;
surroundSampleFrame * m_outBuf;
SampleFrame* m_outBuf;
int m_outBufPos;
int m_outBufSize;

View File

@@ -48,9 +48,9 @@ public:
std::shared_ptr<const SampleBuffer> createSampleBuffer();
private:
void writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) override;
void writeBuffer(const SampleFrame* _ab, const fpp_t _frames) override;
using BufferList = QList<QPair<sampleFrame*, fpp_t>>;
using BufferList = QList<QPair<SampleFrame*, fpp_t>>;
BufferList m_buffers;
} ;

View File

@@ -87,7 +87,7 @@ private:
SDL_AudioSpec m_audioHandle;
surroundSampleFrame * m_outBuf;
SampleFrame* m_outBuf;
#ifdef LMMS_HAVE_SDL2
size_t m_currentBufferFramePos;

View File

@@ -110,7 +110,7 @@ private:
SoundIo *m_soundio;
SoundIoOutStream *m_outstream;
surroundSampleFrame * m_outBuf;
SampleFrame* m_outBuf;
int m_outBufSize;
fpp_t m_outBufFramesTotal;
fpp_t m_outBufFrameIndex;

View File

@@ -32,20 +32,18 @@
namespace lmms
{
class SampleFrame;
class LMMS_EXPORT BufferManager
{
public:
static void init( fpp_t fpp );
static sampleFrame * acquire();
static SampleFrame* acquire();
// audio-buffer-mgm
static void clear( sampleFrame * ab, const f_cnt_t frames,
static void clear( SampleFrame* ab, const f_cnt_t frames,
const f_cnt_t offset = 0 );
#ifndef LMMS_DISABLE_SURROUND
static void clear( surroundSampleFrame * ab, const f_cnt_t frames,
const f_cnt_t offset = 0 );
#endif
static void release( sampleFrame * buf );
static void release( SampleFrame* buf );
private:
static fpp_t s_framesPerPeriod;

View File

@@ -27,33 +27,33 @@
#define LMMS_DRUM_SYNTH_H
#include <stdint.h>
#include "lmms_basics.h"
class QString;
namespace lmms
namespace lmms {
class DrumSynth
{
public:
DrumSynth() = default;
int GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sample_rate_t Fs);
class DrumSynth {
public:
DrumSynth() = default;
int GetDSFileSamples(QString dsfile, int16_t *&wave, int channels, sample_rate_t Fs);
private:
float LoudestEnv();
int LongestEnv();
void UpdateEnv(int e, long t);
void GetEnv(int env, const char* sec, const char* key, QString ini);
private:
float LoudestEnv();
int LongestEnv();
void UpdateEnv(int e, long t);
void GetEnv(int env, const char *sec, const char *key, QString ini);
float waveform(float ph, int form);
int GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, QString file);
int GetPrivateProfileInt(const char *sec, const char *key, int def, QString file);
float GetPrivateProfileFloat(const char *sec, const char *key, float def, QString file);
float waveform(float ph, int form);
int GetPrivateProfileString(
const char* sec, const char* key, const char* def, char* buffer, int size, QString file);
int GetPrivateProfileInt(const char* sec, const char* key, int def, QString file);
float GetPrivateProfileFloat(const char* sec, const char* key, float def, QString file);
};
} // namespace lmms
#endif // LMMS_DRUM_SYNTH_H

View File

@@ -28,7 +28,7 @@
#include "lmms_math.h"
#include "lmms_constants.h"
#include "lmms_basics.h"
#include "SampleFrame.h"
namespace lmms::DspEffectLibrary
{
@@ -80,6 +80,17 @@ namespace lmms::DspEffectLibrary
{
}
void setGain(float gain)
{
leftFX().setGain(gain);
rightFX().setGain(gain);
}
void nextSample(SampleFrame & in)
{
nextSample(in.left(), in.right());
}
void nextSample( sample_t& inLeft, sample_t& inRight )
{
inLeft = m_leftFX.nextSample( inLeft );

View File

@@ -107,7 +107,7 @@ public:
return &m_controls;
}
bool processAudioBuffer( sampleFrame *, const fpp_t ) override
bool processAudioBuffer( SampleFrame*, const fpp_t ) override
{
return false;
}

View File

@@ -49,10 +49,9 @@ public:
~DummyInstrument() override = default;
void playNote( NotePlayHandle *, sampleFrame * buffer ) override
void playNote( NotePlayHandle*, SampleFrame* buffer ) override
{
memset( buffer, 0, sizeof( sampleFrame ) *
Engine::audioEngine()->framesPerPeriod() );
zeroSampleFrames(buffer, Engine::audioEngine()->framesPerPeriod());
}
void saveSettings( QDomDocument &, QDomElement & ) override

View File

@@ -64,7 +64,7 @@ public:
}
virtual bool processAudioBuffer( sampleFrame * _buf,
virtual bool processAudioBuffer( SampleFrame* _buf,
const fpp_t _frames ) = 0;
inline ch_cnt_t processorCount() const
@@ -187,8 +187,8 @@ protected:
// some effects might not be capable of higher sample-rates so they can
// sample it down before processing and back after processing
inline void sampleDown( const sampleFrame * _src_buf,
sampleFrame * _dst_buf,
inline void sampleDown( const SampleFrame* _src_buf,
SampleFrame* _dst_buf,
sample_rate_t _dst_sr )
{
resample( 0, _src_buf,
@@ -197,8 +197,8 @@ protected:
Engine::audioEngine()->framesPerPeriod() );
}
inline void sampleBack( const sampleFrame * _src_buf,
sampleFrame * _dst_buf,
inline void sampleBack( const SampleFrame* _src_buf,
SampleFrame* _dst_buf,
sample_rate_t _src_sr )
{
resample( 1, _src_buf, _src_sr, _dst_buf,
@@ -213,9 +213,9 @@ protected:
private:
EffectChain * m_parent;
void resample( int _i, const sampleFrame * _src_buf,
void resample( int _i, const SampleFrame* _src_buf,
sample_rate_t _src_sr,
sampleFrame * _dst_buf, sample_rate_t _dst_sr,
SampleFrame* _dst_buf, sample_rate_t _dst_sr,
const f_cnt_t _frames );
ch_cnt_t m_processors;

View File

@@ -34,6 +34,7 @@ namespace lmms
{
class Effect;
class SampleFrame;
namespace gui
{
@@ -62,7 +63,7 @@ public:
void removeEffect( Effect * _effect );
void moveDown( Effect * _effect );
void moveUp( Effect * _effect );
bool processAudioBuffer( sampleFrame * _buf, const fpp_t _frames, bool hasInputNoise );
bool processAudioBuffer( SampleFrame* _buf, const fpp_t _frames, bool hasInputNoise );
void startRunning();
void clear();

View File

@@ -90,7 +90,7 @@ public:
};
return s_excludedPaths;
}
static QDir::Filters dirFilters() { return QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot; }
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; }
private slots:
@@ -111,6 +111,8 @@ private:
void onSearch(const QString& filter);
void displaySearch(bool on);
void addContentCheckBox();
FileBrowserTreeWidget * m_fileBrowserTreeWidget;
FileBrowserTreeWidget * m_searchTreeWidget;
@@ -124,9 +126,13 @@ private:
bool m_dirsAsItems;
void addContentCheckBox();
QCheckBox* m_showUserContent = nullptr;
QCheckBox* m_showFactoryContent = nullptr;
QCheckBox* m_showHiddenContent = nullptr;
QBoxLayout *filterWidgetLayout = nullptr;
QBoxLayout *hiddenWidgetLayout = nullptr;
QBoxLayout *outerLayout = nullptr;
QString m_userDir;
QString m_factoryDir;
QList<QString> m_savedExpandedDirs;

View File

@@ -45,6 +45,7 @@ class InstrumentTrack;
class MidiEvent;
class NotePlayHandle;
class Track;
class SampleFrame;
class LMMS_EXPORT Instrument : public Plugin
@@ -75,11 +76,11 @@ public:
// if the plugin doesn't play each note, it can create an instrument-
// play-handle and re-implement this method, so that it mixes its
// output buffer only once per audio engine period
virtual void play( sampleFrame * _working_buffer );
virtual void play( SampleFrame* _working_buffer );
// to be implemented by actual plugin
virtual void playNote( NotePlayHandle * /* _note_to_play */,
sampleFrame * /* _working_buf */ )
SampleFrame* /* _working_buf */ )
{
}
@@ -160,12 +161,12 @@ public:
protected:
// fade in to prevent clicks
void applyFadeIn(sampleFrame * buf, NotePlayHandle * n);
void applyFadeIn(SampleFrame* buf, NotePlayHandle * n);
// instruments may use this to apply a soft fade out at the end of
// notes - method does this only if really less or equal
// desiredReleaseFrames() frames are left
void applyRelease( sampleFrame * buf, const NotePlayHandle * _n );
void applyRelease( SampleFrame* buf, const NotePlayHandle * _n );
float computeReleaseTimeMsByFrameCount(f_cnt_t frames) const;

View File

@@ -41,7 +41,7 @@ public:
~InstrumentPlayHandle() override = default;
void play(sampleFrame * working_buffer) override;
void play(SampleFrame* working_buffer) override;
bool isFinished() const override
{

View File

@@ -34,6 +34,7 @@ namespace lmms
class InstrumentTrack;
class EnvelopeAndLfoParameters;
class NotePlayHandle;
class SampleFrame;
namespace gui
{
@@ -48,7 +49,7 @@ public:
InstrumentSoundShaping( InstrumentTrack * _instrument_track );
~InstrumentSoundShaping() override = default;
void processAudioBuffer( sampleFrame * _ab, const fpp_t _frames,
void processAudioBuffer( SampleFrame* _ab, const fpp_t _frames,
NotePlayHandle * _n );
enum class Target

View File

@@ -66,7 +66,7 @@ public:
~InstrumentTrack() override;
// used by instrument
void processAudioBuffer( sampleFrame * _buf, const fpp_t _frames,
void processAudioBuffer( SampleFrame* _buf, const fpp_t _frames,
NotePlayHandle * _n );
MidiEvent applyMasterKey( const MidiEvent& event );
@@ -86,7 +86,7 @@ public:
// for capturing note-play-events -> need that for arpeggio,
// filter and so on
void playNote( NotePlayHandle * _n, sampleFrame * _working_buffer );
void playNote( NotePlayHandle * _n, SampleFrame* _working_buffer );
QString instrumentName() const;
const Instrument *instrument() const

View File

@@ -43,6 +43,7 @@ namespace lmms
class Lv2Proc;
class PluginIssue;
class SampleFrame;
/**
Common base class for Lv2 plugins
@@ -118,9 +119,9 @@ protected:
void copyModelsToLmms() const;
//! Copy buffer passed by LMMS into our ports
void copyBuffersFromLmms(const sampleFrame *buf, fpp_t frames);
void copyBuffersFromLmms(const SampleFrame* buf, fpp_t frames);
//! Copy our ports into buffers passed by LMMS
void copyBuffersToLmms(sampleFrame *buf, fpp_t frames) const;
void copyBuffersToLmms(SampleFrame* buf, fpp_t frames) const;
//! Run the Lv2 plugin instance for @param frames frames
void run(fpp_t frames);

View File

@@ -41,6 +41,7 @@
namespace lmms
{
class SampleFrame;
struct ConnectPortVisitor;
using LV2_Evbuf = struct LV2_Evbuf_Impl;
@@ -184,15 +185,15 @@ struct Audio : public VisitablePort<Audio, PortBase>
//! Copy buffer passed by LMMS into our ports
//! @param channel channel index into each sample frame
void copyBuffersFromCore(const sampleFrame *lmmsBuf,
void copyBuffersFromCore(const SampleFrame* lmmsBuf,
unsigned channel, fpp_t frames);
//! Add buffer passed by LMMS into our ports, and halve the result
//! @param channel channel index into each sample frame
void averageWithBuffersFromCore(const sampleFrame *lmmsBuf,
void averageWithBuffersFromCore(const SampleFrame* lmmsBuf,
unsigned channel, fpp_t frames);
//! Copy our ports into buffers passed by LMMS
//! @param channel channel index into each sample frame
void copyBuffersToCore(sampleFrame *lmmsBuf,
void copyBuffersToCore(SampleFrame* lmmsBuf,
unsigned channel, fpp_t frames) const;
bool isSideChain() const { return m_sidechain; }

View File

@@ -49,6 +49,7 @@ namespace lmms
{
class PluginIssue;
class SampleFrame;
// forward declare port structs/enums
namespace Lv2Ports
@@ -134,7 +135,7 @@ public:
* @param num Number of channels we must read from @param buf (starting at
* @p offset)
*/
void copyBuffersFromCore(const sampleFrame *buf,
void copyBuffersFromCore(const SampleFrame* buf,
unsigned firstChan, unsigned num, fpp_t frames);
/**
* Copy our ports into buffers passed by the core
@@ -147,7 +148,7 @@ public:
* @param num Number of channels we must write to @param buf (starting at
* @p offset)
*/
void copyBuffersToCore(sampleFrame *buf, unsigned firstChan, unsigned num,
void copyBuffersToCore(SampleFrame* buf, unsigned firstChan, unsigned num,
fpp_t frames) const;
//! Run the Lv2 plugin instance for @param frames frames
void run(fpp_t frames);

View File

@@ -1,49 +0,0 @@
/*
* Copyright (c) 2014 Simon Symeonidis <lethaljellybean/at/gmail/com>
* Copyright (c) 2004-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_MEMORY_HELPER_H
#define LMMS_MEMORY_HELPER_H
#include <cstddef>
namespace lmms
{
/**
* Helper class to alocate aligned memory and free it.
*/
class MemoryHelper {
public:
static void* alignedMalloc( size_t );
static void alignedFree( void* );
private:
};
} // namespace lmms
#endif // LMMS_MEMORY_HELPER_H

View File

@@ -31,52 +31,54 @@ namespace lmms
{
class ValueBuffer;
class SampleFrame;
namespace MixHelpers
{
bool isSilent( const sampleFrame* src, int frames );
bool isSilent( const SampleFrame* src, int frames );
bool useNaNHandler();
void setNaNHandler( bool use );
bool sanitize( sampleFrame * src, int frames );
bool sanitize( SampleFrame* src, int frames );
/*! \brief Add samples from src to dst */
void add( sampleFrame* dst, const sampleFrame* src, int frames );
void add( SampleFrame* dst, const SampleFrame* src, int frames );
/*! \brief Multiply samples from `dst` by `coeff` */
void multiply(sampleFrame* dst, float coeff, int frames);
void multiply(SampleFrame* dst, float coeff, int frames);
/*! \brief Add samples from src multiplied by coeffSrc to dst */
void addMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames );
void addMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffSrc, int frames );
/*! \brief Add samples from src multiplied by coeffSrc to dst, swap inputs */
void addSwappedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames );
void addSwappedMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffSrc, int frames );
/*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst */
void addMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames );
void addMultipliedByBuffer( SampleFrame* dst, const SampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames );
/*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst */
void addMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames );
void addMultipliedByBuffers( SampleFrame* dst, const SampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames );
/*! \brief Same as addMultiplied, but sanitize output (strip out infs/nans) */
void addSanitizedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames );
void addSanitizedMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffSrc, int frames );
/*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst - sanitized version */
void addSanitizedMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames );
void addSanitizedMultipliedByBuffer( SampleFrame* dst, const SampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames );
/*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst - sanitized version */
void addSanitizedMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames );
void addSanitizedMultipliedByBuffers( SampleFrame* dst, const SampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames );
/*! \brief Add samples from src multiplied by coeffSrcLeft/coeffSrcRight to dst */
void addMultipliedStereo( sampleFrame* dst, const sampleFrame* src, float coeffSrcLeft, float coeffSrcRight, int frames );
void addMultipliedStereo( SampleFrame* dst, const SampleFrame* src, float coeffSrcLeft, float coeffSrcRight, int frames );
/*! \brief Multiply dst by coeffDst and add samples from src multiplied by coeffSrc */
void multiplyAndAddMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffDst, float coeffSrc, int frames );
void multiplyAndAddMultiplied( SampleFrame* dst, const SampleFrame* src, float coeffDst, float coeffSrc, int frames );
/*! \brief Multiply dst by coeffDst and add samples from srcLeft/srcRight multiplied by coeffSrc */
void multiplyAndAddMultipliedJoined( sampleFrame* dst, const sample_t* srcLeft, const sample_t* srcRight, float coeffDst, float coeffSrc, int frames );
void multiplyAndAddMultipliedJoined( SampleFrame* dst, const sample_t* srcLeft, const sample_t* srcRight, float coeffDst, float coeffSrc, int frames );
} // namespace MixHelpers

View File

@@ -56,7 +56,7 @@ class MixerChannel : public ThreadableJob
float m_peakLeft;
float m_peakRight;
sampleFrame * m_buffer;
SampleFrame* m_buffer;
bool m_muteBeforeSolo;
BoolModel m_muteModel;
BoolModel m_soloModel;
@@ -137,10 +137,10 @@ public:
Mixer();
~Mixer() override;
void mixToChannel( const sampleFrame * _buf, mix_ch_t _ch );
void mixToChannel( const SampleFrame* _buf, mix_ch_t _ch );
void prepareMasterMix();
void masterMix( sampleFrame * _buf );
void masterMix( SampleFrame* _buf );
void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
void loadSettings( const QDomElement & _this ) override;

View File

@@ -110,7 +110,7 @@ public:
float currentDetuning() const { return m_baseDetuning->value(); }
/*! Renders one chunk using the attached instrument into the buffer */
void play( sampleFrame* buffer ) override;
void play( SampleFrame* buffer ) override;
/*! Returns whether playback of note is finished and thus handle can be deleted */
bool isFinished() const override

View File

@@ -109,7 +109,7 @@ public:
m_userAntiAliasWaveTable = waveform;
}
void update(sampleFrame* ab, const fpp_t frames, const ch_cnt_t chnl, bool modulator = false);
void update(SampleFrame* ab, const fpp_t frames, const ch_cnt_t chnl, bool modulator = false);
// now follow the wave-shape-routines...
static inline sample_t sinSample( const float _sample )
@@ -282,40 +282,40 @@ private:
/* End Multiband wavetable */
void updateNoSub( sampleFrame * _ab, const fpp_t _frames,
void updateNoSub( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
void updatePM( sampleFrame * _ab, const fpp_t _frames,
void updatePM( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
void updateAM( sampleFrame * _ab, const fpp_t _frames,
void updateAM( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
void updateMix( sampleFrame * _ab, const fpp_t _frames,
void updateMix( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
void updateSync( sampleFrame * _ab, const fpp_t _frames,
void updateSync( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
void updateFM( sampleFrame * _ab, const fpp_t _frames,
void updateFM( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
float syncInit( sampleFrame * _ab, const fpp_t _frames,
float syncInit( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
inline bool syncOk( float _osc_coeff );
template<WaveShape W>
void updateNoSub( sampleFrame * _ab, const fpp_t _frames,
void updateNoSub( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShape W>
void updatePM( sampleFrame * _ab, const fpp_t _frames,
void updatePM( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShape W>
void updateAM( sampleFrame * _ab, const fpp_t _frames,
void updateAM( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShape W>
void updateMix( sampleFrame * _ab, const fpp_t _frames,
void updateMix( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShape W>
void updateSync( sampleFrame * _ab, const fpp_t _frames,
void updateSync( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShape W>
void updateFM( sampleFrame * _ab, const fpp_t _frames,
void updateFM( SampleFrame* _ab, const fpp_t _frames,
const ch_cnt_t _chnl );
template<WaveShape W>

View File

@@ -30,6 +30,13 @@
#include "lmms_basics.h"
namespace lmms
{
class SampleFrame;
}
namespace lmms::gui
{
@@ -67,7 +74,7 @@ protected:
protected slots:
void updateAudioBuffer( const lmms::surroundSampleFrame * buffer );
void updateAudioBuffer(const lmms::SampleFrame* buffer);
private:
bool clips(float level) const;
@@ -76,7 +83,7 @@ private:
QPixmap m_background;
QPointF * m_points;
sampleFrame * m_buffer;
SampleFrame* m_buffer;
bool m_active;
QColor m_leftChannelColor;

View File

@@ -41,6 +41,7 @@ namespace lmms
class Track;
class AudioPort;
class SampleFrame;
class LMMS_EXPORT PlayHandle : public ThreadableJob
{
@@ -105,7 +106,7 @@ public:
{
return m_processingLock.tryLock();
}
virtual void play( sampleFrame* buffer ) = 0;
virtual void play( SampleFrame* buffer ) = 0;
virtual bool isFinished() const = 0;
// returns the frameoffset at the start of the playhandle,
@@ -145,14 +146,14 @@ public:
void releaseBuffer();
sampleFrame * buffer();
SampleFrame* buffer();
private:
Type m_type;
f_cnt_t m_offset;
QThread* m_affinity;
QMutex m_processingLock;
sampleFrame* m_playHandleBuffer;
SampleFrame* m_playHandleBuffer;
bool m_bufferReleased;
bool m_usesBuffer;
AudioPort * m_audioPort;

View File

@@ -47,7 +47,7 @@ public:
return true;
}
void play( sampleFrame* buffer ) override;
void play( SampleFrame* buffer ) override;
bool isFinished() const override;
bool isFromTrack( const Track * _track ) const override;

View File

@@ -37,6 +37,7 @@ namespace lmms
class RemotePlugin;
class SampleFrame;
class ProcessWatcher : public QThread
{
@@ -96,7 +97,7 @@ public:
bool processMessage( const message & _m ) override;
bool process( const sampleFrame * _in_buf, sampleFrame * _out_buf );
bool process( const SampleFrame* _in_buf, SampleFrame* _out_buf );
void processMidiEvent( const MidiEvent&, const f_cnt_t _offset );

View File

@@ -44,6 +44,8 @@
namespace lmms
{
class SampleFrame;
class RemotePluginClient : public RemotePluginBase
{
public:
@@ -58,8 +60,8 @@ public:
bool processMessage( const message & _m ) override;
virtual void process( const sampleFrame * _in_buf,
sampleFrame * _out_buf ) = 0;
virtual void process( const SampleFrame* _in_buf,
SampleFrame* _out_buf ) = 0;
virtual void processMidiEvent( const MidiEvent&, const f_cnt_t /* _offset */ )
{
@@ -342,8 +344,8 @@ void RemotePluginClient::doProcessing()
{
if (m_audioBuffer)
{
process( (sampleFrame *)( m_inputCount > 0 ? m_audioBuffer.get() : nullptr ),
(sampleFrame *)( m_audioBuffer.get() +
process( (SampleFrame*)( m_inputCount > 0 ? m_audioBuffer.get() : nullptr ),
(SampleFrame*)( m_audioBuffer.get() +
( m_inputCount*m_bufferSize ) ) );
}
else

View File

@@ -35,6 +35,7 @@
namespace lmms
{
class SampleFrame;
/** \brief A basic LMMS ring buffer for single-thread use. For thread and realtime safe alternative see LocklessRingBuffer.
*/
@@ -105,7 +106,7 @@ public:
* to a specified destination, and advances the position by one period
* \param dst Destination pointer
*/
void pop( sampleFrame * dst );
void pop( SampleFrame* dst );
// note: ringbuffer position is unaffected by all other read functions beside pop()
@@ -113,27 +114,27 @@ public:
* \param dst Destination pointer
* \param offset Offset in frames against current position, may be negative
*/
void read( sampleFrame * dst, f_cnt_t offset=0 );
void read( SampleFrame* dst, f_cnt_t offset = 0 );
/** \brief Reads a period-sized buffer from the ringbuffer and writes it to a specified destination
* \param dst Destination pointer
* \param offset Offset in milliseconds against current position, may be negative
*/
void read( sampleFrame * dst, float offset );
void read( SampleFrame* dst, float offset );
/** \brief Reads a buffer of specified size from the ringbuffer and writes it to a specified destination
* \param dst Destination pointer
* \param offset Offset in frames against current position, may be negative
* \param length Length in frames of the buffer to read - must not be higher than the size of the ringbuffer!
*/
void read( sampleFrame * dst, f_cnt_t offset, f_cnt_t length );
void read( SampleFrame* dst, f_cnt_t offset, f_cnt_t length );
/** \brief Reads a buffer of specified size from the ringbuffer and writes it to a specified destination
* \param dst Destination pointer
* \param offset Offset in milliseconds against current position, may be negative
* \param length Length in frames of the buffer to read - must not be higher than the size of the ringbuffer!
*/
void read( sampleFrame * dst, float offset, f_cnt_t length );
void read( SampleFrame* dst, float offset, f_cnt_t length );
// write functions
@@ -143,28 +144,28 @@ public:
* \param offset Offset in frames against current position, may *NOT* be negative
* \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer!
*/
void write( sampleFrame * src, f_cnt_t offset=0, f_cnt_t length=0 );
void write( SampleFrame* src, f_cnt_t offset=0, f_cnt_t length=0 );
/** \brief Writes a buffer of sampleframes to the ringbuffer at specified position
* \param src Pointer to the source buffer
* \param offset Offset in milliseconds against current position, may *NOT* be negative
* \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer!
*/
void write( sampleFrame * src, float offset, f_cnt_t length=0 );
void write( SampleFrame* src, float offset, f_cnt_t length=0 );
/** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position
* \param src Pointer to the source buffer
* \param offset Offset in frames against current position, may *NOT* be negative
* \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer!
*/
void writeAdding( sampleFrame * src, f_cnt_t offset=0, f_cnt_t length=0 );
void writeAdding( SampleFrame* src, f_cnt_t offset=0, f_cnt_t length=0 );
/** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position
* \param src Pointer to the source buffer
* \param offset Offset in milliseconds against current position, may *NOT* be negative
* \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer!
*/
void writeAdding( sampleFrame * src, float offset, f_cnt_t length=0 );
void writeAdding( SampleFrame* src, float offset, f_cnt_t length=0 );
/** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position, with
* a specified multiplier applied to the frames
@@ -173,7 +174,7 @@ public:
* \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer!
* \param level Multiplier applied to the frames before they're written to the ringbuffer
*/
void writeAddingMultiplied( sampleFrame * src, f_cnt_t offset, f_cnt_t length, float level );
void writeAddingMultiplied( SampleFrame* src, f_cnt_t offset, f_cnt_t length, float level );
/** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position, with
* a specified multiplier applied to the frames
@@ -182,7 +183,7 @@ public:
* \param length Length of the source buffer, if zero, period size is used
* \param level Multiplier applied to the frames before they're written to the ringbuffer
*/
void writeAddingMultiplied( sampleFrame * src, float offset, f_cnt_t length, float level );
void writeAddingMultiplied( SampleFrame* src, float offset, f_cnt_t length, float level );
/** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position, with
* a specified multiplier applied to the frames, with swapped channels
@@ -191,7 +192,7 @@ public:
* \param length Length of the source buffer, if zero, period size is used - must not be higher than the size of the ringbuffer!
* \param level Multiplier applied to the frames before they're written to the ringbuffer
*/
void writeSwappedAddingMultiplied( sampleFrame * src, f_cnt_t offset, f_cnt_t length, float level );
void writeSwappedAddingMultiplied( SampleFrame* src, f_cnt_t offset, f_cnt_t length, float level );
/** \brief Mixes a buffer of sampleframes additively to the ringbuffer at specified position, with
* a specified multiplier applied to the frames, with swapped channels
@@ -200,7 +201,7 @@ public:
* \param length Length of the source buffer, if zero, period size is used
* \param level Multiplier applied to the frames before they're written to the ringbuffer
*/
void writeSwappedAddingMultiplied( sampleFrame * src, float offset, f_cnt_t length, float level );
void writeSwappedAddingMultiplied( SampleFrame* src, float offset, f_cnt_t length, float level );
protected slots:
@@ -215,7 +216,7 @@ private:
const fpp_t m_fpp;
sample_rate_t m_samplerate;
size_t m_size;
sampleFrame * m_buffer;
SampleFrame* m_buffer;
volatile unsigned int m_position;
};

View File

@@ -78,7 +78,7 @@ public:
Sample() = default;
Sample(const QByteArray& base64, int sampleRate = Engine::audioEngine()->outputSampleRate());
Sample(const sampleFrame* data, size_t numFrames, int sampleRate = Engine::audioEngine()->outputSampleRate());
Sample(const SampleFrame* data, size_t numFrames, int sampleRate = Engine::audioEngine()->outputSampleRate());
Sample(const Sample& other);
Sample(Sample&& other);
explicit Sample(const QString& audioFile);
@@ -87,7 +87,7 @@ public:
auto operator=(const Sample&) -> Sample&;
auto operator=(Sample&&) -> Sample&;
auto play(sampleFrame* dst, PlaybackState* state, size_t numFrames, float desiredFrequency = DefaultBaseFreq,
auto play(SampleFrame* dst, PlaybackState* state, size_t numFrames, float desiredFrequency = DefaultBaseFreq,
Loop loopMode = Loop::Off) const -> bool;
auto sampleDuration() const -> std::chrono::milliseconds;
@@ -97,7 +97,7 @@ public:
auto toBase64() const -> QString { return m_buffer->toBase64(); }
auto data() const -> const sampleFrame* { return m_buffer->data(); }
auto data() const -> 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); }
@@ -117,7 +117,7 @@ public:
void setReversed(bool reversed) { m_reversed.store(reversed, std::memory_order_relaxed); }
private:
void playRaw(sampleFrame* dst, size_t numFrames, const PlaybackState* state, Loop loopMode) const;
void playRaw(SampleFrame* dst, size_t numFrames, const PlaybackState* state, Loop loopMode) const;
void advance(PlaybackState* state, size_t advanceAmount, Loop loopMode) const;
private:

View File

@@ -41,22 +41,22 @@ namespace lmms {
class LMMS_EXPORT SampleBuffer
{
public:
using value_type = sampleFrame;
using reference = sampleFrame&;
using const_reference = const sampleFrame&;
using iterator = std::vector<sampleFrame>::iterator;
using const_iterator = std::vector<sampleFrame>::const_iterator;
using difference_type = std::vector<sampleFrame>::difference_type;
using size_type = std::vector<sampleFrame>::size_type;
using reverse_iterator = std::vector<sampleFrame>::reverse_iterator;
using const_reverse_iterator = std::vector<sampleFrame>::const_reverse_iterator;
using value_type = SampleFrame;
using reference = SampleFrame&;
using const_reference = const SampleFrame&;
using iterator = std::vector<SampleFrame>::iterator;
using const_iterator = std::vector<SampleFrame>::const_iterator;
using difference_type = std::vector<SampleFrame>::difference_type;
using size_type = std::vector<SampleFrame>::size_type;
using reverse_iterator = std::vector<SampleFrame>::reverse_iterator;
using const_reverse_iterator = std::vector<SampleFrame>::const_reverse_iterator;
SampleBuffer() = default;
explicit SampleBuffer(const QString& audioFile);
SampleBuffer(const QString& base64, int sampleRate);
SampleBuffer(std::vector<sampleFrame> data, int sampleRate);
SampleBuffer(std::vector<SampleFrame> data, int sampleRate);
SampleBuffer(
const sampleFrame* data, size_t numFrames, int sampleRate = Engine::audioEngine()->outputSampleRate());
const SampleFrame* data, size_t numFrames, int sampleRate = Engine::audioEngine()->outputSampleRate());
friend void swap(SampleBuffer& first, SampleBuffer& second) noexcept;
auto toBase64() const -> QString;
@@ -82,14 +82,14 @@ public:
auto crbegin() const -> const_reverse_iterator { return m_data.crbegin(); }
auto crend() const -> const_reverse_iterator { return m_data.crend(); }
auto data() const -> const sampleFrame* { return m_data.data(); }
auto data() const -> const SampleFrame* { return m_data.data(); }
auto size() const -> size_type { return m_data.size(); }
auto empty() const -> bool { return m_data.empty(); }
static auto emptyBuffer() -> std::shared_ptr<const SampleBuffer>;
private:
std::vector<sampleFrame> m_data;
std::vector<SampleFrame> m_data;
QString m_audioFile;
sample_rate_t m_sampleRate = Engine::audioEngine()->outputSampleRate();
};

View File

@@ -32,6 +32,7 @@
#include <vector>
#include "lmms_basics.h"
#include "SampleFrame.h"
namespace lmms {
class SampleDecoder
@@ -39,7 +40,7 @@ class SampleDecoder
public:
struct Result
{
std::vector<sampleFrame> data;
std::vector<SampleFrame> data;
int sampleRate;
};

230
include/SampleFrame.h Normal file
View File

@@ -0,0 +1,230 @@
/*
* SampleFrame.h - Representation of a stereo sample
*
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2024- Michael Gregorius
*
* 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_SAMPLEFRAME_H
#define LMMS_SAMPLEFRAME_H
#include "lmms_basics.h"
#include <array>
#include <cstddef>
namespace lmms
{
class SampleFrame
{
public:
SampleFrame() : SampleFrame(0., 0.)
{
}
explicit SampleFrame(sample_t value) : SampleFrame(value, value)
{
}
SampleFrame(sample_t left, sample_t right) :
m_samples({ left, right })
{
}
sample_t* data()
{
return m_samples.data();
}
const sample_t* data() const
{
return m_samples.data();
}
sample_t& left()
{
return m_samples[0];
}
const sample_t& left() const
{
return m_samples[0];
}
void setLeft(const sample_t& value)
{
m_samples[0] = value;
}
sample_t& right()
{
return m_samples[1];
}
const sample_t& right() const
{
return m_samples[1];
}
void setRight(const sample_t& value)
{
m_samples[1] = value;
}
sample_t& operator[](size_t index)
{
return m_samples[index];
}
const sample_t& operator[](size_t index) const
{
return m_samples[index];
}
SampleFrame operator+(const SampleFrame& other) const
{
return SampleFrame(left() + other.left(), right() + other.right());
}
SampleFrame& operator+=(const SampleFrame& other)
{
auto & l = left();
auto & r = right();
l += other.left();
r += other.right();
return *this;
}
SampleFrame operator*(float value) const
{
return SampleFrame(left() * value, right() * value);
}
SampleFrame& operator*=(float value)
{
setLeft(left() * value);
setRight(right() * value);
return *this;
}
SampleFrame operator*(const SampleFrame& other) const
{
return SampleFrame(left() * other.left(), right() * other.right());
}
void operator*=(const SampleFrame& other)
{
left() *= other.left();
right() *= other.right();
}
sample_t sumOfSquaredAmplitudes() const
{
return left() * left() + right() * right();
}
SampleFrame abs() const
{
return SampleFrame{std::abs(this->left()), std::abs(this->right())};
}
SampleFrame absMax(const SampleFrame& other)
{
const auto a = abs();
const auto b = other.abs();
return SampleFrame(std::max(a.left(), b.left()), std::max(a.right(), b.right()));
}
sample_t average() const
{
return (left() + right()) / 2;
}
void clamp(sample_t low, sample_t high)
{
auto & l = left();
l = std::clamp(l, low, high);
auto & r = right();
r = std::clamp(r, low, high);
}
bool containsInf() const
{
return std::isinf(left()) || std::isinf(right());
}
bool containsNaN() const
{
return std::isnan(left()) || std::isnan(right());
}
private:
std::array<sample_t, DEFAULT_CHANNELS> m_samples;
};
inline void zeroSampleFrames(SampleFrame* buffer, size_t frames)
{
// The equivalent of the following operation which yields compiler warnings
// memset(buffer, 0, sizeof(SampleFrame) * frames);
std::fill(buffer, buffer + frames, SampleFrame());
}
inline SampleFrame getAbsPeakValues(SampleFrame* buffer, size_t frames)
{
SampleFrame peaks;
for (f_cnt_t i = 0; i < frames; ++i)
{
peaks = peaks.absMax(buffer[i]);
}
return peaks;
}
inline void copyToSampleFrames(SampleFrame* target, const float* source, size_t frames)
{
for (size_t i = 0; i < frames; ++i)
{
target[i].setLeft(source[2*i]);
target[i].setRight(source[2*i + 1]);
}
}
inline void copyFromSampleFrames(float* target, const SampleFrame* source, size_t frames)
{
for (size_t i = 0; i < frames; ++i)
{
target[2*i] = source[i].left();
target[2*i + 1] = source[i].right();
}
}
} // namespace lmms
#endif // LMMS_SAMPLEFRAME_H

View File

@@ -55,7 +55,7 @@ public:
}
void play( sampleFrame * buffer ) override;
void play( SampleFrame* buffer ) override;
bool isFinished() const override;
bool isFromTrack( const Track * _track ) const override;

View File

@@ -48,7 +48,7 @@ public:
SampleRecordHandle(SampleClip* clip, TimePos startRecordTimeOffset);
~SampleRecordHandle() override;
void play( sampleFrame * _working_buffer ) override;
void play( SampleFrame* _working_buffer ) override;
bool isFinished() const override;
bool isFromTrack( const Track * _track ) const override;
@@ -58,10 +58,10 @@ public:
private:
virtual void writeBuffer( const sampleFrame * _ab,
virtual void writeBuffer( const SampleFrame* _ab,
const f_cnt_t _frames );
using bufferList = QList<QPair<sampleFrame*, f_cnt_t>>;
using bufferList = QList<QPair<SampleFrame*, f_cnt_t>>;
bufferList m_buffers;
f_cnt_t m_framesRecorded;
TimePos m_minLength;

View File

@@ -36,7 +36,7 @@ class LMMS_EXPORT SampleWaveform
public:
struct Parameters
{
const sampleFrame* buffer;
const SampleFrame* buffer;
size_t size;
float amplification;
bool reversed;

View File

@@ -43,7 +43,7 @@ public:
virtual ~SweepOscillator() = default;
void update( sampleFrame* buf, const fpp_t frames, const float freq1, const float freq2, const float sampleRate )
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 )

View File

@@ -31,17 +31,10 @@
#include <type_traits>
#include <vector>
#ifdef __MINGW32__
#include <mingw.condition_variable.h>
#include <mingw.future.h>
#include <mingw.mutex.h>
#include <mingw.thread.h>
#else
#include <condition_variable>
#include <future>
#include <mutex>
#include <thread>
#endif
namespace lmms {
//! A thread pool that can be used for asynchronous processing.

View File

@@ -33,6 +33,9 @@
#include <cstdint>
#include <array>
#include <cmath>
#include <algorithm>
namespace lmms
{
@@ -48,7 +51,7 @@ using int_sample_t = int16_t; // 16-bit-int-sample
using sample_rate_t = uint32_t; // sample-rate
using fpp_t = int16_t; // frames per period (0-16384)
using f_cnt_t = int32_t; // standard frame-count
using ch_cnt_t = uint8_t; // channel-count (0-SURROUND_CHANNELS)
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)
@@ -109,14 +112,6 @@ inline bool typeInfo<float>::isEqual( float x, float y )
constexpr ch_cnt_t DEFAULT_CHANNELS = 2;
constexpr ch_cnt_t SURROUND_CHANNELS =
#define LMMS_DISABLE_SURROUND
#ifndef LMMS_DISABLE_SURROUND
4;
#else
2;
#endif
constexpr char LADSPA_PATH_SEPERATOR =
#ifdef LMMS_BUILD_WIN32
';';
@@ -126,11 +121,6 @@ constexpr char LADSPA_PATH_SEPERATOR =
using sampleFrame = std::array<sample_t, DEFAULT_CHANNELS>;
using surroundSampleFrame = std::array<sample_t, SURROUND_CHANNELS>;
constexpr std::size_t LMMS_ALIGN_SIZE = 16;
#define LMMS_STRINGIFY(s) LMMS_STR(s)
#define LMMS_STR(PN) #PN

View File

@@ -36,6 +36,7 @@ constexpr long double LD_PI_R = 1.0 / LD_PI;
constexpr long double LD_PI_SQR = LD_PI * LD_PI;
constexpr long double LD_E = 2.71828182845904523536028747135266249775724709369995;
constexpr long double LD_E_R = 1.0 / LD_E;
constexpr long double LD_SQRT_2 = 1.41421356237309504880168872420969807856967187537695;
constexpr double D_PI = (double) LD_PI;
constexpr double D_2PI = (double) LD_2PI;
@@ -44,6 +45,7 @@ constexpr double D_PI_R = (double) LD_PI_R;
constexpr double D_PI_SQR = (double) LD_PI_SQR;
constexpr double D_E = (double) LD_E;
constexpr double D_E_R = (double) LD_E_R;
constexpr double D_SQRT_2 = (double) LD_SQRT_2;
constexpr float F_PI = (float) LD_PI;
constexpr float F_2PI = (float) LD_2PI;
@@ -52,6 +54,7 @@ constexpr float F_PI_R = (float) LD_PI_R;
constexpr float F_PI_SQR = (float) LD_PI_SQR;
constexpr float F_E = (float) LD_E;
constexpr float F_E_R = (float) LD_E_R;
constexpr float F_SQRT_2 = (float) LD_SQRT_2;
// Microtuner
constexpr unsigned int MaxScaleCount = 10; //!< number of scales per project