Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
143 commits
Select commit Hold shift + click to select a range
adc7b40
Initial commit
regulus79 Dec 10, 2025
c66783f
Temporary Commit
regulus79 Dec 10, 2025
1620912
Kinda sorta working
regulus79 Dec 15, 2025
2469ea1
Temp commit
regulus79 Dec 15, 2025
7762bac
Fix segfault
regulus79 Dec 15, 2025
ed38cb0
Temporary commit
regulus79 Dec 17, 2025
2f8a7c9
Merge branch 'master' into sfzsampler
regulus79 Dec 18, 2025
9a75508
Initial parser
regulus79 Dec 18, 2025
d9cc663
Temp commit, Compiles
regulus79 Dec 18, 2025
5f7c15c
Lots of additions
regulus79 Dec 19, 2025
49d7508
Compiles now
regulus79 Dec 19, 2025
74132e9
Minor changes, temp array
regulus79 Dec 20, 2025
4f34d38
Loading samples
regulus79 Dec 20, 2025
b12a7cf
Makes sound, temp commit
regulus79 Dec 21, 2025
214de19
Use max active voice index optimization
regulus79 Dec 21, 2025
b3e2029
Fix a couple bugs
regulus79 Dec 21, 2025
07e9f28
Add pitch keytrack
regulus79 Dec 21, 2025
9587c53
Add amplitude envelope generator
regulus79 Dec 21, 2025
bc3b4eb
Use value instead of value_or
regulus79 Dec 21, 2025
b26da76
Profiling statments, and optimizations
regulus79 Dec 22, 2025
17c4606
Use custom sample buffer implementation
regulus79 Dec 22, 2025
4d61b10
Add #includes and #defines to sfz parser
regulus79 Dec 24, 2025
ecb9907
Add better code for handling headers, and sample names with spaces
regulus79 Dec 24, 2025
86f7893
Add default_path opcode
regulus79 Dec 24, 2025
32f040c
Initial CC modulation support
regulus79 Dec 26, 2025
ca09891
Add amp_veltrack opcode and clean up some stuff
regulus79 Dec 26, 2025
2518338
Add offset, tune, volume, and pan opcodes
regulus79 Dec 27, 2025
4604ed9
Merge branch 'master' into sfzsampler
regulus79 Dec 28, 2025
e6d811d
Initial support for loop_mode
regulus79 Jan 1, 2026
9facfde
Add filter and fix amp_veltrack
regulus79 Jan 1, 2026
1b6d9a6
Add fil_veltrack and fix some stuff
regulus79 Jan 1, 2026
062c547
Add all the ampeg vel2 and oncc opcodes, and clean up stuff
regulus79 Jan 1, 2026
753694d
Fix key opcode
regulus79 Jan 1, 2026
3083d5e
Fix parsing issue with spaces, and fix error with >128 midi CC numbers
regulus79 Jan 1, 2026
2904607
Add Round Robin Support
regulus79 Jan 1, 2026
2f393ad
Merge branch 'master' into sfzsampler
regulus79 Jan 7, 2026
6571ff0
Fix SampleLoaded includes
regulus79 Jan 8, 2026
15c261e
Add amplitude and amplitue_onccN opcodes
regulus79 Jan 10, 2026
b838ddd
Save the filepath to the sfz file
regulus79 Jan 11, 2026
f9592c0
Fix includes with spaces in filename
regulus79 Jan 11, 2026
7b6c660
Add keyswitch support
regulus79 Jan 11, 2026
1ba2ec6
Remove unused SfzOpcodes.h
regulus79 Jan 11, 2026
eec128f
Add locc and hicc
regulus79 Jan 11, 2026
46542f6
Make noteOn/noteOff events use frame offset
regulus79 Jan 12, 2026
ca1ca5a
Add delay and delay_random opcodes
regulus79 Jan 12, 2026
56ec920
Initial GUI
regulus79 Jan 14, 2026
6e97ff7
Initial piano view
regulus79 Jan 14, 2026
0a4e912
More gui testing
regulus79 Jan 14, 2026
43d79ae
Remove GUI. Maybe the initial version doesn't need a fancy GUI
regulus79 Jan 16, 2026
635569a
Initial GUI, and some provisions for dedicated handling of <controls>…
regulus79 Jan 16, 2026
5ea1dd7
Add label_ccN opcode
regulus79 Jan 16, 2026
d87e7f0
Show only used midi CC's on gui
regulus79 Jan 16, 2026
c992a06
Merge branch 'master' into sfzsampler
regulus79 Jan 17, 2026
0be5090
List switch keys on GUI
regulus79 Jan 17, 2026
18af475
Improve debug
regulus79 Jan 17, 2026
36bd00e
Initial sample pool to prevent duplicate sample loading
regulus79 Jan 18, 2026
16bdfca
Switch key improvements
regulus79 Jan 18, 2026
ec9bb7b
Fix sw_last determination and remove probably incorrect <global> parsing
regulus79 Jan 19, 2026
c0bcc0a
Add partial support for trigger opcode
regulus79 Jan 20, 2026
7988833
Add gain_oncc/gain_cc opcode
regulus79 Jan 20, 2026
7ea0a54
Add volume_oncc opcode
regulus79 Jan 20, 2026
b12ee04
Use a single buffer for voices, instead of one buffer per region
regulus79 Jan 20, 2026
70cbc1f
Optimize checking loccN/hiccN
regulus79 Jan 20, 2026
e0478e3
Add SfzRegionManager to speed up trigger processing by using key as i…
regulus79 Jan 21, 2026
e997053
Remove unneeded include
regulus79 Jan 22, 2026
86fb56c
Fix bug with default_path sometimes not parsing if <global> came afte…
regulus79 Jan 23, 2026
e040a1a
Use the instrument track's midi CC's, not our own
regulus79 Jan 24, 2026
bd8bf1c
Add getters for instrument track midi cc models
regulus79 Jan 25, 2026
a8be0e1
Add copyright info
regulus79 Jan 25, 2026
ea9f20d
Fix warnings
regulus79 Jan 25, 2026
245098e
Allow drag/drop from side panel file browser
regulus79 Jan 25, 2026
d386bc4
Attempt to fix warning
regulus79 Jan 25, 2026
4ececef
Don't allow drag/drop onto instrument
regulus79 Jan 25, 2026
18328bd
Attempt to fix make_shared error
regulus79 Jan 25, 2026
0e58447
Fix drag/drop resetting CC knobs to 0
regulus79 Jan 25, 2026
e6e6d4c
Add more comments
regulus79 Jan 27, 2026
f38572d
Add <master> header
regulus79 Jan 27, 2026
f322008
Make default_path propagate correctly
regulus79 Jan 27, 2026
65f8092
Fix edge cases for opcode state propagation
regulus79 Jan 27, 2026
7bd88d1
Make #defines persist across recursion branches
regulus79 Jan 27, 2026
6b67928
Add debug statements for region lookup tables
regulus79 Jan 27, 2026
2fed7af
Add lorand/hirand opcodes
regulus79 Jan 27, 2026
7b443fb
Merge branch 'master' into sfzsampler
regulus79 Jan 27, 2026
201b435
Add pan_oncc/pan_cc opcodes
regulus79 Feb 1, 2026
3d802bf
Add dummy support for <effect> header
regulus79 Feb 1, 2026
73286e6
Merge branch 'master' into sfzsampler
regulus79 Feb 15, 2026
159c60b
Merge branch 'master' into sfzsampler
regulus79 Mar 9, 2026
715c40f
Temporary commit, refactoring opcode system
regulus79 Apr 30, 2026
b1fb26c
Moving things around, and changing all opcodes into new template format
regulus79 May 1, 2026
218c826
Make modulatedValue override value
regulus79 May 1, 2026
1b5e56e
Make delay modulatable
regulus79 May 1, 2026
1dbefbf
Fix order of assignment
regulus79 May 1, 2026
0fea1cc
Add basic waves and pitcheg
regulus79 May 2, 2026
c1bc589
Add LFOs and pitch envelope/lfo
regulus79 May 3, 2026
9a602e3
Fix LFO fade
regulus79 May 3, 2026
4706ffc
Add comment to fix scripted-checks
regulus79 May 3, 2026
65401e8
Make loading new sfz file not crash when notes are playing
regulus79 May 3, 2026
e691591
Re-enable drag-drop sfz files into instrument window
regulus79 May 3, 2026
cb00037
Sample Loading Thread Partial Fix
regulus79 May 6, 2026
35c2ca4
Hopefully realtime safe now
regulus79 May 6, 2026
9565af5
Add more info to gui
regulus79 May 7, 2026
091ca05
Rework GUI status text
regulus79 May 7, 2026
b669cb4
use std::thread instead of std::jthread to fix builds
regulus79 May 7, 2026
9c68382
Move sample loader thread function into real function instead of lambda
regulus79 May 7, 2026
01be0e3
Merge branch 'master' into sfzsampler
regulus79 May 7, 2026
3053eb3
Fix issues from merge
regulus79 May 7, 2026
734d265
Go through and fix comments, minor issues, etc
regulus79 May 7, 2026
712194a
Use f_cnt_t instead of size_t to fix macos builds
regulus79 May 8, 2026
e4b7d66
Set name of instrument when drag/drop file into song editor
regulus79 May 8, 2026
dc86d26
Rename SfzSampler to SFZ Player
regulus79 May 8, 2026
78ead8f
Accidentally removed Sid
regulus79 May 8, 2026
c1570b2
Add basic modulation curves and mod types, and other minor changes
regulus79 May 9, 2026
5e61811
Fix issue with samples starting partway through
regulus79 May 9, 2026
44f4600
Fix voices staying active way too long when sustain is active
regulus79 May 9, 2026
98dfae4
Store sample objects (mostly) as raw pointers for speed, and add extr…
regulus79 May 10, 2026
190f417
Remember to delete region/sample pools
regulus79 May 10, 2026
e72ae0c
Fix key parsing
regulus79 May 12, 2026
41d2a16
Rework keyswitches and other loops for performance
regulus79 May 12, 2026
4691980
Fix knobs not loading
regulus79 May 12, 2026
6d13cc1
Merge branch 'master' into sfzsampler
regulus79 May 13, 2026
ecbea4b
Overload operators for Opcodes to make them easier to use
regulus79 May 15, 2026
3c80296
Handle failed loading samples without popping up hudnreds of message …
regulus79 May 15, 2026
cbd5e3e
Make SampleDecoder available to plugins to fix windows builds
regulus79 May 15, 2026
2129bfe
Revert sample loading message box fix
regulus79 May 15, 2026
cffb7ef
Attempt new fix
regulus79 May 15, 2026
8bae2c3
Attempt to fix bad commit
regulus79 May 15, 2026
401fd5f
Merge branch 'master' into sfzsampler
regulus79 May 16, 2026
97ab20c
Fix style and remove old profiling code
regulus79 May 16, 2026
3d92c5a
Fix fil_veltrack calculation
regulus79 May 16, 2026
6bddf78
Update comment
regulus79 May 16, 2026
72d65ae
Merge branch 'master' into sfzsampler
regulus79 May 23, 2026
5e1f564
Add pitchbending, microtuning, and note panning
regulus79 May 27, 2026
5d9f5d4
Use double instead of float to store sample frame index
regulus79 May 29, 2026
2008e70
Share sample pool between instances
regulus79 May 31, 2026
e9aca61
Load samples as notes are played
regulus79 Jun 4, 2026
be35246
Handle missing samples better
regulus79 Jun 4, 2026
3af7dec
Fix some builds not supporting std::atomic<std::shared_ptr>
regulus79 Jun 4, 2026
dc44038
Fix issue with path formatting when checking if file exists
regulus79 Jun 5, 2026
6bd05ab
Use ThreadPool instead of std::thread
regulus79 Jun 5, 2026
02b4f81
Fix bugs when playing notes while loading samples
regulus79 Jun 5, 2026
a69ace0
Fix build error
regulus79 Jun 5, 2026
a687917
Make ThreadPool LMMS_EXPORT
regulus79 Jun 5, 2026
ee5e3ea
Merge branch 'master' into sfzsampler
regulus79 Jul 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/modules/PluginList.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ SET(LMMS_PLUGIN_LIST
Sf2Player
Sfxr
Sid
SfzPlayer
SlewDistortion
SlicerT
SpectrumAnalyzer
Expand Down
1 change: 1 addition & 0 deletions include/FileBrowser.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ class FileItem : public FileBrowserWidgetItem
Preset,
Sample,
SoundFont,
SFZ,
Patch,
Midi,
VstPlugin,
Expand Down
3 changes: 3 additions & 0 deletions include/InstrumentTrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ class LMMS_EXPORT InstrumentTrack : public Track, public MidiEventProcessor

void autoAssignMidiDevice( bool );

//! Returns a non-owning pointer to the LED in the MIDI CC rack which toggles whether the knobs send midi control change events
BoolModel* midiCCEnableModel() const { return m_midiCCEnable.get(); }

//! Returns a non-owning pointer to the model for the knob at the given index in the track's MIDI CC rack
FloatModel* midiCCModel(int index) const { return m_midiCCModel[index].get(); }

Expand Down
4 changes: 3 additions & 1 deletion include/ThreadPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#ifndef LMMS_THREAD_POOL_H
#define LMMS_THREAD_POOL_H

#include "lmms_export.h"

#include <atomic>
#include <queue>
#include <tuple>
Expand All @@ -38,7 +40,7 @@

namespace lmms {
//! A thread pool that can be used for asynchronous processing.
class ThreadPool
class LMMS_EXPORT ThreadPool
{
public:
//! Destroys the `ThreadPool` object.
Expand Down
47 changes: 47 additions & 0 deletions plugins/SfzPlayer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
include(BuildPlugin)

build_plugin(sfzplayer
SfzPlayer.cpp
SfzPlayer.h
SfzPlayerView.cpp
SfzPlayerView.h
SfzOpcodes.cpp
SfzOpcodes.h
SfzOpcodeState.cpp
SfzOpcodeState.h
SfzRegion.cpp
SfzRegion.h
SfzParser.cpp
SfzParser.h
SfzRegionPlayState.cpp
SfzRegionPlayState.h
SfzRegionManager.cpp
SfzRegionManager.h
SfzGlobalState.cpp
SfzGlobalState.h
SfzControlsConfig.h
SfzTrigger.cpp
SfzTrigger.h
SfzSampleBuffer.cpp
SfzSampleBuffer.h
SfzSamplePool.cpp
SfzSamplePool.h
SfzBasicWaves.cpp
SfzBasicWaves.h
MOCFILES
SfzPlayer.h
SfzPlayerView.h
SfzOpcodes.h
SfzOpcodeState.h
SfzRegion.h
SfzParser.h
SfzRegionPlayState.h
SfzRegionManager.h
SfzGlobalState.h
SfzControlsConfig.h
SfzTrigger.h
SfzSampleBuffer.h
SfzSamplePool.h
SfzBasicWaves.h
EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.svg"
)
87 changes: 87 additions & 0 deletions plugins/SfzPlayer/SfzBasicWaves.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* SfzBasicWaves.cpp - Generators of basic wave shapes
*
* Copyright (c) 2026 Keratin
*
* 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.
*
*/

#include "SfzBasicWaves.h"
#include "lmms_math.h"
#include <numbers>

namespace lmms
{

const float SfzBasicWaves::generate(Shape shape, float sampleRate, int frame)
{
// By default, the basic waves are played at C4 (midi key 60). This isn't in the spec afaik, but it makes things simple since pitch_keycenter defaults to 60.
constexpr float baseFreq = 261.625565301f;
// Amount through period
const float t = absFraction(frame * baseFreq / sampleRate);
// The region playback state handles incrementing the frame count at different rates based on the pitch, so we don't need to handle the actual frequency calculation here.

switch (shape)
{
case Shape::Sine:
return sine(t);
case Shape::Saw:
return saw(t);
case Shape::Square:
return square(t);
case Shape::Triangle:
return triangle(t);
case Shape::Noise:
return noise(t);
case Shape::Silence:
return 0.0f;
}
return 0.0f;
}


const float SfzBasicWaves::sine(float t)
{
return sin(t * 2 * std::numbers::pi);
}

const float SfzBasicWaves::saw(float t)
{
return 2.0f * t - 1.0f;
}

const float SfzBasicWaves::square(float t)
{
return t > 0.5 ? 1.0f : -1.0f;
}

const float SfzBasicWaves::triangle(float t)
{
return t < 0.5f
? 4.0f * t - 1.0f
: -(4.0f * (t - 0.5f) - 1.0f);
}

const float SfzBasicWaves::noise(float t)
{
return fastRand(-1.0f, 1.0f);
}


} // namespace lmms
56 changes: 56 additions & 0 deletions plugins/SfzPlayer/SfzBasicWaves.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* SfzBasicWaves.h - Generators for audio wave shapes such as sine, saw, triangle, noise, etc
*
* Copyright (c) 2026 Keratin
*
* 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_SFZ_BASIC_WAVES_H
#define LMMS_SFZ_BASIC_WAVES_H

namespace lmms
{

class SfzBasicWaves
{
public:
enum class Shape
{
Sine,
Saw,
Square,
Triangle,
Noise,
Silence
};
//! Returns the calculated value of the waveform shape at the given number of frames from the start, given the sample rate.
static const float generate(Shape shape, float sampleRate, int frame);

private:
static const float sine(float t);
static const float saw(float t);
static const float square(float t);
static const float triangle(float t);
static const float noise(float t);
};

} // namespace lmms

#endif // LMMS_SFZ_BASIC_WAVES_H
55 changes: 55 additions & 0 deletions plugins/SfzPlayer/SfzControlsConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* SfzControlsConfig.h - Helper class for storing info about which keyswitches exist, and which midi CC's are used by the sfz
*
* Copyright (c) 2026 Keratin
*
* 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_SFZ_CONTROLS_CONFIG_H
#define LMMS_SFZ_CONTROLS_CONFIG_H

#include "SfzOpcodeState.h"

namespace lmms
{

class SfzControlsConfig : public SfzOpcodeState
{
public:
//! Keeps track of which CC's are actually used by the instrument, so that the GUI only needs to display those, not all 128
std::array<bool, NumMidiCCs> m_activeMidiCCs = {};

//! Stores information about each switch key, to make it easy to display on the GUI
struct SwitchKeyInfo
{
QString sw_label;
std::optional<int> sw_default;
int sw_lokey;
int sw_hikey;
};
std::map<int, SwitchKeyInfo> m_switchKeyInfo;
};


} // namespace lmms


#endif // LMMS_SFZ_CONTROLS_CONFIG_H
Loading
Loading