emux_effect.c 8.7 KB

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