Skip to content

Commit

Permalink
devsync 6b0d1dc - moving knobs etc
Browse files Browse the repository at this point in the history
  • Loading branch information
eh2k committed Jan 21, 2024
1 parent 0ecb86e commit 690cfd3
Show file tree
Hide file tree
Showing 24 changed files with 2,759 additions and 2,515 deletions.
26 changes: 19 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@
<summary><b>ChangeLog</b></summary>

````
== 2024-01-20
* DevSync:
* Bugfix T4X: CV input > 6 V is received as negative voltage bug
* Bugfix: ClassicVAVCF -> param change Decay/Level
* Enhancement: Modualtion attenuverter resolution 1/2000
* Enhancement/Bugfix: Modulation ranges..
* Enhancement: NEw Modulation CV src aka "+" constant voltage
* Enhancement: Visualizing parameter modulations (moving knobs)
* Enhancement: squares-and-circles app
* Enhancement DSM: Support MID Button (ui navigaten - mid botton back function)
== 2024-01-14
* DevSync: Fix DSM0 audio clipping
== 2023-12-21
Expand Down Expand Up @@ -99,7 +109,6 @@ E.g you can chain the mono audio signal from an oscillator machine to the neighb
* [Short Press [LEFT]/[RIGHT]] scrolls through the 4 machine-tracks.
* [Long press [LEFT]] enters the machine-selection-page.
* [Long press [RIGHT]] enters the I/O-configuration-page.
* [Long press [LEFT] + [RIGHT]] enters the MIDI-settings-page.
* [Long press left or right [ENCODER]] shows the modulation popup
* [Long press [L-ENCODER] + [R-ENCODER]] saves the patch - will be restored at startup
- DEBUG: skip restore - press [RIGHT] button while startup ).
Expand Down Expand Up @@ -178,11 +187,14 @@ Machines/Engines are controlled by individual parameters.

For each parameter a modulation can be assigned:
* **CV**:
* SRC: `C1`, `C2`, `C3`, `C4`
* OP: `THRU`, `S&H-T1`, `S&H-T2`, `S&H-T3`, `S&H-T4`, `T&H-T1`, `T&H-T2`, `T&H-T3`, `T&H-T4`
* THRU - Thru Input
* S&H - Sample and Hold
* T&H - Track and Hold
* SRC:
* `C1`, `C2`, `C3`, `C4` - Analog inputs
* OP: `THRU`, `S&H-T1`, `S&H-T2`, `S&H-T3`, `S&H-T4`, `T&H-T1`, `T&H-T2`, `T&H-T3`, `T&H-T4`
* THRU - Thru Input
* S&H - Sample and Hold
* T&H - Track and Hold
* `+` - Constant internal voltage
* 10V with 1/1000 resolution - nice for fine adjustments (detuning etc)
* Hints:
* Parameter 0 (top-left) is mainly used for V/OCT control. Thus, one single V/OCT signal / CV-Input can be shared by using modulation on parameter-0 with attenuverter = +1 (-3V..+6V) range. It is also possible to select the V/OCT input in the io-configuration page.
* All other parameters can be modulated via CV-input with a assumed voltage-range of -4V..4V at 2kHz sample rate.
Expand Down Expand Up @@ -268,7 +280,7 @@ The I/O-Configuration page lets you virtually patch the engine with the hardware

## MIDI-Settings

