LMMS
Loading...
Searching...
No Matches
lmms::Lb302Synth Class Reference

#include <Lb302.h>

Inheritance diagram for lmms::Lb302Synth:
lmms::Instrument lmms::Plugin lmms::Model lmms::JournallingObject lmms::SerializingObject

Public Slots

void filterChanged ()
void decayChanged ()
 Adjusts m_fs 's Lb302FilterKnobState::envdecay for both sampling rate and s_envInc.
void db24Toggled ()

Public Member Functions

 Lb302Synth (InstrumentTrack *)
void play (SampleFrame *working_buffer) override
void playNote (NotePlayHandle *nph, SampleFrame *working_buffer) override
void deleteNotePluginData (NotePlayHandle *nph) override
void saveSettings (QDomDocument &doc, QDomElement &el) override
void loadSettings (const QDomElement &el) override
QString nodeName () const override
gui::PluginViewinstantiateView (QWidget *parent) override
 Create a view for the model.
Public Member Functions inherited from lmms::Instrument
 Instrument (InstrumentTrack *_instrument_track, const Descriptor *_descriptor, const Descriptor::SubPluginFeatures::Key *key=nullptr, Flags flags=Flag::NoFlags)
 ~Instrument () override=default
virtual bool hasNoteInput () const
virtual f_cnt_t beatLen (NotePlayHandle *_n) const
virtual float desiredReleaseTimeMs () const
f_cnt_t desiredReleaseFrames () const
sample_rate_t getSampleRate () const
bool isSingleStreamed () const
bool isMidiBased () const
bool isBendable () const
virtual bool handleMidiEvent (const MidiEvent &, const TimePos &=TimePos(), f_cnt_t offset=0)
QString fullDisplayName () const override
virtual bool isFromTrack (const Track *_track) const
InstrumentTrackinstrumentTrack () const
Public Member Functions inherited from lmms::Plugin
 Plugin (const Descriptor *descriptor, Model *parent, const Descriptor::SubPluginFeatures::Key *key=nullptr)
 ~Plugin () override=default
QString displayName () const override
 Return display-name out of sub plugin or descriptor.
const PixmapLoaderlogo () const
 Return logo out of sub plugin or descriptor.
Type type () const
 Return plugin type.
const Descriptordescriptor () const
 Return plugin Descriptor.
const Descriptor::SubPluginFeatures::Keykey () const
virtual void loadFile (const QString &file)
virtual AutomatableModelchildModel (const QString &modelName)
gui::PluginViewcreateView (QWidget *parent)
 Create a view for the model.
Public Member Functions inherited from lmms::Model
 Model (Model *parent, QString displayName=QString(), bool defaultConstructed=false)
 ~Model () override=default
bool isDefaultConstructed () const
ModelparentModel () const
virtual void setDisplayName (const QString &displayName)
Public Member Functions inherited from lmms::JournallingObject
 JournallingObject ()
 ~JournallingObject () override
jo_id_t id () const
void saveJournallingState (const bool newState)
void restoreJournallingState ()
void addJournalCheckPoint ()
QDomElement saveState (QDomDocument &_doc, QDomElement &_parent) override
void restoreState (const QDomElement &_this) override
bool isJournalling () const
void setJournalling (const bool _sr)
bool testAndSetJournalling (const bool newState)
bool isJournallingStateStackEmpty () const
Public Member Functions inherited from lmms::SerializingObject
 SerializingObject ()
virtual ~SerializingObject ()
void setHook (SerializingObjectHook *_hook)
SerializingObjectHookhook ()

Private Types

enum class  VcoShape {
  Sawtooth , Triangle , Square , RoundSquare ,
  Moog , Sine , Exponential , WhiteNoise ,
  BLSawtooth , BLSquare , BLTriangle , BLMoog
}
enum class  VcaMode { Attack , Decay , Idle , NeverPlayed }

Private Member Functions

void processNote (NotePlayHandle *nph)
void process (SampleFrame *outbuf, const f_cnt_t size)
void recalcFilter ()
Lb302Filtervcf ()
 Helper to get current vcf.

Private Attributes

FloatModel m_vcfCutKnob
FloatModel m_vcfResKnob
FloatModel m_vcfModKnob
FloatModel m_vcfDecKnob
FloatModel m_vcoDetuneKnob
FloatModel m_distKnob
IntModel m_waveShape
FloatModel m_slideDecKnob
BoolModel m_slideToggle
BoolModel m_accentToggle
BoolModel m_deadToggle
BoolModel m_db24Toggle
float m_vcoInc = 0.f
 Sample increment for the frequency. Creates Sawtooth.
float m_vcoK = 0.f
 Raw oscillator sample [-0.5, 0.5].
float m_vcoC = 0.f
 Raw oscillator sample [-0.5, 0.5].
