Added ALSA MIDI example

Author Mitja Felicijan <mitja.felicijan@gmail.com> 2024-10-07 17:41:54 +0200
Committer Mitja Felicijan <mitja.felicijan@gmail.com> 2024-10-07 17:41:54 +0200
Commit 1eeba03da0222a117054eca53e7be8ee1e8bd970 (patch)
-rw-r--r-- .gitignore 1
-rw-r--r-- Makefile 5
-rw-r--r-- README.md 12
-rw-r--r-- example3.c 14
-rw-r--r-- example4.c 54
5 files changed, 78 insertions, 8 deletions
diff --git a/.gitignore b/.gitignore
1
example1
1
example1
2
example2
2
example2
3
example3
3
example3
  
4
example4
4
  
5
  
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