2 |

3 |
4 | # Sporth AudioKit (AudioKit Operations)
5 |
6 | [](https://github.com/AudioKit/SporthAudioKit/actions?query=workflow%3ACI)
7 | [](https://github.com/AudioKit/SporthAudioKit/blob/main/LICENSE)
8 | [](https://swiftpackageindex.com/AudioKit/SporthAudioKit)
9 | [](https://swiftpackageindex.com/AudioKit/SporthAudioKit)
10 | [](https://houndci.com)
11 | [](https://twitter.com/AudioKitPro)
12 |
13 |
14 |
15 | This extension to AudioKit allows for complex, interconnected DSP.
16 |
17 | ## Installation
18 |
19 | Install using the Swift Package Manager.
20 |
21 | ## Targets
22 |
23 | | Name | Description | Language |
24 | |-----------------|---------------------------------------------|---------------|
25 | | SporthAudioKit | API for creating Sporth-powered Audio Units | Swift |
26 | | CSporthAudioKit | Audio Unit for Operation DSP | Objective-C++ |
27 | | Sporth | Stack-based DSP language | C |
28 |
29 | ## Documentation
30 |
31 | The [AudioKit.io website](https://audiokit.io/SporthAudioKit/) hosts the documentation for this project.
32 |
33 | ## Examples
34 |
35 | See the [AudioKit Cookbook](https://github.com/AudioKit/Cookbook/) for complete examples.
36 |
--------------------------------------------------------------------------------
/Sources/Sporth/ugens/line.c:
--------------------------------------------------------------------------------
1 | #include "plumber.h"
2 |
3 | int sporth_line(sporth_stack *stack, void *ud)
4 | {
5 | plumber_data *pd = ud;
6 | SPFLOAT trig;
7 | SPFLOAT out;
8 | SPFLOAT a;
9 | SPFLOAT dur;
10 | SPFLOAT b;
11 | sp_line *line;
12 |
13 | switch(pd->mode) {
14 | case PLUMBER_CREATE:
15 |
16 | #ifdef DEBUG_MODE
17 | plumber_print(pd, "line: Creating\n");
18 | #endif
19 |
20 | sp_line_create(&line);
21 | plumber_add_ugen(pd, SPORTH_LINE, line);
22 | if(sporth_check_args(stack, "ffff") != SPORTH_OK) {
23 | plumber_print(pd,"Not enough arguments for line\n");
24 | stack->error++;
25 | return PLUMBER_NOTOK;
26 | }
27 | sporth_stack_push_float(stack, 0);
28 | break;
29 | case PLUMBER_INIT:
30 |
31 | #ifdef DEBUG_MODE
32 | plumber_print(pd, "line: Initialising\n");
33 | #endif
34 |
35 | b = sporth_stack_pop_float(stack);
36 | dur = sporth_stack_pop_float(stack);
37 | a = sporth_stack_pop_float(stack);
38 | trig = sporth_stack_pop_float(stack);
39 | line = pd->last->ud;
40 | sp_line_init(pd->sp, line);
41 | sporth_stack_push_float(stack, 0);
42 | break;
43 | case PLUMBER_COMPUTE:
44 | b = sporth_stack_pop_float(stack);
45 | dur = sporth_stack_pop_float(stack);
46 | a = sporth_stack_pop_float(stack);
47 | trig = sporth_stack_pop_float(stack);
48 | line = pd->last->ud;
49 | line->a = a;
50 | line->dur = dur;
51 | line->b = b;
52 | sp_line_compute(pd->sp, line, &trig, &out);
53 | sporth_stack_push_float(stack, out);
54 | break;
55 | case PLUMBER_DESTROY:
56 | line = pd->last->ud;
57 | sp_line_destroy(&line);
58 | break;
59 | default:
60 | plumber_print(pd, "line: Unknown mode!\n");
61 | break;
62 | }
63 | return PLUMBER_OK;
64 | }
65 |
--------------------------------------------------------------------------------
/Sources/Sporth/ugens/mode.c:
--------------------------------------------------------------------------------
1 | #include "plumber.h"
2 |
3 | int sporth_mode(sporth_stack *stack, void *ud)
4 | {
5 | plumber_data *pd = ud;
6 | SPFLOAT in;
7 | SPFLOAT out;
8 | SPFLOAT freq;
9 | SPFLOAT q;
10 | sp_mode *mode;
11 |
12 | switch(pd->mode) {
13 | case PLUMBER_CREATE:
14 |
15 | #ifdef DEBUG_MODE
16 | plumber_print(pd, "mode: Creating\n");
17 | #endif
18 |
19 | sp_mode_create(&mode);
20 | plumber_add_ugen(pd, SPORTH_MODE, mode);
21 | if(sporth_check_args(stack, "fff") != SPORTH_OK) {
22 | plumber_print(pd,"Not enough arguments for mode\n");
23 | stack->error++;
24 | return PLUMBER_NOTOK;
25 | }
26 | q = sporth_stack_pop_float(stack);
27 | freq = sporth_stack_pop_float(stack);
28 | in = sporth_stack_pop_float(stack);
29 | sporth_stack_push_float(stack, 0);
30 | break;
31 | case PLUMBER_INIT:
32 |
33 | #ifdef DEBUG_MODE
34 | plumber_print(pd, "mode: Initialising\n");
35 | #endif
36 |
37 | q = sporth_stack_pop_float(stack);
38 | freq = sporth_stack_pop_float(stack);
39 | in = sporth_stack_pop_float(stack);
40 | mode = pd->last->ud;
41 | sp_mode_init(pd->sp, mode);
42 | sporth_stack_push_float(stack, 0);
43 | break;
44 | case PLUMBER_COMPUTE:
45 | q = sporth_stack_pop_float(stack);
46 | freq = sporth_stack_pop_float(stack);
47 | in = sporth_stack_pop_float(stack);
48 | mode = pd->last->ud;
49 | mode->freq = freq;
50 | mode->q = q;
51 | sp_mode_compute(pd->sp, mode, &in, &out);
52 | sporth_stack_push_float(stack, out);
53 | break;
54 | case PLUMBER_DESTROY:
55 | mode = pd->last->ud;
56 | sp_mode_destroy(&mode);
57 | break;
58 | default:
59 | plumber_print(pd, "mode: Unknown mode!\n");
60 | break;
61 | }
62 | return PLUMBER_OK;
63 | }
64 |
--------------------------------------------------------------------------------
/Sources/Sporth/ugens/pan.c:
--------------------------------------------------------------------------------
1 | #include "plumber.h"
2 |
3 | int sporth_pan2(sporth_stack *stack, void *ud)
4 | {
5 | plumber_data *pd = ud;
6 | SPFLOAT in;
7 | SPFLOAT out_left;
8 | SPFLOAT out_right;
9 | SPFLOAT pan;
10 | sp_pan2 *pan2;
11 |
12 | switch(pd->mode) {
13 | case PLUMBER_CREATE:
14 |
15 | #ifdef DEBUG_MODE
16 | plumber_print(pd, "pan2: Creating\n");
17 | #endif
18 |
19 | sp_pan2_create(&pan2);
20 | plumber_add_ugen(pd, SPORTH_PAN, pan2);
21 | if(sporth_check_args(stack, "ff") != SPORTH_OK) {
22 | plumber_print(pd,"Not enough arguments for pan2\n");
23 | stack->error++;
24 | return PLUMBER_NOTOK;
25 | }
26 | pan = sporth_stack_pop_float(stack);
27 | in = sporth_stack_pop_float(stack);
28 | sporth_stack_push_float(stack, 0);
29 | sporth_stack_push_float(stack, 0);
30 | break;
31 | case PLUMBER_INIT:
32 |
33 | #ifdef DEBUG_MODE
34 | plumber_print(pd, "pan2: Initialising\n");
35 | #endif
36 | pan = sporth_stack_pop_float(stack);
37 | in = sporth_stack_pop_float(stack);
38 | pan2 = pd->last->ud;
39 | sp_pan2_init(pd->sp, pan2);
40 | sporth_stack_push_float(stack, 0);
41 | sporth_stack_push_float(stack, 0);
42 | break;
43 | case PLUMBER_COMPUTE:
44 | pan = sporth_stack_pop_float(stack);
45 | in = sporth_stack_pop_float(stack);
46 | pan2 = pd->last->ud;
47 | pan2->pan = pan;
48 | sp_pan2_compute(pd->sp, pan2, &in, &out_left, &out_right);
49 | sporth_stack_push_float(stack, out_left);
50 | sporth_stack_push_float(stack, out_right);
51 | break;
52 | case PLUMBER_DESTROY:
53 | pan2 = pd->last->ud;
54 | sp_pan2_destroy(&pan2);
55 | break;
56 | default:
57 | plumber_print(pd, "pan2: Unknown mode!\n");
58 | break;
59 | }
60 | return PLUMBER_OK;
61 | }
62 |
--------------------------------------------------------------------------------
/Sources/Sporth/ugens/expon.c:
--------------------------------------------------------------------------------
1 | #include "plumber.h"
2 |
3 | int sporth_expon(sporth_stack *stack, void *ud)
4 | {
5 | plumber_data *pd = ud;
6 | SPFLOAT trig;
7 | SPFLOAT out;
8 | SPFLOAT a;
9 | SPFLOAT dur;
10 | SPFLOAT b;
11 | sp_expon *expon;
12 |
13 | switch(pd->mode) {
14 | case PLUMBER_CREATE:
15 |
16 | #ifdef DEBUG_MODE
17 | plumber_print(pd, "expon: Creating\n");
18 | #endif
19 |
20 | sp_expon_create(&expon);
21 | plumber_add_ugen(pd, SPORTH_EXPON, expon);
22 | if(sporth_check_args(stack, "ffff") != SPORTH_OK) {
23 | plumber_print(pd,"Not enough arguments for expon\n");
24 | stack->error++;
25 | return PLUMBER_NOTOK;
26 | }
27 | sporth_stack_push_float(stack, 0);
28 | break;
29 | case PLUMBER_INIT:
30 |
31 | #ifdef DEBUG_MODE
32 | plumber_print(pd, "expon: Initialising\n");
33 | #endif
34 |
35 | b = sporth_stack_pop_float(stack);
36 | dur = sporth_stack_pop_float(stack);
37 | a = sporth_stack_pop_float(stack);
38 | trig = sporth_stack_pop_float(stack);
39 | expon = pd->last->ud;
40 | sp_expon_init(pd->sp, expon);
41 | sporth_stack_push_float(stack, 0);
42 | break;
43 | case PLUMBER_COMPUTE:
44 | b = sporth_stack_pop_float(stack);
45 | dur = sporth_stack_pop_float(stack);
46 | a = sporth_stack_pop_float(stack);
47 | trig = sporth_stack_pop_float(stack);
48 | expon = pd->last->ud;
49 | expon->a = a;
50 | expon->dur = dur;
51 | expon->b = b;
52 | sp_expon_compute(pd->sp, expon, &trig, &out);
53 | sporth_stack_push_float(stack, out);
54 | break;
55 | case PLUMBER_DESTROY:
56 | expon = pd->last->ud;
57 | sp_expon_destroy(&expon);
58 | break;
59 | default:
60 | plumber_print(pd, "expon: Unknown mode!\n");
61 | break;
62 | }
63 | return PLUMBER_OK;
64 | }
65 |
--------------------------------------------------------------------------------
/Sources/Sporth/ugens/scale.c:
--------------------------------------------------------------------------------
1 | #include "plumber.h"
2 |
3 | int sporth_scale(sporth_stack *stack, void *ud)
4 | {
5 | plumber_data *pd = ud;
6 | SPFLOAT in;
7 | SPFLOAT out;
8 | SPFLOAT min;
9 | SPFLOAT max;
10 | sp_scale *scale;
11 |
12 | switch(pd->mode) {
13 | case PLUMBER_CREATE:
14 |
15 | #ifdef DEBUG_MODE
16 | plumber_print(pd, "scale: Creating\n");
17 | #endif
18 |
19 | sp_scale_create(&scale);
20 | plumber_add_ugen(pd, SPORTH_SCALE, scale);
21 | if(sporth_check_args(stack, "fff") != SPORTH_OK) {
22 | plumber_print(pd,"Not enough arguments for scale\n");
23 | stack->error++;
24 | return PLUMBER_NOTOK;
25 | }
26 | max = sporth_stack_pop_float(stack);
27 | min = sporth_stack_pop_float(stack);
28 | in = sporth_stack_pop_float(stack);
29 | sporth_stack_push_float(stack, 0);
30 | break;
31 | case PLUMBER_INIT:
32 |
33 | #ifdef DEBUG_MODE
34 | plumber_print(pd, "scale: Initialising\n");
35 | #endif
36 | max = sporth_stack_pop_float(stack);
37 | min = sporth_stack_pop_float(stack);
38 | in = sporth_stack_pop_float(stack);
39 | scale = pd->last->ud;
40 | sp_scale_init(pd->sp, scale);
41 | sporth_stack_push_float(stack, 0);
42 | break;
43 | case PLUMBER_COMPUTE:
44 | max = sporth_stack_pop_float(stack);
45 | min = sporth_stack_pop_float(stack);
46 | in = sporth_stack_pop_float(stack);
47 | scale = pd->last->ud;
48 | scale->min = min;
49 | scale->max = max;
50 | sp_scale_compute(pd->sp, scale, &in, &out);
51 | sporth_stack_push_float(stack, out);
52 | break;
53 | case PLUMBER_DESTROY:
54 | scale = pd->last->ud;
55 | sp_scale_destroy(&scale);
56 | break;
57 | default:
58 | plumber_print(pd, "scale: Unknown mode!\n");
59 | break;
60 | }
61 | return PLUMBER_OK;
62 | }
63 |
--------------------------------------------------------------------------------
/Sources/Sporth/ugens/count.c:
--------------------------------------------------------------------------------
1 | #include "plumber.h"
2 |
3 | int sporth_count(sporth_stack *stack, void *ud)
4 | {
5 | plumber_data *pd = ud;
6 | SPFLOAT trig;
7 | SPFLOAT out;
8 | SPFLOAT count;
9 | SPFLOAT mode;
10 | sp_count *cnt;
11 |
12 | switch(pd->mode) {
13 | case PLUMBER_CREATE:
14 |
15 | #ifdef DEBUG_MODE
16 | plumber_print(pd, "count: Creating\n");
17 | #endif
18 |
19 | sp_count_create(&cnt);
20 | plumber_add_ugen(pd, SPORTH_COUNT, cnt);
21 | if(sporth_check_args(stack, "fff") != SPORTH_OK) {
22 | plumber_print(pd,"Not enough arguments for count\n");
23 | stack->error++;
24 | return PLUMBER_NOTOK;
25 | }
26 | mode = sporth_stack_pop_float(stack);
27 | count = sporth_stack_pop_float(stack);
28 | trig = sporth_stack_pop_float(stack);
29 | sporth_stack_push_float(stack, 0);
30 | break;
31 | case PLUMBER_INIT:
32 |
33 | #ifdef DEBUG_MODE
34 | plumber_print(pd, "count: Initialising\n");
35 | #endif
36 | mode = sporth_stack_pop_float(stack);
37 | count = sporth_stack_pop_float(stack);
38 | trig = sporth_stack_pop_float(stack);
39 | cnt = pd->last->ud;
40 | sp_count_init(pd->sp, cnt);
41 | sporth_stack_push_float(stack, 0);
42 | break;
43 | case PLUMBER_COMPUTE:
44 | mode = sporth_stack_pop_float(stack);
45 | count = sporth_stack_pop_float(stack);
46 | trig = sporth_stack_pop_float(stack);
47 | cnt = pd->last->ud;
48 | cnt->count = count;
49 | cnt->mode = mode;
50 | sp_count_compute(pd->sp, cnt, &trig, &out);
51 | sporth_stack_push_float(stack, out);
52 | break;
53 | case PLUMBER_DESTROY:
54 | cnt = pd->last->ud;
55 | sp_count_destroy(&cnt);
56 | break;
57 | default:
58 | plumber_print(pd, "count: Unknown mode!\n");
59 | break;
60 | }
61 | return PLUMBER_OK;
62 | }
63 |
--------------------------------------------------------------------------------
/Sources/Sporth/ugens/trand.c:
--------------------------------------------------------------------------------
1 | #include "plumber.h"
2 |
3 | int sporth_trand(sporth_stack *stack, void *ud)
4 | {
5 | plumber_data *pd = ud;
6 | SPFLOAT trig;
7 | SPFLOAT out;
8 | SPFLOAT min;
9 | SPFLOAT max;
10 | sp_trand *trand;
11 |
12 | switch(pd->mode) {
13 | case PLUMBER_CREATE:
14 |
15 | #ifdef DEBUG_MODE
16 | plumber_print(pd, "trand: Creating\n");
17 | #endif
18 |
19 | sp_trand_create(&trand);
20 | plumber_add_ugen(pd, SPORTH_TRAND, trand);
21 | if(sporth_check_args(stack, "fff") != SPORTH_OK) {
22 | plumber_print(pd,"Not enough arguments for trand\n");
23 | stack->error++;
24 | return PLUMBER_NOTOK;
25 | }
26 | max = sporth_stack_pop_float(stack);
27 | min = sporth_stack_pop_float(stack);
28 | trig = sporth_stack_pop_float(stack);
29 | sporth_stack_push_float(stack, 0);
30 | break;
31 | case PLUMBER_INIT:
32 |
33 | #ifdef DEBUG_MODE
34 | plumber_print(pd, "trand: Initialising\n");
35 | #endif
36 | max = sporth_stack_pop_float(stack);
37 | min = sporth_stack_pop_float(stack);
38 | trig = sporth_stack_pop_float(stack);
39 | trand = pd->last->ud;
40 | sp_trand_init(pd->sp, trand);
41 | sporth_stack_push_float(stack, 0);
42 | break;
43 | case PLUMBER_COMPUTE:
44 | max = sporth_stack_pop_float(stack);
45 | min = sporth_stack_pop_float(stack);
46 | trig = sporth_stack_pop_float(stack);
47 | trand = pd->last->ud;
48 | trand->min = min;
49 | trand->max = max;
50 | sp_trand_compute(pd->sp, trand, &trig, &out);
51 | sporth_stack_push_float(stack, out);
52 | break;
53 | case PLUMBER_DESTROY:
54 | trand = pd->last->ud;
55 | sp_trand_destroy(&trand);
56 | break;
57 | default:
58 | plumber_print(pd, "trand: Unknown mode!\n");
59 | break;
60 | }
61 | return PLUMBER_OK;
62 | }
63 |
--------------------------------------------------------------------------------
/Sources/Sporth/ugens/comb.c:
--------------------------------------------------------------------------------
1 | #include "plumber.h"
2 |
3 | int sporth_comb(sporth_stack *stack, void *ud)
4 | {
5 | plumber_data *pd = ud;
6 | SPFLOAT input;
7 | SPFLOAT out;
8 | SPFLOAT looptime;
9 | SPFLOAT revtime;
10 | sp_comb *comb;
11 |
12 | switch(pd->mode) {
13 | case PLUMBER_CREATE:
14 |
15 | #ifdef DEBUG_MODE
16 | plumber_print(pd, "comb: Creating\n");
17 | #endif
18 |
19 | sp_comb_create(&comb);
20 | plumber_add_ugen(pd, SPORTH_COMB, comb);
21 | if(sporth_check_args(stack, "fff") != SPORTH_OK) {
22 | plumber_print(pd,"Not enough arguments for comb\n");
23 | stack->error++;
24 | return PLUMBER_NOTOK;
25 | }
26 | looptime = sporth_stack_pop_float(stack);
27 | revtime = sporth_stack_pop_float(stack);
28 | input = sporth_stack_pop_float(stack);
29 | sporth_stack_push_float(stack, 0);
30 | break;
31 | case PLUMBER_INIT:
32 |
33 | #ifdef DEBUG_MODE
34 | plumber_print(pd, "comb: Initialising\n");
35 | #endif
36 |
37 | looptime = sporth_stack_pop_float(stack);
38 | revtime = sporth_stack_pop_float(stack);
39 | input = sporth_stack_pop_float(stack);
40 | comb = pd->last->ud;
41 | sp_comb_init(pd->sp, comb, looptime);
42 | sporth_stack_push_float(stack, 0);
43 | break;
44 | case PLUMBER_COMPUTE:
45 | looptime = sporth_stack_pop_float(stack);
46 | revtime = sporth_stack_pop_float(stack);
47 | input = sporth_stack_pop_float(stack);
48 | comb = pd->last->ud;
49 | comb->revtime = revtime;
50 | sp_comb_compute(pd->sp, comb, &input, &out);
51 | sporth_stack_push_float(stack, out);
52 | break;
53 | case PLUMBER_DESTROY:
54 | comb = pd->last->ud;
55 | sp_comb_destroy(&comb);
56 | break;
57 | default:
58 | plumber_print(pd, "comb: Unknown mode!\n");
59 | break;
60 | }
61 | return PLUMBER_OK;
62 | }
63 |
--------------------------------------------------------------------------------
/Sources/Sporth/ugens/tenv2.c:
--------------------------------------------------------------------------------
1 | #include "plumber.h"
2 |
3 | int sporth_tenv2(sporth_stack *stack, void *ud)
4 | {
5 | plumber_data *pd = ud;
6 | SPFLOAT trig;
7 | SPFLOAT out;
8 | SPFLOAT atk;
9 | SPFLOAT rel;
10 | sp_tenv2 *tenv2;
11 |
12 | switch(pd->mode) {
13 | case PLUMBER_CREATE:
14 |
15 | #ifdef DEBUG_MODE
16 | plumber_print(pd, "tenv2: Creating\n");
17 | #endif
18 |
19 | sp_tenv2_create(&tenv2);
20 | plumber_add_ugen(pd, SPORTH_TENV2, tenv2);
21 | if(sporth_check_args(stack, "fff") != SPORTH_OK) {
22 | plumber_print(pd,"Not enough arguments for tenv2\n");
23 | stack->error++;
24 | return PLUMBER_NOTOK;
25 | }
26 | rel = sporth_stack_pop_float(stack);
27 | atk = sporth_stack_pop_float(stack);
28 | trig = sporth_stack_pop_float(stack);
29 | sporth_stack_push_float(stack, 0);
30 | break;
31 | case PLUMBER_INIT:
32 |
33 | #ifdef DEBUG_MODE
34 | plumber_print(pd, "tenv2: Initialising\n");
35 | #endif
36 |
37 | rel = sporth_stack_pop_float(stack);
38 | atk = sporth_stack_pop_float(stack);
39 | trig = sporth_stack_pop_float(stack);
40 | tenv2 = pd->last->ud;
41 | sp_tenv2_init(pd->sp, tenv2);
42 | sporth_stack_push_float(stack, 0);
43 | break;
44 | case PLUMBER_COMPUTE:
45 | rel = sporth_stack_pop_float(stack);
46 | atk = sporth_stack_pop_float(stack);
47 | trig = sporth_stack_pop_float(stack);
48 | tenv2 = pd->last->ud;
49 | tenv2->atk = atk;
50 | tenv2->rel = rel;
51 | sp_tenv2_compute(pd->sp, tenv2, &trig, &out);
52 | sporth_stack_push_float(stack, out);
53 | break;
54 | case PLUMBER_DESTROY:
55 | tenv2 = pd->last->ud;
56 | sp_tenv2_destroy(&tenv2);
57 | break;
58 | default:
59 | plumber_print(pd, "tenv2: Unknown mode!\n");
60 | break;
61 | }
62 | return PLUMBER_OK;
63 | }
64 |
--------------------------------------------------------------------------------
/Sources/Sporth/hash.c:
--------------------------------------------------------------------------------
1 | #include