bool m_newFreq = false
float m_trueFreq = 0.f
float m_slide = 0.f
 Current value of slide exponential curve. Nonzero=sliding.
float m_slideInc = 0.f
 Slide base to use in next node. Nonzero=slide next note.
float m_slideBase = 0.f
 The base m_vcoInc while sliding.
VcoShape m_vcoShape = VcoShape::BLSawtooth
Lb302FilterKnobState m_fs = {}
std::array< std::unique_ptr< Lb302Filter >, 2 > m_vcfs
 Filters (just keep both loaded and switch).
f_cnt_t m_vcfEnvPos = s_envInc
 Update counter. Updates when >= s_envInc.
f_cnt_t m_releaseFrame = 0
float m_vca = 0.f
 Amplifier coefficient.
float m_noteVolume = 1.f
 The per-note volume (velocity) of the most recent note, within [0, 1].
panning_t m_notePan = DefaultPanning
 The per-note panning of the most recent note.
VcaMode m_vcaMode = VcaMode::NeverPlayed
NotePlayHandlem_playingNote = nullptr
std::array< NotePlayHandle *, s_maxPendingNotesm_notes {}
 Backing array for the multiple-producer single-consumer realtime-safe ring buffer queue for note events.
std::atomic_size_t m_notesReadSeq {0}
 Sequence number indicating complete dequeue operations.
std::atomic_size_t m_notesWriteCommitted {0}
 Sequence number indicating complete enqueue operations.
std::atomic_size_t m_notesWriteClaimed {0}
 Sequence number indicating in-progress enqueue operations.

Static Private Attributes

static constexpr float s_distRatio = 4.f
static constexpr f_cnt_t s_envInc = 64
 Envelope Recalculation period
static constexpr float s_vcaAttack = 1.f - 0.96406088f
 Amplitude attack.
static constexpr float s_vcaInitial = 0.5f
 Initial amplifier coefficient.
static constexpr std::size_t s_maxPendingNotes = 128
 The maximum number of note events Lb302 can process per audio buffer.
static constexpr std::size_t s_maxNoteEnqueueRetries = s_maxPendingNotes
 The maximum number of retries permitted per enqueue operation before a note is dropped.
static constexpr std::size_t s_notesBufMask = s_maxPendingNotes - 1
 Bitmask used to wrap arbitrary indicies within the bounds of m_notes.

Friends

class gui::Lb302SynthView

Additional Inherited Members

Public Types inherited from lmms::Instrument
enum class  Flag { NoFlags = 0x00 , IsSingleStreamed = 0x01 , IsMidiBased = 0x02 , IsNotBendable = 0x04 }
using Flags = lmms::Flags<Flag>
Public Types inherited from lmms::Plugin
enum class  Type {
  Instrument , Effect , ImportFilter , ExportFilter ,
  Tool , Library , Other , Undefined = 255
}
using DescriptorList = QList<Descriptor*>
Signals inherited from lmms::Model
void dataChanged ()
void dataUnchanged ()
void propertiesChanged ()
Static Public Member Functions inherited from lmms::Instrument
static Instrumentinstantiate (const QString &_plugin_name, InstrumentTrack *_instrument_track, const Plugin::Descriptor::SubPluginFeatures::Key *key, bool keyFromDnd=false)
Static Public Member Functions inherited from lmms::Plugin
static PlugininstantiateWithKey (const QString &pluginName, Model *parent, const Descriptor::SubPluginFeatures::Key *key, bool keyFromDnd=false)
static Plugininstantiate (const QString &pluginName, Model *parent, void *data)
Protected Member Functions inherited from lmms::Instrument
void applyFadeIn (SampleFrame *buf, NotePlayHandle *n)
void applyRelease (SampleFrame *buf, const NotePlayHandle *_n)
float computeReleaseTimeMsByFrameCount (f_cnt_t frames) const
Protected Member Functions inherited from lmms::Plugin
void collectErrorForUI (QString errMsg)
Protected Member Functions inherited from lmms::JournallingObject
void changeID (jo_id_t _id)

Member Enumeration Documentation

◆ VcaMode

enum class lmms::Lb302Synth::VcaMode
strongprivate
Enumerator
Attack 
Decay 
Idle 
NeverPlayed 

◆ VcoShape

enum class lmms::Lb302Synth::VcoShape
strongprivate
Enumerator
Sawtooth 
Triangle 
Square 
RoundSquare 
Moog 
Sine 
Exponential 
WhiteNoise 
BLSawtooth 
BLSquare 
BLTriangle 
BLMoog 

Constructor & Destructor Documentation

◆ Lb302Synth()

lmms::Lb302Synth::Lb302Synth ( InstrumentTrack * instrumentTrack)

Member Function Documentation

◆ db24Toggled

void lmms::Lb302Synth::db24Toggled ( )
slot

◆ decayChanged

