opl3_synth.c (16436B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) by Uros Bizjak <uros@kss-loka.si> 4 * 5 * Routines for OPL2/OPL3/OPL4 control 6 */ 7 8#include <linux/slab.h> 9#include <linux/export.h> 10#include <linux/nospec.h> 11#include <sound/opl3.h> 12#include <sound/asound_fm.h> 13#include "opl3_voice.h" 14 15#if IS_ENABLED(CONFIG_SND_SEQUENCER) 16#define OPL3_SUPPORT_SYNTH 17#endif 18 19/* 20 * There is 18 possible 2 OP voices 21 * (9 in the left and 9 in the right). 22 * The first OP is the modulator and 2nd is the carrier. 23 * 24 * The first three voices in the both sides may be connected 25 * with another voice to a 4 OP voice. For example voice 0 26 * can be connected with voice 3. The operators of voice 3 are 27 * used as operators 3 and 4 of the new 4 OP voice. 28 * In this case the 2 OP voice number 0 is the 'first half' and 29 * voice 3 is the second. 30 */ 31 32 33/* 34 * Register offset table for OPL2/3 voices, 35 * OPL2 / one OPL3 register array side only 36 */ 37 38char snd_opl3_regmap[MAX_OPL2_VOICES][4] = 39{ 40/* OP1 OP2 OP3 OP4 */ 41/* ------------------------ */ 42 { 0x00, 0x03, 0x08, 0x0b }, 43 { 0x01, 0x04, 0x09, 0x0c }, 44 { 0x02, 0x05, 0x0a, 0x0d }, 45 46 { 0x08, 0x0b, 0x00, 0x00 }, 47 { 0x09, 0x0c, 0x00, 0x00 }, 48 { 0x0a, 0x0d, 0x00, 0x00 }, 49 50 { 0x10, 0x13, 0x00, 0x00 }, /* used by percussive voices */ 51 { 0x11, 0x14, 0x00, 0x00 }, /* if the percussive mode */ 52 { 0x12, 0x15, 0x00, 0x00 } /* is selected (only left reg block) */ 53}; 54 55EXPORT_SYMBOL(snd_opl3_regmap); 56 57/* 58 * prototypes 59 */ 60static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note); 61static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice); 62static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params); 63static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode); 64static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection); 65 66/* ------------------------------ */ 67 68/* 69 * open the device exclusively 70 */ 71int snd_opl3_open(struct snd_hwdep * hw, struct file *file) 72{ 73 return 0; 74} 75 76/* 77 * ioctl for hwdep device: 78 */ 79int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file, 80 unsigned int cmd, unsigned long arg) 81{ 82 struct snd_opl3 *opl3 = hw->private_data; 83 void __user *argp = (void __user *)arg; 84 85 if (snd_BUG_ON(!opl3)) 86 return -EINVAL; 87 88 switch (cmd) { 89 /* get information */ 90 case SNDRV_DM_FM_IOCTL_INFO: 91 { 92 struct snd_dm_fm_info info; 93 94 memset(&info, 0, sizeof(info)); 95 96 info.fm_mode = opl3->fm_mode; 97 info.rhythm = opl3->rhythm; 98 if (copy_to_user(argp, &info, sizeof(struct snd_dm_fm_info))) 99 return -EFAULT; 100 return 0; 101 } 102 103 case SNDRV_DM_FM_IOCTL_RESET: 104#ifdef CONFIG_SND_OSSEMUL 105 case SNDRV_DM_FM_OSS_IOCTL_RESET: 106#endif 107 snd_opl3_reset(opl3); 108 return 0; 109 110 case SNDRV_DM_FM_IOCTL_PLAY_NOTE: 111#ifdef CONFIG_SND_OSSEMUL 112 case SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE: 113#endif 114 { 115 struct snd_dm_fm_note note; 116 if (copy_from_user(¬e, argp, sizeof(struct snd_dm_fm_note))) 117 return -EFAULT; 118 return snd_opl3_play_note(opl3, ¬e); 119 } 120 121 case SNDRV_DM_FM_IOCTL_SET_VOICE: 122#ifdef CONFIG_SND_OSSEMUL 123 case SNDRV_DM_FM_OSS_IOCTL_SET_VOICE: 124#endif 125 { 126 struct snd_dm_fm_voice voice; 127 if (copy_from_user(&voice, argp, sizeof(struct snd_dm_fm_voice))) 128 return -EFAULT; 129 return snd_opl3_set_voice(opl3, &voice); 130 } 131 132 case SNDRV_DM_FM_IOCTL_SET_PARAMS: 133#ifdef CONFIG_SND_OSSEMUL 134 case SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS: 135#endif 136 { 137 struct snd_dm_fm_params params; 138 if (copy_from_user(¶ms, argp, sizeof(struct snd_dm_fm_params))) 139 return -EFAULT; 140 return snd_opl3_set_params(opl3, ¶ms); 141 } 142 143 case SNDRV_DM_FM_IOCTL_SET_MODE: 144#ifdef CONFIG_SND_OSSEMUL 145 case SNDRV_DM_FM_OSS_IOCTL_SET_MODE: 146#endif 147 return snd_opl3_set_mode(opl3, (int) arg); 148 149 case SNDRV_DM_FM_IOCTL_SET_CONNECTION: 150#ifdef CONFIG_SND_OSSEMUL 151 case SNDRV_DM_FM_OSS_IOCTL_SET_OPL: 152#endif 153 return snd_opl3_set_connection(opl3, (int) arg); 154 155#ifdef OPL3_SUPPORT_SYNTH 156 case SNDRV_DM_FM_IOCTL_CLEAR_PATCHES: 157 snd_opl3_clear_patches(opl3); 158 return 0; 159#endif 160 161#ifdef CONFIG_SND_DEBUG 162 default: 163 snd_printk(KERN_WARNING "unknown IOCTL: 0x%x\n", cmd); 164#endif 165 } 166 return -ENOTTY; 167} 168 169/* 170 * close the device 171 */ 172int snd_opl3_release(struct snd_hwdep * hw, struct file *file) 173{ 174 struct snd_opl3 *opl3 = hw->private_data; 175 176 snd_opl3_reset(opl3); 177 return 0; 178} 179 180#ifdef OPL3_SUPPORT_SYNTH 181/* 182 * write the device - load patches 183 */ 184long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count, 185 loff_t *offset) 186{ 187 struct snd_opl3 *opl3 = hw->private_data; 188 long result = 0; 189 int err = 0; 190 struct sbi_patch inst; 191 192 while (count >= sizeof(inst)) { 193 unsigned char type; 194 if (copy_from_user(&inst, buf, sizeof(inst))) 195 return -EFAULT; 196 if (!memcmp(inst.key, FM_KEY_SBI, 4) || 197 !memcmp(inst.key, FM_KEY_2OP, 4)) 198 type = FM_PATCH_OPL2; 199 else if (!memcmp(inst.key, FM_KEY_4OP, 4)) 200 type = FM_PATCH_OPL3; 201 else /* invalid type */ 202 break; 203 err = snd_opl3_load_patch(opl3, inst.prog, inst.bank, type, 204 inst.name, inst.extension, 205 inst.data); 206 if (err < 0) 207 break; 208 result += sizeof(inst); 209 count -= sizeof(inst); 210 } 211 return result > 0 ? result : err; 212} 213 214 215/* 216 * Patch management 217 */ 218 219/* offsets for SBI params */ 220#define AM_VIB 0 221#define KSL_LEVEL 2 222#define ATTACK_DECAY 4 223#define SUSTAIN_RELEASE 6 224#define WAVE_SELECT 8 225 226/* offset for SBI instrument */ 227#define CONNECTION 10 228#define OFFSET_4OP 11 229 230/* 231 * load a patch, obviously. 232 * 233 * loaded on the given program and bank numbers with the given type 234 * (FM_PATCH_OPLx). 235 * data is the pointer of SBI record _without_ header (key and name). 236 * name is the name string of the patch. 237 * ext is the extension data of 7 bytes long (stored in name of SBI 238 * data up to offset 25), or NULL to skip. 239 * return 0 if successful or a negative error code. 240 */ 241int snd_opl3_load_patch(struct snd_opl3 *opl3, 242 int prog, int bank, int type, 243 const char *name, 244 const unsigned char *ext, 245 const unsigned char *data) 246{ 247 struct fm_patch *patch; 248 int i; 249 250 patch = snd_opl3_find_patch(opl3, prog, bank, 1); 251 if (!patch) 252 return -ENOMEM; 253 254 patch->type = type; 255 256 for (i = 0; i < 2; i++) { 257 patch->inst.op[i].am_vib = data[AM_VIB + i]; 258 patch->inst.op[i].ksl_level = data[KSL_LEVEL + i]; 259 patch->inst.op[i].attack_decay = data[ATTACK_DECAY + i]; 260 patch->inst.op[i].sustain_release = data[SUSTAIN_RELEASE + i]; 261 patch->inst.op[i].wave_select = data[WAVE_SELECT + i]; 262 } 263 patch->inst.feedback_connection[0] = data[CONNECTION]; 264 265 if (type == FM_PATCH_OPL3) { 266 for (i = 0; i < 2; i++) { 267 patch->inst.op[i+2].am_vib = 268 data[OFFSET_4OP + AM_VIB + i]; 269 patch->inst.op[i+2].ksl_level = 270 data[OFFSET_4OP + KSL_LEVEL + i]; 271 patch->inst.op[i+2].attack_decay = 272 data[OFFSET_4OP + ATTACK_DECAY + i]; 273 patch->inst.op[i+2].sustain_release = 274 data[OFFSET_4OP + SUSTAIN_RELEASE + i]; 275 patch->inst.op[i+2].wave_select = 276 data[OFFSET_4OP + WAVE_SELECT + i]; 277 } 278 patch->inst.feedback_connection[1] = 279 data[OFFSET_4OP + CONNECTION]; 280 } 281 282 if (ext) { 283 patch->inst.echo_delay = ext[0]; 284 patch->inst.echo_atten = ext[1]; 285 patch->inst.chorus_spread = ext[2]; 286 patch->inst.trnsps = ext[3]; 287 patch->inst.fix_dur = ext[4]; 288 patch->inst.modes = ext[5]; 289 patch->inst.fix_key = ext[6]; 290 } 291 292 if (name) 293 strscpy(patch->name, name, sizeof(patch->name)); 294 295 return 0; 296} 297EXPORT_SYMBOL(snd_opl3_load_patch); 298 299/* 300 * find a patch with the given program and bank numbers, returns its pointer 301 * if no matching patch is found and create_patch is set, it creates a 302 * new patch object. 303 */ 304struct fm_patch *snd_opl3_find_patch(struct snd_opl3 *opl3, int prog, int bank, 305 int create_patch) 306{ 307 /* pretty dumb hash key */ 308 unsigned int key = (prog + bank) % OPL3_PATCH_HASH_SIZE; 309 struct fm_patch *patch; 310 311 for (patch = opl3->patch_table[key]; patch; patch = patch->next) { 312 if (patch->prog == prog && patch->bank == bank) 313 return patch; 314 } 315 if (!create_patch) 316 return NULL; 317 318 patch = kzalloc(sizeof(*patch), GFP_KERNEL); 319 if (!patch) 320 return NULL; 321 patch->prog = prog; 322 patch->bank = bank; 323 patch->next = opl3->patch_table[key]; 324 opl3->patch_table[key] = patch; 325 return patch; 326} 327EXPORT_SYMBOL(snd_opl3_find_patch); 328 329/* 330 * Clear all patches of the given OPL3 instance 331 */ 332void snd_opl3_clear_patches(struct snd_opl3 *opl3) 333{ 334 int i; 335 for (i = 0; i < OPL3_PATCH_HASH_SIZE; i++) { 336 struct fm_patch *patch, *next; 337 for (patch = opl3->patch_table[i]; patch; patch = next) { 338 next = patch->next; 339 kfree(patch); 340 } 341 } 342 memset(opl3->patch_table, 0, sizeof(opl3->patch_table)); 343} 344#endif /* OPL3_SUPPORT_SYNTH */ 345 346/* ------------------------------ */ 347 348void snd_opl3_reset(struct snd_opl3 * opl3) 349{ 350 unsigned short opl3_reg; 351 352 unsigned short reg_side; 353 unsigned char voice_offset; 354 355 int max_voices, i; 356 357 max_voices = (opl3->hardware < OPL3_HW_OPL3) ? 358 MAX_OPL2_VOICES : MAX_OPL3_VOICES; 359 360 for (i = 0; i < max_voices; i++) { 361 /* Get register array side and offset of voice */ 362 if (i < MAX_OPL2_VOICES) { 363 /* Left register block for voices 0 .. 8 */ 364 reg_side = OPL3_LEFT; 365 voice_offset = i; 366 } else { 367 /* Right register block for voices 9 .. 17 */ 368 reg_side = OPL3_RIGHT; 369 voice_offset = i - MAX_OPL2_VOICES; 370 } 371 opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + snd_opl3_regmap[voice_offset][0]); 372 opl3->command(opl3, opl3_reg, OPL3_TOTAL_LEVEL_MASK); /* Operator 1 volume */ 373 opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + snd_opl3_regmap[voice_offset][1]); 374 opl3->command(opl3, opl3_reg, OPL3_TOTAL_LEVEL_MASK); /* Operator 2 volume */ 375 376 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); 377 opl3->command(opl3, opl3_reg, 0x00); /* Note off */ 378 } 379 380 opl3->max_voices = MAX_OPL2_VOICES; 381 opl3->fm_mode = SNDRV_DM_FM_MODE_OPL2; 382 383 opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT); 384 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00); /* Melodic mode */ 385 opl3->rhythm = 0; 386} 387 388EXPORT_SYMBOL(snd_opl3_reset); 389 390static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note) 391{ 392 unsigned short reg_side; 393 unsigned char voice_offset; 394 395 unsigned short opl3_reg; 396 unsigned char reg_val; 397 398 /* Voices 0 - 8 in OPL2 mode */ 399 /* Voices 0 - 17 in OPL3 mode */ 400 if (note->voice >= ((opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) ? 401 MAX_OPL3_VOICES : MAX_OPL2_VOICES)) 402 return -EINVAL; 403 404 /* Get register array side and offset of voice */ 405 if (note->voice < MAX_OPL2_VOICES) { 406 /* Left register block for voices 0 .. 8 */ 407 reg_side = OPL3_LEFT; 408 voice_offset = note->voice; 409 } else { 410 /* Right register block for voices 9 .. 17 */ 411 reg_side = OPL3_RIGHT; 412 voice_offset = note->voice - MAX_OPL2_VOICES; 413 } 414 415 /* Set lower 8 bits of note frequency */ 416 reg_val = (unsigned char) note->fnum; 417 opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset); 418 opl3->command(opl3, opl3_reg, reg_val); 419 420 reg_val = 0x00; 421 /* Set output sound flag */ 422 if (note->key_on) 423 reg_val |= OPL3_KEYON_BIT; 424 /* Set octave */ 425 reg_val |= (note->octave << 2) & OPL3_BLOCKNUM_MASK; 426 /* Set higher 2 bits of note frequency */ 427 reg_val |= (unsigned char) (note->fnum >> 8) & OPL3_FNUM_HIGH_MASK; 428 429 /* Set OPL3 KEYON_BLOCK register of requested voice */ 430 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); 431 opl3->command(opl3, opl3_reg, reg_val); 432 433 return 0; 434} 435 436 437static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice) 438{ 439 unsigned short reg_side; 440 unsigned char op_offset; 441 unsigned char voice_offset, voice_op; 442 443 unsigned short opl3_reg; 444 unsigned char reg_val; 445 446 /* Only operators 1 and 2 */ 447 if (voice->op > 1) 448 return -EINVAL; 449 /* Voices 0 - 8 in OPL2 mode */ 450 /* Voices 0 - 17 in OPL3 mode */ 451 if (voice->voice >= ((opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) ? 452 MAX_OPL3_VOICES : MAX_OPL2_VOICES)) 453 return -EINVAL; 454 455 /* Get register array side and offset of voice */ 456 if (voice->voice < MAX_OPL2_VOICES) { 457 /* Left register block for voices 0 .. 8 */ 458 reg_side = OPL3_LEFT; 459 voice_offset = voice->voice; 460 } else { 461 /* Right register block for voices 9 .. 17 */ 462 reg_side = OPL3_RIGHT; 463 voice_offset = voice->voice - MAX_OPL2_VOICES; 464 } 465 /* Get register offset of operator */ 466 voice_offset = array_index_nospec(voice_offset, MAX_OPL2_VOICES); 467 voice_op = array_index_nospec(voice->op, 4); 468 op_offset = snd_opl3_regmap[voice_offset][voice_op]; 469 470 reg_val = 0x00; 471 /* Set amplitude modulation (tremolo) effect */ 472 if (voice->am) 473 reg_val |= OPL3_TREMOLO_ON; 474 /* Set vibrato effect */ 475 if (voice->vibrato) 476 reg_val |= OPL3_VIBRATO_ON; 477 /* Set sustaining sound phase */ 478 if (voice->do_sustain) 479 reg_val |= OPL3_SUSTAIN_ON; 480 /* Set keyboard scaling bit */ 481 if (voice->kbd_scale) 482 reg_val |= OPL3_KSR; 483 /* Set harmonic or frequency multiplier */ 484 reg_val |= voice->harmonic & OPL3_MULTIPLE_MASK; 485 486 /* Set OPL3 AM_VIB register of requested voice/operator */ 487 opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset); 488 opl3->command(opl3, opl3_reg, reg_val); 489 490 /* Set decreasing volume of higher notes */ 491 reg_val = (voice->scale_level << 6) & OPL3_KSL_MASK; 492 /* Set output volume */ 493 reg_val |= ~voice->volume & OPL3_TOTAL_LEVEL_MASK; 494 495 /* Set OPL3 KSL_LEVEL register of requested voice/operator */ 496 opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset); 497 opl3->command(opl3, opl3_reg, reg_val); 498 499 /* Set attack phase level */ 500 reg_val = (voice->attack << 4) & OPL3_ATTACK_MASK; 501 /* Set decay phase level */ 502 reg_val |= voice->decay & OPL3_DECAY_MASK; 503 504 /* Set OPL3 ATTACK_DECAY register of requested voice/operator */ 505 opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset); 506 opl3->command(opl3, opl3_reg, reg_val); 507 508 /* Set sustain phase level */ 509 reg_val = (voice->sustain << 4) & OPL3_SUSTAIN_MASK; 510 /* Set release phase level */ 511 reg_val |= voice->release & OPL3_RELEASE_MASK; 512 513 /* Set OPL3 SUSTAIN_RELEASE register of requested voice/operator */ 514 opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset); 515 opl3->command(opl3, opl3_reg, reg_val); 516 517 /* Set inter-operator feedback */ 518 reg_val = (voice->feedback << 1) & OPL3_FEEDBACK_MASK; 519 /* Set inter-operator connection */ 520 if (voice->connection) 521 reg_val |= OPL3_CONNECTION_BIT; 522 /* OPL-3 only */ 523 if (opl3->fm_mode == SNDRV_DM_FM_MODE_OPL3) { 524 if (voice->left) 525 reg_val |= OPL3_VOICE_TO_LEFT; 526 if (voice->right) 527 reg_val |= OPL3_VOICE_TO_RIGHT; 528 } 529 /* Feedback/connection bits are applicable to voice */ 530 opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset); 531 opl3->command(opl3, opl3_reg, reg_val); 532 533 /* Select waveform */ 534 reg_val = voice->waveform & OPL3_WAVE_SELECT_MASK; 535 opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset); 536 opl3->command(opl3, opl3_reg, reg_val); 537 538 return 0; 539} 540 541static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params) 542{ 543 unsigned char reg_val; 544 545 reg_val = 0x00; 546 /* Set keyboard split method */ 547 if (params->kbd_split) 548 reg_val |= OPL3_KEYBOARD_SPLIT; 549 opl3->command(opl3, OPL3_LEFT | OPL3_REG_KBD_SPLIT, reg_val); 550 551 reg_val = 0x00; 552 /* Set amplitude modulation (tremolo) depth */ 553 if (params->am_depth) 554 reg_val |= OPL3_TREMOLO_DEPTH; 555 /* Set vibrato depth */ 556 if (params->vib_depth) 557 reg_val |= OPL3_VIBRATO_DEPTH; 558 /* Set percussion mode */ 559 if (params->rhythm) { 560 reg_val |= OPL3_PERCUSSION_ENABLE; 561 opl3->rhythm = 1; 562 } else { 563 opl3->rhythm = 0; 564 } 565 /* Play percussion instruments */ 566 if (params->bass) 567 reg_val |= OPL3_BASSDRUM_ON; 568 if (params->snare) 569 reg_val |= OPL3_SNAREDRUM_ON; 570 if (params->tomtom) 571 reg_val |= OPL3_TOMTOM_ON; 572 if (params->cymbal) 573 reg_val |= OPL3_CYMBAL_ON; 574 if (params->hihat) 575 reg_val |= OPL3_HIHAT_ON; 576 577 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, reg_val); 578 return 0; 579} 580 581static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode) 582{ 583 if ((mode == SNDRV_DM_FM_MODE_OPL3) && (opl3->hardware < OPL3_HW_OPL3)) 584 return -EINVAL; 585 586 opl3->fm_mode = mode; 587 if (opl3->hardware >= OPL3_HW_OPL3) 588 opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT, 0x00); /* Clear 4-op connections */ 589 590 return 0; 591} 592 593static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection) 594{ 595 unsigned char reg_val; 596 597 /* OPL-3 only */ 598 if (opl3->fm_mode != SNDRV_DM_FM_MODE_OPL3) 599 return -EINVAL; 600 601 reg_val = connection & (OPL3_RIGHT_4OP_0 | OPL3_RIGHT_4OP_1 | OPL3_RIGHT_4OP_2 | 602 OPL3_LEFT_4OP_0 | OPL3_LEFT_4OP_1 | OPL3_LEFT_4OP_2); 603 /* Set 4-op connections */ 604 opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT, reg_val); 605 606 return 0; 607} 608