Files
lmms/plugins/Vibed/VibratingString.h
saker b2f2fc4ad1 Revisit the initialization for local variables (#7143)
* clang-tidy: Apply cppcoreguidelines-init-variables everywhere (treating NaNs as zeros)

* Initialize msec and tick outside switch

* Update plugins/Vestige/Vestige.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/Vestige/Vestige.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/Vestige/Vestige.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/VstEffect/VstEffectControls.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/VstEffect/VstEffectControls.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/VstEffect/VstEffectControls.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Use initialization with =

* Use tabs

* Use static_cast

* Update DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Do not use tabs for alignment in src/core/DrumSynth.cpp

Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>

* Move x variable inside loop

* Use ternary operator for b variable

* Revert "Use tabs"

This reverts commit 07afd8a83f58b539c3673310b2aad4b63c9198a0.

* Remove unnecessary variables in XpressiveView

* Simplify initialization in Plugin

* Combine declaration and initialization in EqCurve

* Combine declaration and initialization in Song

* Combine declaration and initialization in AudioAlsa

* Combine declaration and initialization in EqCurve (again)

* Missed some

* Undo changes made to non-LMMS files

* Undo indentation changes in SidInstrument.cpp

* Combine declaration with assignment in IoHelper

* Combine declaration with assignment using auto in Carla

* Combine declaration with assignment

* Combine declaration with assignment in BasicFilters

* Simplify assignments in AudioFileProcessorWaveView::zoom

* Simplify out sample variable in BitInvader

* Remove sampleLength variable in DelayEffect

* Move gain variable in DynamicsProcessor

* Combine peak variable declaration with assignment in EqSpectrumView

* Move left/right lfo variables in for loop in FlangerEffect

* Use ternary operator for group variable in LadspaControlDialog

* Combine declaration with assignment in Lb302

* Combine declaration with assignment in MidiExport

* Combine declaration with assignment in MidiFile

* Combine declaration with assignment in MidiImport

* Use ternary operator for vel_adjusted variable in OpulenZ

* Move tmpL and dcblkL variables in for loop in ReverbSC

* Combine declaration with initialization in SlicerT

* Combine declaration with assignment in SaSpectrumView

* Combine declaration with assignment in SaWaterfallView

* Combine declaration with assignment in StereoEnhancerEffect

* Combine declaration with assignment in VibratingString

* Combine declaration with assignment in VstEffectControls

* Combine declaration with assignment in Xpressive

* Combine declaration with assignment in AutomatableModel

* Combine declaration with assignment in AutomationClip

* Move sample variable in for loop in BandLimitedWave

* Combine declaration with assignment in DataFile

* Combine declaration with assignment in DrumSynth

* Combine declaration with assignment in Effect

* Remove redundant assignment to nphsLeft in InstrumentPlayHandle

* Combine declaration with assignment in LadspaManager

* Combine declaration with assignment in LinkedModelGroups

* Combine declaration with assignment in MemoryHelper

* Combine declaration with assignment in AudioAlsa

* Combine declaration with assignment in AudioFileOgg

* Combine declaration with assignment in AudioPortAudio

* Combine declaration with assignment in AudioSoundIo

* Combine declaration with assignment in Lv2Evbuf

* Combine declaration with assignment in Lv2Proc

* Combine declaration with assignment in main

* Combine declaration with assignment in MidiAlsaRaw

* Combine declaration with assignment in MidiAlsaSeq

* Combine declaration with assignment in MidiController

* Combine declaration with assignment in MidiJack

* Combine declaration with assignment in MidiSndio

* Combine declaration with assignment in ControlLayout

* Combine declaration with assignment in MainWindow

* Combine declaration with assignment in ProjectNotes

* Use ternary operator for nextValue variable in AutomationClipView

* Combine declaration with assignment in AutomationEditor

* Move length variable in for-loop in PianoRoll

* Combine declaration with assignment in ControllerConnectionDialog

* Combine declaration with assignment in Graph

* Combine declaration with assignment in LcdFloatSpinBox

* Combine declaration with assignment in TimeDisplayWidget

* Remove currentNote variable in InstrumentTrack

* Combine declaration with assignment in DrumSynth (again)

* Use ternary operator for factor variable in BitInvader

* Use ternary operator for highestBandwich variable in EqCurve

Bandwich?

* Move sum variable into for loop in Graph

* Fix format in MidiSndio

* Fixup a few more

* Cleanup error variables

* Use ternary operators and combine declaration with initialization

* Combine declaration with initialization

* Update plugins/LadspaEffect/LadspaControlDialog.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/OpulenZ/OpulenZ.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/SpectrumAnalyzer/SaProcessor.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/midi/MidiAlsaRaw.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/gui/MainWindow.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/gui/clips/AutomationClipView.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/gui/editors/AutomationEditor.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/gui/widgets/Fader.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Move static_cast conversion into separate variable

* Use real index when interpolating

* Remove empty line

* Make helpBtn a private member

* Move controller type into separate variable

* Fix format of DrumSynth::waveform function

* Use tabs and static_cast

* Remove redundant if branch

* Refactor using static_cast/reinterpret_cast

* Add std namespace prefix

* Store repeated conditional into boolean variable

* Cast to int before assigning to m_currentLength

* Rename note_frames to noteFrames

* Update src/core/Controller.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/gui/widgets/Graph.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Revert changes that initialized variables redudantly

For situations where the initialization is
more complex or passed into a function
by a pointer, we dont need to do
initialization ourselves since it is
already done for us, just in a different way.

* Remove redundant err variable

* Remove explicit check of err variable

* Clean up changes and address review

* Do not initialize to 0/nullptr when not needed

* Wrap condition in parentheses for readability

---------

Co-authored-by: Kevin Zander <veratil@gmail.com>
Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
2024-03-28 17:21:31 -04:00

250 lines
6.6 KiB
C++

/*
* VibratingString.h - model of a vibrating string lifted from pluckedSynth
*
* Copyright (c) 2006-2007 Danny McRae <khjklujn/at/yahoo/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 LMMS_VIBRATING_STRING_H
#define LMMS_VIBRATING_STRING_H
#include <memory>
#include <cstdlib>
#include "lmms_basics.h"
namespace lmms
{
class VibratingString
{
public:
VibratingString() = default;
VibratingString(float pitch, float pick, float pickup, const float* impulse, int len,
sample_rate_t sampleRate, int oversample, float randomize, float stringLoss, float detune, bool state);
~VibratingString() = default;
VibratingString(const VibratingString&) = delete;
VibratingString& operator=(const VibratingString&) = delete;
VibratingString(VibratingString&&) noexcept = delete;
VibratingString& operator=(VibratingString&&) noexcept = default;
sample_t nextSample()
{
for (int i = 0; i < m_oversample; ++i)
{
// Output at pickup position
m_outsamp[i] = fromBridgeAccess(m_fromBridge.get(), m_pickupLoc);
m_outsamp[i] += toBridgeAccess(m_toBridge.get(), m_pickupLoc);
// Sample traveling into "bridge"
sample_t ym0 = toBridgeAccess(m_toBridge.get(), 1);
// Sample to "nut"
sample_t ypM = fromBridgeAccess(m_fromBridge.get(), m_fromBridge->length - 2);
// String state update
// Decrement pointer and then update
fromBridgeUpdate(m_fromBridge.get(), -bridgeReflection(ym0));
// Update and then increment pointer
toBridgeUpdate(m_toBridge.get(), -ypM);
}
return m_outsamp[m_choice];
}
private:
struct DelayLine
{
std::unique_ptr<sample_t[]> data;
int length;
sample_t* pointer;
sample_t* end;
};
std::unique_ptr<DelayLine> m_fromBridge;
std::unique_ptr<DelayLine> m_toBridge;
int m_pickupLoc;
int m_oversample;
float m_randomize;
float m_stringLoss;
std::unique_ptr<float[]> m_impulse;
int m_choice;
float m_state;
std::unique_ptr<sample_t[]> m_outsamp;
std::unique_ptr<DelayLine> initDelayLine(int len);
void resample(const float* src, f_cnt_t srcFrames, f_cnt_t dstFrames);
/**
* setDelayLine initializes the string with an impulse at the pick
* position unless the impulse is longer than the string, in which
* case the impulse gets truncated.
*/
void setDelayLine(DelayLine* dl, int pick, const float* values, int len, float scale, bool state)
{
if (!state)
{
for (int i = 0; i < pick; ++i)
{
float r = static_cast<float>(std::rand()) / RAND_MAX;
float offset = (m_randomize / 2.0f - m_randomize) * r;
dl->data[i] = scale * values[dl->length - i - 1] + offset;
}
for (int i = pick; i < dl->length; ++i)
{
float r = static_cast<float>(std::rand()) / RAND_MAX;
float offset = (m_randomize / 2.0f - m_randomize) * r;
dl->data[i] = scale * values[i - pick] + offset;
}
}
else
{
if (len + pick > dl->length)
{
for (int i = pick; i < dl->length; ++i)
{
float r = static_cast<float>(std::rand()) / RAND_MAX;
float offset = (m_randomize / 2.0f - m_randomize) * r;
dl->data[i] = scale * values[i - pick] + offset;
}
}
else
{
for (int i = 0; i < len; ++i)
{
float r = static_cast<float>(std::rand()) / RAND_MAX;
float offset = (m_randomize / 2.0f - m_randomize) * r;
dl->data[i+pick] = scale * values[i] + offset;
}
}
}
}
/**
* toBridgeUpdate(dl, insamp);
* Places "nut-reflected" sample from upper delay-line into
* current lower delay-line pointer position (which represents
* x = 0 position). The pointer is then incremented (i.e. the
* wave travels one sample to the left), turning the previous
* position into an "effective" x = L position for the next
* iteration.
*/
void toBridgeUpdate(DelayLine* dl, sample_t insamp)
{
sample_t* ptr = dl->pointer;
*ptr = insamp * m_stringLoss;
++ptr;
if (ptr > dl->end)
{
ptr = dl->data.get();
}
dl->pointer = ptr;
}
/**
* fromBridgeUpdate(dl, insamp);
* Decrements current upper delay-line pointer position (i.e.
* the wave travels one sample to the right), moving it to the
* "effective" x = 0 position for the next iteration. The
* "bridge-reflected" sample from lower delay-line is then placed
* into this position.
*/
void fromBridgeUpdate(DelayLine* dl, sample_t insamp)
{
sample_t* ptr = dl->pointer;
--ptr;
if (ptr < dl->data.get())
{
ptr = dl->end;
}
*ptr = insamp * m_stringLoss;
dl->pointer = ptr;
}
/**
* dlAccess(dl, position);
* Returns sample "position" samples into delay-line's past.
* Position "0" points to the most recently inserted sample.
*/
static sample_t dlAccess(DelayLine* dl, int position)
{
sample_t* outpos = dl->pointer + position;
while (outpos < dl->data.get())
{
outpos += dl->length;
}
while (outpos > dl->end)
{
outpos -= dl->length;
}
return *outpos;
}
/*
* Right-going delay line:
* -->---->---->---
* x=0
* (pointer)
* Left-going delay line:
* --<----<----<---
* x=0
* (pointer)
*/
/**
* fromBridgeAccess(dl, position);
* Returns spatial sample at position "position", where position zero
* is equal to the current upper delay-line pointer position (x = 0).
* In a right-going delay-line, position increases to the right, and
* delay increases to the right => left = past and right = future.
*/
static sample_t fromBridgeAccess(DelayLine* dl, int position)
{
return dlAccess(dl, position);
}
/**
* toBridgeAccess(dl, position);
* Returns spatial sample at position "position", where position zero
* is equal to the current lower delay-line pointer position (x = 0).
* In a left-going delay-line, position increases to the right, and
* delay DEcreases to the right => left = future and right = past.
*/
static sample_t toBridgeAccess(DelayLine* dl, int position)
{
return dlAccess(dl, position);
}
sample_t bridgeReflection(sample_t insamp)
{
m_state = (m_state + insamp) * 0.5;
return m_state;
}
};
} // namespace lmms
#endif // LMMS_VIBRATING_STRING_H