void lmms::Lb302Synth::decayChanged ( )
slot

Adjusts m_fs 's Lb302FilterKnobState::envdecay for both sampling rate and s_envInc.

◆ deleteNotePluginData()

void lmms::Lb302Synth::deleteNotePluginData ( NotePlayHandle * nph)
overridevirtual

Reimplemented from lmms::Instrument.

◆ filterChanged

void lmms::Lb302Synth::filterChanged ( )
slot

◆ instantiateView()

gui::PluginView * lmms::Lb302Synth::instantiateView ( QWidget * )
overridevirtual

Create a view for the model.

Implements lmms::Plugin.

◆ loadSettings()

void lmms::Lb302Synth::loadSettings ( const QDomElement & el)
overridevirtual

◆ nodeName()

QString lmms::Lb302Synth::nodeName ( void ) const
overridevirtual

◆ play()

void lmms::Lb302Synth::play ( SampleFrame * working_buffer)
overridevirtual

Reimplemented from lmms::Instrument.

◆ playNote()

void lmms::Lb302Synth::playNote ( NotePlayHandle * nph,
SampleFrame * working_buffer )
overridevirtual

Reimplemented from lmms::Instrument.

◆ process()

void lmms::Lb302Synth::process ( SampleFrame * outbuf,
const f_cnt_t size )
private

◆ processNote()

void lmms::Lb302Synth::processNote ( NotePlayHandle * nph)
private

Start a new note.

◆ recalcFilter()

void lmms::Lb302Synth::recalcFilter ( )
private

◆ saveSettings()

void lmms::Lb302Synth::saveSettings ( QDomDocument & doc,
QDomElement & el )
overridevirtual

◆ vcf()

Lb302Filter & lmms::Lb302Synth::vcf ( )
inlineprivate

Helper to get current vcf.

See also
m_vcfs
db24Toggle

◆ gui::Lb302SynthView

friend class gui::Lb302SynthView
friend

Member Data Documentation

◆ m_accentToggle

BoolModel lmms::Lb302Synth::m_accentToggle
private

◆ m_db24Toggle

BoolModel lmms::Lb302Synth::m_db24Toggle
private

◆ m_deadToggle

BoolModel lmms::Lb302Synth::m_deadToggle
private

◆ m_distKnob

FloatModel lmms::Lb302Synth::m_distKnob
private

◆ m_fs

Lb302FilterKnobState lmms::Lb302Synth::m_fs = {}
private

◆ m_newFreq

bool lmms::Lb302Synth::m_newFreq = false
private

◆ m_notePan

panning_t lmms::Lb302Synth::m_notePan = DefaultPanning
private

The per-note panning of the most recent note.

◆ m_notes

std::array<NotePlayHandle*, s_maxPendingNotes> lmms::Lb302Synth::m_notes {}
private

Backing array for the multiple-producer single-consumer realtime-safe ring buffer queue for note events.

This is used to implement monophony, since multiple LMMS threads can independently send note events to an instance of Lb302.

See also
s_maxPendingNotes
m_notesReadSeq
m_notesWriteCommitted
m_notesWriteClaimed

◆ m_notesReadSeq

std::atomic_size_t lmms::Lb302Synth::m_notesReadSeq {0}
private

Sequence number indicating complete dequeue operations.

As notes are dequeued, this sequence number is incremented. It can be used as an index into m_notes if bitwise-AND'd with s_notesBufMask.

The difference between this sequence number and m_notesReadSeq is the number of currently vacant indicies in m_notes that are available to be written to, and can never exceed s_maxPendingNotes.

See also
play

◆ m_notesWriteClaimed

std::atomic_size_t lmms::Lb302Synth::m_notesWriteClaimed {0}
private

Sequence number indicating in-progress enqueue operations.

As note enqueue operations begin, this sequence number is incremented. It can be used as an index into m_notes if bitwise-AND'd with s_notesBufMask.

The difference between this sequence number and m_notesReadSeq is the number of currently occupied indicies in m_notes (even those not yet written to), and can never exceed s_maxPendingNotes.

See also
playNote

◆ m_notesWriteCommitted

std::atomic_size_t lmms::Lb302Synth::m_notesWriteCommitted {0}
private

Sequence number indicating complete enqueue operations.

As note enqueue operations complete, this sequence number is incremented. It can be used as an index into m_notes if bitwise-AND'd with s_notesBufMask.

The difference between this sequence number and m_notesReadSeq is the number of currently enqueued notes ready to be dequeued, and can never exceed s_maxPendingNotes. It should always be less than or equal to m_notesWriteClaimed.

See also
playNote

◆ m_noteVolume

float lmms::Lb302Synth::m_noteVolume = 1.f
private

The per-note volume (velocity) of the most recent note, within [0, 1].

◆ m_playingNote

