emu10k1_patch.c 5.4 KB

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