From 3224efa22d368e3326bc0e88681cdc46402d24a2 Mon Sep 17 00:00:00 2001 From: scanner-darkly Date: Mon, 17 Apr 2023 11:14:52 -0700 Subject: [PATCH] SCALE0 op (#311) --- CHANGELOG.md | 1 + docs/ops/maths.toml | 5 +++++ docs/whats_new.md | 1 + module/help_mode.c | 4 +++- src/match_token.rl | 2 ++ src/ops/maths.c | 26 +++++++++++++++++++++++++- src/ops/maths.h | 2 ++ src/ops/op.c | 20 ++++++++++---------- src/ops/op_enum.h | 2 ++ 9 files changed, 51 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8138ab4f..b9626a09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - **FIX**: fix MIDI IN ops channel number being off by 1 - **FIX**: improve `TR.P` accuracy - **FIX**: fix `KILL` not stopping TR pulses in progress +- **NEW**: new op: `SCALE0` / `SCL0` ## v4.0.0 diff --git a/docs/ops/maths.toml b/docs/ops/maths.toml index ba9ad817..32527a3a 100644 --- a/docs/ops/maths.toml +++ b/docs/ops/maths.toml @@ -269,6 +269,11 @@ prototype = "SCALE a b x y i" aliases = ["SCL"] short = "scale `i` from range `a` to `b` to range `x` to `y`, i.e. `i * (y - x) / (b - a)`" +[SCALE0] +prototype = "SCALE a b i" +aliases = ["SCL0"] +short = "scale `i` from range `0` to `a` to range `0` to `b`" + [ER] prototype = "ER f l i" short = "Euclidean rhythm, `f` is fill (`1-32`), `l` is length (`1-32`) and `i` is step (any value), returns `0` or `1`" diff --git a/docs/whats_new.md b/docs/whats_new.md index 61bb7d4b..e802d5a5 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -22,6 +22,7 @@ - **FIX**: fix MIDI IN ops channel number being off by 1 - **FIX**: improve `TR.P` accuracy - **FIX**: fix `KILL` not stopping TR pulses in progress +- **NEW**: new op: `SCALE0` / `SCL0` ## v4.0.0 diff --git a/module/help_mode.c b/module/help_mode.c index d16a8237..196b9b01 100644 --- a/module/help_mode.c +++ b/module/help_mode.c @@ -281,7 +281,7 @@ const char* help4[HELP4_LENGTH] = { "4/17 DATA AND TABLES", " S = STEP (0-15)" }; -#define HELP5_LENGTH 128 +#define HELP5_LENGTH 130 const char* help5[HELP5_LENGTH] = { "5/17 OPERATORS", " ", "RAND A|RANDOM 0 - A", @@ -341,6 +341,8 @@ const char* help5[HELP5_LENGTH] = { "5/17 OPERATORS", "WRAP A B C|WRAP A AROUND B-C", "SCALE A B X Y I", " SCALE I FROM A..B TO X..Y", + "SCALE0 A B I", + " SCALE I FROM 0..A TO 0..B", "QT A B|QUANTIZE A TO B*X", "QT.S X R S|QUANTIZE TO SCALE", " X = INPUT *", diff --git a/src/match_token.rl b/src/match_token.rl index 3ba85cf4..62657670 100644 --- a/src/match_token.rl +++ b/src/match_token.rl @@ -243,6 +243,8 @@ "JI" => { MATCH_OP(E_OP_JI); }; "SCALE" => { MATCH_OP(E_OP_SCALE); }; "SCL" => { MATCH_OP(E_OP_SCL); }; + "SCALE0" => { MATCH_OP(E_OP_SCALE0); }; + "SCL0" => { MATCH_OP(E_OP_SCL0); }; "N" => { MATCH_OP(E_OP_N); }; "VN" => { MATCH_OP(E_OP_VN); }; "HZ" => { MATCH_OP(E_OP_HZ); }; diff --git a/src/ops/maths.c b/src/ops/maths.c index 518bfbc6..2610c21e 100644 --- a/src/ops/maths.c +++ b/src/ops/maths.c @@ -111,6 +111,8 @@ static void op_JI_get(const void *data, scene_state_t *ss, exec_state_t *es, command_state_t *cs); static void op_SCALE_get(const void *data, scene_state_t *ss, exec_state_t *es, command_state_t *cs); +static void op_SCALE0_get(const void *data, scene_state_t *ss, exec_state_t *es, + command_state_t *cs); static void op_N_get(const void *data, scene_state_t *ss, exec_state_t *es, command_state_t *cs); static void op_VN_get(const void *data, scene_state_t *ss, exec_state_t *es, @@ -233,6 +235,8 @@ const tele_op_t op_OR4 = MAKE_GET_OP(OR4 , op_OR4_get , 4, true); const tele_op_t op_JI = MAKE_GET_OP(JI , op_JI_get , 2, true); const tele_op_t op_SCALE = MAKE_GET_OP(SCALE , op_SCALE_get , 5, true); const tele_op_t op_SCL = MAKE_GET_OP(SCL , op_SCALE_get , 5, true); +const tele_op_t op_SCALE0 = MAKE_GET_OP(SCALE0 , op_SCALE0_get , 3, true); +const tele_op_t op_SCL0 = MAKE_GET_OP(SCL0 , op_SCALE0_get , 3, true); const tele_op_t op_N = MAKE_GET_OP(N , op_N_get , 1, true); const tele_op_t op_VN = MAKE_GET_OP(VN , op_VN_get , 1, true); const tele_op_t op_HZ = MAKE_GET_OP(HZ , op_HZ_get , 1, true); @@ -970,6 +974,26 @@ static void op_SCALE_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss), cs_push(cs, result + x); } +static void op_SCALE0_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss), + exec_state_t *NOTUSED(es), command_state_t *cs) { + int32_t b, y, i; + int32_t a = 0; + b = cs_pop(cs); + int32_t x = 0; + y = cs_pop(cs); + i = cs_pop(cs); + + if ((b - a) == 0) { + cs_push(cs, 0); + return; + } + + int32_t result = (i - a) * (y - x) * 2 / (b - a); + result = result / 2 + (result & 1); // rounding + + cs_push(cs, result + x); +} + static void op_N_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss), exec_state_t *NOTUSED(es), command_state_t *cs) { int16_t a = cs_pop(cs); @@ -1256,7 +1280,7 @@ static void op_BPM_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss), if (a < 2) a = 2; if (a > 1000) a = 1000; ret = ((((uint32_t)(1 << 31)) / ((a << 20) / 60)) * 1000) >> 10; - ret = ret / 2 + (ret & 1); // rounding + ret = ret / 2 + (ret & 1); // rounding cs_push(cs, (int16_t)ret); } diff --git a/src/ops/maths.h b/src/ops/maths.h index e865131a..bf3f6d31 100644 --- a/src/ops/maths.h +++ b/src/ops/maths.h @@ -55,6 +55,8 @@ extern const tele_op_t op_OR4; extern const tele_op_t op_JI; extern const tele_op_t op_SCALE; extern const tele_op_t op_SCL; +extern const tele_op_t op_SCALE0; +extern const tele_op_t op_SCL0; extern const tele_op_t op_N; extern const tele_op_t op_VN; extern const tele_op_t op_HZ; diff --git a/src/ops/op.c b/src/ops/op.c index 88d1ec4e..f684b1f9 100644 --- a/src/ops/op.c +++ b/src/ops/op.c @@ -94,16 +94,16 @@ const tele_op_t *tele_ops[E_OP__LENGTH] = { &op_AVG, &op_EQ, &op_NE, &op_LT, &op_GT, &op_LTE, &op_GTE, &op_INR, &op_OUTR, &op_INRI, &op_OUTRI, &op_NZ, &op_EZ, &op_RSH, &op_LSH, &op_LROT, &op_RROT, &op_EXP, &op_ABS, &op_SGN, &op_AND, &op_OR, &op_AND3, &op_OR3, - &op_AND4, &op_OR4, &op_JI, &op_SCALE, &op_SCL, &op_N, &op_VN, &op_HZ, - &op_N_S, &op_N_C, &op_N_CS, &op_N_B, &op_N_BX, &op_V, &op_VV, &op_ER, - &op_NR, &op_DR_T, &op_DR_P, &op_DR_V, &op_BPM, &op_BIT_OR, &op_BIT_AND, - &op_BIT_NOT, &op_BIT_XOR, &op_BSET, &op_BGET, &op_BCLR, &op_BTOG, &op_BREV, - &op_XOR, &op_CHAOS, &op_CHAOS_R, &op_CHAOS_ALG, &op_SYM_PLUS, &op_SYM_DASH, - &op_SYM_STAR, &op_SYM_FORWARD_SLASH, &op_SYM_PERCENTAGE, &op_SYM_EQUAL_x2, - &op_SYM_EXCLAMATION_EQUAL, &op_SYM_LEFT_ANGLED, &op_SYM_RIGHT_ANGLED, - &op_SYM_LEFT_ANGLED_EQUAL, &op_SYM_RIGHT_ANGLED_EQUAL, - &op_SYM_RIGHT_ANGLED_LEFT_ANGLED, &op_SYM_LEFT_ANGLED_RIGHT_ANGLED, - &op_SYM_RIGHT_ANGLED_EQUAL_LEFT_ANGLED, + &op_AND4, &op_OR4, &op_JI, &op_SCALE, &op_SCL, &op_SCALE0, &op_SCL0, &op_N, + &op_VN, &op_HZ, &op_N_S, &op_N_C, &op_N_CS, &op_N_B, &op_N_BX, &op_V, + &op_VV, &op_ER, &op_NR, &op_DR_T, &op_DR_P, &op_DR_V, &op_BPM, &op_BIT_OR, + &op_BIT_AND, &op_BIT_NOT, &op_BIT_XOR, &op_BSET, &op_BGET, &op_BCLR, + &op_BTOG, &op_BREV, &op_XOR, &op_CHAOS, &op_CHAOS_R, &op_CHAOS_ALG, + &op_SYM_PLUS, &op_SYM_DASH, &op_SYM_STAR, &op_SYM_FORWARD_SLASH, + &op_SYM_PERCENTAGE, &op_SYM_EQUAL_x2, &op_SYM_EXCLAMATION_EQUAL, + &op_SYM_LEFT_ANGLED, &op_SYM_RIGHT_ANGLED, &op_SYM_LEFT_ANGLED_EQUAL, + &op_SYM_RIGHT_ANGLED_EQUAL, &op_SYM_RIGHT_ANGLED_LEFT_ANGLED, + &op_SYM_LEFT_ANGLED_RIGHT_ANGLED, &op_SYM_RIGHT_ANGLED_EQUAL_LEFT_ANGLED, &op_SYM_LEFT_ANGLED_EQUAL_RIGHT_ANGLED, &op_SYM_EXCLAMATION, &op_SYM_LEFT_ANGLED_x2, &op_SYM_RIGHT_ANGLED_x2, &op_SYM_LEFT_ANGLED_x3, &op_SYM_RIGHT_ANGLED_x3, &op_SYM_AMPERSAND_x2, &op_SYM_PIPE_x2, diff --git a/src/ops/op_enum.h b/src/ops/op_enum.h index 32b61a85..e9dbea34 100644 --- a/src/ops/op_enum.h +++ b/src/ops/op_enum.h @@ -216,6 +216,8 @@ typedef enum { E_OP_JI, E_OP_SCALE, E_OP_SCL, + E_OP_SCALE0, + E_OP_SCL0, E_OP_N, E_OP_VN, E_OP_HZ,