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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
|
/*
Copyright (C) 2000 Stefan Westerfeld
stefan@space.twc.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/*
* DISCLAIMER: The interfaces in artsmidi.idl (and the derived .cc/.h files)
* DO NOT GUARANTEE BINARY COMPATIBILITY YET.
*
* They are intended for developers. You shouldn't expect that applications in
* binary form will be fully compatibile with further releases of these
* interfaces.
*/
#include <artsflow.idl>
module Arts {
/* This is modelled somewhat after
- the AudioManager concept
- the aRts-0.3.4.1 MidiPort concept
- libkmid
It adds timing as new feature compared to older implementation, and also
tries to do the full set of midi operations.
It's current state is "experimental", and "binary compatibility not kept".
*/
/**
* an absolute timestamp
*/
struct TimeStamp {
long sec,usec;
};
/**
* different status of a midi command
*/
enum MidiCommandStatus {
// Masks:
mcsCommandMask = 0xf0,
mcsChannelMask = 0x0f,
// Commands:
mcsNoteOff = 0x80,
mcsNoteOn = 0x90,
mcsKeyPressure = 0xa0,
mcsParameter = 0xb0,
mcsProgram = 0xc0,
mcsChannelPressure = 0xd0,
mcsPitchWheel = 0xe0
};
/**
* the following are to be used once status is (mcsParameter|channel):
*/
enum MidiCommandParameter {
mcpSustain = 0x40,
mcpAllNotesOff = 0x7b
};
/**
* a midi command
*/
struct MidiCommand {
byte status;
byte data1;
byte data2;
};
/**
* a midi event
*/
struct MidiEvent {
TimeStamp time;
MidiCommand command;
};
/**
* a midi port
*/
interface MidiPort {
/**
* the current absolute time (since the existence of the midi device)
*/
readonly attribute TimeStamp time;
/**
* the current play time
*
* Some midi devices, for instance synthetic audio devices, have a certain
* amount of internal buffering. This causes a time difference between
* where events are currently being rendered, which is the timestamp
* obtained by "time", and the events that the listener is hearing right
* now, which is this timestamp, the "playTime".
*/
readonly attribute TimeStamp playTime;
/**
* processes a midi command
*/
oneway void processCommand(MidiCommand command);
/**
* processes a midi event
*/
oneway void processEvent(MidiEvent event);
};
enum MidiClientDirection { mcdPlay, mcdRecord };
enum MidiClientType { mctDestination, mctApplication };
/**
* information about a midi client
*/
struct MidiClientInfo {
long ID;
sequence<long> connections;
MidiClientDirection direction;
MidiClientType type;
string title, autoRestoreID;
};
/**
* a midi manager client
*/
interface MidiClient {
readonly attribute MidiClientInfo info;
/**
* you can change the title of your client on the fly - everything else
* (besides the actual assignment) is static
*/
attribute string title;
/**
* creates a new port through which the client can receive data from
* the midi manager
*/
void addInputPort(MidiPort port);
/**
* creates a new port through which the client can send data to the
* midi manager
*/
MidiPort addOutputPort();
/**
* removes a port
*/
void removePort(MidiPort port);
};
interface AudioSync;
/**
* this synchronizes multiple midi clients - it also allows synchronization
* with audio events
*/
interface MidiSyncGroup {
/**
* adds a midi client to the synchronization group
*
* hint: during adding the client, the timestamps related to that
* client will jump
*/
void addClient(MidiClient client);
/**
* deletes a midi client from the synchronization group
*/
void removeClient(MidiClient client);
/**
* adds an AudioSync object to the synchronization group
*
* hint: during adding the AudioSync object, the timestamps related to
* that object might jump
*/
void addAudioSync(AudioSync audioSync);
/**
* deletes an AudioSync object from the synchronization group
*/
void removeAudioSync(AudioSync audioSync);
};
/**
* Some general notes to the understanding of the midi manager. The midi
* manager has the task to intelligently assign applications to destinations.
*
* It is important to understand what it actually does to understand the
* distinction first, which is expressed through the "MidiClientType" of
* each client.
*
* APPLICATIONS: An application is a user visible application, that produces
* or records midi data. It is important for the understanding of an
* application, that an application actually *wants* to be supplied with
* data, or wants to get its data played. Thus, adding an application to
* the midi manager is an implicit request: "go and find a place where to
* put the events to (or get the events from)".
*
* Examples for applications would be games or midi players.
*
* DESTINATIONS: A destination is a system service that plays or supplies
* midi data. The characteristic here is that a destination is something
* that is there if you need it.
*
* Examples for destinations might be might be a hardware device or an
* emulation of a hardware device (such as a virtual sampler).
*
* So the process is as follows:
* - destinations register themselves at the midi manager, and provide
* system services in that way
*
* - when the user starts an application (such as a midi player), the midi
* manager's task is to assign it to a suitable destination
*
* - the user can interact with the process by changing the way applications
* are assigned to destinations - the midi manager will try to learn
* what the user wants, and next time do a better job while assigning
*
* To actually record or play some data, you need to register a client first,
* and after that, you can add Input or Output "MidiPort"s to your client,
* so that you can actually send or receive events with them.
*/
interface MidiManager { // SINGLETON: Arts_MidiManager
/**
* a list of clients
*/
readonly attribute sequence<MidiClientInfo> clients;
/**
* add a client
*
* this creates a new MidiManagerClient
*/
MidiClient addClient(MidiClientDirection direction, MidiClientType type,
string title, string autoRestoreID);
/**
* connect two clients
*/
void connect(long clientID, long destinationID);
/**
* disconnect two clients
*/
void disconnect(long clientID, long destinationID);
/**
* add a synchronization group
*
* this creates a new MidiSyncGroup
*/
MidiSyncGroup addSyncGroup();
};
interface MidiTest : MidiPort {
};
interface RawMidiPort : MidiPort {
attribute string device;
attribute boolean input, output;
attribute boolean running;
boolean open();
};
interface AlsaMidiGateway {
boolean rescan();
};
interface AlsaMidiPort : MidiPort {
attribute long client;
attribute long port;
boolean open();
};
/**
* EXPERIMENTAL interface for audio synchronization - this allows multiple
* objects to be started and stopped at a precisely defined timestamp
*/
interface AudioSync {
/**
* the current time
*/
readonly attribute TimeStamp time;
/**
* the current play time
*
* Since aRts has internal buffering, there is a time difference between
* where events are currently being rendered, which is the timestamp
* obtained by "time", and the events that the listener is hearing right
* now, which is this timestamp, the "playTime".
*/
readonly attribute TimeStamp playTime;
/**
* queues calling synthModule.start() later
*
* (will keep a reference on the module until executed)
*/
void queueStart(SynthModule synthModule);
/**
* queues calling synthModule.stop() later
*
* (will keep a reference on the module until executed)
*/
void queueStop(SynthModule synthModule);
/**
* atomically executes all queued modification to the flow system
*/
void execute();
/**
* atomically executes all queued modifications to the flow system
* at a given time
*/
void executeAt(TimeStamp timeStamp);
};
/**
* Midi Timer - can be used to provide timing for midi ports that have
* no "native" timing.
*/
interface MidiTimer
{
/**
* the current time
*/
readonly attribute TimeStamp time;
/**
* this will put the event into an event queue and send it to the port
* once the time for the event has been reached
*/
oneway void queueEvent(MidiPort port, MidiEvent event);
};
/**
* Uses the system time (i.e. gettimeofday() and similar) to provide midi
* timing
*/
interface SystemMidiTimer : MidiTimer
{
};
/**
* Uses the audio time (i.e. samples rendered to /dev/dsp) to provide midi
* timing
*/
interface AudioMidiTimer : MidiTimer
{
};
};
|