NotePlayHandle* lmms::Lb302Synth::m_playingNote = nullptr
private

◆ m_releaseFrame

f_cnt_t lmms::Lb302Synth::m_releaseFrame = 0
private

◆ m_slide

float lmms::Lb302Synth::m_slide = 0.f
private

Current value of slide exponential curve. Nonzero=sliding.

◆ m_slideBase

float lmms::Lb302Synth::m_slideBase = 0.f
private

The base m_vcoInc while sliding.

◆ m_slideDecKnob

FloatModel lmms::Lb302Synth::m_slideDecKnob
private

◆ m_slideInc

float lmms::Lb302Synth::m_slideInc = 0.f
private

Slide base to use in next node. Nonzero=slide next note.

◆ m_slideToggle

BoolModel lmms::Lb302Synth::m_slideToggle
private

◆ m_trueFreq

float lmms::Lb302Synth::m_trueFreq = 0.f
private

◆ m_vca

float lmms::Lb302Synth::m_vca = 0.f
private

Amplifier coefficient.

◆ m_vcaMode

VcaMode lmms::Lb302Synth::m_vcaMode = VcaMode::NeverPlayed
private

◆ m_vcfCutKnob

FloatModel lmms::Lb302Synth::m_vcfCutKnob
private

◆ m_vcfDecKnob

FloatModel lmms::Lb302Synth::m_vcfDecKnob
private

◆ m_vcfEnvPos

f_cnt_t lmms::Lb302Synth::m_vcfEnvPos = s_envInc
private

Update counter. Updates when >= s_envInc.

◆ m_vcfModKnob

FloatModel lmms::Lb302Synth::m_vcfModKnob
private

◆ m_vcfResKnob

FloatModel lmms::Lb302Synth::m_vcfResKnob
private

◆ m_vcfs

std::array<std::unique_ptr<Lb302Filter>, 2> lmms::Lb302Synth::m_vcfs
private

Filters (just keep both loaded and switch).

◆ m_vcoC

float lmms::Lb302Synth::m_vcoC = 0.f
private

Raw oscillator sample [-0.5, 0.5].

◆ m_vcoDetuneKnob

FloatModel lmms::Lb302Synth::m_vcoDetuneKnob
private

◆ m_vcoInc

float lmms::Lb302Synth::m_vcoInc = 0.f
private

Sample increment for the frequency. Creates Sawtooth.

◆ m_vcoK

float lmms::Lb302Synth::m_vcoK = 0.f
private

Raw oscillator sample [-0.5, 0.5].

◆ m_vcoShape

VcoShape lmms::Lb302Synth::m_vcoShape = VcoShape::BLSawtooth
private

◆ m_waveShape

IntModel lmms::Lb302Synth::m_waveShape
private

◆ s_distRatio

float lmms::Lb302Synth::s_distRatio = 4.f
staticconstexprprivate

◆ s_envInc

f_cnt_t lmms::Lb302Synth::s_envInc = 64
staticconstexprprivate

Envelope Recalculation period

◆ s_maxNoteEnqueueRetries

std::size_t lmms::Lb302Synth::s_maxNoteEnqueueRetries = s_maxPendingNotes
staticconstexprprivate

The maximum number of retries permitted per enqueue operation before a note is dropped.

Enqueue operations may fail during high contention as multiple threads attempt to reserve the next spot in the ringbuffer using atomic CAS operations, or when there are already s_maxPendingNotes enqueued notes in the ringbuffer. This constant determines the maximum number of times an enqueue operation is allowed to retry under either of these circumstances before it gives up and drops the note.

This limit should never be met under normal operation and is a failsafe for catastrophic performance situations to prevent hanging in spinlocks.

See also
playNote

◆ s_maxPendingNotes

std::size_t lmms::Lb302Synth::s_maxPendingNotes = 128
staticconstexprprivate

The maximum number of note events Lb302 can process per audio buffer.

This value was arbitrarily chosen based off of stress tests with LMMS's buffer size set to its maximum value (4096 samples) to maximize the ratio of enqueue operations to dequeue operations per buffer. It may be adjusted as needed, but it must always be a power of 2.

See also
m_notes

◆ s_notesBufMask

std::size_t lmms::Lb302Synth::s_notesBufMask = s_maxPendingNotes - 1
staticconstexprprivate

Bitmask used to wrap arbitrary indicies within the bounds of m_notes.

See also
m_notesReadSeq
m_notesWriteCommitted
m_notesWriteClaimed

◆ s_vcaAttack

float lmms::Lb302Synth::s_vcaAttack = 1.f - 0.96406088f
staticconstexprprivate

Amplitude attack.

◆ s_vcaInitial

float lmms::Lb302Synth::s_vcaInitial = 0.5f
staticconstexprprivate

Initial amplifier coefficient.


The documentation for this class was generated from the following files: