aboutsummaryrefslogtreecommitdiff
path: root/core/qmpmidimapperrtmidi.cpp
blob: 263cada192f0f0793ff1ad907670a30d42511d17 (plain) (blame)
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
#include <cstdio>
#include <cstring>
#include <vector>
#include RT_MIDI_H
#include "qmpmidimappers.hpp"
RtMidiOut* qmpMidiMapperRtMidi::dummy=NULL;
qmpMidiMapperRtMidi::qmpMidiMapperRtMidi()
{
	try{dummy=new RtMidiOut();}
	catch(RtMidiError &e)
	{
		printf("Failed to initialize the dummy device: %s\n",e.what());
		dummy=NULL;
	}
	memset(ports,0,sizeof(ports));
}
qmpMidiMapperRtMidi::~qmpMidiMapperRtMidi()
{
	delete dummy;dummy=NULL;
	for(int i=0;i<16;++i)if(ports[i])delete ports[i];
}
int qmpMidiMapperRtMidi::enumDevices()
{
	return dummy?dummy->getPortCount():0;
}
std::string qmpMidiMapperRtMidi::deviceName(int id)
{
	return dummy?dummy->getPortName(id):"";
}
int qmpMidiMapperRtMidi::deviceInit(int id)
{
	int i=0;for(;ports[i]&&i<16;++i);
	if(i==16)return -1;
	try
	{
		ports[i]=new RtMidiOut();
		ports[i]->openPort(id);
	}
	catch(RtMidiError &e)
	{
		printf("Device initialization failure: %s\n",e.what());
		ports[i]=NULL;
		return -1;
	}
	return i;
}
void qmpMidiMapperRtMidi::deviceDeinit(int iid)
{
	if(ports[iid]){ports[iid]->closePort();delete ports[iid];ports[iid]=NULL;}
}
void qmpMidiMapperRtMidi::noteOn(int iid,int ch,int key,int vel)
{
	if(!ports[iid])return;ch&=0x0F;
	std::vector<unsigned char>message;
	message.push_back(0x90|ch);
	message.push_back(key);
	message.push_back(vel);
	ports[iid]->sendMessage(&message);
}
void qmpMidiMapperRtMidi::noteOff(int iid,int ch,int key)
{
	if(!ports[iid])return;ch&=0x0F;
	std::vector<unsigned char>message;
	message.push_back(0x80|ch);message.push_back(key);message.push_back(0);
	ports[iid]->sendMessage(&message);
}
void qmpMidiMapperRtMidi::ctrlChange(int iid,int ch,int cc,int val)
{
	if(!ports[iid])return;ch&=0x0F;
	std::vector<unsigned char>message;
	message.push_back(0xB0|ch);message.push_back(cc);message.push_back(val);
	ports[iid]->sendMessage(&message);
}
void qmpMidiMapperRtMidi::progChange(int iid,int ch,int val)
{
	if(!ports[iid])return;ch&=0x0F;
	std::vector<unsigned char>message;
	message.push_back(0xC0|ch);message.push_back(val);
	ports[iid]->sendMessage(&message);
}
void qmpMidiMapperRtMidi::pitchBend(int iid,int ch,int val)
{
	if(!ports[iid])return;ch&=0x0F;
	std::vector<unsigned char>message;
	message.push_back(0xE0|ch);message.push_back(val&0x7F);
	message.push_back(val>>7);ports[iid]->sendMessage(&message);
}
void qmpMidiMapperRtMidi::sysEx(int iid,int length,const char *data)
{
	if(!ports[iid])return;
	std::vector<unsigned char>message(data,data+length);
	ports[iid]->sendMessage(&message);
}
void qmpMidiMapperRtMidi::panic(int iid,int ch)
{
	//maybe all notes off is more close to panic?
	pitchBend(iid,ch,8192);
	ctrlChange(iid,ch,120,0);
	//ctrlChange(iid,ch,123,0);
}
void qmpMidiMapperRtMidi::reset(int iid,int ch)
{
	ctrlChange(iid,ch,120,0);
	ctrlChange(iid,ch,121,0);
}