Skip to content

Commit

Permalink
dev sync bbdf4c7 #97 #110 #109 #108
Browse files Browse the repository at this point in the history
  • Loading branch information
eh2k committed Nov 30, 2024
1 parent 3a6a2c8 commit 5c87eb5
Show file tree
Hide file tree
Showing 23 changed files with 1,006 additions and 162 deletions.
13 changes: 1 addition & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,4 @@ jobs:
run: |
git remote add --mirror=fetch secondary https://${{ secrets.CODEBERG_AUTH }}@codeberg.org/eh2k/squares-and-circles.git
git fetch origin
git push secondary --all --force
export hash=$(git rev-parse --short HEAD)
for f in .pio/build/*/*.hex; do
FIRMWARE=$(basename $(dirname ${f%.*}))
HEX_FILE=./${FIRMWARE}_engines_$hash.hex
ZIP_FILE=./${FIRMWARE}_engines_$hash.zip
mv -v "$f" $HEX_FILE
zip -j -9 $ZIP_FILE $HEX_FILE .github/workflows/LICENSE.txt $(dirname ${f%.*})/loader.sha
sha256sum $ZIP_FILE
curl -fs -X PUT -u ${{ secrets.UPLOAD_KEY }} ${{ secrets.LATEST_DROP_FOLDER }}/$ZIP_FILE --upload-file $ZIP_FILE || true
curl -fs -X PUT -u ${{ secrets.UPLOAD_KEY }} ${{ secrets.LATEST_DROP_FOLDER }}/${FIRMWARE}_latest.sha -d "$hash"
done
git push secondary --all --force
93 changes: 6 additions & 87 deletions .pio/builder/main.py
Original file line number Diff line number Diff line change
@@ -1,96 +1,15 @@
from SCons.Script import DefaultEnvironment, Default
import shutil, os
import subprocess
import json
import shutil
import io
import zlib
import time
import intelhex # pip install intelhex - #https://python-intelhex.readthedocs.io/en/latest/part2-2.html
import os, json, io

env = DefaultEnvironment()

# if env.get("PROGNAME", "program") == "program":
# env.Replace(PROGNAME="firmware")
if env.get("PROGNAME", "program") == "program":
env.Replace(PROGNAME="firmware")

# print(env.Dump())

env.AddPlatformTarget(
"build", None, env.GetBuildPath(f"$PROJECT_DIR/app/build.sh"), "Upload"
)
env.AddPlatformTarget(
"upload", "build", env.GetBuildPath(f"$PROJECT_DIR/app/upload.py"), "Upload"
)


def udynlink_size(file):
with open(file, "rb") as f:
f.read(4)
l = int.from_bytes(f.read(2), byteorder="little") # num_lot
r = int.from_bytes(f.read(2), byteorder="little")
# num_rels
a = int.from_bytes(f.read(4), byteorder="little")
# symt_size
b = int.from_bytes(f.read(4), byteorder="little")
# code_size
c = int.from_bytes(f.read(4), byteorder="little")
# data_size
d = int.from_bytes(f.read(4), byteorder="little")
# bss_size
h = 24 + (r * 8) + a
return h + b + c


def make_engines_hex(apps_json, ih=intelhex.IntelHex(), offset=int(1024 * 1024 / 2)):

print(apps_json)
if not os.path.exists(apps_json):
print(apps_json, "not found!")
else:
with open(apps_json) as f:
apps = json.load(f)
i = 1
for file in apps["apps"]:
bin_file = os.path.dirname(apps_json) + "/" + str(file)
if not os.path.exists(bin_file):
continue
bin_size = os.path.getsize(bin_file)

ih.loadbin(bin_file, offset=offset)
bin_offset = offset
offset += bin_size
with open(bin_file, "rb") as f:
crc32sum = zlib.crc32(f.read())
ih.puts(offset, crc32sum.to_bytes(4, "little"))
offset += 4

print(
i,
"0x%x" % bin_offset,
bin_file,
bin_size,
udynlink_size(bin_file) % 4,
"CRC32: %x" % crc32sum,
)
i += 1
offset += 4096 - (offset % 4096)

ih.puts(offset, 0xFFFF.to_bytes(4, "little"))
return ih


def post_program_action(source, target, env):
apps_json = env.GetProjectOption("apps_json")
ahx = make_engines_hex(apps_json)
program_path = env.GetBuildPath("$PROJECT_DIR/.pio/build/$PIOENV/engines.hex")
ahx.tofile(program_path, format="hex")
loader_sha = env.GetBuildPath("$PROJECT_DIR/.pio/build/$PIOENV/loader.sha")
with open(loader_sha, "w") as f:
f.write(env.GetProjectOption("squares_and_circles_loader"))
print(program_path, len(ahx))


env.AddPostAction("build", post_program_action)

Default(["build"])
env.AddPlatformTarget("build", None, env.GetBuildPath(f"$PROJECT_DIR/app/build.sh"), "Upload")
env.AddPlatformTarget("upload", "build", env.GetBuildPath(f"$PROJECT_DIR/app/upload.py"), "Upload")

Default(["build"])
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
<summary><b>ChangeLog</b></summary>

````
== 2024-11-30
* Bugfix:
* Crash on patch saving/restoring (#97)
* Enhancements:
* M-OSC/Waveforms: Braids Renaissance Chords (#110)
* SEQ/TuringMachine - OutputModes: Note-3...Note-7 (#109)
* Internal signal routing: src: $1-$9 (#108)
== 2024-11-07
* Bugfix:
* M-OSC/Waveforms - V_OCT modulation
Expand Down Expand Up @@ -354,7 +361,7 @@ For each parameter a modulation can be assigned:

>[Long press [RIGHT]] enters the I/O-Configuration page.
The I/O-Configuration page lets you virtually patch the engine with the hardware ports. Depending on the engine interface, trigger, gate, accent and V/OCT can be configured. In addition to the trigger, which is set with a rising edge, a gate state is also provided, that can be processed by the engine. Engines like Closed/Open-HiHats have an additional accent input - this works technically like a second trigger. The V/OCT input can optionally be quantized and transposed. In addition to the Tx inputs, the Cx inputs can also be used as a source for triggers and accents. The output can be configured as mono or stereo. Several engines can share the same output - the signal is mixed.
The I/O-Configuration page lets you virtually patch the engine with the hardware ports and internal gate/cv signals ($1-$9). Depending on the engine interface, trigger, gate, accent and V/OCT can be configured. In addition to the trigger, which is set with a rising edge, a gate state is also provided, that can be processed by the engine. Engines like Closed/Open-HiHats have an additional accent input - this works technically like a second trigger. The V/OCT input can optionally be quantized and transposed. In addition to the Tx inputs, the Cx inputs can also be used as a source for triggers and accents. The output can be configured as mono or stereo. Several engines can share the same output - the signal is mixed.

### Ctrl / Inputs

Expand Down
Binary file modified app/M-OSC/Waveforms.bin
Binary file not shown.
34 changes: 29 additions & 5 deletions app/M-OSC/Waveforms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "braids/settings.h"

#include "braids/vco_jitter_source.h"
#include "braids/quantizer.h"
#include <algorithm>

using namespace braids;
Expand All @@ -44,6 +45,25 @@ MacroOscillator osc1;
MacroOscillator osc2;
Envelope envelope;
VcoJitterSource jitter_source;
braids::Quantizer quantizer;

void Quantizer::Init()
{}

bool Quantizer::enabled() {
return engine::qz_enabled();
}

int32_t Quantizer::Process(int32_t pitch, int32_t root, int8_t *note)
{
auto ret = engine::qz_process(pitch, root + (PITCH_PER_OCTAVE * 8), note);
return ret;
}

int16_t Quantizer::Lookup(uint8_t index)
{
return engine::qz_lookup(index) + (PITCH_PER_OCTAVE * 8);
}

uint8_t sync_samples[FRAME_BUFFER_SIZE] = {};

Expand All @@ -61,12 +81,12 @@ void engine::setup()
osc2.Init();
jitter_source.Init();
envelope.Init();
quantizer.Init();

// std::fill(&sync_samples[0], &sync_samples[FRAME_BUFFER_SIZE], 0);

// settings.SetValue(SETTING_AD_VCA, true);
settings.SetValue(SETTING_SAMPLE_RATE, 5);
settings.SetValue(SETTING_PITCH_OCTAVE, 4);
settings.SetValue(SETTING_PITCH_RANGE, PITCH_RANGE_EXTERNAL);

engine::addParam(V_OCT, &_pitch, -4 * PITCH_PER_OCTAVE, 4 * PITCH_PER_OCTAVE); // is added internal to engine::cv
Expand Down Expand Up @@ -98,7 +118,7 @@ void engine::process()
uint32_t ad_value = envelope.Render();

int32_t pitchV = engine::cv_i32();
int32_t pitch = pitchV + (DEFAULT_NOTE + 12) * 128;
int32_t pitch = pitchV + (PITCH_PER_OCTAVE * 8);

// if (!settings.meta_modulation())
// {
Expand All @@ -124,7 +144,7 @@ void engine::process()
osc2.set_shape((braids::MacroOscillatorShape)_shape);

osc1.set_parameters(_timbre >> 1, _color >> 1);
osc1.set_pitch(pitch + settings.pitch_transposition());
osc1.set_pitch(pitch);

auto audio_samples = engine::outputBuffer_i16<0>();
osc1.Render(sync_samples, audio_samples, FRAME_BUFFER_SIZE);
Expand All @@ -146,7 +166,7 @@ void engine::process()
color = _color - stereo;

osc2.set_parameters((timbre >> 1), (color >> 1));
osc2.set_pitch(pitch + settings.pitch_transposition() + stereo);
osc2.set_pitch(pitch + stereo);

auto audio_samples = engine::outputBuffer_i16<1>();
osc2.Render(sync_samples, audio_samples, FRAME_BUFFER_SIZE);
Expand Down Expand Up @@ -187,4 +207,8 @@ void engine::draw()
#include "braids/settings.cc"
#include "braids/macro_oscillator.cc"
#include "braids/resources.cc"
#include "stmlib/utils/random.cc"
#include "stmlib/utils/random.cc"

#define chords chords2
#define mini_wave_line mini_wave_line2
#include "braids/chords_stack.cc"
2 changes: 1 addition & 1 deletion app/NOISE/WhitePink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
// See http://creativecommons.org/licenses/MIT/ for more information.
//

// ENGINE_NAME:NOISE/White/Pink
// ENGINE_NAME:NOISE/WhitePink

#include "../squares-and-circles-api.h"
#include "misc/noise.hxx"
Expand Down
Binary file modified app/SEQ/EuclidArp.bin
Binary file not shown.
4 changes: 2 additions & 2 deletions app/SEQ/EuclidArp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ void engine::process()
_cv_out = _cv;
}

_cv_out = (float)engine::cv_quantize(engine::cv_i32() + _cv_out * PITCH_PER_OCTAVE) / PITCH_PER_OCTAVE;
_cv_out = (float)engine::qz_process(engine::cv_i32() + _cv_out * PITCH_PER_OCTAVE, 0, nullptr) / PITCH_PER_OCTAVE;

if (engine::t() % 20 == 0)
{
Expand All @@ -426,7 +426,7 @@ void engine::process()
scope_pos -= LEN_OF(scope);
}

std::fill_n(engine::outputBuffer<1>(), FRAME_BUFFER_SIZE, _cv_out);
std::fill_n(engine::outputBuffer_i16<1>(), FRAME_BUFFER_SIZE, _cv_out * PITCH_PER_OCTAVE);
std::fill_n(engine::outputBuffer_i16<0>(), FRAME_BUFFER_SIZE, trig);
}

Expand Down
Binary file modified app/SEQ/TuringMachine.bin
Binary file not shown.
52 changes: 45 additions & 7 deletions app/SEQ/TuringMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,20 @@ inline uint32_t Rand()
return _rng_state;
}

const char *pulse_modes[17] = {};
const char *pulse_modes[21] = {};

int32_t note_from_scale(uint8_t bits)
{
//origin: https://github.com/Chysn/O_C-HemisphereSuite/blob/893deeb27ecacddad638ff9180f244a411623e35/software/o_c_REV/enigma/EnigmaOutput.h#L104

uint8_t mask = 0;
for (uint8_t s = 0; s < bits; s++)
mask |= (0x01 << s);
int note_shift = bits == 7 ? 0 : 64; // Note types under 7-bit start at Middle C
int note_number = (_turing_byte & mask) + note_shift;
CONSTRAIN(note_number, 0, 127);
return engine::qz_lookup(note_number);
}

int32_t output(uint32_t mode, const char **name)
{
Expand Down Expand Up @@ -139,13 +152,37 @@ int32_t output(uint32_t mode, const char **name)
}
case 15:
{
*name = "CV";
*name = "CV_5V";
return (int32_t)_turing_byte * (5 * PITCH_PER_OCTAVE / 255);
}
case 16:
{
*name = "CV-INV";
return (int32_t)(255-_turing_byte) * (5 * PITCH_PER_OCTAVE / 255);
*name = "NOTE-7";
return note_from_scale(7);
}
case 17:
{
*name = "NOTE-6";
return note_from_scale(6);
}
case 18:
{
*name = "NOTE-5";
return note_from_scale(5);
}
case 19:
{
*name = "NOTE-4";
return note_from_scale(4);
}
case 20:
{
*name = "NOTE-3";
return note_from_scale(3);
}
case LEN_OF(pulse_modes):
{
break;
}
}

Expand Down Expand Up @@ -224,15 +261,16 @@ void engine::process()
cv1 = 5 * PITCH_PER_OCTAVE;
trig_pulse1 = clock::samples_per_step() / 2;
}
else
cv1 += engine::cv_i32();

if (cv2 == INT16_MAX)
{
cv2 = 5 * PITCH_PER_OCTAVE;
trig_pulse2 = clock::samples_per_step() / 2;
}

cv1 = engine::cv_quantize(cv1) + engine::cv_i32();
cv2 = engine::cv_quantize(cv2) + engine::cv_i32();
else
cv2 += engine::cv_i32();
}

if (trig_pulse1 > 0)
Expand Down
5 changes: 2 additions & 3 deletions app/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ fi

pip install jinja2 pyelftools elf_size_analyze --upgrade pip

if [ "$1" = "--rebuild" ]; then
find "${SCRIPT_PATH}" -type f -name *.bin -exec touch {} +
if [[ "$1" == "--rebuild" ]]; then
find "${SCRIPT_PATH}/" -type f -name "*.bin" -print0 -exec touch {} +
fi

for f in $(find "${SCRIPT_PATH}" -mindepth 2 -maxdepth 2 -type f -name '*.cpp'); do

X="${f%.*}"

if [ -f $oo ] && [ "$(date -R -r $X.bin)" = "$(date -R -r $f)" ]; then
continue
fi
Expand Down
11 changes: 10 additions & 1 deletion app/squares-and-circles-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ namespace engine
constexpr uint32_t PARAM_MODULATION = 0x2;

EXTERN_C uint32_t getParamFlags(const void *valuePtr);
EXTERN_C void selectParam(const void *val);
inline uint32_t isParamModulated(const void *valuePtr)
{
return getParamFlags(valuePtr) & PARAM_MODULATION;
}
inline uint32_t isParamSelected(const void *valuePtr)
{
return getParamFlags(valuePtr) & PARAM_SELECTED;
Expand All @@ -309,7 +314,11 @@ namespace engine
EXTERN_C void *dsp_sample_Am6070(const uint8_t *data, int len, int sample_rate, int amp_mul);
EXTERN_C void dsp_set_sample_pos(void *smpl, float pos, float amplitude, float decay);
EXTERN_C void dsp_process_sample(void *smpl, float start, float end, float pitch, float output[FRAME_BUFFER_SIZE]);
EXTERN_C int32_t cv_quantize(int32_t cv);

EXTERN_C bool qz_enabled();
EXTERN_C const char* qz_name();
EXTERN_C int32_t qz_process(int32_t pitch, int32_t root, int8_t *note);
EXTERN_C int16_t qz_lookup(int8_t note); //0-127 note-values
}

enum EventType : uint16_t
Expand Down
Loading

0 comments on commit 5c87eb5

Please sign in to comment.