1 /* 2 * synth callback routines for Emu10k1 3 * 4 * Copyright (C) 2000 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 "emu10k1_synth_local.h" 22 #include <sound/asoundef.h> 23 24 /* voice status */ 25 enum { 26 V_FREE=0, V_OFF, V_RELEASED, V_PLAYING, V_END 27 }; 28 29 /* Keeps track of what we are finding */ 30 typedef struct best_voice { 31 unsigned int time; 32 int voice; 33 } best_voice_t; 34 35 /* 36 * prototypes 37 */ 38 static void lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_only); 39 static snd_emux_voice_t *get_voice(snd_emux_t *emu, snd_emux_port_t *port); 40 static int start_voice(snd_emux_voice_t *vp); 41 static void trigger_voice(snd_emux_voice_t *vp); 42 static void release_voice(snd_emux_voice_t *vp); 43 static void update_voice(snd_emux_voice_t *vp, int update); 44 static void terminate_voice(snd_emux_voice_t *vp); 45 static void free_voice(snd_emux_voice_t *vp); 46 47 static void set_fmmod(emu10k1_t *hw, snd_emux_voice_t *vp); 48 static void set_fm2frq2(emu10k1_t *hw, snd_emux_voice_t *vp); 49 static void set_filterQ(emu10k1_t *hw, snd_emux_voice_t *vp); 50 51 /* 52 * Ensure a value is between two points 53 * macro evaluates its args more than once, so changed to upper-case. 54 */ 55 #define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0) 56 #define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0) 57 58 59 /* 60 * set up operators 61 */ 62 static snd_emux_operators_t emu10k1_ops = { 63 .owner = THIS_MODULE, 64 .get_voice = get_voice, 65 .prepare = start_voice, 66 .trigger = trigger_voice, 67 .release = release_voice, 68 .update = update_voice, 69 .terminate = terminate_voice, 70 .free_voice = free_voice, 71 .sample_new = snd_emu10k1_sample_new, 72 .sample_free = snd_emu10k1_sample_free, 73 }; 74 75 void 76 snd_emu10k1_ops_setup(snd_emux_t *emu) 77 { 78 emu->ops = emu10k1_ops; 79 } 80 81 82 /* 83 * get more voice for pcm 84 * 85 * terminate most inactive voice and give it as a pcm voice. 86 */ 87 int 88 snd_emu10k1_synth_get_voice(emu10k1_t *hw) 89 { 90 snd_emux_t *emu; 91 snd_emux_voice_t *vp; 92 best_voice_t best[V_END]; 93 unsigned long flags; 94 int i; 95 96 emu = hw->synth; 97 98 spin_lock_irqsave(&emu->voice_lock, flags); 99 lookup_voices(emu, hw, best, 1); /* no OFF voices */ 100 for (i = 0; i < V_END; i++) { 101 if (best[i].voice >= 0) { 102 int ch; 103 vp = &emu->voices[best[i].voice]; 104 if ((ch = vp->ch) < 0) { 105 //printk("synth_get_voice: ch < 0 (%d) ??", i); 106 continue; 107 } 108 vp->emu->num_voices--; 109 vp->ch = -1; 110 vp->state = SNDRV_EMUX_ST_OFF; 111 spin_unlock_irqrestore(&emu->voice_lock, flags); 112 return ch; 113 } 114 } 115 spin_unlock_irqrestore(&emu->voice_lock, flags); 116 117 /* not found */ 118 return -ENOMEM; 119 } 120 121 122 /* 123 * turn off the voice (not terminated) 124 */ 125 static void 126 release_voice(snd_emux_voice_t *vp) 127 { 128 int dcysusv; 129 emu10k1_t *hw; 130 131 hw = vp->hw; 132 dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease; 133 snd_emu10k1_ptr_write(hw, DCYSUSM, vp->ch, dcysusv); 134 dcysusv = 0x8000 | (unsigned char)vp->reg.parm.volrelease | DCYSUSV_CHANNELENABLE_MASK; 135 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, dcysusv); 136 } 137 138 139 /* 140 * terminate the voice 141 */ 142 static void 143 terminate_voice(snd_emux_voice_t *vp) 144 { 145 emu10k1_t *hw; 146 147 snd_assert(vp, return); 148 hw = vp->hw; 149 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK); 150 if (vp->block) { 151 emu10k1_memblk_t *emem; 152 emem = (emu10k1_memblk_t *)vp->block; 153 if (emem->map_locked > 0) 154 emem->map_locked--; 155 } 156 } 157 158 /* 159 * release the voice to system 160 */ 161 static void 162 free_voice(snd_emux_voice_t *vp) 163 { 164 emu10k1_t *hw; 165 166 hw = vp->hw; 167 if (vp->ch >= 0) { 168 snd_emu10k1_ptr_write(hw, IFATN, vp->ch, 0xff00); 169 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK); 170 // snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0); 171 snd_emu10k1_ptr_write(hw, VTFT, vp->ch, 0xffff); 172 snd_emu10k1_ptr_write(hw, CVCF, vp->ch, 0xffff); 173 snd_emu10k1_voice_free(hw, &hw->voices[vp->ch]); 174 vp->emu->num_voices--; 175 vp->ch = -1; 176 } 177 } 178 179 180 /* 181 * update registers 182 */ 183 static void 184 update_voice(snd_emux_voice_t *vp, int update) 185 { 186 emu10k1_t *hw; 187 188 hw = vp->hw; 189 if (update & SNDRV_EMUX_UPDATE_VOLUME) 190 snd_emu10k1_ptr_write(hw, IFATN_ATTENUATION, vp->ch, vp->avol); 191 if (update & SNDRV_EMUX_UPDATE_PITCH) 192 snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch); 193 if (update & SNDRV_EMUX_UPDATE_PAN) { 194 snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_A, vp->ch, vp->apan); 195 snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_B, vp->ch, vp->aaux); 196 } 197 if (update & SNDRV_EMUX_UPDATE_FMMOD) 198 set_fmmod(hw, vp); 199 if (update & SNDRV_EMUX_UPDATE_TREMFREQ) 200 snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq); 201 if (update & SNDRV_EMUX_UPDATE_FM2FRQ2) 202 set_fm2frq2(hw, vp); 203 if (update & SNDRV_EMUX_UPDATE_Q) 204 set_filterQ(hw, vp); 205 } 206 207 208 /* 209 * look up voice table - get the best voice in order of preference 210 */ 211 /* spinlock held! */ 212 static void 213 lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_only) 214 { 215 snd_emux_voice_t *vp; 216 best_voice_t *bp; 217 int i; 218 219 for (i = 0; i < V_END; i++) { 220 best[i].time = (unsigned int)-1; /* XXX MAX_?INT really */; 221 best[i].voice = -1; 222 } 223 224 /* 225 * Go through them all and get a best one to use. 226 * NOTE: could also look at volume and pick the quietest one. 227 */ 228 for (i = 0; i < emu->max_voices; i++) { 229 int state, val; 230 231 vp = &emu->voices[i]; 232 state = vp->state; 233 if (state == SNDRV_EMUX_ST_OFF) { 234 if (vp->ch < 0) { 235 if (active_only) 236 continue; 237 bp = best + V_FREE; 238 } else 239 bp = best + V_OFF; 240 } 241 else if (state == SNDRV_EMUX_ST_RELEASED || 242 state == SNDRV_EMUX_ST_PENDING) { 243 bp = best + V_RELEASED; 244 #if 0 245 val = snd_emu10k1_ptr_read(hw, CVCF_CURRENTVOL, vp->ch); 246 if (! val) 247 bp = best + V_OFF; 248 #endif 249 } 250 else if (state == SNDRV_EMUX_ST_STANDBY) 251 continue; 252 else if (state & SNDRV_EMUX_ST_ON) 253 bp = best + V_PLAYING; 254 else 255 continue; 256 257 /* check if sample is finished playing (non-looping only) */ 258 if (bp != best + V_OFF && bp != best + V_FREE && 259 (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) { 260 val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch); 261 if (val >= vp->reg.loopstart) 262 bp = best + V_OFF; 263 } 264 265 if (vp->time < bp->time) { 266 bp->time = vp->time; 267 bp->voice = i; 268 } 269 } 270 } 271 272 /* 273 * get an empty voice 274 * 275 * emu->voice_lock is already held. 276 */ 277 static snd_emux_voice_t * 278 get_voice(snd_emux_t *emu, snd_emux_port_t *port) 279 { 280 emu10k1_t *hw; 281 snd_emux_voice_t *vp; 282 best_voice_t best[V_END]; 283 int i; 284 285 hw = emu->hw; 286 287 lookup_voices(emu, hw, best, 0); 288 for (i = 0; i < V_END; i++) { 289 if (best[i].voice >= 0) { 290 vp = &emu->voices[best[i].voice]; 291 if (vp->ch < 0) { 292 /* allocate a voice */ 293 emu10k1_voice_t *hwvoice; 294 if (snd_emu10k1_voice_alloc(hw, EMU10K1_SYNTH, 1, &hwvoice) < 0 || hwvoice == NULL) 295 continue; 296 vp->ch = hwvoice->number; 297 emu->num_voices++; 298 } 299 return vp; 300 } 301 } 302 303 /* not found */ 304 return NULL; 305 } 306 307 /* 308 * prepare envelopes and LFOs 309 */ 310 static int 311 start_voice(snd_emux_voice_t *vp) 312 { 313 unsigned int temp; 314 int ch; 315 unsigned int addr, mapped_offset; 316 snd_midi_channel_t *chan; 317 emu10k1_t *hw; 318 emu10k1_memblk_t *emem; 319 320 hw = vp->hw; 321 ch = vp->ch; 322 snd_assert(ch >= 0, return -EINVAL); 323 chan = vp->chan; 324 325 emem = (emu10k1_memblk_t *)vp->block; 326 if (emem == NULL) 327 return -EINVAL; 328 emem->map_locked++; 329 if (snd_emu10k1_memblk_map(hw, emem) < 0) { 330 // printk("emu: cannot map!\n"); 331 return -ENOMEM; 332 } 333 mapped_offset = snd_emu10k1_memblk_offset(emem) >> 1; 334 vp->reg.start += mapped_offset; 335 vp->reg.end += mapped_offset; 336 vp->reg.loopstart += mapped_offset; 337 vp->reg.loopend += mapped_offset; 338 339 /* set channel routing */ 340 /* A = left(0), B = right(1), C = reverb(c), D = chorus(d) */ 341 if (hw->audigy) { 342 temp = FXBUS_MIDI_LEFT | (FXBUS_MIDI_RIGHT << 8) | 343 (FXBUS_MIDI_REVERB << 16) | (FXBUS_MIDI_CHORUS << 24); 344 snd_emu10k1_ptr_write(hw, A_FXRT1, ch, temp); 345 } else { 346 temp = (FXBUS_MIDI_LEFT << 16) | (FXBUS_MIDI_RIGHT << 20) | 347 (FXBUS_MIDI_REVERB << 24) | (FXBUS_MIDI_CHORUS << 28); 348 snd_emu10k1_ptr_write(hw, FXRT, ch, temp); 349 } 350 351 /* channel to be silent and idle */ 352 snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0080); 353 snd_emu10k1_ptr_write(hw, VTFT, ch, 0x0000FFFF); 354 snd_emu10k1_ptr_write(hw, CVCF, ch, 0x0000FFFF); 355 snd_emu10k1_ptr_write(hw, PTRX, ch, 0); 356 snd_emu10k1_ptr_write(hw, CPF, ch, 0); 357 358 /* set pitch offset */ 359 snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch); 360 361 /* set envelope parameters */ 362 snd_emu10k1_ptr_write(hw, ENVVAL, ch, vp->reg.parm.moddelay); 363 snd_emu10k1_ptr_write(hw, ATKHLDM, ch, vp->reg.parm.modatkhld); 364 snd_emu10k1_ptr_write(hw, DCYSUSM, ch, vp->reg.parm.moddcysus); 365 snd_emu10k1_ptr_write(hw, ENVVOL, ch, vp->reg.parm.voldelay); 366 snd_emu10k1_ptr_write(hw, ATKHLDV, ch, vp->reg.parm.volatkhld); 367 /* decay/sustain parameter for volume envelope is used 368 for triggerg the voice */ 369 370 /* cutoff and volume */ 371 temp = (unsigned int)vp->acutoff << 8 | (unsigned char)vp->avol; 372 snd_emu10k1_ptr_write(hw, IFATN, vp->ch, temp); 373 374 /* modulation envelope heights */ 375 snd_emu10k1_ptr_write(hw, PEFE, ch, vp->reg.parm.pefe); 376 377 /* lfo1/2 delay */ 378 snd_emu10k1_ptr_write(hw, LFOVAL1, ch, vp->reg.parm.lfo1delay); 379 snd_emu10k1_ptr_write(hw, LFOVAL2, ch, vp->reg.parm.lfo2delay); 380 381 /* lfo1 pitch & cutoff shift */ 382 set_fmmod(hw, vp); 383 /* lfo1 volume & freq */ 384 snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq); 385 /* lfo2 pitch & freq */ 386 set_fm2frq2(hw, vp); 387 388 /* reverb and loop start (reverb 8bit, MSB) */ 389 temp = vp->reg.parm.reverb; 390 temp += (int)vp->chan->control[MIDI_CTL_E1_REVERB_DEPTH] * 9 / 10; 391 LIMITMAX(temp, 255); 392 addr = vp->reg.loopstart; 393 snd_emu10k1_ptr_write(hw, PSST, vp->ch, (temp << 24) | addr); 394 395 /* chorus & loop end (chorus 8bit, MSB) */ 396 addr = vp->reg.loopend; 397 temp = vp->reg.parm.chorus; 398 temp += (int)chan->control[MIDI_CTL_E3_CHORUS_DEPTH] * 9 / 10; 399 LIMITMAX(temp, 255); 400 temp = (temp <<24) | addr; 401 snd_emu10k1_ptr_write(hw, DSL, ch, temp); 402 403 /* clear filter delay memory */ 404 snd_emu10k1_ptr_write(hw, Z1, ch, 0); 405 snd_emu10k1_ptr_write(hw, Z2, ch, 0); 406 407 /* invalidate maps */ 408 temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK; 409 snd_emu10k1_ptr_write(hw, MAPA, ch, temp); 410 snd_emu10k1_ptr_write(hw, MAPB, ch, temp); 411 #if 0 412 /* cache */ 413 { 414 unsigned int val, sample; 415 val = 32; 416 if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS) 417 sample = 0x80808080; 418 else { 419 sample = 0; 420 val *= 2; 421 } 422 423 /* cache */ 424 snd_emu10k1_ptr_write(hw, CCR, ch, 0x1c << 16); 425 snd_emu10k1_ptr_write(hw, CDE, ch, sample); 426 snd_emu10k1_ptr_write(hw, CDF, ch, sample); 427 428 /* invalidate maps */ 429 temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK; 430 snd_emu10k1_ptr_write(hw, MAPA, ch, temp); 431 snd_emu10k1_ptr_write(hw, MAPB, ch, temp); 432 433 /* fill cache */ 434 val -= 4; 435 val <<= 25; 436 val |= 0x1c << 16; 437 snd_emu10k1_ptr_write(hw, CCR, ch, val); 438 } 439 #endif 440 441 /* Q & current address (Q 4bit value, MSB) */ 442 addr = vp->reg.start; 443 temp = vp->reg.parm.filterQ; 444 temp = (temp<<28) | addr; 445 if (vp->apitch < 0xe400) 446 temp |= CCCA_INTERPROM_0; 447 else { 448 unsigned int shift = (vp->apitch - 0xe000) >> 10; 449 temp |= shift << 25; 450 } 451 if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS) 452 temp |= CCCA_8BITSELECT; 453 snd_emu10k1_ptr_write(hw, CCCA, ch, temp); 454 455 /* reset volume */ 456 temp = (unsigned int)vp->vtarget << 16; 457 snd_emu10k1_ptr_write(hw, VTFT, ch, temp | vp->ftarget); 458 snd_emu10k1_ptr_write(hw, CVCF, ch, temp | 0xff00); 459 return 0; 460 } 461 462 /* 463 * Start envelope 464 */ 465 static void 466 trigger_voice(snd_emux_voice_t *vp) 467 { 468 unsigned int temp, ptarget; 469 emu10k1_t *hw; 470 emu10k1_memblk_t *emem; 471 472 hw = vp->hw; 473 474 emem = (emu10k1_memblk_t *)vp->block; 475 if (! emem || emem->mapped_page < 0) 476 return; /* not mapped */ 477 478 #if 0 479 ptarget = (unsigned int)vp->ptarget << 16; 480 #else 481 ptarget = IP_TO_CP(vp->apitch); 482 #endif 483 /* set pitch target and pan (volume) */ 484 temp = ptarget | (vp->apan << 8) | vp->aaux; 485 snd_emu10k1_ptr_write(hw, PTRX, vp->ch, temp); 486 487 /* pitch target */ 488 snd_emu10k1_ptr_write(hw, CPF, vp->ch, ptarget); 489 490 /* trigger voice */ 491 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, vp->reg.parm.voldcysus|DCYSUSV_CHANNELENABLE_MASK); 492 } 493 494 #define MOD_SENSE 18 495 496 /* set lfo1 modulation height and cutoff */ 497 static void 498 set_fmmod(emu10k1_t *hw, snd_emux_voice_t *vp) 499 { 500 unsigned short fmmod; 501 short pitch; 502 unsigned char cutoff; 503 int modulation; 504 505 pitch = (char)(vp->reg.parm.fmmod>>8); 506 cutoff = (vp->reg.parm.fmmod & 0xff); 507 modulation = vp->chan->gm_modulation + vp->chan->midi_pressure; 508 pitch += (MOD_SENSE * modulation) / 1200; 509 LIMITVALUE(pitch, -128, 127); 510 fmmod = ((unsigned char)pitch<<8) | cutoff; 511 snd_emu10k1_ptr_write(hw, FMMOD, vp->ch, fmmod); 512 } 513 514 /* set lfo2 pitch & frequency */ 515 static void 516 set_fm2frq2(emu10k1_t *hw, snd_emux_voice_t *vp) 517 { 518 unsigned short fm2frq2; 519 short pitch; 520 unsigned char freq; 521 int modulation; 522 523 pitch = (char)(vp->reg.parm.fm2frq2>>8); 524 freq = vp->reg.parm.fm2frq2 & 0xff; 525 modulation = vp->chan->gm_modulation + vp->chan->midi_pressure; 526 pitch += (MOD_SENSE * modulation) / 1200; 527 LIMITVALUE(pitch, -128, 127); 528 fm2frq2 = ((unsigned char)pitch<<8) | freq; 529 snd_emu10k1_ptr_write(hw, FM2FRQ2, vp->ch, fm2frq2); 530 } 531 532 /* set filterQ */ 533 static void 534 set_filterQ(emu10k1_t *hw, snd_emux_voice_t *vp) 535 { 536 unsigned int val; 537 val = snd_emu10k1_ptr_read(hw, CCCA, vp->ch) & ~CCCA_RESONANCE; 538 val |= (vp->reg.parm.filterQ << 28); 539 snd_emu10k1_ptr_write(hw, CCCA, vp->ch, val); 540 } 541