Skip to content

Commit

Permalink
Merge branch 'make-a-demo-tune-and-fix-bugs'
Browse files Browse the repository at this point in the history
  • Loading branch information
sjoerdvankreel committed Oct 22, 2024
2 parents 6f5b64b + 67920ad commit d94ac9a
Show file tree
Hide file tree
Showing 36 changed files with 7,965 additions and 163 deletions.
7 changes: 7 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
### October 23, 2024 - V1.9.6.

- Fixed a couple of outdated parameter descriptions.
- Show parameter descriptions (from reference document) in tooltips.
- Bugfix: CV-to-envelope modulation did not take the voice start sample position within the block into account.
- Optionally allow global LFO's to sync to DAW project time (does NOT work with rate modulation, i.e. causes full phase reset).

### October 9, 2024 - V1.9.5.

- Added arpeggiator (see manual).
Expand Down
File renamed without changes.
Binary file added demos/demo/demo_track_psytrance.xrns
Binary file not shown.
Empty file.
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
4,196 changes: 4,196 additions & 0 deletions demos/host_test/glfo_snap_test_reaper_clap.rpp

Large diffs are not rendered by default.

3,487 changes: 3,487 additions & 0 deletions demos/host_test/glfo_snap_test_reaper_vst3.rpp

Large diffs are not rendered by default.

