1 /* 2 * OSS compatible sequencer driver 3 * 4 * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 #include "seq_oss_device.h" 22 #include "seq_oss_synth.h" 23 #include "seq_oss_midi.h" 24 #include "seq_oss_event.h" 25 #include "seq_oss_timer.h" 26 #include <sound/seq_oss_legacy.h> 27 #include "seq_oss_readq.h" 28 #include "seq_oss_writeq.h" 29 #include <linux/nospec.h> 30 31 32 /* 33 * prototypes 34 */ 35 static int extended_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev); 36 static int chn_voice_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev); 37 static int chn_common_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev); 38 static int timing_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev); 39 static int local_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev); 40 static int old_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev); 41 static int note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev); 42 static int note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev); 43 static int set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev); 44 static int set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev); 45 static int set_echo_event(struct seq_oss_devinfo *dp, union evrec *rec, struct snd_seq_event *ev); 46 47 48 /* 49 * convert an OSS event to ALSA event 50 * return 0 : enqueued 51 * non-zero : invalid - ignored 52 */ 53 54 int 55 snd_seq_oss_process_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev) 56 { 57 switch (q->s.code) { 58 case SEQ_EXTENDED: 59 return extended_event(dp, q, ev); 60 61 case EV_CHN_VOICE: 62 return chn_voice_event(dp, q, ev); 63 64 case EV_CHN_COMMON: 65 return chn_common_event(dp, q, ev); 66 67 case EV_TIMING: 68 return timing_event(dp, q, ev); 69 70 case EV_SEQ_LOCAL: 71 return local_event(dp, q, ev); 72 73 case EV_SYSEX: 74 return snd_seq_oss_synth_sysex(dp, q->x.dev, q->x.buf, ev); 75 76 case SEQ_MIDIPUTC: 77 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) 78 return -EINVAL; 79 /* put a midi byte */ 80 if (! is_write_mode(dp->file_mode)) 81 break; 82 if (snd_seq_oss_midi_open(dp, q->s.dev, SNDRV_SEQ_OSS_FILE_WRITE)) 83 break; 84 if (snd_seq_oss_midi_filemode(dp, q->s.dev) & SNDRV_SEQ_OSS_FILE_WRITE) 85 return snd_seq_oss_midi_putc(dp, q->s.dev, q->s.parm1, ev); 86 break; 87 88 case SEQ_ECHO: 89 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) 90 return -EINVAL; 91 return set_echo_event(dp, q, ev); 92 93 case SEQ_PRIVATE: 94 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) 95 return -EINVAL; 96 return snd_seq_oss_synth_raw_event(dp, q->c[1], q->c, ev); 97 98 default: 99 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) 100 return -EINVAL; 101 return old_event(dp, q, ev); 102 } 103 return -EINVAL; 104 } 105 106 /* old type events: mode1 only */ 107 static int 108 old_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev) 109 { 110 switch (q->s.code) { 111 case SEQ_NOTEOFF: 112 return note_off_event(dp, 0, q->n.chn, q->n.note, q->n.vel, ev); 113 114 case SEQ_NOTEON: 115 return note_on_event(dp, 0, q->n.chn, q->n.note, q->n.vel, ev); 116 117 case SEQ_WAIT: 118 /* skip */ 119 break; 120 121 case SEQ_PGMCHANGE: 122 return set_control_event(dp, 0, SNDRV_SEQ_EVENT_PGMCHANGE, 123 q->n.chn, 0, q->n.note, ev); 124 125 case SEQ_SYNCTIMER: 126 return snd_seq_oss_timer_reset(dp->timer); 127 } 128 129 return -EINVAL; 130 } 131 132 /* 8bytes extended event: mode1 only */ 133 static int 134 extended_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev) 135 { 136 int val; 137 138 switch (q->e.cmd) { 139 case SEQ_NOTEOFF: 140 return note_off_event(dp, q->e.dev, q->e.chn, q->e.p1, q->e.p2, ev); 141 142 case SEQ_NOTEON: 143 return note_on_event(dp, q->e.dev, q->e.chn, q->e.p1, q->e.p2, ev); 144 145 case SEQ_PGMCHANGE: 146 return set_control_event(dp, q->e.dev, SNDRV_SEQ_EVENT_PGMCHANGE, 147 q->e.chn, 0, q->e.p1, ev); 148 149 case SEQ_AFTERTOUCH: 150 return set_control_event(dp, q->e.dev, SNDRV_SEQ_EVENT_CHANPRESS, 151 q->e.chn, 0, q->e.p1, ev); 152 153 case SEQ_BALANCE: 154 /* convert -128:127 to 0:127 */ 155 val = (char)q->e.p1; 156 val = (val + 128) / 2; 157 return set_control_event(dp, q->e.dev, SNDRV_SEQ_EVENT_CONTROLLER, 158 q->e.chn, CTL_PAN, val, ev); 159 160 case SEQ_CONTROLLER: 161 val = ((short)q->e.p3 << 8) | (short)q->e.p2; 162 switch (q->e.p1) { 163 case CTRL_PITCH_BENDER: /* SEQ1 V2 control */ 164 /* -0x2000:0x1fff */ 165 return set_control_event(dp, q->e.dev, 166 SNDRV_SEQ_EVENT_PITCHBEND, 167 q->e.chn, 0, val, ev); 168 case CTRL_PITCH_BENDER_RANGE: 169 /* conversion: 100/semitone -> 128/semitone */ 170 return set_control_event(dp, q->e.dev, 171 SNDRV_SEQ_EVENT_REGPARAM, 172 q->e.chn, 0, val*128/100, ev); 173 default: 174 return set_control_event(dp, q->e.dev, 175 SNDRV_SEQ_EVENT_CONTROL14, 176 q->e.chn, q->e.p1, val, ev); 177 } 178 179 case SEQ_VOLMODE: 180 return snd_seq_oss_synth_raw_event(dp, q->e.dev, q->c, ev); 181 182 } 183 return -EINVAL; 184 } 185 186 /* channel voice events: mode1 and 2 */ 187 static int 188 chn_voice_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev) 189 { 190 if (q->v.chn >= 32) 191 return -EINVAL; 192 switch (q->v.cmd) { 193 case MIDI_NOTEON: 194 return note_on_event(dp, q->v.dev, q->v.chn, q->v.note, q->v.parm, ev); 195 196 case MIDI_NOTEOFF: 197 return note_off_event(dp, q->v.dev, q->v.chn, q->v.note, q->v.parm, ev); 198 199 case MIDI_KEY_PRESSURE: 200 return set_note_event(dp, q->v.dev, SNDRV_SEQ_EVENT_KEYPRESS, 201 q->v.chn, q->v.note, q->v.parm, ev); 202 203 } 204 return -EINVAL; 205 } 206 207 /* channel common events: mode1 and 2 */ 208 static int 209 chn_common_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev) 210 { 211 if (q->l.chn >= 32) 212 return -EINVAL; 213 switch (q->l.cmd) { 214 case MIDI_PGM_CHANGE: 215 return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_PGMCHANGE, 216 q->l.chn, 0, q->l.p1, ev); 217 218 case MIDI_CTL_CHANGE: 219 return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_CONTROLLER, 220 q->l.chn, q->l.p1, q->l.val, ev); 221 222 case MIDI_PITCH_BEND: 223 /* conversion: 0:0x3fff -> -0x2000:0x1fff */ 224 return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_PITCHBEND, 225 q->l.chn, 0, q->l.val - 8192, ev); 226 227 case MIDI_CHN_PRESSURE: 228 return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_CHANPRESS, 229 q->l.chn, 0, q->l.val, ev); 230 } 231 return -EINVAL; 232 } 233 234 /* timer events: mode1 and mode2 */ 235 static int 236 timing_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev) 237 { 238 switch (q->t.cmd) { 239 case TMR_ECHO: 240 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) 241 return set_echo_event(dp, q, ev); 242 else { 243 union evrec tmp; 244 memset(&tmp, 0, sizeof(tmp)); 245 /* XXX: only for little-endian! */ 246 tmp.echo = (q->t.time << 8) | SEQ_ECHO; 247 return set_echo_event(dp, &tmp, ev); 248 } 249 250 case TMR_STOP: 251 if (dp->seq_mode) 252 return snd_seq_oss_timer_stop(dp->timer); 253 return 0; 254 255 case TMR_CONTINUE: 256 if (dp->seq_mode) 257 return snd_seq_oss_timer_continue(dp->timer); 258 return 0; 259 260 case TMR_TEMPO: 261 if (dp->seq_mode) 262 return snd_seq_oss_timer_tempo(dp->timer, q->t.time); 263 return 0; 264 } 265 266 return -EINVAL; 267 } 268 269 /* local events: mode1 and 2 */ 270 static int 271 local_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev) 272 { 273 return -EINVAL; 274 } 275 276 /* 277 * process note-on event for OSS synth 278 * three different modes are available: 279 * - SNDRV_SEQ_OSS_PROCESS_EVENTS (for one-voice per channel mode) 280 * Accept note 255 as volume change. 281 * - SNDRV_SEQ_OSS_PASS_EVENTS 282 * Pass all events to lowlevel driver anyway 283 * - SNDRV_SEQ_OSS_PROCESS_KEYPRESS (mostly for Emu8000) 284 * Use key-pressure if note >= 128 285 */ 286 static int 287 note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev) 288 { 289 struct seq_oss_synthinfo *info; 290 291 info = snd_seq_oss_synth_info(dp, dev); 292 if (!info) 293 return -ENXIO; 294 295 switch (info->arg.event_passing) { 296 case SNDRV_SEQ_OSS_PROCESS_EVENTS: 297 if (! info->ch || ch < 0 || ch >= info->nr_voices) { 298 /* pass directly */ 299 return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev); 300 } 301 302 ch = array_index_nospec(ch, info->nr_voices); 303 if (note == 255 && info->ch[ch].note >= 0) { 304 /* volume control */ 305 int type; 306 //if (! vel) 307 /* set volume to zero -- note off */ 308 // type = SNDRV_SEQ_EVENT_NOTEOFF; 309 //else 310 if (info->ch[ch].vel) 311 /* sample already started -- volume change */ 312 type = SNDRV_SEQ_EVENT_KEYPRESS; 313 else 314 /* sample not started -- start now */ 315 type = SNDRV_SEQ_EVENT_NOTEON; 316 info->ch[ch].vel = vel; 317 return set_note_event(dp, dev, type, ch, info->ch[ch].note, vel, ev); 318 } else if (note >= 128) 319 return -EINVAL; /* invalid */ 320 321 if (note != info->ch[ch].note && info->ch[ch].note >= 0) 322 /* note changed - note off at beginning */ 323 set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEOFF, ch, info->ch[ch].note, 0, ev); 324 /* set current status */ 325 info->ch[ch].note = note; 326 info->ch[ch].vel = vel; 327 if (vel) /* non-zero velocity - start the note now */ 328 return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev); 329 return -EINVAL; 330 331 case SNDRV_SEQ_OSS_PASS_EVENTS: 332 /* pass the event anyway */ 333 return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev); 334 335 case SNDRV_SEQ_OSS_PROCESS_KEYPRESS: 336 if (note >= 128) /* key pressure: shifted by 128 */ 337 return set_note_event(dp, dev, SNDRV_SEQ_EVENT_KEYPRESS, ch, note - 128, vel, ev); 338 else /* normal note-on event */ 339 return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev); 340 } 341 return -EINVAL; 342 } 343 344 /* 345 * process note-off event for OSS synth 346 */ 347 static int 348 note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev) 349 { 350 struct seq_oss_synthinfo *info; 351 352 info = snd_seq_oss_synth_info(dp, dev); 353 if (!info) 354 return -ENXIO; 355 356 switch (info->arg.event_passing) { 357 case SNDRV_SEQ_OSS_PROCESS_EVENTS: 358 if (! info->ch || ch < 0 || ch >= info->nr_voices) { 359 /* pass directly */ 360 return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev); 361 } 362 363 ch = array_index_nospec(ch, info->nr_voices); 364 if (info->ch[ch].note >= 0) { 365 note = info->ch[ch].note; 366 info->ch[ch].vel = 0; 367 info->ch[ch].note = -1; 368 return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEOFF, ch, note, vel, ev); 369 } 370 return -EINVAL; /* invalid */ 371 372 case SNDRV_SEQ_OSS_PASS_EVENTS: 373 case SNDRV_SEQ_OSS_PROCESS_KEYPRESS: 374 /* pass the event anyway */ 375 return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEOFF, ch, note, vel, ev); 376 377 } 378 return -EINVAL; 379 } 380 381 /* 382 * create a note event 383 */ 384 static int 385 set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev) 386 { 387 if (!snd_seq_oss_synth_info(dp, dev)) 388 return -ENXIO; 389 390 ev->type = type; 391 snd_seq_oss_synth_addr(dp, dev, ev); 392 ev->data.note.channel = ch; 393 ev->data.note.note = note; 394 ev->data.note.velocity = vel; 395 396 return 0; 397 } 398 399 /* 400 * create a control event 401 */ 402 static int 403 set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev) 404 { 405 if (!snd_seq_oss_synth_info(dp, dev)) 406 return -ENXIO; 407 408 ev->type = type; 409 snd_seq_oss_synth_addr(dp, dev, ev); 410 ev->data.control.channel = ch; 411 ev->data.control.param = param; 412 ev->data.control.value = val; 413 414 return 0; 415 } 416 417 /* 418 * create an echo event 419 */ 420 static int 421 set_echo_event(struct seq_oss_devinfo *dp, union evrec *rec, struct snd_seq_event *ev) 422 { 423 ev->type = SNDRV_SEQ_EVENT_ECHO; 424 /* echo back to itself */ 425 snd_seq_oss_fill_addr(dp, ev, dp->addr.client, dp->addr.port); 426 memcpy(&ev->data, rec, LONG_EVENT_SIZE); 427 return 0; 428 } 429 430 /* 431 * event input callback from ALSA sequencer: 432 * the echo event is processed here. 433 */ 434 int 435 snd_seq_oss_event_input(struct snd_seq_event *ev, int direct, void *private_data, 436 int atomic, int hop) 437 { 438 struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private_data; 439 union evrec *rec; 440 441 if (ev->type != SNDRV_SEQ_EVENT_ECHO) 442 return snd_seq_oss_midi_input(ev, direct, private_data); 443 444 if (ev->source.client != dp->cseq) 445 return 0; /* ignored */ 446 447 rec = (union evrec*)&ev->data; 448 if (rec->s.code == SEQ_SYNCTIMER) { 449 /* sync echo back */ 450 snd_seq_oss_writeq_wakeup(dp->writeq, rec->t.time); 451 452 } else { 453 /* echo back event */ 454 if (dp->readq == NULL) 455 return 0; 456 snd_seq_oss_readq_put_event(dp->readq, rec); 457 } 458 return 0; 459 } 460 461