Skip to content

Commit f8b74c6

Browse files
authored
Merge pull request #27 from ahihi/dirt-compressor-needs
nodes for making Dirt compressor work
2 parents 22bf887 + e2a76f2 commit f8b74c6

File tree

5 files changed

+134
-2
lines changed

5 files changed

+134
-2
lines changed

packages/cli/src/clib/ugens.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ double lerp(double x, double y0, double y1)
2323
return y0 + x * (y1 - y0);
2424
}
2525

26+
// a pair of values
27+
// used to implement e.g. argmin and argmax
28+
typedef struct pair {
29+
double a;
30+
double b;
31+
} pair;
32+
2633
// SineOsc
2734

2835
typedef struct SineOsc
@@ -831,6 +838,26 @@ void *Clock_create()
831838
return (void *)node;
832839
}
833840

841+
// Pick
842+
843+
typedef struct Pick {} Pick;
844+
845+
void Pick_init(Pick *self)
846+
{
847+
}
848+
849+
double Pick_update(Sequence *self, float index, int len, float *inputs)
850+
{
851+
return inputs[((int) floor(index)) % len];
852+
}
853+
854+
void *Pick_create()
855+
{
856+
Pick *node = (Pick *)malloc(sizeof(Pick));
857+
Pick_init(node);
858+
return (void *)node;
859+
}
860+
834861
#endif // UGENS_H
835862

836863
/*
@@ -890,4 +917,4 @@ void *Template_create()
890917
return (void *)node;
891918
}
892919
893-
*/
920+
*/

packages/lib/src/lang/c.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export let def = (name, value, comment) =>
55

