/[svn]/linuxsampler/trunk/src/drivers/midi/VirtualMidiDevice.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/drivers/midi/VirtualMidiDevice.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2025 - (hide annotations) (download)
Sun Nov 1 18:47:59 2009 UTC (14 years, 5 months ago) by schoenebeck
File size: 5096 byte(s)
* added support for sending MIDI CC messages via LSCP command
  "SEND CHANNEL MIDI_DATA CC <sampler-chan> <ctrl> <val>"

1 schoenebeck 1659 /*
2 schoenebeck 2025 Copyright (C) 2008 - 2009 Christian Schoenebeck
3 schoenebeck 1659 */
4    
5     #include "VirtualMidiDevice.h"
6    
7     #include "../../common/global_private.h"
8     #include "../../common/atomic.h"
9     #include "../../common/RingBuffer.h"
10    
11 schoenebeck 2025 #define MIDI_KEYS 128
12     #define MIDI_CONTROLLERS 128
13 schoenebeck 1659
14     // assuming VirtualMidiDevice implementation is only controlled
15     // by mouse (and the user not being Billy the Kid)
16     #define MAX_EVENTS 12
17    
18     namespace LinuxSampler {
19    
20 persson 1896 struct VirtualMidiDevice::private_data_t {
21 schoenebeck 1659 atomic_t notesChanged; // whether some key changed at all
22     atomic_t pNoteChanged[MIDI_KEYS]; // which key(s) changed
23     atomic_t pNoteIsActive[MIDI_KEYS]; // status of each key (either active or inactive)
24 schoenebeck 1663 atomic_t pNoteOnVelocity[MIDI_KEYS];
25     atomic_t pNoteOffVelocity[MIDI_KEYS];
26 schoenebeck 2025 atomic_t ccsChanged; // whether some controller changed at all
27     atomic_t pCCChanged[MIDI_CONTROLLERS]; // which controller(s) changed
28     atomic_t pCCValue[MIDI_CONTROLLERS]; // current value of each controller
29 schoenebeck 1659 RingBuffer<VirtualMidiDevice::event_t,false> events;
30    
31 persson 1896 private_data_t() : events(MAX_EVENTS, 0) {}
32 schoenebeck 1659 };
33    
34 persson 1896 VirtualMidiDevice::VirtualMidiDevice() : p(new private_data_t) {
35 schoenebeck 1659 atomic_t zero = ATOMIC_INIT(0);
36 schoenebeck 1663 atomic_t defaultVelocity = ATOMIC_INIT(127);
37 schoenebeck 2025 atomic_t defaultCCValue = ATOMIC_INIT(0);
38 schoenebeck 1659 p->notesChanged = zero;
39 schoenebeck 2025 p->ccsChanged = zero;
40 schoenebeck 1659 for (int i = 0; i < MIDI_KEYS; i++) {
41     p->pNoteChanged[i] = zero;
42     p->pNoteIsActive[i] = zero;
43 schoenebeck 1663 p->pNoteOnVelocity[i] = defaultVelocity;
44     p->pNoteOffVelocity[i] = defaultVelocity;
45 schoenebeck 2025 p->pCCChanged[i] = zero;
46     p->pCCValue[i] = defaultCCValue;
47 schoenebeck 1659 }
48     }
49    
50     VirtualMidiDevice::~VirtualMidiDevice() {
51 persson 1896 delete p;
52 schoenebeck 1659 }
53    
54     bool VirtualMidiDevice::SendNoteOnToSampler(uint8_t Key, uint8_t Velocity) {
55     if (Key >= MIDI_KEYS || Velocity > 127) return false;
56     event_t ev = { EVENT_TYPE_NOTEON, Key, Velocity };
57     if (p->events.write_space() <= 0) return false;
58     p->events.push(&ev);
59     return true;
60     }
61    
62     bool VirtualMidiDevice::SendNoteOffToSampler(uint8_t Key, uint8_t Velocity) {
63     if (Key >= MIDI_KEYS || Velocity > 127) return false;
64     event_t ev = { EVENT_TYPE_NOTEOFF, Key, Velocity };
65     if (p->events.write_space() <= 0) return false;
66     p->events.push(&ev);
67     return true;
68     }
69 schoenebeck 2025
70     bool VirtualMidiDevice::SendCCToSampler(uint8_t Controller, uint8_t Value) {
71     if (Controller >= MIDI_CONTROLLERS || Value > 127) return false;
72     event_t ev = { EVENT_TYPE_CC, Controller, Value };
73     if (p->events.write_space() <= 0) return false;
74     p->events.push(&ev);
75     return true;
76     }
77 schoenebeck 1659
78     bool VirtualMidiDevice::GetMidiEventFromDevice(event_t& Event) {
79     return (p->events.pop(&Event) > 0);
80     }
81    
82     bool VirtualMidiDevice::NotesChanged() {
83     int c = atomic_read( &p->notesChanged );
84     atomic_sub(c, &p->notesChanged );
85     return c;
86     }
87 schoenebeck 2025
88     bool VirtualMidiDevice::ControllersChanged() {
89     int c = atomic_read( &p->ccsChanged );
90     atomic_sub(c, &p->ccsChanged );
91     return c;
92     }
93 schoenebeck 1659
94     bool VirtualMidiDevice::NoteChanged(uint8_t Key) {
95     int c = atomic_read( &(p->pNoteChanged)[Key] );
96     atomic_sub(c, &(p->pNoteChanged)[Key] );
97     return c;
98     }
99 schoenebeck 2025
100     bool VirtualMidiDevice::ControllerChanged(uint8_t Controller) {
101     int c = atomic_read( &(p->pCCChanged)[Controller] );
102     atomic_sub(c, &(p->pCCChanged)[Controller] );
103     return c;
104     }
105 schoenebeck 1659
106     bool VirtualMidiDevice::NoteIsActive(uint8_t Key) {
107     return atomic_read( &(p->pNoteIsActive)[Key] );
108     }
109    
110 schoenebeck 1663 uint8_t VirtualMidiDevice::NoteOnVelocity(uint8_t Key) {
111     return atomic_read( &(p->pNoteOnVelocity)[Key] );
112     }
113    
114     uint8_t VirtualMidiDevice::NoteOffVelocity(uint8_t Key) {
115     return atomic_read( &(p->pNoteOffVelocity)[Key] );
116     }
117 schoenebeck 2025
118     uint8_t VirtualMidiDevice::ControllerValue(uint8_t Controller) {
119     return atomic_read( &(p->pCCValue)[Controller] );
120     }
121 schoenebeck 1663
122     void VirtualMidiDevice::SendNoteOnToDevice(uint8_t Key, uint8_t Velocity) {
123 schoenebeck 1659 if (Key >= MIDI_KEYS) return;
124 schoenebeck 1663 atomic_set( &(p->pNoteOnVelocity)[Key], Velocity );
125 schoenebeck 1659 atomic_inc( &(p->pNoteIsActive)[Key] );
126     atomic_inc( &(p->pNoteChanged)[Key] );
127     atomic_inc( &p->notesChanged );
128     }
129    
130 schoenebeck 1663 void VirtualMidiDevice::SendNoteOffToDevice(uint8_t Key, uint8_t Velocity) {
131 schoenebeck 1659 if (Key >= MIDI_KEYS) return;
132 schoenebeck 1663 atomic_set( &(p->pNoteOffVelocity)[Key], Velocity );
133 schoenebeck 1659 atomic_dec( &(p->pNoteIsActive)[Key] );
134     atomic_inc( &(p->pNoteChanged)[Key] );
135     atomic_inc( &p->notesChanged );
136     }
137 schoenebeck 2025
138     void VirtualMidiDevice::SendCCToDevice(uint8_t Controller, uint8_t Value) {
139     if (Controller >= MIDI_CONTROLLERS) return;
140     atomic_set( &(p->pCCValue)[Controller], Value );
141     atomic_inc( &(p->pCCChanged)[Controller] );
142     atomic_inc( &p->ccsChanged );
143     }
144 schoenebeck 1659
145     } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC