Loading...
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 | =============================== OSS Sequencer Emulation on ALSA =============================== Copyright (c) 1998,1999 by Takashi Iwai ver.0.1.8; Nov. 16, 1999 Description =========== This directory contains the OSS sequencer emulation driver on ALSA. Note that this program is still in the development state. What this does - it provides the emulation of the OSS sequencer, access via ``/dev/sequencer`` and ``/dev/music`` devices. The most of applications using OSS can run if the appropriate ALSA sequencer is prepared. The following features are emulated by this driver: * Normal sequencer and MIDI events: They are converted to the ALSA sequencer events, and sent to the corresponding port. * Timer events: The timer is not selectable by ioctl. The control rate is fixed to 100 regardless of HZ. That is, even on Alpha system, a tick is always 1/100 second. The base rate and tempo can be changed in ``/dev/music``. * Patch loading: It purely depends on the synth drivers whether it's supported since the patch loading is realized by callback to the synth driver. * I/O controls: Most of controls are accepted. Some controls are dependent on the synth driver, as well as even on original OSS. Furthermore, you can find the following advanced features: * Better queue mechanism: The events are queued before processing them. * Multiple applications: You can run two or more applications simultaneously (even for OSS sequencer)! However, each MIDI device is exclusive - that is, if a MIDI device is opened once by some application, other applications can't use it. No such a restriction in synth devices. * Real-time event processing: The events can be processed in real time without using out of bound ioctl. To switch to real-time mode, send ABSTIME 0 event. The followed events will be processed in real-time without queued. To switch off the real-time mode, send RELTIME 0 event. * ``/proc`` interface: The status of applications and devices can be shown via ``/proc/asound/seq/oss`` at any time. In the later version, configuration will be changed via ``/proc`` interface, too. Installation ============ Run configure script with both sequencer support (``--with-sequencer=yes``) and OSS emulation (``--with-oss=yes``) options. A module ``snd-seq-oss.o`` will be created. If the synth module of your sound card supports for OSS emulation (so far, only Emu8000 driver), this module will be loaded automatically. Otherwise, you need to load this module manually. At beginning, this module probes all the MIDI ports which have been already connected to the sequencer. Once after that, the creation and deletion of ports are watched by announcement mechanism of ALSA sequencer. The available synth and MIDI devices can be found in proc interface. Run ``cat /proc/asound/seq/oss``, and check the devices. For example, if you use an AWE64 card, you'll see like the following: :: OSS sequencer emulation version 0.1.8 ALSA client number 63 ALSA receiver port 0 Number of applications: 0 Number of synth devices: 1 synth 0: [EMU8000] type 0x1 : subtype 0x20 : voices 32 capabilities : ioctl enabled / load_patch enabled Number of MIDI devices: 3 midi 0: [Emu8000 Port-0] ALSA port 65:0 capability write / opened none midi 1: [Emu8000 Port-1] ALSA port 65:1 capability write / opened none midi 2: [0: MPU-401 (UART)] ALSA port 64:0 capability read/write / opened none Note that the device number may be different from the information of ``/proc/asound/oss-devices`` or ones of the original OSS driver. Use the device number listed in ``/proc/asound/seq/oss`` to play via OSS sequencer emulation. Using Synthesizer Devices ========================= Run your favorite program. I've tested playmidi-2.4, awemidi-0.4.3, gmod-3.1 and xmp-1.1.5. You can load samples via ``/dev/sequencer`` like sfxload, too. If the lowlevel driver supports multiple access to synth devices (like Emu8000 driver), two or more applications are allowed to run at the same time. Using MIDI Devices ================== So far, only MIDI output was tested. MIDI input was not checked at all, but hopefully it will work. Use the device number listed in ``/proc/asound/seq/oss``. Be aware that these numbers are mostly different from the list in ``/proc/asound/oss-devices``. Module Options ============== The following module options are available: maxqlen specifies the maximum read/write queue length. This queue is private for OSS sequencer, so that it is independent from the queue length of ALSA sequencer. Default value is 1024. seq_oss_debug specifies the debug level and accepts zero (= no debug message) or positive integer. Default value is 0. Queue Mechanism =============== OSS sequencer emulation uses an ALSA priority queue. The events from ``/dev/sequencer`` are processed and put onto the queue specified by module option. All the events from ``/dev/sequencer`` are parsed at beginning. The timing events are also parsed at this moment, so that the events may be processed in real-time. Sending an event ABSTIME 0 switches the operation mode to real-time mode, and sending an event RELTIME 0 switches it off. In the real-time mode, all events are dispatched immediately. The queued events are dispatched to the corresponding ALSA sequencer ports after scheduled time by ALSA sequencer dispatcher. If the write-queue is full, the application sleeps until a certain amount (as default one half) becomes empty in blocking mode. The synchronization to write timing was implemented, too. The input from MIDI devices or echo-back events are stored on read FIFO queue. If application reads ``/dev/sequencer`` in blocking mode, the process will be awaked. Interface to Synthesizer Device =============================== Registration ------------ To register an OSS synthesizer device, use snd_seq_oss_synth_register() function: :: int snd_seq_oss_synth_register(char *name, int type, int subtype, int nvoices, snd_seq_oss_callback_t *oper, void *private_data) The arguments ``name``, ``type``, ``subtype`` and ``nvoices`` are used for making the appropriate synth_info structure for ioctl. The return value is an index number of this device. This index must be remembered for unregister. If registration is failed, -errno will be returned. To release this device, call snd_seq_oss_synth_unregister() function: :: int snd_seq_oss_synth_unregister(int index) where the ``index`` is the index number returned by register function. Callbacks --------- OSS synthesizer devices have capability for sample downloading and ioctls like sample reset. In OSS emulation, these special features are realized by using callbacks. The registration argument oper is used to specify these callbacks. The following callback functions must be defined: :: snd_seq_oss_callback_t: int (*open)(snd_seq_oss_arg_t *p, void *closure); int (*close)(snd_seq_oss_arg_t *p); int (*ioctl)(snd_seq_oss_arg_t *p, unsigned int cmd, unsigned long arg); int (*load_patch)(snd_seq_oss_arg_t *p, int format, const char *buf, int offs, int count); int (*reset)(snd_seq_oss_arg_t *p); Except for ``open`` and ``close`` callbacks, they are allowed to be NULL. Each callback function takes the argument type ``snd_seq_oss_arg_t`` as the first argument. :: struct snd_seq_oss_arg_t { int app_index; int file_mode; int seq_mode; snd_seq_addr_t addr; void *private_data; int event_passing; }; The first three fields, ``app_index``, ``file_mode`` and ``seq_mode`` are initialized by OSS sequencer. The ``app_index`` is the application index which is unique to each application opening OSS sequencer. The ``file_mode`` is bit-flags indicating the file operation mode. See ``seq_oss.h`` for its meaning. The ``seq_mode`` is sequencer operation mode. In the current version, only ``SND_OSSSEQ_MODE_SYNTH`` is used. The next two fields, ``addr`` and ``private_data``, must be filled by the synth driver at open callback. The ``addr`` contains the address of ALSA sequencer port which is assigned to this device. If the driver allocates memory for ``private_data``, it must be released in close callback by itself. The last field, ``event_passing``, indicates how to translate note-on / off events. In ``PROCESS_EVENTS`` mode, the note 255 is regarded as velocity change, and key pressure event is passed to the port. In ``PASS_EVENTS`` mode, all note on/off events are passed to the port without modified. ``PROCESS_KEYPRESS`` mode checks the note above 128 and regards it as key pressure event (mainly for Emu8000 driver). Open Callback ------------- The ``open`` is called at each time this device is opened by an application using OSS sequencer. This must not be NULL. Typically, the open callback does the following procedure: #. Allocate private data record. #. Create an ALSA sequencer port. #. Set the new port address on ``arg->addr``. #. Set the private data record pointer on ``arg->private_data``. Note that the type bit-flags in port_info of this synth port must NOT contain ``TYPE_MIDI_GENERIC`` bit. Instead, ``TYPE_SPECIFIC`` should be used. Also, ``CAP_SUBSCRIPTION`` bit should NOT be included, too. This is necessary to tell it from other normal MIDI devices. If the open procedure succeeded, return zero. Otherwise, return -errno. Ioctl Callback -------------- The ``ioctl`` callback is called when the sequencer receives device-specific ioctls. The following two ioctls should be processed by this callback: IOCTL_SEQ_RESET_SAMPLES reset all samples on memory -- return 0 IOCTL_SYNTH_MEMAVL return the available memory size FM_4OP_ENABLE can be ignored usually The other ioctls are processed inside the sequencer without passing to the lowlevel driver. Load_Patch Callback ------------------- The ``load_patch`` callback is used for sample-downloading. This callback must read the data on user-space and transfer to each device. Return 0 if succeeded, and -errno if failed. The format argument is the patch key in patch_info record. The buf is user-space pointer where patch_info record is stored. The offs can be ignored. The count is total data size of this sample data. Close Callback -------------- The ``close`` callback is called when this device is closed by the application. If any private data was allocated in open callback, it must be released in the close callback. The deletion of ALSA port should be done here, too. This callback must not be NULL. Reset Callback -------------- The ``reset`` callback is called when sequencer device is reset or closed by applications. The callback should turn off the sounds on the relevant port immediately, and initialize the status of the port. If this callback is undefined, OSS seq sends a ``HEARTBEAT`` event to the port. Events ====== Most of the events are processed by sequencer and translated to the adequate ALSA sequencer events, so that each synth device can receive by input_event callback of ALSA sequencer port. The following ALSA events should be implemented by the driver: ============= =================== ALSA event Original OSS events ============= =================== NOTEON SEQ_NOTEON, MIDI_NOTEON NOTE SEQ_NOTEOFF, MIDI_NOTEOFF KEYPRESS MIDI_KEY_PRESSURE CHANPRESS SEQ_AFTERTOUCH, MIDI_CHN_PRESSURE PGMCHANGE SEQ_PGMCHANGE, MIDI_PGM_CHANGE PITCHBEND SEQ_CONTROLLER(CTRL_PITCH_BENDER), MIDI_PITCH_BEND CONTROLLER MIDI_CTL_CHANGE, SEQ_BALANCE (with CTL_PAN) CONTROL14 SEQ_CONTROLLER REGPARAM SEQ_CONTROLLER(CTRL_PITCH_BENDER_RANGE) SYSEX SEQ_SYSEX ============= =================== The most of these behavior can be realized by MIDI emulation driver included in the Emu8000 lowlevel driver. In the future release, this module will be independent. Some OSS events (``SEQ_PRIVATE`` and ``SEQ_VOLUME`` events) are passed as event type SND_SEQ_OSS_PRIVATE. The OSS sequencer passes these event 8 byte packets without any modification. The lowlevel driver should process these events appropriately. Interface to MIDI Device ======================== Since the OSS emulation probes the creation and deletion of ALSA MIDI sequencer ports automatically by receiving announcement from ALSA sequencer, the MIDI devices don't need to be registered explicitly like synth devices. However, the MIDI port_info registered to ALSA sequencer must include a group name ``SND_SEQ_GROUP_DEVICE`` and a capability-bit ``CAP_READ`` or ``CAP_WRITE``. Also, subscription capabilities, ``CAP_SUBS_READ`` or ``CAP_SUBS_WRITE``, must be defined, too. If these conditions are not satisfied, the port is not registered as OSS sequencer MIDI device. The events via MIDI devices are parsed in OSS sequencer and converted to the corresponding ALSA sequencer events. The input from MIDI sequencer is also converted to MIDI byte events by OSS sequencer. This works just a reverse way of seq_midi module. Known Problems / TODO's ======================= * Patch loading via ALSA instrument layer is not implemented yet. |