-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMidiOutput.cpp
More file actions
114 lines (90 loc) · 2.82 KB
/
MidiOutput.cpp
File metadata and controls
114 lines (90 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "MidiOutput.h"
#include <stdio.h>
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
/*
https://www.midi.org/specifications/item/table-1-summary-of-midi-message
*/
MidiOutput::MidiOutput(){
}
MidiOutput::~MidiOutput(){
}
void MidiOutput::openDevice(const char* device) {
// open midi device
midifd = open(device, O_WRONLY, 0);
if (midifd < 0) {
std::cout << "MidiOutput: Error: cannot open midi device " << device << "\n";
} else {
std::cout << "MidiOutput: opened midi device " << device << "\n";
}
}
int MidiOutput::parseInt(const char* a, int offset) {
int sign, n, c;
c = 0;
n = 0;
if (a[offset] == '-') { // Handle negative integers
sign = -1;
offset++;
} else {
sign = 1;
}
while(a[offset]!='/' && offset<strlen(a)){
n = n * 10 + a[offset] - '0';
offset++;
c++;
}
if (sign == -1) {
n = -n;
}
return n;
}
void MidiOutput::message(const char* path, int offset, float value) {
if (midifd>0 && false) {
std::cout << "ignoring midi message, no output";
}
//parse midi channel
int channel = parseInt(path, offset);
offset += channel<10?1:channel<100?2:3;
if (strncmp(path+offset, "/cc/", 3)==0) {
offset += 4;
int number = parseInt(path, offset);
//std::cout << "channel:" << channel << " cc:" << number << " value:"<< value << " \n" ;
cc(channel,number,value);
} else if (strncmp(path+offset, "/noteOn/", 8)==0) {
offset += 8;
int note = parseInt(path, offset);
//std::cout << "channel:" << channel << " noteOn:" << note << " value:"<< value << " \n" ;
noteOn(channel,note,value);
} else if (strncmp(path+offset, "/noteOff/", 9)==0) {
offset += 9;
int note = parseInt(path, offset);
//std::cout << "channel:" << channel << " noteOff:" << note << " value:"<< value << " \n" ;
noteOff(channel,note,value);
} else {
std::cout << "unknown message '" << path << "' \n" ;
}
}
void MidiOutput::noteOn(int channel, int note, int velocity) {
unsigned char packet[3];
packet[0] = 0b10010000+(char)(channel-1); //1011=cc. 1001=noteOn, 1000=noteOff
packet[1] = (unsigned int) (note-1); //note / cc
packet[2] = (unsigned int) velocity; //(unsigned int) value
write(midifd, &packet, 3);
}
void MidiOutput::noteOff(int channel, int note, int velocity){
unsigned char packet[3];
packet[0] = 0b10000000+(char)(channel-1); //1011=cc. 1001=noteOn, 1000=noteOff
packet[1] = (unsigned int) (note-1); //note / cc
packet[2] = (unsigned int) velocity; //(unsigned int) value
write(midifd, &packet, 3);
}
void MidiOutput::cc(int channel, int number, int value){
unsigned char packet[3];
packet[0] = 0b10110000+(char)(channel-1); //1011=cc. 1001=noteOn, 1000=noteOff
packet[1] = (unsigned int) (number-1); //note / cc
packet[2] = (unsigned int) value; //(unsigned int) value
write(midifd, &packet, 3);
}