Root/midi2osc/midi2osc.c

Source at commit 102033aab573ce0c75b1832035aedaf0e33df448 created 7 years 10 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
24static 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
58static void usage(const char *name)
59{
60    fprintf(stderr, "usage: %s hostname [port]\n", name);
61    exit(1);
62}
63
64
65int 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

Archive Download this file

Branches:
master



interactive