Binary file not shown.
4 changes: 2 additions & 2 deletions macos/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.9.5</string>
<string>1.9.6</string>
<key>CFBundleVersion</key>
<string>1.9.5</string>
<string>1.9.6</string>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>NSHighResolutionCapable</key>
Expand Down
45 changes: 31 additions & 14 deletions param_reference.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<html>
<head>
<title>Firefly Synth 1.9.5</title>
<title>Firefly Synth 1.9.6</title>
<style>th, td { padding: 3px; }a, a:visited { color: #666666; }.description { background:#EEEEEE; }h1 { font-size: 19px; color: black; }h2 { font-size: 17px; color: black; }h3 { font-size: 15px; color: black; }body { font-family: Verdana; color: black; }html { position: relative; max-width: 1024px; margin: auto; }tr td { width: auto; white-space: nowrap; } tr th { width: auto; white-space: nowrap; }table, th, td { font-size: 13px; border: 1px solid gray; border-collapse: collapse; text-align: left; }tr td:last-child { width: 100%; white-space: wrap; } tr th:last-child { width: 100%; white-space: wrap; }</style>
</head>
<body>
<h1>Firefly Synth 1.9.5</h1>
<h1>Firefly Synth 1.9.6</h1>
<h2>Module Overview</h2>
<table>
<tr>
Expand Down Expand Up @@ -61,7 +61,7 @@ <h2>Module Overview</h2>
<td>Yes</td>
<td>Before voice</td>
<td>10</td>
<td class='description'>Optional tempo-synced LFO with repeating and one-shot types, various periodic waveforms, smooth noise, static noise and free-running static noise, smoothing control, phase andjustment, stair-stepping and horizontal and vertical skewing controls with various types.</td>
<td class='description'>Optional tempo-synced LFO with repeating and one-shot types, various periodic waveforms, smooth noise, static noise, smoothing control, phase andjustment, stair-stepping and horizontal and vertical skewing controls with various types.</td>
</tr>
<tr>
<td><a href='#7'>7</a></td>
Expand Down Expand Up @@ -117,7 +117,7 @@ <h2>Module Overview</h2>
<td>Yes</td>
<td>Voice</td>
<td>10</td>
<td class='description'>Optional tempo-synced LFO with repeating and one-shot types, various periodic waveforms, smooth noise, static noise and free-running static noise, smoothing control, phase andjustment, stair-stepping and horizontal and vertical skewing controls with various types.</td>
<td class='description'>Optional tempo-synced LFO with repeating and one-shot types, various periodic waveforms, smooth noise, static noise, smoothing control, phase andjustment, stair-stepping and horizontal and vertical skewing controls with various types.</td>
</tr>
<tr>
<td><a href='#14'>14</a></td>
Expand Down Expand Up @@ -592,7 +592,7 @@ <h3>Global LFO</h3>
<td>N/A</td>
</tr>
<tr>
<td colspan='11' class='description'>Selects time or tempo-synced and repeating or one-shot type. For regular one-shot type, the LFO stays at it's end value after exactly 1 cycle. For phase one-shot type, the end value takes the phase offset parameter into account.</td>
<td colspan='11' class='description'>Selects repeating or one-shot type. For regular one-shot type, the LFO stays at it's end value after exactly 1 cycle. For phase one-shot type, the end value takes the phase offset parameter into account.</td>
</tr>
<tr>
<td rowspan='2'>Rate</td>
Expand Down Expand Up @@ -728,7 +728,7 @@ <h3>Global LFO</h3>
<td>N/A</td>
</tr>
<tr>
<td colspan='11' class='description'>Selects waveform plus horizontal and vertical skewing modes. Waveforms are various periodic functions plus smooth noise, static noise and free-running static noise. Skewing modes are off (cpu efficient, so use it if you dont need the extra control), linear, scale unipolar/bipolar and exponential unipolar/bipolar.</td>
<td colspan='11' class='description'>Selects waveform: various periodic functions plus smooth and static noise.</td>
</tr>
<tr>
<td rowspan='2'>Steps</td>
Expand Down Expand Up @@ -798,6 +798,23 @@ <h3>Global LFO</h3>
<tr>
<td colspan='11' class='description'>Applies a lowpass filter to smooth out rough edges.</td>
</tr>
<tr>
<td rowspan='2'>Snap To Project</td>
<td>Phase</td>
<td>Yes</td>
<td>Patch</td>
<td>1</td>
<td>Input</td>
<td>Block</td>
<td>Automate</td>
<td>Off</td>
<td>On</td>
<td>Off</td>
<td>N/A</td>
</tr>
<tr>
<td colspan='11' class='description'>In global module, snaps lfo phase to project/song time. Note this defeats rate modulation!</td>
</tr>
</table>
<a name='7'/>
<h3>GCV-A</h3>
Expand Down Expand Up @@ -1412,7 +1429,7 @@ <h3>Env</h3>
<td>N/A</td>
</tr>
<tr>
<td colspan='11' class='description'>Selects envelope slode mode.<br/>Linear - linear slope, most cpu efficient.<br/>Exponential unipolar - regular exponential slope.<br/>Exponential bipolar - vertically splits section in 2 exponential parts.<br/>Exponential split - horizontally and vertically splits section in 2 exponential parts to generate smooth curves.</td>
<td colspan='11' class='description'>Selects envelope slope mode.<br/>Linear - linear slope, most cpu efficient.<br/>Exponential unipolar - regular exponential slope.<br/>Exponential bipolar - vertically splits section in 2 exponential parts.<br/>Exponential split - horizontally and vertically splits section in 2 exponential parts to generate smooth curves.</td>
</tr>
<tr>
<td rowspan='2'>Tempo Sync</td>
Expand Down Expand Up @@ -1736,7 +1753,7 @@ <h3>Voice LFO</h3>
<td>N/A</td>
</tr>
<tr>
<td colspan='11' class='description'>Selects time or tempo-synced and repeating or one-shot type. For regular one-shot type, the LFO stays at it's end value after exactly 1 cycle. For phase one-shot type, the end value takes the phase offset parameter into account.</td>
<td colspan='11' class='description'>Selects repeating or one-shot type. For regular one-shot type, the LFO stays at it's end value after exactly 1 cycle. For phase one-shot type, the end value takes the phase offset parameter into account.</td>
</tr>
<tr>
<td rowspan='2'>Rate</td>
Expand Down Expand Up @@ -1872,7 +1889,7 @@ <h3>Voice LFO</h3>
<td>N/A</td>
</tr>
<tr>
<td colspan='11' class='description'>Selects waveform plus horizontal and vertical skewing modes. Waveforms are various periodic functions plus smooth noise, static noise and free-running static noise. Skewing modes are off (cpu efficient, so use it if you dont need the extra control), linear, scale unipolar/bipolar and exponential unipolar/bipolar.</td>
<td colspan='11' class='description'>Selects waveform: various periodic functions plus smooth and static noise.</td>
</tr>
<tr>
<td rowspan='2'>Steps</td>
Expand Down Expand Up @@ -1943,7 +1960,7 @@ <h3>Voice LFO</h3>
<td colspan='11' class='description'>Applies a lowpass filter to smooth out rough edges.</td>
</tr>
<tr>
<td rowspan='2'>Phs</td>
<td rowspan='2'>Phase Offset</td>
<td>Phase</td>
<td>Yes</td>
<td>Patch</td>
Expand Down Expand Up @@ -2146,7 +2163,7 @@ <h3>Voice</h3>
<td>N/A</td>
</tr>
<tr>
<td colspan='11' class='description'>Oversampling for those rare cases where it makes a positive difference. Only affects FM and hardsync, but not AM. Oversampling is per unison voice, so setting both this and unison to 8 results in an oscillator being 64 times as expensive to calculate.</td>
<td colspan='11' class='description'>Oversampling for those rare cases where it makes a positive difference. Only affects FM and hardsync, but not AM. Oversampling is per osc unison voice, so setting both this and osc unison to 4 results in an oscillator being 16 times as expensive to calculate. Then multiply that by global unison.</td>
</tr>
<tr>
<td rowspan='2'>Porta Tempo Sync</td>
Expand Down Expand Up @@ -2880,7 +2897,7 @@ <h3>Osc</h3>
<td>N/A</td>
</tr>
<tr>
<td colspan='11' class='description'>Detune unison voices. Only applicable to Basic and DSF generators.</td>
<td colspan='11' class='description'>Detune unison voices. Only applicable to Basic, KPS and DSF generators.</td>
</tr>
<tr>
<td rowspan='2'>Unison Phase</td>
Expand Down Expand Up @@ -3629,7 +3646,7 @@ <h3>Voice FX</h3>
<td>1.00</td>
</tr>
<tr>
<td colspan='11' class='description'>Gain amount to drive the shaper and X/Y parameters. Use an Osc with gain envelope to have the effect of the distortion gradually fall-off.</td>
<td colspan='11' class='description'>Gain amount to drive the shaper and X/Y parameters. For per-voice, use an Osc with gain envelope to have the effect of the distortion gradually fall-off.</td>
</tr>
<tr>
<td rowspan='2'>Dist Mix</td>
Expand Down Expand Up @@ -4380,7 +4397,7 @@ <h3>Global FX</h3>
<td>1.00</td>
</tr>
<tr>
<td colspan='11' class='description'>Gain amount to drive the shaper and X/Y parameters. Use an Osc with gain envelope to have the effect of the distortion gradually fall-off.</td>
<td colspan='11' class='description'>Gain amount to drive the shaper and X/Y parameters. For per-voice, use an Osc with gain envelope to have the effect of the distortion gradually fall-off.</td>
</tr>
<tr>
<td rowspan='2'>Dist Mix</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -656,9 +656,16 @@ pb_plugin::process(clap_process const* process) noexcept
block.mts_client = _mts_client;
block.frame_count = process->frames_count;
block.audio_out = process->audio_outputs[0].data32;
block.shared.bpm = process->transport? process->transport->tempo: 0;
block.shared.audio_in = process->audio_inputs? process->audio_inputs[0].data32: nullptr;

block.shared.bpm = 0;
block.shared.project_time = 0;
if (process->transport != nullptr)
{
block.shared.bpm = process->transport->tempo;
block.shared.project_time = (std::int64_t)std::round((double)process->transport->song_pos_seconds / (double)CLAP_SECTIME_FACTOR * _splice_engine.get_sample_rate());
}

process_gui_to_audio_events(process->out_events);

// make sure we only push per-block events at most 1 time
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pb_component::process(ProcessData& data)
block.mts_client = _mts_client;
block.frame_count = data.numSamples;
block.shared.bpm = data.processContext ? data.processContext->tempo : 0;
block.shared.project_time = data.processContext ? data.processContext->projectTimeSamples: 0;

if(data.outputs && data.outputs[0].channelBuffers32)
block.audio_out = data.outputs[0].channelBuffers32;
Expand Down
31 changes: 31 additions & 0 deletions plugin_base/src/plugin_base/plugin_base/desc/param.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@

namespace plugin_base {

// https://stackoverflow.com/questions/3418231/replace-part-of-a-string-with-another-string
static bool
string_replace(std::string& str, std::string const& from, std::string const& to) {
std::size_t start_pos = str.find(from);
if(start_pos == std::string::npos) return false;
str.replace(start_pos, from.length(), to);
return true;
}

static void
string_replace_all(std::string &str, std::string const& from, std::string const& to)
{
while(string_replace(str, from, to));
}

param_desc::
param_desc(
module_topo const& module_, int module_slot,
Expand All @@ -30,4 +45,20 @@ param_desc::validate(module_desc const& module, int index) const
info.validate(module.params.size(), param->info.slot_count);
}

std::string
param_desc::tooltip(plain_value plain) const
{
std::string value_text;
if (param->domain.type == domain_type::item)
value_text = param->domain.plain_to_item_tooltip(plain);
else
value_text = param->domain.plain_to_text(false, plain);
std::string result = info.name + std::string(": ") + value_text;
if (param->info.description.size())
result += std::string("\n\n") + param->info.description;
// descriptions are in html format
string_replace_all(result, "<br/>", "\n");
return result;
}

}
3 changes: 3 additions & 0 deletions plugin_base/src/plugin_base/plugin_base/desc/param.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ struct param_desc final {
param_topo const* param = {};

PB_PREVENT_ACCIDENTAL_COPY_DEFAULT_CTOR(param_desc);

std::string tooltip(plain_value plain) const;
void validate(module_desc const& module, int index) const;

param_desc(
module_topo const& module_, int module_slot,
param_topo const& param_, int topo, int slot, int local_, int global);
Expand Down
1 change: 1 addition & 0 deletions plugin_base/src/plugin_base/plugin_base/dsp/block/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ host_block::prepare()

frame_count = 0;
shared.bpm = 0;
shared.project_time = 0;
shared.audio_in = nullptr;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct note_id final {

// shared host/plug
struct shared_block final {
std::int64_t project_time; // in frames
float bpm;
float const* const* audio_in;
};
Expand Down
1 change: 1 addition & 0 deletions plugin_base/src/plugin_base/plugin_base/dsp/engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class plugin_engine final {
void activate(int max_frame_count);
void init_from_state(plugin_state const* state);

int get_sample_rate() const { return _sample_rate; }
void set_sample_rate(int sample_rate) { _sample_rate = sample_rate; }
void mark_param_as_automated(int m, int mi, int p, int pi) { _param_was_automated[m][mi][p][pi] = 1; }
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ plugin_splice_engine::process()
inner_block.frame_count = this_block_frames;
inner_block.mts_client = _host_block.mts_client;
inner_block.shared.bpm = _host_block.shared.bpm;
inner_block.shared.project_time = _host_block.shared.project_time + this_block_start;

float* this_audio_out[2];
this_audio_out[0] = _host_block.audio_out[0] + this_block_start;
Expand Down
2 changes: 2 additions & 0 deletions plugin_base/src/plugin_base/plugin_base/dsp/splice_engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class plugin_splice_engine final {
void release_block() {}
void activate_modules() { _engine.activate_modules(); }
void automation_state_dirty() { _engine.automation_state_dirty(); }

int get_sample_rate() const { return _engine.get_sample_rate(); }
void set_sample_rate(int sample_rate) { _engine.set_sample_rate(sample_rate); }
void process_voice(int v, bool threaded) { _engine.process_voice(v, threaded); }
void mark_param_as_automated(int m, int mi, int p, int pi) { _engine.mark_param_as_automated(m, mi, p, pi); }
Expand Down
25 changes: 16 additions & 9 deletions plugin_base/src/plugin_base/plugin_base/gui/controls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ param_value_label::own_param_changed(plain_value plain)
{
std::string text = _gui->automation_state()->plain_to_text_at_index(false, _param->info.global, plain);
setText(text, dontSendNotification);
setTooltip(_param->info.name + ": " + text);
setTooltip(_param->tooltip(_gui->automation_state()->get_plain_at_index(_param->info.global)));
}

MouseCursor
Expand Down Expand Up @@ -504,7 +504,7 @@ param_toggle_button::own_param_changed(plain_value plain)
{
_checked = plain.step() != 0;
setToggleState(plain.step() != 0, dontSendNotification);
setTooltip(_param->info.name + ": " + _param->param->domain.plain_to_text(false, plain));
setTooltip(_param->tooltip(plain));
}

void
Expand All @@ -521,7 +521,7 @@ param_toggle_button(plugin_gui* gui, module_desc const* module, param_desc const
param_component(gui, module, param), autofit_togglebutton(lnf, param->param->gui.tabular)
{
auto value = param->param->domain.default_plain(module->info.slot, param->info.slot);
setTooltip(_param->info.name + ": " + _param->param->domain.plain_to_text(false, value));
setTooltip(_param->tooltip(value));
_checked = value.step() != 0;
addListener(this);
init();
Expand All @@ -539,7 +539,8 @@ param_slider::
param_slider(plugin_gui* gui, module_desc const* module, param_desc const* param) :
param_component(gui, module, param), Slider()
{
setPopupDisplayEnabled(true, true, nullptr);
setPopupDisplayEnabled(true, true, nullptr);

switch (param->param->gui.edit_type)
{
case gui_edit_type::knob: setSliderStyle(Slider::RotaryVerticalDrag); break;
Expand All @@ -553,6 +554,9 @@ param_component(gui, module, param), Slider()
if (param->param->dsp.can_modulate(param->info.slot))
gui->add_modulation_output_listener(this);

auto value = param->param->domain.default_plain(module->info.slot, param->info.slot);
setTooltip(_param->tooltip(value));

setTextBoxStyle(Slider::NoTextBox, true, 0, 0);
if(param->param->domain.unit.size())
setTextValueSuffix(" " + param->param->domain.unit);
Expand Down Expand Up @@ -590,6 +594,13 @@ param_slider::modulation_outputs_reset()
repaint();
}

void
param_slider::own_param_changed(plain_value plain)
{
setTooltip(_param->tooltip(plain));
setValue(_param->param->domain.plain_to_raw(plain), juce::dontSendNotification);
}

void
param_slider::modulation_outputs_changed(std::vector<modulation_output> const& outputs)
{
Expand Down Expand Up @@ -678,11 +689,7 @@ param_combobox::own_param_changed(plain_value plain)
{
std::string value;
setSelectedId(plain.step() + 1 - _param->param->domain.min, dontSendNotification);
if(_param->param->domain.type == domain_type::item)
value = _param->param->domain.plain_to_item_tooltip(plain);
else
value = _param->param->domain.plain_to_text(false, plain);
setTooltip(_param->info.name + ": " + value);
setTooltip(_param->tooltip(plain));
}

void
Expand Down
5 changes: 2 additions & 3 deletions plugin_base/src/plugin_base/plugin_base/gui/controls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,7 @@ public modulation_output_listener
std::vector<modulation_output> _this_mod_outputs = {};

protected:
void own_param_changed(plain_value plain) override final
{ setValue(_param->param->domain.plain_to_raw(plain), juce::dontSendNotification); }
void own_param_changed(plain_value plain) override final;

public:
~param_slider();
Expand All @@ -260,7 +259,7 @@ public modulation_output_listener
void valueChanged() override;
void stoppedDragging() override { _gui->param_end_changes(_param->info.global); }
void startedDragging() override { _gui->param_begin_changes(_param->info.global); }

juce::String getTextFromValue(double value) override
{ return juce::String(_param->info.name + ": ") + juce::Slider::getTextFromValue(value * (_param->param->domain.display == domain_display::percentage ? 100 : 1)); }
};
Expand Down
8 changes: 4 additions & 4 deletions scripts/build_linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ make
cd ../../../dist/"$1"/linux
./plugin_base.ref_gen firefly_synth_1.vst3/Contents/x86_64-linux/firefly_synth_1.so ../../../param_reference.html

zip -r firefly_synth_1.9.5_linux_vst3_fx.zip firefly_synth_fx_1.vst3
zip -r firefly_synth_1.9.5_linux_vst3_instrument.zip firefly_synth_1.vst3
zip -r firefly_synth_1.9.5_linux_clap_fx.zip firefly_synth_fx_1.clap
zip -r firefly_synth_1.9.5_linux_clap_instrument.zip firefly_synth_1.clap
zip -r firefly_synth_1.9.6_linux_vst3_fx.zip firefly_synth_fx_1.vst3
zip -r firefly_synth_1.9.6_linux_vst3_instrument.zip firefly_synth_1.vst3
zip -r firefly_synth_1.9.6_linux_clap_fx.zip firefly_synth_fx_1.clap
zip -r firefly_synth_1.9.6_linux_clap_instrument.zip firefly_synth_1.clap

cd ../../../scripts
Loading

0 comments on commit d94ac9a

Please sign in to comment.