emux_effect.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /*
  2. * Midi synth routines for the Emu8k/Emu10k1
  3. *
  4. * Copyright (C) 1999 Steve Ratcliffe
  5. * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
  6. *
  7. * Contains code based on awe_wave.c by Takashi Iwai
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. *
  23. */
  24. #include "emux_voice.h"
  25. #include <linux/slab.h>
  26. #ifdef SNDRV_EMUX_USE_RAW_EFFECT
  27. /*
  28. * effects table
  29. */
  30. #define xoffsetof(type,tag) ((long)(&((type)NULL)->tag) - (long)(NULL))
  31. #define parm_offset(tag) xoffsetof(struct soundfont_voice_parm *, tag)
  32. #define PARM_IS_BYTE (1 << 0)
  33. #define PARM_IS_WORD (1 << 1)
  34. #define PARM_IS_ALIGNED (3 << 2)
  35. #define PARM_IS_ALIGN_HI (1 << 2)
  36. #define PARM_IS_ALIGN_LO (2 << 2)
  37. #define PARM_IS_SIGNED (1 << 4)
  38. #define PARM_WORD (PARM_IS_WORD)
  39. #define PARM_BYTE_LO (PARM_IS_BYTE|PARM_IS_ALIGN_LO)
  40. #define PARM_BYTE_HI (PARM_IS_BYTE|PARM_IS_ALIGN_HI)
  41. #define PARM_BYTE (PARM_IS_BYTE)
  42. #define PARM_SIGN_LO (PARM_IS_BYTE|PARM_IS_ALIGN_LO|PARM_IS_SIGNED)
  43. #define PARM_SIGN_HI (PARM_IS_BYTE|PARM_IS_ALIGN_HI|PARM_IS_SIGNED)
  44. static struct emux_parm_defs {
  45. int type; /* byte or word */
  46. int low, high; /* value range */
  47. long offset; /* offset in parameter record (-1 = not written) */
  48. int update; /* flgas for real-time update */
  49. } parm_defs[EMUX_NUM_EFFECTS] = {
  50. {PARM_WORD, 0, 0x8000, parm_offset(moddelay), 0}, /* env1 delay */
  51. {PARM_BYTE_LO, 1, 0x80, parm_offset(modatkhld), 0}, /* env1 attack */
  52. {PARM_BYTE_HI, 0, 0x7e, parm_offset(modatkhld), 0}, /* env1 hold */
  53. {PARM_BYTE_LO, 1, 0x7f, parm_offset(moddcysus), 0}, /* env1 decay */
  54. {PARM_BYTE_LO, 1, 0x7f, parm_offset(modrelease), 0}, /* env1 release */
  55. {PARM_BYTE_HI, 0, 0x7f, parm_offset(moddcysus), 0}, /* env1 sustain */
  56. {PARM_BYTE_HI, 0, 0xff, parm_offset(pefe), 0}, /* env1 pitch */
  57. {PARM_BYTE_LO, 0, 0xff, parm_offset(pefe), 0}, /* env1 fc */
  58. {PARM_WORD, 0, 0x8000, parm_offset(voldelay), 0}, /* env2 delay */
  59. {PARM_BYTE_LO, 1, 0x80, parm_offset(volatkhld), 0}, /* env2 attack */
  60. {PARM_BYTE_HI, 0, 0x7e, parm_offset(volatkhld), 0}, /* env2 hold */
  61. {PARM_BYTE_LO, 1, 0x7f, parm_offset(voldcysus), 0}, /* env2 decay */
  62. {PARM_BYTE_LO, 1, 0x7f, parm_offset(volrelease), 0}, /* env2 release */
  63. {PARM_BYTE_HI, 0, 0x7f, parm_offset(voldcysus), 0}, /* env2 sustain */
  64. {PARM_WORD, 0, 0x8000, parm_offset(lfo1delay), 0}, /* lfo1 delay */
  65. {PARM_BYTE_LO, 0, 0xff, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ}, /* lfo1 freq */
  66. {PARM_SIGN_HI, -128, 127, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ}, /* lfo1 vol */
  67. {PARM_SIGN_HI, -128, 127, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD}, /* lfo1 pitch */
  68. {PARM_BYTE_LO, 0, 0xff, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD}, /* lfo1 cutoff */
  69. {PARM_WORD, 0, 0x8000, parm_offset(lfo2delay), 0}, /* lfo2 delay */
  70. {PARM_BYTE_LO, 0, 0xff, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2}, /* lfo2 freq */
  71. {PARM_SIGN_HI, -128, 127, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2}, /* lfo2 pitch */
  72. {PARM_WORD, 0, 0xffff, -1, SNDRV_EMUX_UPDATE_PITCH}, /* initial pitch */
  73. {PARM_BYTE, 0, 0xff, parm_offset(chorus), 0}, /* chorus */
  74. {PARM_BYTE, 0, 0xff, parm_offset(reverb), 0}, /* reverb */
  75. {PARM_BYTE, 0, 0xff, parm_offset(cutoff), SNDRV_EMUX_UPDATE_VOLUME}, /* cutoff */
  76. {PARM_BYTE, 0, 15, parm_offset(filterQ), SNDRV_EMUX_UPDATE_Q}, /* resonance */
  77. {PARM_WORD, 0, 0xffff, -1, 0}, /* sample start */
  78. {PARM_WORD, 0, 0xffff, -1, 0}, /* loop start */
  79. {PARM_WORD, 0, 0xffff, -1, 0}, /* loop end */
  80. {PARM_WORD, 0, 0xffff, -1, 0}, /* coarse sample start */
  81. {PARM_WORD, 0, 0xffff, -1, 0}, /* coarse loop start */
  82. {PARM_WORD, 0, 0xffff, -1, 0}, /* coarse loop end */
  83. {PARM_BYTE, 0, 0xff, -1, SNDRV_EMUX_UPDATE_VOLUME}, /* initial attenuation */
  84. };
  85. /* set byte effect value */
  86. static void
  87. effect_set_byte(unsigned char *valp, struct snd_midi_channel *chan, int type)
  88. {
  89. short effect;
  90. struct snd_emux_effect_table *fx = chan->private;
  91. effect = fx->val[type];
  92. if (fx->flag[type] == EMUX_FX_FLAG_ADD) {
  93. if (parm_defs[type].type & PARM_IS_SIGNED)
  94. effect += *(char*)valp;
  95. else
  96. effect += *valp;
  97. }
  98. if (effect < parm_defs[type].low)
  99. effect = parm_defs[type].low;
  100. else if (effect > parm_defs[type].high)
  101. effect = parm_defs[type].high;
  102. *valp = (unsigned char)effect;
  103. }
  104. /* set word effect value */
  105. static void
  106. effect_set_word(unsigned short *valp, struct snd_midi_channel *chan, int type)
  107. {
  108. int effect;
  109. struct snd_emux_effect_table *fx = chan->private;
  110. effect = *(unsigned short*)&fx->val[type];
  111. if (fx->flag[type] == EMUX_FX_FLAG_ADD)
  112. effect += *valp;
  113. if (effect < parm_defs[type].low)
  114. effect = parm_defs[type].low;
  115. else if (effect > parm_defs[type].high)
  116. effect = parm_defs[type].high;
  117. *valp = (unsigned short)effect;
  118. }
  119. /* address offset */
  120. static int
  121. effect_get_offset(struct snd_midi_channel *chan, int lo, int hi, int mode)
  122. {
  123. int addr = 0;
  124. struct snd_emux_effect_table *fx = chan->private;
  125. if (fx->flag[hi])
  126. addr = (short)fx->val[hi];
  127. addr = addr << 15;
  128. if (fx->flag[lo])
  129. addr += (short)fx->val[lo];
  130. if (!(mode & SNDRV_SFNT_SAMPLE_8BITS))
  131. addr /= 2;
  132. return addr;
  133. }
  134. #ifdef CONFIG_SND_SEQUENCER_OSS
  135. /* change effects - for OSS sequencer compatibility */
  136. void
  137. snd_emux_send_effect_oss(struct snd_emux_port *port,
  138. struct snd_midi_channel *chan, int type, int val)
  139. {
  140. int mode;
  141. if (type & 0x40)
  142. mode = EMUX_FX_FLAG_OFF;
  143. else if (type & 0x80)
  144. mode = EMUX_FX_FLAG_ADD;
  145. else
  146. mode = EMUX_FX_FLAG_SET;
  147. type &= 0x3f;
  148. snd_emux_send_effect(port, chan, type, val, mode);
  149. }
  150. #endif
  151. /* Modify the effect value.
  152. * if update is necessary, call emu8000_control
  153. */
  154. void
  155. snd_emux_send_effect(struct snd_emux_port *port, struct snd_midi_channel *chan,
  156. int type, int val, int mode)
  157. {
  158. int i;
  159. int offset;
  160. unsigned char *srcp, *origp;
  161. struct snd_emux *emu;
  162. struct snd_emux_effect_table *fx;
  163. unsigned long flags;
  164. emu = port->emu;
  165. fx = chan->private;
  166. if (emu == NULL || fx == NULL)
  167. return;
  168. if (type < 0 || type >= EMUX_NUM_EFFECTS)
  169. return;
  170. fx->val[type] = val;
  171. fx->flag[type] = mode;
  172. /* do we need to modify the register in realtime ? */
  173. if (! parm_defs[type].update || (offset = parm_defs[type].offset) < 0)
  174. return;
  175. #ifdef SNDRV_LITTLE_ENDIAN
  176. if (parm_defs[type].type & PARM_IS_ALIGN_HI)
  177. offset++;
  178. #else
  179. if (parm_defs[type].type & PARM_IS_ALIGN_LO)
  180. offset++;
  181. #endif
  182. /* modify the register values */
  183. spin_lock_irqsave(&emu->voice_lock, flags);
  184. for (i = 0; i < emu->max_voices; i++) {
  185. struct snd_emux_voice *vp = &emu->voices[i];
  186. if (!STATE_IS_PLAYING(vp->state) || vp->chan != chan)
  187. continue;
  188. srcp = (unsigned char*)&vp->reg.parm + offset;
  189. origp = (unsigned char*)&vp->zone->v.parm + offset;
  190. if (parm_defs[i].type & PARM_IS_BYTE) {
  191. *srcp = *origp;
  192. effect_set_byte(srcp, chan, type);
  193. } else {
  194. *(unsigned short*)srcp = *(unsigned short*)origp;
  195. effect_set_word((unsigned short*)srcp, chan, type);
  196. }
  197. }
  198. spin_unlock_irqrestore(&emu->voice_lock, flags);
  199. /* activate them */
  200. snd_emux_update_channel(port, chan, parm_defs[type].update);
  201. }
  202. /* copy wavetable registers to voice table */
  203. void
  204. snd_emux_setup_effect(struct snd_emux_voice *vp)
  205. {
  206. struct snd_midi_channel *chan = vp->chan;
  207. struct snd_emux_effect_table *fx;
  208. unsigned char *srcp;
  209. int i;
  210. if (! (fx = chan->private))
  211. return;
  212. /* modify the register values via effect table */
  213. for (i = 0; i < EMUX_FX_END; i++) {
  214. int offset;
  215. if (! fx->flag[i] || (offset = parm_defs[i].offset) < 0)
  216. continue;
  217. #ifdef SNDRV_LITTLE_ENDIAN
  218. if (parm_defs[i].type & PARM_IS_ALIGN_HI)
  219. offset++;
  220. #else
  221. if (parm_defs[i].type & PARM_IS_ALIGN_LO)
  222. offset++;
  223. #endif
  224. srcp = (unsigned char*)&vp->reg.parm + offset;
  225. if (parm_defs[i].type & PARM_IS_BYTE)
  226. effect_set_byte(srcp, chan, i);
  227. else
  228. effect_set_word((unsigned short*)srcp, chan, i);
  229. }
  230. /* correct sample and loop points */
  231. vp->reg.start += effect_get_offset(chan, EMUX_FX_SAMPLE_START,
  232. EMUX_FX_COARSE_SAMPLE_START,
  233. vp->reg.sample_mode);
  234. vp->reg.loopstart += effect_get_offset(chan, EMUX_FX_LOOP_START,
  235. EMUX_FX_COARSE_LOOP_START,
  236. vp->reg.sample_mode);
  237. vp->reg.loopend += effect_get_offset(chan, EMUX_FX_LOOP_END,
  238. EMUX_FX_COARSE_LOOP_END,
  239. vp->reg.sample_mode);
  240. }
  241. /*
  242. * effect table
  243. */
  244. void
  245. snd_emux_create_effect(struct snd_emux_port *p)
  246. {
  247. int i;
  248. p->effect = kcalloc(p->chset.max_channels,
  249. sizeof(struct snd_emux_effect_table), GFP_KERNEL);
  250. if (p->effect) {
  251. for (i = 0; i < p->chset.max_channels; i++)
  252. p->chset.channels[i].private = p->effect + i;
  253. } else {
  254. for (i = 0; i < p->chset.max_channels; i++)
  255. p->chset.channels[i].private = NULL;
  256. }
  257. }
  258. void
  259. snd_emux_delete_effect(struct snd_emux_port *p)
  260. {
  261. kfree(p->effect);
  262. p->effect = NULL;
  263. }
  264. void
  265. snd_emux_clear_effect(struct snd_emux_port *p)
  266. {
  267. if (p->effect) {
  268. memset(p->effect, 0, sizeof(struct snd_emux_effect_table) *
  269. p->chset.max_channels);
  270. }
  271. }
  272. #endif /* SNDRV_EMUX_USE_RAW_EFFECT */