diff --git a/.gitignore b/.gitignore index 1e3381d2..18d9cb85 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,7 @@ __pycache__/ /docs/cheatsheet/* !/docs/cheatsheet/cheatsheet.tex /docs/testServe/ + +# Jet Brains +.idea +*.iml diff --git a/CHANGELOG.md b/CHANGELOG.md index ba5f4da2..84a7a35a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ - **FIX**: delay when opening docs - **FIX**: `PROB 100` would only execute 99.01% of the time. - **FIX**: some `G.FDR` configurations caused incorrect rendering in grid visualizer +- **NEW**: `PROB` accepts an `ELSE` condition +- **NEW**: alias `PRB` for `PROB` +- **NEW**: new op: `WTOSS`, alias `WT` ## v4.0.0 diff --git a/docs/ops/controlflow.toml b/docs/ops/controlflow.toml index 1a704ef9..97ad8c4e 100644 --- a/docs/ops/controlflow.toml +++ b/docs/ops/controlflow.toml @@ -60,7 +60,7 @@ short = "if all previous `IF` / `ELIF` fail, and `x` is not zero, execute comman [ELSE] prototype = "ELSE: ..." -short = "if all previous `IF` / `ELIF` fail, excute command" +short = "if all previous `IF` / `ELIF` fail, execute command" [L] prototype = "L x y: ..." @@ -155,7 +155,13 @@ Negative numbers will synchronize to to the divisor value, such that `SYNC -1` c [PROB] prototype = "PROB x: ..." +aliases = ["PRB"] short = "potentially execute command with probability `x` (0-100)" +description = """ +If `x` is within probability execute command. + +The `ElSE` / `ELIF` statements can follow PROB on subsequent lines to operate as a Bernoulli gate of sorts. +""" [SCRIPT] prototype = "SCRIPT" diff --git a/docs/ops/maths.toml b/docs/ops/maths.toml index a8738844..11603b37 100644 --- a/docs/ops/maths.toml +++ b/docs/ops/maths.toml @@ -38,6 +38,11 @@ short = "generate a random number between `x` and `y` inclusive" prototype = "TOSS" short = "randomly return `0` or `1`" +[WTOSS] +prototype = "WTOSS x" +aliases = ["WT"] +short = "return `0` or `1` based on a weighted probability of `x` (0-100)" + ["?"] prototype = "? x y z" short = "if condition `x` is true return `y`, otherwise return `z`" @@ -365,7 +370,7 @@ N.B 2 R101011010101 ==> set scale to D-major CV 1 N.B 3 ==> set CV 1 to 3rd degree of scale (F#, value corresponding to N 6) N.B 3 R100101010010 ==> set scale to Eb-minor pentatonic -CV 1 N.B 2 ==> set CV 1 to 2nd degree of scale +CV 1 N.B 2 ==> set CV 1 to 2nd degree of scale (Gb, value corresponding to N 6) N.B 5 -3 ==> set scale to F-lydian using preset ``` @@ -454,7 +459,7 @@ Chords - `11` = Minor 6th `{0, 3, 7, 9}` - `12` = 7sus4 `{0, 5, 7, 10}` """ - + ["N.CS"] prototype = "N.CS r s d c" short = "Note Chord Scale operator, `r` is the root note (`0-127`), `s` is the scale (`0-8`), `d` is the scale degree (`1-7`) and `c` is the chord component (`0-3`), returns a value from the `N` table." @@ -472,7 +477,7 @@ Chord Scales - Refer to chord indices in `N.C` OP - `7` = Myxolidian `{6, 0, 1, 1, 0, 2, 1}` - `8` = Locrian `{6, 0, 1, 1, 0, 2, 1}` """ - + [V] prototype = "V x" short = "converts a voltage to a value usable by the CV outputs (`x` between `0` and `10`)" diff --git a/docs/ops/seed.toml b/docs/ops/seed.toml index 8301af14..c7a330dc 100644 --- a/docs/ops/seed.toml +++ b/docs/ops/seed.toml @@ -13,7 +13,7 @@ short = "get / set the random number generator seed for `R`, `RRAND`, and `RAND` prototype = "TOSS.SEED" prototype_set = "TOSS.SEED x" aliases = ["TOSS.SD"] -short = "get / set the random number generator seed for the `TOSS` op" +short = "get / set the random number generator seed for the `TOSS` and `WTOSS` ops" ["PROB.SEED"] prototype = "PROB.SEED" diff --git a/docs/whats_new.md b/docs/whats_new.md index 4bb40176..b03f8454 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -5,6 +5,9 @@ - **FIX**: delay when opening docs - **FIX**: `PROB 100` would execute only 99.01% of the time. - **FIX**: some `G.FDR` configurations caused incorrect rendering in grid visualizer +- **NEW**: `PROB` accepts an `ELSE` condition +- **NEW**: alias `PRB` for `PROB` +- **NEW**: new op: `WTOSS`, alias `WT` ## v4.0.0 diff --git a/src/match_token.rl b/src/match_token.rl index b0cdd6a6..d922a7b8 100644 --- a/src/match_token.rl +++ b/src/match_token.rl @@ -204,6 +204,8 @@ "R.MIN" => { MATCH_OP(E_OP_R_MIN); }; "R.MAX" => { MATCH_OP(E_OP_R_MAX); }; "TOSS" => { MATCH_OP(E_OP_TOSS); }; + "WTOSS" => { MATCH_OP(E_OP_WTOSS); }; + "WT" => { MATCH_OP(E_OP_WT); }; "MIN" => { MATCH_OP(E_OP_MIN); }; "MAX" => { MATCH_OP(E_OP_MAX); }; "LIM" => { MATCH_OP(E_OP_LIM); }; @@ -225,7 +227,7 @@ "OUTR" => { MATCH_OP(E_OP_OUTR); }; "INRI" => { MATCH_OP(E_OP_INRI); }; "OUTRI" => { MATCH_OP(E_OP_OUTRI); }; - "NZ" => { MATCH_OP(E_OP_NZ); }; + "NZ" => { MATCH_OP(E_OP_NZ); }; "EZ" => { MATCH_OP(E_OP_EZ); }; "RSH" => { MATCH_OP(E_OP_RSH); }; "LSH" => { MATCH_OP(E_OP_LSH); }; @@ -897,6 +899,7 @@ # delay "PROB" => { MATCH_MOD(E_MOD_PROB); }; + "PRB" => { MATCH_MOD(E_MOD_PRB); }; "DEL" => { MATCH_MOD(E_MOD_DEL); }; "DEL.X" => { MATCH_MOD(E_MOD_DEL_X); }; "DEL.R" => { MATCH_MOD(E_MOD_DEL_R); }; diff --git a/src/ops/controlflow.c b/src/ops/controlflow.c index 3cfebf69..c3af83ee 100644 --- a/src/ops/controlflow.c +++ b/src/ops/controlflow.c @@ -57,6 +57,7 @@ static void op_SYNC_get(const void *data, scene_state_t *ss, exec_state_t *es, // clang-format off const tele_mod_t mod_PROB = MAKE_MOD(PROB, mod_PROB_func, 1); +const tele_mod_t mod_PRB = MAKE_MOD(PRB, mod_PROB_func, 1); const tele_mod_t mod_IF = MAKE_MOD(IF, mod_IF_func, 1); const tele_mod_t mod_ELIF = MAKE_MOD(ELIF, mod_ELIF_func, 1); const tele_mod_t mod_ELSE = MAKE_MOD(ELSE, mod_ELSE_func, 0); @@ -86,7 +87,11 @@ static void mod_PROB_func(scene_state_t *ss, exec_state_t *es, int16_t a = cs_pop(cs); random_state_t *r = &ss->rand_states.s.prob.rand; - if (random_next(r) % 100 < a) { process_command(ss, es, post_command); } + es_variables(es)->if_else_condition = false; + if (random_next(r) % 100 < a) { + es_variables(es)->if_else_condition = true; + process_command(ss, es, post_command); + } } static void mod_IF_func(scene_state_t *ss, exec_state_t *es, diff --git a/src/ops/controlflow.h b/src/ops/controlflow.h index 5d2477f5..d1a760f8 100644 --- a/src/ops/controlflow.h +++ b/src/ops/controlflow.h @@ -4,6 +4,7 @@ #include "ops/op.h" extern const tele_mod_t mod_PROB; +extern const tele_mod_t mod_PRB; extern const tele_mod_t mod_IF; extern const tele_mod_t mod_ELIF; extern const tele_mod_t mod_ELSE; diff --git a/src/ops/maths.c b/src/ops/maths.c index 270630b8..f518e5ef 100644 --- a/src/ops/maths.c +++ b/src/ops/maths.c @@ -36,6 +36,8 @@ static void op_R_MAX_set(const void *data, scene_state_t *ss, exec_state_t *es, command_state_t *cs); static void op_TOSS_get(const void *data, scene_state_t *ss, exec_state_t *es, command_state_t *cs); +static void op_WTOSS_get(const void *data, scene_state_t *ss, exec_state_t *es, + command_state_t *cs); static void op_MIN_get(const void *data, scene_state_t *ss, exec_state_t *es, command_state_t *cs); static void op_MAX_get(const void *data, scene_state_t *ss, exec_state_t *es, @@ -187,6 +189,8 @@ const tele_op_t op_R = MAKE_GET_SET_OP(R, op_R_get, op_R_set, 0, true); const tele_op_t op_R_MIN = MAKE_GET_SET_OP(R.MIN, op_R_MIN_get, op_R_MIN_set, 0, true); const tele_op_t op_R_MAX = MAKE_GET_SET_OP(R.MAX, op_R_MAX_get, op_R_MAX_set, 0, true); const tele_op_t op_TOSS = MAKE_GET_OP(TOSS , op_TOSS_get , 0, true); +const tele_op_t op_WTOSS = MAKE_GET_OP(WTOSS , op_WTOSS_get , 1, true); +const tele_op_t op_WT = MAKE_GET_OP(WT , op_WTOSS_get , 1, true); const tele_op_t op_MIN = MAKE_GET_OP(MIN , op_MIN_get , 2, true); const tele_op_t op_MAX = MAKE_GET_OP(MAX , op_MAX_get , 2, true); const tele_op_t op_LIM = MAKE_GET_OP(LIM , op_LIM_get , 3, true); @@ -548,6 +552,13 @@ static void op_TOSS_get(const void *NOTUSED(data), scene_state_t *ss, cs_push(cs, random_next(r) & 1); } +static void op_WTOSS_get(const void *NOTUSED(data), scene_state_t *ss, + exec_state_t *NOTUSED(es), command_state_t *cs) { + int16_t a = cs_pop(cs); + random_state_t *r = &ss->rand_states.s.toss.rand; + cs_push(cs, random_next(r) % 100 < a ? 1 : 0); +} + static void op_MIN_get(const void *NOTUSED(data), scene_state_t *NOTUSED(ss), exec_state_t *NOTUSED(es), command_state_t *cs) { int16_t a, b; diff --git a/src/ops/maths.h b/src/ops/maths.h index bbbbb2e9..72f68937 100644 --- a/src/ops/maths.h +++ b/src/ops/maths.h @@ -16,6 +16,8 @@ extern const tele_op_t op_R; extern const tele_op_t op_R_MIN; extern const tele_op_t op_R_MAX; extern const tele_op_t op_TOSS; +extern const tele_op_t op_WTOSS; +extern const tele_op_t op_WT; extern const tele_op_t op_MIN; extern const tele_op_t op_MAX; extern const tele_op_t op_LIM; diff --git a/src/ops/op.c b/src/ops/op.c index fd8dbbc8..bc299900 100644 --- a/src/ops/op.c +++ b/src/ops/op.c @@ -88,9 +88,9 @@ const tele_op_t *tele_ops[E_OP__LENGTH] = { // maths &op_ADD, &op_SUB, &op_MUL, &op_DIV, &op_MOD, &op_RAND, &op_RND, &op_RRAND, - &op_RRND, &op_R, &op_R_MIN, &op_R_MAX, &op_TOSS, &op_MIN, &op_MAX, &op_LIM, - &op_WRAP, &op_WRP, &op_QT, &op_QT_S, &op_QT_CS, &op_QT_B, &op_QT_BX, - &op_AVG, &op_EQ, &op_NE, &op_LT, &op_GT, &op_LTE, &op_GTE, &op_INR, + &op_RRND, &op_R, &op_R_MIN, &op_R_MAX, &op_TOSS, &op_WTOSS, &op_WT, &op_MIN, + &op_MAX, &op_LIM, &op_WRAP, &op_WRP, &op_QT, &op_QT_S, &op_QT_CS, &op_QT_B, + &op_QT_BX, &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, @@ -293,7 +293,7 @@ const tele_op_t *tele_ops[E_OP__LENGTH] = { const tele_mod_t *tele_mods[E_MOD__LENGTH] = { // controlflow &mod_IF, &mod_ELIF, &mod_ELSE, &mod_L, &mod_W, &mod_EVERY, &mod_EV, - &mod_SKIP, &mod_OTHER, &mod_PROB, + &mod_SKIP, &mod_OTHER, &mod_PROB, &mod_PRB, // delay &mod_DEL, &mod_DEL_X, &mod_DEL_R, &mod_DEL_G, &mod_DEL_B, diff --git a/src/ops/op_enum.h b/src/ops/op_enum.h index dad0ed69..9b59bb19 100644 --- a/src/ops/op_enum.h +++ b/src/ops/op_enum.h @@ -177,6 +177,8 @@ typedef enum { E_OP_R_MIN, E_OP_R_MAX, E_OP_TOSS, + E_OP_WTOSS, + E_OP_WT, E_OP_MIN, E_OP_MAX, E_OP_LIM, @@ -817,6 +819,7 @@ typedef enum { E_MOD_SKIP, E_MOD_OTHER, E_MOD_PROB, + E_MOD_PRB, E_MOD_DEL, E_MOD_DEL_X, E_MOD_DEL_R,