66
export let defUgen = (meta, ...args) => {
77
args.unshift(`nodes[${meta.ugenIndex}]`);
8-
if (meta.ugen === "Sequence") {
8+
if (meta.ugen === "Sequence" || meta.ugen === "Pick") {
99
const len = args.length - 2;
1010
const seq = `(float[${len}]){${args.slice(2).join(",")}}`;
1111
return def(
@@ -28,3 +28,11 @@ export let pow = (a, b) => `pow(${a}, ${b})`;
2828
export let exp = (a) => `exp(${a})`;
2929
export let log = (input) => `log(${input})`;
3030
export let mod = (a, b) => `${a}>=${b}?${a}-${b}:${a}`;
31+
export let abs = (input) => `fabs(${input})`;
32+
export let min = (a, b) => `fmin(${a}, ${b})`;
33+
export let max = (a, b) => `fmax(${a}, ${b})`;
34+
export let pair_make = (value, i) => `((pair) {${value}, ${i}})`;
35+
export let pair_a = (p) => `${p}.a`;
36+
export let pair_b = (p) => `${p}.b`;
37+
export let pair_a_min = (p, q) => `(${pair_a(p)} < ${pair_a(q)} ? ${p} : ${q})`;
38+
export let pair_a_max = (p, q) => `(${pair_a(p)} > ${pair_a(q)} ? ${p} : ${q})`;

packages/lib/src/lang/js.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,11 @@ export let pow = (a, b) => `${a} ** ${b}`;
2222
export let exp = (input) => `Math.exp(${input})`;
2323
export let log = (input) => `Math.log(${input})`;
2424
export let mod = (a, b) => `${a}%${b}`;
25+
export let abs = (input) => `Math.abs(${input})`;
26+
export let min = (a, b) => `Math.min(${a}, ${b})`;
27+
export let max = (a, b) => `Math.max(${a}, ${b})`;
28+
export let pair_make = (a, b) => `[${a}, ${b}]`;
29+
export let pair_a = (p) => `${p}[0]`;
30+
export let pair_b = (p) => `${p}[1]`;
31+
export let pair_a_min = (p, q) => `(${pair_a(p)} < ${pair_a(q)} ? ${p} : ${q})`;
32+
export let pair_a_max = (p, q) => `(${pair_a(p)} > ${pair_a(q)} ? ${p} : ${q})`;

packages/lib/src/lib.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,64 @@ export let mod = registerNode("mod", {
585585
compile: ({ vars, name, lang }) =>
586586
langs[lang].def(name, langs[lang].mod(...vars) || 0),
587587
});
588+
export let abs = registerNode("abs", {
589+
tags: ["math"],
590+
description: "returns the absolute value of the signal",
591+
ins: [{ name: "in" }],
592+
examples: [`sine(440).abs().out()`],
593+
compile: ({ vars: [input = 0], name, lang }) =>
594+
langs[lang].def(name, langs[lang].abs(input)),
595+
});
596+
export let min = registerNode("min", {
597+
tags: ["math"],
598+
description: "returns the minimum of the given signals",
599+
examples: [
600+
`impulse(4).apply(x => min(x.seq(0,3,2), x.seq(0,7,0,5,0)).add(48).midinote().sine()).out()`,
601+
],
602+
ins: [{ name: "in", dynamic: true }],
603+
compile: ({ vars, name, lang }) =>
604+
langs[lang].def(name, vars.reduce(langs[lang].min) || 0),
605+
});
606+
export let max = registerNode("max", {
607+
tags: ["math"],
608+
description: "returns the maximum of the given signals",
609+
examples: [
610+
`impulse(4).apply(x => max(x.seq(0,3,2), x.seq(0,7,0,5,0)).add(48).midinote().sine()).out()`,
611+
],
612+
ins: [{ name: "in", dynamic: true }],
613+
compile: ({ vars, name, lang }) =>
614+
langs[lang].def(name, vars.reduce(langs[lang].max) || 0),
615+
});
616+
export let argmin = registerNode("argmin", {
617+
tags: ["math"],
618+
description: "returns the index of the minimum of the given signals",
619+
examples: [
620+
`argmin(saw(1), saw(3), saw(5)).mul(12).add(48).midinote().sine().out()`,
621+
],
622+
ins: [{ name: "in", dynamic: true }],
623+
compile: ({ vars, name, lang }) =>
624+
langs[lang].def(
625+
name,
626+
langs[lang].pair_b(
627+
vars.map(langs[lang].pair_make).reduce(langs[lang].pair_a_min)
628+
) || 0
629+
),
630+
});
631+
export let argmax = registerNode("argmax", {
632+
tags: ["math"],
633+
description: "returns the index of the maximum of the given signals",
634+
examples: [
635+
`argmax(saw(1), saw(3), saw(5)).mul(12).add(48).midinote().sine().out()`,
636+
],
637+
ins: [{ name: "in", dynamic: true }],
638+
compile: ({ vars, name, lang }) =>
639+
langs[lang].def(
640+
name,
641+
langs[lang].pair_b(
642+
vars.map(langs[lang].pair_make).reduce(langs[lang].pair_a_max)
643+
) || 0
644+
),
645+
});
588646
export let greater = registerNode("greater", {
589647
tags: ["logic"],
590648
description: "returns 1 if input is greater then threshold",
@@ -785,6 +843,31 @@ export let pan = module(
785843
}
786844
);
787845

846+
export let pick = registerNode("pick", {
847+
tags: ["multi-channel"],
848+
ugen: "Pick",
849+
description: "Pick",
850+
ins: [{ name: "index" }, { name: "inputs", dynamic: true }],
851+
compile: ({ vars, ...meta }) => langs[meta.lang].defUgen(meta, ...vars),
852+
});
853+
854+
export let split = register(
855+
"split",
856+
(input, fn) => {
857+
if (input.type !== "poly") {
858+
return fn([input]);
859+
}
860+
return fn(input.ins);
861+
},
862+
{
863+
ins: [{ name: "input" }, { name: "fn" }],
864+
tags: ["multi-channel"],
865+
description:
866+
"apply fn to an array of signals, one for each channel in input",
867+
examples: [`sine([220,330,550]).split(chs => add(...chs)).out()`],
868+
}
869+
);
870+
788871
export let mix = register(
789872
"mix",
790873
(input, channels = 1) => {

packages/lib/src/ugens.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,3 +769,9 @@ export class Sequence extends AudioNode {
769769
return ins[this.step];
770770
}
771771
}
772+
773+
export class Pick extends AudioNode {
774+
update(index, ...inputs) {
775+
return inputs[Math.floor(index) % inputs.length];
776+
}
777+
}

0 commit comments

Comments
 (0)