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