1 |
/* |
/* |
2 |
Copyright (C) 2008 - 2014 Christian Schoenebeck |
Copyright (C) 2008 - 2021 Christian Schoenebeck |
3 |
*/ |
*/ |
4 |
|
|
5 |
#include "VirtualMidiDevice.h" |
#include "VirtualMidiDevice.h" |
15 |
// by mouse (and the user not being Billy the Kid) |
// by mouse (and the user not being Billy the Kid) |
16 |
#define MAX_EVENTS 12 |
#define MAX_EVENTS 12 |
17 |
|
|
18 |
|
#define DEFAULT_CC_VALUE 0 |
19 |
|
#define DEFAULT_VELOCITY 127 |
20 |
|
|
21 |
namespace LinuxSampler { |
namespace LinuxSampler { |
22 |
|
|
23 |
struct VirtualMidiDevice::private_data_t { |
struct VirtualMidiDevice::private_data_t { |
32 |
RingBuffer<VirtualMidiDevice::event_t,false> events; |
RingBuffer<VirtualMidiDevice::event_t,false> events; |
33 |
|
|
34 |
private_data_t() : events(MAX_EVENTS, 0) {} |
private_data_t() : events(MAX_EVENTS, 0) {} |
35 |
|
|
36 |
|
void resetNotes() { |
37 |
|
for (int i = 0; i < MIDI_KEYS; i++) { |
38 |
|
atomic_set( &pNoteOnVelocity[i], DEFAULT_VELOCITY ); |
39 |
|
atomic_set( &pNoteOffVelocity[i], DEFAULT_VELOCITY ); |
40 |
|
atomic_set( &pNoteIsActive[i], 0 ); |
41 |
|
// should be non zero, because we changed the state above, that |
42 |
|
// way forcing the virtual MIDI device user (e.g. UI) to refresh |
43 |
|
atomic_inc( &pNoteChanged[i] ); |
44 |
|
} |
45 |
|
// this should also be non zero, for the same reason as above |
46 |
|
atomic_inc( ¬esChanged ); |
47 |
|
} |
48 |
|
|
49 |
|
void resetCCs() { |
50 |
|
for (int i = 0; i < MIDI_CONTROLLERS; i++) { |
51 |
|
atomic_set( &pCCValue[i], DEFAULT_CC_VALUE ); |
52 |
|
// should be non zero, because we changed the state above, that |
53 |
|
// way forcing the virtual MIDI device user (e.g. UI) to refresh |
54 |
|
atomic_inc( &pCCChanged[i] ); |
55 |
|
} |
56 |
|
// this should also be non zero, for the same reason as above |
57 |
|
atomic_inc( &ccsChanged ); |
58 |
|
} |
59 |
}; |
}; |
60 |
|
|
61 |
VirtualMidiDevice::VirtualMidiDevice() : p(new private_data_t) { |
VirtualMidiDevice::VirtualMidiDevice() : p(new private_data_t) { |
109 |
return true; |
return true; |
110 |
} |
} |
111 |
|
|
112 |
|
bool VirtualMidiDevice::SendChannelPressureToSampler(uint8_t Pressure) { |
113 |
|
if (Pressure > 127) return false; |
114 |
|
event_t ev = { EVENT_TYPE_CHPRESSURE, 128 /*actually ignored by engine*/, Pressure }; |
115 |
|
if (p->events.write_space() <= 0) return false; |
116 |
|
p->events.push(&ev); |
117 |
|
return true; |
118 |
|
} |
119 |
|
|
120 |
bool VirtualMidiDevice::SendPitchBendToSampler(int Pitch) { |
bool VirtualMidiDevice::SendPitchBendToSampler(int Pitch) { |
121 |
if (Pitch < -8192 || Pitch > 8191) return false; |
if (Pitch < -8192 || Pitch > 8191) return false; |
122 |
Pitch += 8192; |
Pitch += 8192; |
123 |
// order: LSB, MSB like it would be in a regular pitch bend MIDI message |
// order: LSB, MSB like it would be in a regular pitch bend MIDI message |
124 |
event_t ev = { EVENT_TYPE_PITCHBEND, Pitch & 0x7f, (Pitch >> 7) & 0x7f }; |
event_t ev = { |
125 |
|
EVENT_TYPE_PITCHBEND, |
126 |
|
static_cast<uint8_t>(Pitch & 0x7f), |
127 |
|
static_cast<uint8_t>((Pitch >> 7) & 0x7f) |
128 |
|
}; |
129 |
if (p->events.write_space() <= 0) return false; |
if (p->events.write_space() <= 0) return false; |
130 |
p->events.push(&ev); |
p->events.push(&ev); |
131 |
return true; |
return true; |
132 |
} |
} |
133 |
|
|
134 |
bool VirtualMidiDevice::SendProgramChangeToSampler(int Program) { |
bool VirtualMidiDevice::SendProgramChangeToSampler(uint8_t Program) { |
135 |
if (Program < 0 || Program > 127) return false; |
if (Program > 127) return false; |
136 |
event_t ev = { EVENT_TYPE_PROGRAM, Program, 0 }; |
event_t ev = { EVENT_TYPE_PROGRAM, Program, 0 }; |
137 |
if (p->events.write_space() <= 0) return false; |
if (p->events.write_space() <= 0) return false; |
138 |
p->events.push(&ev); |
p->events.push(&ev); |
211 |
atomic_inc( &p->ccsChanged ); |
atomic_inc( &p->ccsChanged ); |
212 |
} |
} |
213 |
|
|
214 |
|
void VirtualMidiDevice::Reset() { |
215 |
|
p->resetNotes(); |
216 |
|
p->resetCCs(); |
217 |
|
} |
218 |
|
|
219 |
} // namespace LinuxSampler |
} // namespace LinuxSampler |