|
diff --git a/Makefile b/Makefile
|
| ... |
| 3 |
$(CC) -Wall example2.c minisdl_audio.c -lm -ldl -lpthread -o example2 |
3 |
$(CC) -Wall example2.c minisdl_audio.c -lm -ldl -lpthread -o example2 |
| 4 |
$(CC) -Wall example3.c -L./portmidi -lportmidi -o example3 |
4 |
$(CC) -Wall example3.c -L./portmidi -lportmidi -o example3 |
| 5 |
|
5 |
|
| 6 |
run-example3: |
6 |
run-example3: tests |
| 7 |
LD_LIBRARY_PATH=./portmidi ./example3 |
7 |
LD_LIBRARY_PATH=./portmidi ./example3 |
|
|
8 |
|
|
|
9 |
run-example4: |
|
|
10 |
$(CC) example4.c -lasound -lm -o example4 && ./example4 |
| 8 |
|
11 |
|
| 9 |
build-portmidi: |
12 |
build-portmidi: |
| 10 |
cd portmidi && cmake . && make |
13 |
cd portmidi && cmake . && make |
|
diff --git a/README.md b/README.md
|
| 1 |
# Tiny terminal DAW |
1 |
# Tiny terminal DAW |
| 2 |
|
2 |
|
|
|
3 |
`ttdaw` is a tiny terminal based digital audio workstation made for fun and |
|
|
4 |
experimentation and learning more about audio and MIDI in general. |
|
|
5 |
|
|
|
6 |
## Documentations |
|
|
7 |
|
|
|
8 |
- https://developer.apple.com/documentation/coremidi |
|
|
9 |
- https://www.alsa-project.org/alsa-doc/alsa-lib/seq.html |
|
|
10 |
|
|
|
11 |
## Reading material |
|
|
12 |
|
|
|
13 |
- https://www.izotope.com/en/learn/fundamental-frequency-harmonics.html |
|
|
14 |
|
| 3 |
## Soundfonts |
15 |
## Soundfonts |
| 4 |
|
16 |
|
| 5 |
- https://dev.nando.audio/pages/soundfonts.html |
17 |
- https://dev.nando.audio/pages/soundfonts.html |
| ... |
|
diff --git a/example3.c b/example3.c
|
| ... |
| 20 |
} |
20 |
} |
| 21 |
|
21 |
|
| 22 |
/* // Open a MIDI input device */ |
22 |
/* // Open a MIDI input device */ |
| 23 |
/* stream = Pm_OpenInput(&err, NULL, NULL, NUM_INPUTS, NULL, 0); */ |
23 |
stream = (PortMidiStream *)Pm_OpenInput(&err, NULL, NULL, NUM_INPUTS, NULL, 0); |
| 24 |
/* if (err != pmNoError) { */ |
24 |
if (err != pmNoError) { |
| 25 |
/* fprintf(stderr, "Error opening MIDI input device: %s\n", Pm_GetErrorText(err)); */ |
25 |
fprintf(stderr, "Error opening MIDI input device: %s\n", Pm_GetErrorText(err)); |
| 26 |
/* Pm_Terminate(); */ |
26 |
Pm_Terminate(); |
| 27 |
/* exit(1); */ |
27 |
exit(1); |
| 28 |
/* } */ |
28 |
} |
| 29 |
|
29 |
|
| 30 |
/* // Read MIDI messages from the input device */ |
30 |
/* // Read MIDI messages from the input device */ |
| 31 |
/* while (1) { */ |
31 |
/* while (1) { */ |
| ... |
| 43 |
/* } */ |
43 |
/* } */ |
| 44 |
|
44 |
|
| 45 |
/* // Close the MIDI input device */ |
45 |
/* // Close the MIDI input device */ |
| 46 |
/* Pm_Close(stream); */ |
46 |
Pm_Close(stream); |
| 47 |
|
47 |
|
| 48 |
// Terminate PortMIDI |
48 |
// Terminate PortMIDI |
| 49 |
Pm_Terminate(); |
49 |
Pm_Terminate(); |
| ... |
|
diff --git a/example4.c b/example4.c
|
|
|
1 |
#include <stdio.h> |
|
|
2 |
#include <stdlib.h> |
|
|
3 |
#include <alsa/asoundlib.h> |
|
|
4 |
|
|
|
5 |
#define CLIENT_NAME "ttdaw" |
|
|
6 |
#define MAX_MIDI_PORTS 4 |
|
|
7 |
|
|
|
8 |
static snd_seq_t *seq_handle; |
|
|
9 |
static snd_seq_addr_t *ports; |
|
|
10 |
static int rate = 44100; |
|
|
11 |
|
|
|
12 |
int main(void) { |
|
|
13 |
fprintf(stdout, "Example: Reading MIDI input\n"); |
|
|
14 |
|
|
|
15 |
snd_seq_t *seq_handle; |
|
|
16 |
|
|
|
17 |
if (snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { |
|
|
18 |
fprintf(stderr, "Error opening ALSA sequencer.\n"); |
|
|
19 |
exit(1); |
|
|
20 |
} |
|
|
21 |
|
|
|
22 |
if (snd_seq_set_client_name(seq_handle, CLIENT_NAME) < 0) { |
|
|
23 |
fprintf(stderr, "Could not set up client name.\n"); |
|
|
24 |
exit(1); |
|
|
25 |
} |
|
|
26 |
|
|
|
27 |
if (snd_seq_create_simple_port(seq_handle, CLIENT_NAME, |
|
|
28 |
SND_SEQ_PORT_CAP_WRITE | |
|
|
29 |
SND_SEQ_PORT_CAP_SUBS_WRITE, |
|
|
30 |
SND_SEQ_PORT_TYPE_MIDI_GENERIC | |
|
|
31 |
SND_SEQ_PORT_TYPE_APPLICATION) < 0) { |
|
|
32 |
fprintf(stderr, "Error creating sequencer port.\n"); |
|
|
33 |
exit(1); |
|
|
34 |
} |
|
|
35 |
|
|
|
36 |
char *port_name = "28:0"; |
|
|
37 |
if (snd_seq_parse_address(seq_handle, &ports[0], port_name) < 0) { |
|
|
38 |
fprintf(stderr, "Invalid port %s.\n", port_name); |
|
|
39 |
exit(1); |
|
|
40 |
} |
|
|
41 |
|
|
|
42 |
// Connecting ports. |
|
|
43 |
for (int i = 0; i < MAX_MIDI_PORTS; ++i) { |
|
|
44 |
int err = snd_seq_connect_from(seq_handle, 0, ports[i].client, ports[i].port); |
|
|
45 |
if (err < 0) { |
|
|
46 |
fprintf(stderr, "Cannot connect from port %d:%d - %s", ports[i].client, ports[i].port, snd_strerror(err)); |
|
|
47 |
exit(1); |
|
|
48 |
} |
|
|
49 |
} |
|
|
50 |
|
|
|
51 |
snd_seq_close(seq_handle); |
|
|
52 |
return 0; |
|
|
53 |
} |
|
|
54 |
|