emux_effect.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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(soundfont_voice_parm_t*, 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, snd_midi_channel_t *chan, int type)
  88. {
  89. short effect;
  90. snd_emux_effect_table_t *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, snd_midi_channel_t *chan, int type)
  107. {
  108. int effect;
  109. snd_emux_effect_table_t *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(snd_midi_channel_t *chan, int lo, int hi, int mode)
  122. {
  123. int addr = 0;
  124. snd_emux_effect_table_t *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(snd_emux_port_t *port, snd_midi_channel_t *chan, int type, int val)
  138. {
  139. int mode;
  140. if (type & 0x40)
  141. mode = EMUX_FX_FLAG_OFF;
  142. else if (type & 0x80)
  143. mode = EMUX_FX_FLAG_ADD;
  144. else
  145. mode = EMUX_FX_FLAG_SET;
  146. type &= 0x3f;
  147. snd_emux_send_effect(port, chan, type, val, mode);
  148. }
  149. #endif
  150. /* Modify the effect value.
  151. * if update is necessary, call emu8000_control
  152. */
  153. void
  154. snd_emux_send_effect(snd_emux_port_t *port, snd_midi_channel_t *chan, int type, int val, int mode)
  155. {
  156. int i;
  157. int offset;
  158. unsigned char *srcp, *origp;
  159. snd_emux_t *emu;
  160. snd_emux_effect_table_t *fx;
  161. unsigned long flags;
  162. emu = port->emu;
  163. fx = chan->private;
  164. if (emu == NULL || fx == NULL)
  165. return;
  166. if (type < 0 || type >= EMUX_NUM_EFFECTS)
  167. return;
  168. fx->val[type] = val;
  169. fx->flag[type] = mode;
  170. /* do we need to modify the register in realtime ? */
  171. if (! parm_defs[type].update || (offset = parm_defs[type].offset) < 0)
  172. return;
  173. #ifdef SNDRV_LITTLE_ENDIAN
  174. if (parm_defs[type].type & PARM_IS_ALIGN_HI)
  175. offset++;
  176. #else
  177. if (parm_defs[type].type & PARM_IS_ALIGN_LO)
  178. offset++;
  179. #endif
  180. /* modify the register values */
  181. spin_lock_irqsave(&emu->voice_lock, flags);
  182. for (i = 0; i < emu->max_voices; i++) {
  183. snd_emux_voice_t *vp = &emu->voices[i];
  184. if (!STATE_IS_PLAYING(vp->state) || vp->chan != chan)
  185. continue;
  186. srcp = (unsigned char*)&vp->reg.parm + offset;
  187. origp = (unsigned char*)&vp->zone->v.parm + offset;
  188. if (parm_defs[i].type & PARM_IS_BYTE) {
  189. *srcp = *origp;
  190. effect_set_byte(srcp, chan, type);
  191. } else {
  192. *(unsigned short*)srcp = *(unsigned short*)origp;
  193. effect_set_word((unsigned short*)srcp, chan, type);
  194. }
  195. }
  196. spin_unlock_irqrestore(&emu->voice_lock, flags);
  197. /* activate them */
  198. snd_emux_update_channel(port, chan, parm_defs[type].update);
  199. }
  200. /* copy wavetable registers to voice table */
  201. void
  202. snd_emux_setup_effect(snd_emux_voice_t *vp)
  203. {
  204. snd_midi_channel_t *chan = vp->chan;
  205. snd_emux_effect_table_t *fx;
  206. unsigned char *srcp;
  207. int i;
  208. if (! (fx = chan->private))
  209. return;
  210. /* modify the register values via effect table */
  211. for (i = 0; i < EMUX_FX_END; i++) {
  212. int offset;
  213. if (! fx->flag[i] || (offset = parm_defs[i].offset) < 0)
  214. continue;
  215. #ifdef SNDRV_LITTLE_ENDIAN
  216. if (parm_defs[i].type & PARM_IS_ALIGN_HI)
  217. offset++;
  218. #else
  219. if (parm_defs[i].type & PARM_IS_ALIGN_LO)
  220. offset++;
  221. #endif
  222. srcp = (unsigned char*)&vp->reg.parm + offset;
  223. if (parm_defs[i].type & PARM_IS_BYTE)
  224. effect_set_byte(srcp, chan, i);
  225. else
  226. effect_set_word((unsigned short*)srcp, chan, i);
  227. }
  228. /* correct sample and loop points */
  229. vp->reg.start += effect_get_offset(chan, EMUX_FX_SAMPLE_START,
  230. EMUX_FX_COARSE_SAMPLE_START,
  231. vp->reg.sample_mode);
  232. vp->reg.loopstart += effect_get_offset(chan, EMUX_FX_LOOP_START,
  233. EMUX_FX_COARSE_LOOP_START,
  234. vp->reg.sample_mode);
  235. vp->reg.loopend += effect_get_offset(chan, EMUX_FX_LOOP_END,
  236. EMUX_FX_COARSE_LOOP_END,
  237. vp->reg.sample_mode);
  238. }
  239. /*
  240. * effect table
  241. */
  242. void
  243. snd_emux_create_effect(snd_emux_port_t *p)
  244. {
  245. int i;
  246. p->effect = kcalloc(p->chset.max_channels, sizeof(snd_emux_effect_table_t), GFP_KERNEL);
  247. if (p->effect) {
  248. for (i = 0; i < p->chset.max_channels; i++)
  249. p->chset.channels[i].private = p->effect + i;
  250. } else {
  251. for (i = 0; i < p->chset.max_channels; i++)
  252. p->chset.channels[i].private = NULL;
  253. }
  254. }
  255. void
  256. snd_emux_delete_effect(snd_emux_port_t *p)
  257. {
  258. kfree(p->effect);
  259. p->effect = NULL;
  260. }
  261. void
  262. snd_emux_clear_effect(snd_emux_port_t *p)
  263. {
  264. if (p->effect) {
  265. memset(p->effect, 0, sizeof(snd_emux_effect_table_t) * p->chset.max_channels);
  266. }
  267. }
  268. #endif /* SNDRV_EMUX_USE_RAW_EFFECT */