Werner's Miscellanea
Sign in or create your account | Project List | Help
Werner's Miscellanea Git Source Tree
Root/
Source at commit 102033aab573ce0c75b1832035aedaf0e33df448 created 12 years 4 months ago. By Werner Almesberger, midi2osc/: simple MIDI to OSC forwarder | |
---|---|
1 | /* |
2 | * midi2osc.c - MIDI to OSC forwarder |
3 | * |
4 | * Written 2011 by Werner Almesberger |
5 | * Copyright 2011 Werner Almesberger |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. |
11 | */ |
12 | |
13 | |
14 | #include <stdint.h> |
15 | #include <stdlib.h> |
16 | #include <stdio.h> |
17 | #include <alsa/asoundlib.h> |
18 | #include "lo/lo.h" |
19 | |
20 | |
21 | #define NAME "midi2osc" |
22 | |
23 | |
24 | static void forward(snd_seq_t *midi, lo_address osc) |
25 | { |
26 | snd_seq_event_t *ev; |
27 | uint8_t msg[4] = { 0, }; |
28 | |
29 | while (snd_seq_event_input(midi, &ev)) { |
30 | switch (ev->type) { |
31 | case SND_SEQ_EVENT_NOTEON: |
32 | msg[1] = 0x90 | ev->data.control.channel; |
33 | msg[2] = ev->data.note.note; |
34 | msg[3] = ev->data.note.velocity; |
35 | break; |
36 | case SND_SEQ_EVENT_CONTROLLER: |
37 | msg[1] = 0xb0 | ev->data.control.channel; |
38 | msg[2] = ev->data.control.param; |
39 | msg[3] = ev->data.control.value; |
40 | break; |
41 | case SND_SEQ_EVENT_PITCHBEND: |
42 | msg[1] = 0xe0 | ev->data.control.channel; |
43 | msg[2] = ev->data.control.value; |
44 | msg[3] = 0; |
45 | break; |
46 | default: |
47 | /* Flickernoise currently doesn't support any others */ |
48 | snd_seq_free_event(ev); |
49 | continue; |
50 | } |
51 | if (lo_send(osc, "/midi", "m", msg) < 0) |
52 | fprintf(stderr, "%s\n", lo_address_errstr(osc)); |
53 | snd_seq_free_event(ev); |
54 | } |
55 | } |
56 | |
57 | |
58 | static void usage(const char *name) |
59 | { |
60 | fprintf(stderr, "usage: %s hostname [port]\n", name); |
61 | exit(1); |
62 | } |
63 | |
64 | |
65 | int main(int argc, char **argv) |
66 | { |
67 | const char *port = "4444"; /* Milkymist One OSC port */ |
68 | lo_address osc; |
69 | snd_seq_t *midi; |
70 | |
71 | switch (argc) { |
72 | case 2: |
73 | break; |
74 | case 3: |
75 | port = argv[2]; |
76 | break; |
77 | default: |
78 | usage(*argv); |
79 | } |
80 | |
81 | osc = lo_address_new(argv[1], port); |
82 | if (!osc) { |
83 | fprintf(stderr, "invalid address %s %s\n", argv[1], port); |
84 | exit(1); |
85 | } |
86 | |
87 | if (snd_seq_open(&midi, "hw", SND_SEQ_OPEN_INPUT,0) < 0) { |
88 | fprintf(stderr, "can't open ALSA sequencer\n"); |
89 | exit(1); |
90 | } |
91 | snd_seq_set_client_name(midi, NAME); |
92 | if (snd_seq_create_simple_port(midi, NAME, |
93 | SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, |
94 | SND_SEQ_PORT_TYPE_APPLICATION) < 0) { |
95 | fprintf(stderr, "can't create sequencer port\n"); |
96 | exit(1); |
97 | } |
98 | |
99 | forward(midi, osc); |
100 | |
101 | return 0; |
102 | } |
103 |
Branches:
master