emu10k1_patch.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Patch transfer callback 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. * All the code for loading in a patch. There is very little that is
  22. * chip specific here. Just the actual writing to the board.
  23. */
  24. #include "emu10k1_synth_local.h"
  25. /*
  26. */
  27. #define BLANK_LOOP_START 4
  28. #define BLANK_LOOP_END 8
  29. #define BLANK_LOOP_SIZE 12
  30. #define BLANK_HEAD_SIZE 32
  31. /*
  32. * allocate a sample block and copy data from userspace
  33. */
  34. int
  35. snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
  36. struct snd_util_memhdr *hdr,
  37. const void __user *data, long count)
  38. {
  39. int offset;
  40. int truesize, size, loopsize, blocksize;
  41. int loopend, sampleend;
  42. unsigned int start_addr;
  43. struct snd_emu10k1 *emu;
  44. emu = rec->hw;
  45. if (snd_BUG_ON(!sp || !hdr))
  46. return -EINVAL;
  47. if (sp->v.size == 0) {
  48. dev_dbg(emu->card->dev,
  49. "emu: rom font for sample %d\n", sp->v.sample);
  50. return 0;
  51. }
  52. /* recalculate address offset */
  53. sp->v.end -= sp->v.start;
  54. sp->v.loopstart -= sp->v.start;
  55. sp->v.loopend -= sp->v.start;
  56. sp->v.start = 0;
  57. /* some samples have invalid data. the addresses are corrected in voice info */
  58. sampleend = sp->v.end;
  59. if (sampleend > sp->v.size)
  60. sampleend = sp->v.size;
  61. loopend = sp->v.loopend;
  62. if (loopend > sampleend)
  63. loopend = sampleend;
  64. /* be sure loop points start < end */
  65. if (sp->v.loopstart >= sp->v.loopend) {
  66. int tmp = sp->v.loopstart;
  67. sp->v.loopstart = sp->v.loopend;
  68. sp->v.loopend = tmp;
  69. }
  70. /* compute true data size to be loaded */
  71. truesize = sp->v.size + BLANK_HEAD_SIZE;
  72. loopsize = 0;
  73. #if 0 /* not supported */
  74. if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP))
  75. loopsize = sp->v.loopend - sp->v.loopstart;
  76. truesize += loopsize;
  77. #endif
  78. if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK)
  79. truesize += BLANK_LOOP_SIZE;
  80. /* try to allocate a memory block */
  81. blocksize = truesize;
  82. if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
  83. blocksize *= 2;
  84. sp->block = snd_emu10k1_synth_alloc(emu, blocksize);
  85. if (sp->block == NULL) {
  86. dev_dbg(emu->card->dev,
  87. "synth malloc failed (size=%d)\n", blocksize);
  88. /* not ENOMEM (for compatibility with OSS) */
  89. return -ENOSPC;
  90. }
  91. /* set the total size */
  92. sp->v.truesize = blocksize;
  93. /* write blank samples at head */
  94. offset = 0;
  95. size = BLANK_HEAD_SIZE;
  96. if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
  97. size *= 2;
  98. if (offset + size > blocksize)
  99. return -EINVAL;
  100. snd_emu10k1_synth_bzero(emu, sp->block, offset, size);
  101. offset += size;
  102. /* copy start->loopend */
  103. size = loopend;
  104. if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
  105. size *= 2;
  106. if (offset + size > blocksize)
  107. return -EINVAL;
  108. if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
  109. snd_emu10k1_synth_free(emu, sp->block);
  110. sp->block = NULL;
  111. return -EFAULT;
  112. }
  113. offset += size;
  114. data += size;
  115. #if 0 /* not supported yet */
  116. /* handle reverse (or bidirectional) loop */
  117. if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) {
  118. /* copy loop in reverse */
  119. if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
  120. int woffset;
  121. unsigned short *wblock = (unsigned short*)block;
  122. woffset = offset / 2;
  123. if (offset + loopsize * 2 > blocksize)
  124. return -EINVAL;
  125. for (i = 0; i < loopsize; i++)
  126. wblock[woffset + i] = wblock[woffset - i -1];
  127. offset += loopsize * 2;
  128. } else {
  129. if (offset + loopsize > blocksize)
  130. return -EINVAL;
  131. for (i = 0; i < loopsize; i++)
  132. block[offset + i] = block[offset - i -1];
  133. offset += loopsize;
  134. }
  135. /* modify loop pointers */
  136. if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_BIDIR_LOOP) {
  137. sp->v.loopend += loopsize;
  138. } else {
  139. sp->v.loopstart += loopsize;
  140. sp->v.loopend += loopsize;
  141. }
  142. /* add sample pointer */
  143. sp->v.end += loopsize;
  144. }
  145. #endif
  146. /* loopend -> sample end */
  147. size = sp->v.size - loopend;
  148. if (size < 0)
  149. return -EINVAL;
  150. if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
  151. size *= 2;
  152. if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
  153. snd_emu10k1_synth_free(emu, sp->block);
  154. sp->block = NULL;
  155. return -EFAULT;
  156. }
  157. offset += size;
  158. /* clear rest of samples (if any) */
  159. if (offset < blocksize)
  160. snd_emu10k1_synth_bzero(emu, sp->block, offset, blocksize - offset);
  161. if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) {
  162. /* if no blank loop is attached in the sample, add it */
  163. if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT) {
  164. sp->v.loopstart = sp->v.end + BLANK_LOOP_START;
  165. sp->v.loopend = sp->v.end + BLANK_LOOP_END;
  166. }
  167. }
  168. #if 0 /* not supported yet */
  169. if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) {
  170. /* unsigned -> signed */
  171. if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
  172. unsigned short *wblock = (unsigned short*)block;
  173. for (i = 0; i < truesize; i++)
  174. wblock[i] ^= 0x8000;
  175. } else {
  176. for (i = 0; i < truesize; i++)
  177. block[i] ^= 0x80;
  178. }
  179. }
  180. #endif
  181. /* recalculate offset */
  182. start_addr = BLANK_HEAD_SIZE * 2;
  183. if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
  184. start_addr >>= 1;
  185. sp->v.start += start_addr;
  186. sp->v.end += start_addr;
  187. sp->v.loopstart += start_addr;
  188. sp->v.loopend += start_addr;
  189. return 0;
  190. }
  191. /*
  192. * free a sample block
  193. */
  194. int
  195. snd_emu10k1_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp,
  196. struct snd_util_memhdr *hdr)
  197. {
  198. struct snd_emu10k1 *emu;
  199. emu = rec->hw;
  200. if (snd_BUG_ON(!sp || !hdr))
  201. return -EINVAL;
  202. if (sp->block) {
  203. snd_emu10k1_synth_free(emu, sp->block);
  204. sp->block = NULL;
  205. }
  206. return 0;
  207. }