]>
Commit | Line | Data |
---|---|---|
07aecc06 TI |
1 | =============================== |
2 | OSS Sequencer Emulation on ALSA | |
3 | =============================== | |
4 | ||
5 | Copyright (c) 1998,1999 by Takashi Iwai | |
6 | ||
7 | ver.0.1.8; Nov. 16, 1999 | |
8 | ||
9 | Description | |
10 | =========== | |
11 | ||
12 | This directory contains the OSS sequencer emulation driver on ALSA. Note | |
13 | that this program is still in the development state. | |
14 | ||
15 | What this does - it provides the emulation of the OSS sequencer, access | |
16 | via ``/dev/sequencer`` and ``/dev/music`` devices. | |
17 | The most of applications using OSS can run if the appropriate ALSA | |
18 | sequencer is prepared. | |
19 | ||
20 | The following features are emulated by this driver: | |
21 | ||
22 | * Normal sequencer and MIDI events: | |
23 | ||
24 | They are converted to the ALSA sequencer events, and sent to the | |
25 | corresponding port. | |
26 | ||
27 | * Timer events: | |
28 | ||
29 | The timer is not selectable by ioctl. The control rate is fixed to | |
30 | 100 regardless of HZ. That is, even on Alpha system, a tick is always | |
31 | 1/100 second. The base rate and tempo can be changed in ``/dev/music``. | |
32 | ||
33 | * Patch loading: | |
34 | ||
35 | It purely depends on the synth drivers whether it's supported since | |
36 | the patch loading is realized by callback to the synth driver. | |
37 | ||
38 | * I/O controls: | |
39 | ||
40 | Most of controls are accepted. Some controls | |
41 | are dependent on the synth driver, as well as even on original OSS. | |
42 | ||
43 | Furthermore, you can find the following advanced features: | |
44 | ||
45 | * Better queue mechanism: | |
46 | ||
47 | The events are queued before processing them. | |
48 | ||
49 | * Multiple applications: | |
50 | ||
51 | You can run two or more applications simultaneously (even for OSS | |
52 | sequencer)! | |
53 | However, each MIDI device is exclusive - that is, if a MIDI device | |
54 | is opened once by some application, other applications can't use | |
55 | it. No such a restriction in synth devices. | |
56 | ||
57 | * Real-time event processing: | |
58 | ||
59 | The events can be processed in real time without using out of bound | |
60 | ioctl. To switch to real-time mode, send ABSTIME 0 event. The followed | |
61 | events will be processed in real-time without queued. To switch off the | |
62 | real-time mode, send RELTIME 0 event. | |
63 | ||
64 | * ``/proc`` interface: | |
65 | ||
66 | The status of applications and devices can be shown via | |
67 | ``/proc/asound/seq/oss`` at any time. In the later version, | |
68 | configuration will be changed via ``/proc`` interface, too. | |
69 | ||
70 | ||
71 | Installation | |
72 | ============ | |
73 | ||
74 | Run configure script with both sequencer support (``--with-sequencer=yes``) | |
75 | and OSS emulation (``--with-oss=yes``) options. A module ``snd-seq-oss.o`` | |
76 | will be created. If the synth module of your sound card supports for OSS | |
77 | emulation (so far, only Emu8000 driver), this module will be loaded | |
78 | automatically. | |
79 | Otherwise, you need to load this module manually. | |
80 | ||
81 | At beginning, this module probes all the MIDI ports which have been | |
82 | already connected to the sequencer. Once after that, the creation and deletion | |
83 | of ports are watched by announcement mechanism of ALSA sequencer. | |
84 | ||
85 | The available synth and MIDI devices can be found in proc interface. | |
86 | Run ``cat /proc/asound/seq/oss``, and check the devices. For example, | |
87 | if you use an AWE64 card, you'll see like the following: | |
88 | :: | |
89 | ||
90 | OSS sequencer emulation version 0.1.8 | |
91 | ALSA client number 63 | |
92 | ALSA receiver port 0 | |
93 | ||
94 | Number of applications: 0 | |
95 | ||
96 | Number of synth devices: 1 | |
97 | synth 0: [EMU8000] | |
98 | type 0x1 : subtype 0x20 : voices 32 | |
99 | capabilties : ioctl enabled / load_patch enabled | |
100 | ||
101 | Number of MIDI devices: 3 | |
102 | midi 0: [Emu8000 Port-0] ALSA port 65:0 | |
103 | capability write / opened none | |
104 | ||
105 | midi 1: [Emu8000 Port-1] ALSA port 65:1 | |
106 | capability write / opened none | |
107 | ||
108 | midi 2: [0: MPU-401 (UART)] ALSA port 64:0 | |
109 | capability read/write / opened none | |
110 | ||
111 | Note that the device number may be different from the information of | |
112 | ``/proc/asound/oss-devices`` or ones of the original OSS driver. | |
113 | Use the device number listed in ``/proc/asound/seq/oss`` | |
114 | to play via OSS sequencer emulation. | |
115 | ||
116 | Using Synthesizer Devices | |
117 | ========================= | |
118 | ||
119 | Run your favorite program. I've tested playmidi-2.4, awemidi-0.4.3, gmod-3.1 | |
120 | and xmp-1.1.5. You can load samples via ``/dev/sequencer`` like sfxload, | |
121 | too. | |
122 | ||
123 | If the lowlevel driver supports multiple access to synth devices (like | |
124 | Emu8000 driver), two or more applications are allowed to run at the same | |
125 | time. | |
126 | ||
127 | Using MIDI Devices | |
128 | ================== | |
129 | ||
130 | So far, only MIDI output was tested. MIDI input was not checked at all, | |
131 | but hopefully it will work. Use the device number listed in | |
132 | ``/proc/asound/seq/oss``. | |
133 | Be aware that these numbers are mostly different from the list in | |
134 | ``/proc/asound/oss-devices``. | |
135 | ||
136 | Module Options | |
137 | ============== | |
138 | ||
139 | The following module options are available: | |
140 | ||
141 | maxqlen | |
142 | specifies the maximum read/write queue length. This queue is private | |
143 | for OSS sequencer, so that it is independent from the queue length of ALSA | |
144 | sequencer. Default value is 1024. | |
145 | ||
146 | seq_oss_debug | |
147 | specifies the debug level and accepts zero (= no debug message) or | |
148 | positive integer. Default value is 0. | |
149 | ||
150 | Queue Mechanism | |
151 | =============== | |
152 | ||
153 | OSS sequencer emulation uses an ALSA priority queue. The | |
154 | events from ``/dev/sequencer`` are processed and put onto the queue | |
155 | specified by module option. | |
156 | ||
157 | All the events from ``/dev/sequencer`` are parsed at beginning. | |
158 | The timing events are also parsed at this moment, so that the events may | |
159 | be processed in real-time. Sending an event ABSTIME 0 switches the operation | |
160 | mode to real-time mode, and sending an event RELTIME 0 switches it off. | |
161 | In the real-time mode, all events are dispatched immediately. | |
162 | ||
163 | The queued events are dispatched to the corresponding ALSA sequencer | |
164 | ports after scheduled time by ALSA sequencer dispatcher. | |
165 | ||
166 | If the write-queue is full, the application sleeps until a certain amount | |
167 | (as default one half) becomes empty in blocking mode. The synchronization | |
168 | to write timing was implemented, too. | |
169 | ||
170 | The input from MIDI devices or echo-back events are stored on read FIFO | |
171 | queue. If application reads ``/dev/sequencer`` in blocking mode, the | |
172 | process will be awaked. | |
173 | ||
174 | Interface to Synthesizer Device | |
175 | =============================== | |
176 | ||
177 | Registration | |
178 | ------------ | |
179 | ||
180 | To register an OSS synthesizer device, use snd_seq_oss_synth_register() | |
181 | function: | |
182 | :: | |
183 | ||
184 | int snd_seq_oss_synth_register(char *name, int type, int subtype, int nvoices, | |
185 | snd_seq_oss_callback_t *oper, void *private_data) | |
186 | ||
187 | The arguments ``name``, ``type``, ``subtype`` and ``nvoices`` | |
188 | are used for making the appropriate synth_info structure for ioctl. The | |
189 | return value is an index number of this device. This index must be remembered | |
190 | for unregister. If registration is failed, -errno will be returned. | |
191 | ||
192 | To release this device, call snd_seq_oss_synth_unregister() function: | |
193 | :: | |
194 | ||
195 | int snd_seq_oss_synth_unregister(int index) | |
196 | ||
197 | where the ``index`` is the index number returned by register function. | |
198 | ||
199 | Callbacks | |
200 | --------- | |
201 | ||
202 | OSS synthesizer devices have capability for sample downloading and ioctls | |
203 | like sample reset. In OSS emulation, these special features are realized | |
204 | by using callbacks. The registration argument oper is used to specify these | |
205 | callbacks. The following callback functions must be defined: | |
206 | :: | |
207 | ||
208 | snd_seq_oss_callback_t: | |
209 | int (*open)(snd_seq_oss_arg_t *p, void *closure); | |
210 | int (*close)(snd_seq_oss_arg_t *p); | |
211 | int (*ioctl)(snd_seq_oss_arg_t *p, unsigned int cmd, unsigned long arg); | |
212 | int (*load_patch)(snd_seq_oss_arg_t *p, int format, const char *buf, int offs, int count); | |
213 | int (*reset)(snd_seq_oss_arg_t *p); | |
214 | ||
215 | Except for ``open`` and ``close`` callbacks, they are allowed to be NULL. | |
216 | ||
217 | Each callback function takes the argument type ``snd_seq_oss_arg_t`` as the | |
218 | first argument. | |
219 | :: | |
220 | ||
221 | struct snd_seq_oss_arg_t { | |
222 | int app_index; | |
223 | int file_mode; | |
224 | int seq_mode; | |
225 | snd_seq_addr_t addr; | |
226 | void *private_data; | |
227 | int event_passing; | |
228 | }; | |
229 | ||
230 | The first three fields, ``app_index``, ``file_mode`` and ``seq_mode`` | |
231 | are initialized by OSS sequencer. The ``app_index`` is the application | |
232 | index which is unique to each application opening OSS sequencer. The | |
233 | ``file_mode`` is bit-flags indicating the file operation mode. See | |
234 | ``seq_oss.h`` for its meaning. The ``seq_mode`` is sequencer operation | |
235 | mode. In the current version, only ``SND_OSSSEQ_MODE_SYNTH`` is used. | |
236 | ||
237 | The next two fields, ``addr`` and ``private_data``, must be | |
238 | filled by the synth driver at open callback. The ``addr`` contains | |
239 | the address of ALSA sequencer port which is assigned to this device. If | |
240 | the driver allocates memory for ``private_data``, it must be released | |
241 | in close callback by itself. | |
242 | ||
243 | The last field, ``event_passing``, indicates how to translate note-on | |
244 | / off events. In ``PROCESS_EVENTS`` mode, the note 255 is regarded | |
245 | as velocity change, and key pressure event is passed to the port. In | |
246 | ``PASS_EVENTS`` mode, all note on/off events are passed to the port | |
247 | without modified. ``PROCESS_KEYPRESS`` mode checks the note above 128 | |
248 | and regards it as key pressure event (mainly for Emu8000 driver). | |
249 | ||
250 | Open Callback | |
251 | ------------- | |
252 | ||
253 | The ``open`` is called at each time this device is opened by an application | |
254 | using OSS sequencer. This must not be NULL. Typically, the open callback | |
255 | does the following procedure: | |
256 | ||
257 | #. Allocate private data record. | |
258 | #. Create an ALSA sequencer port. | |
259 | #. Set the new port address on ``arg->addr``. | |
260 | #. Set the private data record pointer on ``arg->private_data``. | |
261 | ||
262 | Note that the type bit-flags in port_info of this synth port must NOT contain | |
263 | ``TYPE_MIDI_GENERIC`` | |
264 | bit. Instead, ``TYPE_SPECIFIC`` should be used. Also, ``CAP_SUBSCRIPTION`` | |
265 | bit should NOT be included, too. This is necessary to tell it from other | |
266 | normal MIDI devices. If the open procedure succeeded, return zero. Otherwise, | |
267 | return -errno. | |
268 | ||
269 | Ioctl Callback | |
270 | -------------- | |
271 | ||
272 | The ``ioctl`` callback is called when the sequencer receives device-specific | |
273 | ioctls. The following two ioctls should be processed by this callback: | |
274 | ||
275 | IOCTL_SEQ_RESET_SAMPLES | |
276 | reset all samples on memory -- return 0 | |
277 | ||
278 | IOCTL_SYNTH_MEMAVL | |
279 | return the available memory size | |
280 | ||
281 | FM_4OP_ENABLE | |
282 | can be ignored usually | |
283 | ||
284 | The other ioctls are processed inside the sequencer without passing to | |
285 | the lowlevel driver. | |
286 | ||
287 | Load_Patch Callback | |
288 | ------------------- | |
289 | ||
290 | The ``load_patch`` callback is used for sample-downloading. This callback | |
291 | must read the data on user-space and transfer to each device. Return 0 | |
292 | if succeeded, and -errno if failed. The format argument is the patch key | |
293 | in patch_info record. The buf is user-space pointer where patch_info record | |
294 | is stored. The offs can be ignored. The count is total data size of this | |
295 | sample data. | |
296 | ||
297 | Close Callback | |
298 | -------------- | |
299 | ||
300 | The ``close`` callback is called when this device is closed by the | |
301 | application. If any private data was allocated in open callback, it must | |
302 | be released in the close callback. The deletion of ALSA port should be | |
303 | done here, too. This callback must not be NULL. | |
304 | ||
305 | Reset Callback | |
306 | -------------- | |
307 | ||
308 | The ``reset`` callback is called when sequencer device is reset or | |
309 | closed by applications. The callback should turn off the sounds on the | |
310 | relevant port immediately, and initialize the status of the port. If this | |
311 | callback is undefined, OSS seq sends a ``HEARTBEAT`` event to the | |
312 | port. | |
313 | ||
314 | Events | |
315 | ====== | |
316 | ||
317 | Most of the events are processed by sequencer and translated to the adequate | |
318 | ALSA sequencer events, so that each synth device can receive by input_event | |
319 | callback of ALSA sequencer port. The following ALSA events should be | |
320 | implemented by the driver: | |
321 | ||
322 | ============= =================== | |
323 | ALSA event Original OSS events | |
324 | ============= =================== | |
325 | NOTEON SEQ_NOTEON, MIDI_NOTEON | |
326 | NOTE SEQ_NOTEOFF, MIDI_NOTEOFF | |
327 | KEYPRESS MIDI_KEY_PRESSURE | |
328 | CHANPRESS SEQ_AFTERTOUCH, MIDI_CHN_PRESSURE | |
329 | PGMCHANGE SEQ_PGMCHANGE, MIDI_PGM_CHANGE | |
330 | PITCHBEND SEQ_CONTROLLER(CTRL_PITCH_BENDER), | |
331 | MIDI_PITCH_BEND | |
332 | CONTROLLER MIDI_CTL_CHANGE, | |
333 | SEQ_BALANCE (with CTL_PAN) | |
334 | CONTROL14 SEQ_CONTROLLER | |
335 | REGPARAM SEQ_CONTROLLER(CTRL_PITCH_BENDER_RANGE) | |
336 | SYSEX SEQ_SYSEX | |
337 | ============= =================== | |
338 | ||
339 | The most of these behavior can be realized by MIDI emulation driver | |
340 | included in the Emu8000 lowlevel driver. In the future release, this module | |
341 | will be independent. | |
342 | ||
343 | Some OSS events (``SEQ_PRIVATE`` and ``SEQ_VOLUME`` events) are passed as event | |
344 | type SND_SEQ_OSS_PRIVATE. The OSS sequencer passes these event 8 byte | |
345 | packets without any modification. The lowlevel driver should process these | |
346 | events appropriately. | |
347 | ||
348 | Interface to MIDI Device | |
349 | ======================== | |
350 | ||
351 | Since the OSS emulation probes the creation and deletion of ALSA MIDI | |
352 | sequencer ports automatically by receiving announcement from ALSA | |
353 | sequencer, the MIDI devices don't need to be registered explicitly | |
354 | like synth devices. | |
355 | However, the MIDI port_info registered to ALSA sequencer must include | |
356 | a group name ``SND_SEQ_GROUP_DEVICE`` and a capability-bit | |
357 | ``CAP_READ`` or ``CAP_WRITE``. Also, subscription capabilities, | |
358 | ``CAP_SUBS_READ`` or ``CAP_SUBS_WRITE``, must be defined, too. If | |
359 | these conditions are not satisfied, the port is not registered as OSS | |
360 | sequencer MIDI device. | |
361 | ||
362 | The events via MIDI devices are parsed in OSS sequencer and converted | |
363 | to the corresponding ALSA sequencer events. The input from MIDI sequencer | |
364 | is also converted to MIDI byte events by OSS sequencer. This works just | |
365 | a reverse way of seq_midi module. | |
366 | ||
367 | Known Problems / TODO's | |
368 | ======================= | |
369 | ||
370 | * Patch loading via ALSA instrument layer is not implemented yet. | |
371 |