voicemgr.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /*
  2. **********************************************************************
  3. * voicemgr.c - Voice manager for emu10k1 driver
  4. * Copyright 1999, 2000 Creative Labs, Inc.
  5. *
  6. **********************************************************************
  7. *
  8. * Date Author Summary of changes
  9. * ---- ------ ------------------
  10. * October 20, 1999 Bertrand Lee base code release
  11. *
  12. **********************************************************************
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License as
  16. * published by the Free Software Foundation; either version 2 of
  17. * the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public
  25. * License along with this program; if not, write to the Free
  26. * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  27. * USA.
  28. *
  29. **********************************************************************
  30. */
  31. #include "voicemgr.h"
  32. #include "8010.h"
  33. #define PITCH_48000 0x00004000
  34. #define PITCH_96000 0x00008000
  35. #define PITCH_85000 0x00007155
  36. #define PITCH_80726 0x00006ba2
  37. #define PITCH_67882 0x00005a82
  38. #define PITCH_57081 0x00004c1c
  39. static u32 emu10k1_select_interprom(struct emu10k1_card *card,
  40. struct emu_voice *voice)
  41. {
  42. if(voice->pitch_target==PITCH_48000)
  43. return CCCA_INTERPROM_0;
  44. else if(voice->pitch_target<PITCH_48000)
  45. return CCCA_INTERPROM_1;
  46. else if(voice->pitch_target>=PITCH_96000)
  47. return CCCA_INTERPROM_0;
  48. else if(voice->pitch_target>=PITCH_85000)
  49. return CCCA_INTERPROM_6;
  50. else if(voice->pitch_target>=PITCH_80726)
  51. return CCCA_INTERPROM_5;
  52. else if(voice->pitch_target>=PITCH_67882)
  53. return CCCA_INTERPROM_4;
  54. else if(voice->pitch_target>=PITCH_57081)
  55. return CCCA_INTERPROM_3;
  56. else
  57. return CCCA_INTERPROM_2;
  58. }
  59. /**
  60. * emu10k1_voice_alloc_buffer -
  61. *
  62. * allocates the memory buffer for a voice. Two page tables are kept for each buffer.
  63. * One (dma_handle) keeps track of the host memory pages used and the other (virtualpagetable)
  64. * is passed to the device so that it can do DMA to host memory.
  65. *
  66. */
  67. int emu10k1_voice_alloc_buffer(struct emu10k1_card *card, struct voice_mem *mem, u32 pages)
  68. {
  69. u32 pageindex, pagecount;
  70. u32 busaddx;
  71. int i;
  72. DPD(2, "requested pages is: %d\n", pages);
  73. if ((mem->emupageindex = emu10k1_addxmgr_alloc(pages * PAGE_SIZE, card)) < 0)
  74. {
  75. DPF(1, "couldn't allocate emu10k1 address space\n");
  76. return -1;
  77. }
  78. /* Fill in virtual memory table */
  79. for (pagecount = 0; pagecount < pages; pagecount++) {
  80. if ((mem->addr[pagecount] = pci_alloc_consistent(card->pci_dev, PAGE_SIZE, &mem->dma_handle[pagecount]))
  81. == NULL) {
  82. mem->pages = pagecount;
  83. DPF(1, "couldn't allocate dma memory\n");
  84. return -1;
  85. }
  86. DPD(2, "Virtual Addx: %p\n", mem->addr[pagecount]);
  87. for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
  88. busaddx = (u32) mem->dma_handle[pagecount] + i * EMUPAGESIZE;
  89. DPD(3, "Bus Addx: %#x\n", busaddx);
  90. pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
  91. ((u32 *) card->virtualpagetable.addr)[pageindex] = cpu_to_le32((busaddx * 2) | pageindex);
  92. }
  93. }
  94. mem->pages = pagecount;
  95. return 0;
  96. }
  97. /**
  98. * emu10k1_voice_free_buffer -
  99. *
  100. * frees the memory buffer for a voice.
  101. */
  102. void emu10k1_voice_free_buffer(struct emu10k1_card *card, struct voice_mem *mem)
  103. {
  104. u32 pagecount, pageindex;
  105. int i;
  106. if (mem->emupageindex < 0)
  107. return;
  108. for (pagecount = 0; pagecount < mem->pages; pagecount++) {
  109. pci_free_consistent(card->pci_dev, PAGE_SIZE,
  110. mem->addr[pagecount],
  111. mem->dma_handle[pagecount]);
  112. for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
  113. pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
  114. ((u32 *) card->virtualpagetable.addr)[pageindex] =
  115. cpu_to_le32(((u32) card->silentpage.dma_handle * 2) | pageindex);
  116. }
  117. }
  118. emu10k1_addxmgr_free(card, mem->emupageindex);
  119. mem->emupageindex = -1;
  120. }
  121. int emu10k1_voice_alloc(struct emu10k1_card *card, struct emu_voice *voice)
  122. {
  123. u8 *voicetable = card->voicetable;
  124. int i;
  125. unsigned long flags;
  126. DPF(2, "emu10k1_voice_alloc()\n");
  127. spin_lock_irqsave(&card->lock, flags);
  128. if (voice->flags & VOICE_FLAGS_STEREO) {
  129. for (i = 0; i < NUM_G; i += 2)
  130. if ((voicetable[i] == VOICE_USAGE_FREE) && (voicetable[i + 1] == VOICE_USAGE_FREE)) {
  131. voicetable[i] = voice->usage;
  132. voicetable[i + 1] = voice->usage;
  133. break;
  134. }
  135. } else {
  136. for (i = 0; i < NUM_G; i++)
  137. if (voicetable[i] == VOICE_USAGE_FREE) {
  138. voicetable[i] = voice->usage;
  139. break;
  140. }
  141. }
  142. spin_unlock_irqrestore(&card->lock, flags);
  143. if (i >= NUM_G)
  144. return -1;
  145. voice->card = card;
  146. voice->num = i;
  147. for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
  148. DPD(2, " voice allocated -> %d\n", voice->num + i);
  149. sblive_writeptr_tag(card, voice->num + i, IFATN, 0xffff,
  150. DCYSUSV, 0,
  151. VTFT, 0x0000ffff,
  152. PTRX, 0,
  153. TAGLIST_END);
  154. }
  155. return 0;
  156. }
  157. void emu10k1_voice_free(struct emu_voice *voice)
  158. {
  159. struct emu10k1_card *card = voice->card;
  160. int i;
  161. unsigned long flags;
  162. DPF(2, "emu10k1_voice_free()\n");
  163. if (voice->usage == VOICE_USAGE_FREE)
  164. return;
  165. for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
  166. DPD(2, " voice released -> %d\n", voice->num + i);
  167. sblive_writeptr_tag(card, voice->num + i, DCYSUSV, 0,
  168. VTFT, 0x0000ffff,
  169. PTRX_PITCHTARGET, 0,
  170. CVCF, 0x0000ffff,
  171. //CPF, 0,
  172. TAGLIST_END);
  173. sblive_writeptr(card, CPF, voice->num + i, 0);
  174. }
  175. voice->usage = VOICE_USAGE_FREE;
  176. spin_lock_irqsave(&card->lock, flags);
  177. card->voicetable[voice->num] = VOICE_USAGE_FREE;
  178. if (voice->flags & VOICE_FLAGS_STEREO)
  179. card->voicetable[voice->num + 1] = VOICE_USAGE_FREE;
  180. spin_unlock_irqrestore(&card->lock, flags);
  181. }
  182. void emu10k1_voice_playback_setup(struct emu_voice *voice)
  183. {
  184. struct emu10k1_card *card = voice->card;
  185. u32 start;
  186. int i;
  187. DPF(2, "emu10k1_voice_playback_setup()\n");
  188. if (voice->flags & VOICE_FLAGS_STEREO) {
  189. /* Set stereo bit */
  190. start = 28;
  191. sblive_writeptr(card, CPF, voice->num, CPF_STEREO_MASK);
  192. sblive_writeptr(card, CPF, voice->num + 1, CPF_STEREO_MASK);
  193. } else {
  194. start = 30;
  195. sblive_writeptr(card, CPF, voice->num, 0);
  196. }
  197. if(!(voice->flags & VOICE_FLAGS_16BIT))
  198. start *= 2;
  199. voice->start += start;
  200. for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
  201. if (card->is_audigy) {
  202. sblive_writeptr(card, A_FXRT1, voice->num + i, voice->params[i].send_routing);
  203. sblive_writeptr(card, A_FXRT2, voice->num + i, voice->params[i].send_routing2);
  204. sblive_writeptr(card, A_SENDAMOUNTS, voice->num + i, voice->params[i].send_hgfe);
  205. } else {
  206. sblive_writeptr(card, FXRT, voice->num + i, voice->params[i].send_routing << 16);
  207. }
  208. /* Stop CA */
  209. /* Assumption that PT is already 0 so no harm overwriting */
  210. sblive_writeptr(card, PTRX, voice->num + i, ((voice->params[i].send_dcba & 0xff) << 8)
  211. | ((voice->params[i].send_dcba & 0xff00) >> 8));
  212. sblive_writeptr_tag(card, voice->num + i,
  213. /* CSL, ST, CA */
  214. DSL, voice->endloop | (voice->params[i].send_dcba & 0xff000000),
  215. PSST, voice->startloop | ((voice->params[i].send_dcba & 0x00ff0000) << 8),
  216. CCCA, (voice->start) | emu10k1_select_interprom(card,voice) |
  217. ((voice->flags & VOICE_FLAGS_16BIT) ? 0 : CCCA_8BITSELECT),
  218. /* Clear filter delay memory */
  219. Z1, 0,
  220. Z2, 0,
  221. /* Invalidate maps */
  222. MAPA, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
  223. MAPB, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
  224. /* modulation envelope */
  225. CVCF, 0x0000ffff,
  226. VTFT, 0x0000ffff,
  227. ATKHLDM, 0,
  228. DCYSUSM, 0x007f,
  229. LFOVAL1, 0x8000,
  230. LFOVAL2, 0x8000,
  231. FMMOD, 0,
  232. TREMFRQ, 0,
  233. FM2FRQ2, 0,
  234. ENVVAL, 0x8000,
  235. /* volume envelope */
  236. ATKHLDV, 0x7f7f,
  237. ENVVOL, 0x8000,
  238. /* filter envelope */
  239. PEFE_FILTERAMOUNT, 0x7f,
  240. /* pitch envelope */
  241. PEFE_PITCHAMOUNT, 0, TAGLIST_END);
  242. voice->params[i].fc_target = 0xffff;
  243. }
  244. }
  245. void emu10k1_voices_start(struct emu_voice *first_voice, unsigned int num_voices, int set)
  246. {
  247. struct emu10k1_card *card = first_voice->card;
  248. struct emu_voice *voice;
  249. unsigned int voicenum;
  250. int j;
  251. DPF(2, "emu10k1_voices_start()\n");
  252. for (voicenum = 0; voicenum < num_voices; voicenum++)
  253. {
  254. voice = first_voice + voicenum;
  255. if (!set) {
  256. u32 cra, ccis, cs, sample;
  257. if (voice->flags & VOICE_FLAGS_STEREO) {
  258. cra = 64;
  259. ccis = 28;
  260. cs = 4;
  261. } else {
  262. cra = 64;
  263. ccis = 30;
  264. cs = 2;
  265. }
  266. if(voice->flags & VOICE_FLAGS_16BIT) {
  267. sample = 0x00000000;
  268. } else {
  269. sample = 0x80808080;
  270. ccis *= 2;
  271. }
  272. for(j = 0; j < cs; j++)
  273. sblive_writeptr(card, CD0 + j, voice->num, sample);
  274. /* Reset cache */
  275. sblive_writeptr(card, CCR_CACHEINVALIDSIZE, voice->num, 0);
  276. if (voice->flags & VOICE_FLAGS_STEREO)
  277. sblive_writeptr(card, CCR_CACHEINVALIDSIZE, voice->num + 1, 0);
  278. sblive_writeptr(card, CCR_READADDRESS, voice->num, cra);
  279. if (voice->flags & VOICE_FLAGS_STEREO)
  280. sblive_writeptr(card, CCR_READADDRESS, voice->num + 1, cra);
  281. /* Fill cache */
  282. sblive_writeptr(card, CCR_CACHEINVALIDSIZE, voice->num, ccis);
  283. }
  284. for (j = 0; j < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); j++) {
  285. sblive_writeptr_tag(card, voice->num + j,
  286. IFATN, (voice->params[j].initial_fc << 8) | voice->params[j].initial_attn,
  287. VTFT, (voice->params[j].volume_target << 16) | voice->params[j].fc_target,
  288. CVCF, (voice->params[j].volume_target << 16) | voice->params[j].fc_target,
  289. DCYSUSV, (voice->params[j].byampl_env_sustain << 8) | voice->params[j].byampl_env_decay,
  290. TAGLIST_END);
  291. emu10k1_clear_stop_on_loop(card, voice->num + j);
  292. }
  293. }
  294. for (voicenum = 0; voicenum < num_voices; voicenum++)
  295. {
  296. voice = first_voice + voicenum;
  297. for (j = 0; j < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); j++) {
  298. sblive_writeptr(card, PTRX_PITCHTARGET, voice->num + j, voice->pitch_target);
  299. if (j == 0)
  300. sblive_writeptr(card, CPF_CURRENTPITCH, voice->num, voice->pitch_target);
  301. sblive_writeptr(card, IP, voice->num + j, voice->initial_pitch);
  302. }
  303. }
  304. }
  305. void emu10k1_voices_stop(struct emu_voice *first_voice, int num_voices)
  306. {
  307. struct emu10k1_card *card = first_voice->card;
  308. struct emu_voice *voice;
  309. unsigned int voice_num;
  310. int j;
  311. DPF(2, "emu10k1_voice_stop()\n");
  312. for (voice_num = 0; voice_num < num_voices; voice_num++)
  313. {
  314. voice = first_voice + voice_num;
  315. for (j = 0; j < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); j++) {
  316. sblive_writeptr_tag(card, voice->num + j,
  317. PTRX_PITCHTARGET, 0,
  318. CPF_CURRENTPITCH, 0,
  319. IFATN, 0xffff,
  320. VTFT, 0x0000ffff,
  321. CVCF, 0x0000ffff,
  322. IP, 0,
  323. TAGLIST_END);
  324. }
  325. }
  326. }