>[Long press [LEFT] + [RIGHT]] enters the MIDI-Settings page.
>[Long press [LEFT] + [RIGHT]] for getting to the MIDI-Settings page.
The MIDI-Settings page lets you select the MIDI-Input. MIDI via USB is active by default - alternatively the [T1 input can be used as MIDI-Input](#-midi-expander). Each engine can be assigned to a MIDI-Channel - it is possible to control single mono engines together polyphonically (for this all engines have to be set to the same midi channel). [Midi-Engines](src/polyVA.cxx) consume the MIDI-Stream directly, therefore the MIDI-Messages are not converted as incoming CVs or triggers.

Expand Down
634 changes: 322 additions & 312 deletions app/DRUMS/Djembe.bin.h

Large diffs are not rendered by default.

21 changes: 10 additions & 11 deletions app/DRUMS/Djembe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
#include "faust/ui.hxx"
#include "faust/djembe.dsp.h"

static float *_trig = nullptr;

void UIGlue::addButton(const char *ui, const char *label, float *zone)
{
dsp_param_f(TRIG, zone);
if (_trig == nullptr)
_trig = zone;
}

void UIGlue::addNumEntry(const char *ui, const char *label, float *zone, float init, float min, float max, float step)
Expand All @@ -28,29 +31,25 @@ void UIGlue::addHorizontalSlider(const char *ui, const char *label, float *zone,
if (zone)
{
*zone = init;
dsp_param_f2(label, zone, min, max);
//dsp_param_step_f(label, step);
engine::addParam(label, zone, min, max);
}
}

static FAUSTCLASS dsp;

static float outputL[FRAME_BUFFER_SIZE];

DSP_SETUP
void setup()
void engine::setup()
{
initmydsp(&dsp, SAMPLE_RATE);

UIGlue ui;
buildUserInterfacemydsp(&dsp, &ui);

dsp_frame_f(OUTPUT_L, outputL);
}

DSP_PROCESS
void process()
void engine::process()
{
if (_trig != nullptr)
*_trig = engine::trig();
auto outputL = engine::outputBuffer<0>();
float *outputs[] = {outputL, nullptr};
computemydsp(&dsp, FRAME_BUFFER_SIZE, nullptr, &outputs[0]);
}
261 changes: 261 additions & 0 deletions app/FX/Delay.bin.h

Large diffs are not rendered by default.

156 changes: 156 additions & 0 deletions app/FX/Delay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// Copyright (C)2021 - Eduard Heidt
//
// Author: Eduard Heidt (eh2k@gmx.de)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// See http://creativecommons.org/licenses/MIT/ for more information.
//

#include "../squares-and-circles-api.h"
#include "stmlib/stmlib.h"
#include "stmlib/dsp/units.h"
#include "stmlib/dsp/filter.h"
#include "stmlib/dsp/delay_line.h"
#include <stdio.h>

#define clamp(value, min, max) \
(value > max ? max : value < min ? min \
: value)

int32_t time_steps = 16;
float time = 0.5f;
float color = 0.5f;
float level = 0.5f;
float pan = 0.5f;

constexpr static int delay_len = 48000; // 1s

stmlib::DelayLine<uint16_t, delay_len> delay_mem[2];
stmlib::OnePole filterLP[2];
stmlib::OnePole filterHP[2];

inline const float DelayRead(stmlib::DelayLine<uint16_t, delay_len> *line_, float delay)
{
return static_cast<float>(static_cast<int16_t>(line_->Read(delay))) / 32768.0f;
}

inline void DelayWrite(stmlib::DelayLine<uint16_t, delay_len> *line_, const float sample)
{
line_->Write(static_cast<uint16_t>(
stmlib::Clip16(static_cast<int32_t>(sample * 32768.0f))));
}

char time_info[64] = "Time";

void engine::setup()
{
delay_mem[0].Init();
delay_mem[1].Init();

engine::addParam(time_info, &time_steps, 1, 64);
engine::addParam("Feedb", &level);
engine::addParam("Color", &color);
engine::addParam("Pan", &pan);
}

float delay = 0;
float t_32 = 0;

bool calc_t_step32()
{
uint32_t midi_bpm = machine::midi_bpm();// / 100;
if (midi_bpm > 0)
{
engine::addParam(time_info, &time_steps, 1, 128);
uint32_t bpm = midi_bpm;
auto t_per_beat = 6000.f / bpm; // * machine::SAMPLE_RATE
t_32 = t_per_beat / 32;
return true;
}
else
{
engine::addParam(time_info, &time);
t_32 = 1.f / 256.f;
return false;
}
}

void sync_params()
{
if (calc_t_step32())
time = time_steps * t_32;

float colorFreq = std::pow(100.f, 2.f * color - 1.f);
float lowpassFreq = clamp(20000.f * colorFreq, 20.f, 20000.f) / SAMPLE_RATE;
float highpassFreq = clamp(20.f * colorFreq, 20.f, 20000.f) / SAMPLE_RATE;

filterLP[0].set_f<stmlib::FREQUENCY_DIRTY>(lowpassFreq);
filterLP[1].set_f<stmlib::FREQUENCY_DIRTY>(lowpassFreq);
filterHP[0].set_f<stmlib::FREQUENCY_DIRTY>(highpassFreq);
filterHP[1].set_f<stmlib::FREQUENCY_DIRTY>(highpassFreq);
}

void engine::process()
{
sync_params();

int n = time / t_32;
float d = n * t_32 * SAMPLE_RATE;

if (fabsf(d - delay) > SAMPLE_RATE / 10)
delay = d;
else
ONE_POLE(delay, d, 0.01f);

auto inputL = engine::inputBuffer<0>();
auto inputR = engine::inputBuffer<1>();
auto outputL = engine::outputBuffer<0>();
auto outputR = engine::outputBuffer<1>();

for (int i = 0; i < FRAME_BUFFER_SIZE; i++)
{
float readL = DelayRead(&delay_mem[0], (int)delay);
float readR = DelayRead(&delay_mem[1], (int)delay);

auto inL = inputL[i];
auto inR = inputR[i];

inL = filterLP[0].Process<stmlib::FILTER_MODE_LOW_PASS>(inL);
inL = filterHP[0].Process<stmlib::FILTER_MODE_HIGH_PASS>(inL);
inR = filterLP[1].Process<stmlib::FILTER_MODE_LOW_PASS>(inR);
inR = filterHP[1].Process<stmlib::FILTER_MODE_HIGH_PASS>(inR);

DelayWrite(&delay_mem[0], (readR + inL * (0 + pan) * 2) * level);
DelayWrite(&delay_mem[1], (readL + inR * (1 - pan) * 2) * level);

outputL[i] = readL + inputL[i];
outputR[i] = readR + inputR[i];
}
}

void engine::draw()
{
if (calc_t_step32())
{
sprintf(time_info, ">t=%d", time_steps);
}
else
sprintf(time_info, ">T:%d ms", (int)(time * 1000));
}
Loading

0 comments on commit 690cfd3

Please sign in to comment.