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; |
209 |
atomic_set( &(p->pCCValue)[Controller], Value ); |
atomic_set( &(p->pCCValue)[Controller], Value ); |
210 |
atomic_inc( &(p->pCCChanged)[Controller] ); |
atomic_inc( &(p->pCCChanged)[Controller] ); |
211 |
atomic_inc( &p->ccsChanged ); |
atomic_inc( &p->ccsChanged ); |
212 |
|
if (Controller == 120 /* all sound off */ || |
213 |
|
Controller == 123 /* all notes off */) |
214 |
|
p->resetNotes(); |
215 |
|
} |
216 |
|
|
217 |
|
void VirtualMidiDevice::Reset() { |
218 |
|
p->resetNotes(); |
219 |
|
p->resetCCs(); |
220 |
} |
} |
221 |
|
|
222 |
} // namespace LinuxSampler |
} // namespace LinuxSampler |