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