smb improvements (rodries)
[libogc.git] / libaesnd / aesndlib.c
blobe9c5f95c57cc9be8ea78ce272f84e75d214ad2e4
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <string.h>
4 #include <ogcsys.h>
5 #include <gccore.h>
6 #include <ogc/lwp_watchdog.h>
7 #include <ogc/machine/processor.h>
9 #include "aesndlib.h"
10 #include "dspmixer.h"
12 #define PB_STRUCT_SIZE 64
13 #define DSP_DRAMSIZE 8192
15 #define VOICE_PAUSE 0x00000004
16 #define VOICE_LOOP 0x00000008
17 #define VOICE_ONCE 0x00000010
18 #define VOICE_STREAM 0x00000020
20 #define VOICE_FINISHED 0x00100000
21 #define VOICE_STOPPED 0x00200000
22 #define VOICE_RUNNING 0x40000000
23 #define VOICE_USED 0x80000000
25 struct aesndpb_t
27 u32 out_buf; //0
29 u32 buf_start; //4
30 u32 buf_end; //8
31 u32 buf_curr; //12
33 u16 yn1; //16
34 u16 yn2; //18
35 u16 pds; //20
37 u16 freq_h; //22
38 u16 freq_l; //24
39 u16 counter; //26
41 s16 left,right; //28,30
42 u16 volume_l,volume_r; //32,34
44 u32 delay; //36
46 u32 flags; //40
48 u8 _pad[20];
50 u32 mram_start;
51 u32 mram_curr;
52 u32 mram_end;
53 u32 stream_last;
55 u32 voiceno;
56 u32 shift;
57 AESNDVoiceCallback cb;
59 AESNDAudioCallback audioCB;
60 } ATTRIBUTE_PACKED;
62 static dsptask_t __aesnddsptask;
64 static vu32 __aesndinit = 0;
65 static vu32 __aesndcurrab = 0;
66 static vu32 __aesnddspinit = 0;
67 static vu32 __aesndcurrvoice = 0;
68 static vu32 __aesnddspcomplete = 0;
69 static vu64 __aesnddspstarttime = 0;
70 static vu64 __aesnddspprocesstime = 0;
71 static vu32 __aesnddspabrequested = 0;
72 static volatile bool __aesndglobalpause = false;
73 static volatile bool __aesndvoicesstopped = true;
75 #if defined(HW_DOL)
76 static u32 __aesndarambase = 0;
77 static u32 __aesndaramblocks[MAX_VOICES];
78 static u32 __aesndarammemory[MAX_VOICES];
79 #endif
81 static AESNDPB __aesndvoicepb[MAX_VOICES];
82 static AESNDPB __aesndcommand ATTRIBUTE_ALIGN(32);
83 static u8 __dspdram[DSP_DRAMSIZE] ATTRIBUTE_ALIGN(32);
84 static u8 mute_buffer[SND_BUFFERSIZE] ATTRIBUTE_ALIGN(32);
85 static u8 audio_buffer[2][SND_BUFFERSIZE] ATTRIBUTE_ALIGN(32);
87 static __inline__ void snd_set0b(char *p,int n)
89 while(n>0) { *p++ = 0; n--; }
92 static __inline__ void snd_set0w(int *p,int n)
94 while(n>0) { *p++ = 0; n--; }
97 static __inline__ void __aesndcopycommand(AESNDPB *dst,AESNDPB *src)
99 dst->buf_start = src->buf_start;
100 dst->buf_end = src->buf_end;
101 dst->buf_curr = src->buf_curr;
103 dst->yn1 = src->yn1;
104 dst->yn2 = src->yn2;
105 dst->pds = src->pds;
107 dst->freq_h = src->freq_h;
108 dst->freq_l = src->freq_l;
109 dst->counter = src->counter;
111 dst->left = src->left;
112 dst->right = src->right;
114 dst->volume_l = src->volume_l;
115 dst->volume_r = src->volume_r;
117 dst->flags = src->flags;
118 dst->delay = src->delay;
120 dst->mram_start = src->mram_start;
121 dst->mram_curr = src->mram_curr;
122 dst->mram_end = src->mram_end;
123 dst->stream_last = src->stream_last;
125 dst->voiceno = src->voiceno;
126 dst->shift = src->shift;
127 dst->cb = src->cb;
130 static __inline__ void __aesndsetvoiceformat(AESNDPB *pb,u32 format)
132 pb->flags = (pb->flags&~0x03)|(format&0x03);
133 switch((format&0x03)) {
134 case VOICE_MONO8:
135 case VOICE_STEREO8:
136 pb->shift = 0;
137 break;
138 case VOICE_MONO16:
139 case VOICE_STEREO16:
140 pb->shift = 1;
141 break;
145 static __inline__ void __aesndsetvoicebuffer(AESNDPB *pb,void* buffer,u32 len)
147 pb->mram_start = (u32)buffer;
148 pb->mram_curr = (u32)buffer;
149 pb->mram_end = (u32)buffer + len;
152 static __inline__ void __aesndsetvoicefreq(AESNDPB *pb,u32 freq)
154 register u32 ratio = 0x00010000*((f32)freq/(f32)DSP_DEFAULT_FREQ);
155 pb->freq_h = (u16)(ratio>>16);
156 pb->freq_l = (u16)(ratio&0xffff);
159 #if defined(HW_DOL)
160 static ARQRequest arq_request[MAX_VOICES];
161 static u8 stream_buffer[DSP_STREAMBUFFER_SIZE*2] ATTRIBUTE_ALIGN(32);
163 static void __aesndarqcallback(ARQRequest *req)
165 __aesndvoicepb[req->owner].flags |= VOICE_RUNNING;
168 static void __aesndfillbuffer(AESNDPB *pb,u32 buffer)
170 register u32 copy_len;
171 register u32 buf_addr;
173 buf_addr = __aesndaramblocks[pb->voiceno];
174 if(buffer) buf_addr += DSP_STREAMBUFFER_SIZE;
176 copy_len = (pb->mram_end - pb->mram_curr);
177 if(copy_len>DSP_STREAMBUFFER_SIZE) copy_len = DSP_STREAMBUFFER_SIZE;
179 memcpy(stream_buffer,(void*)pb->mram_curr,copy_len);
180 if(copy_len<DSP_STREAMBUFFER_SIZE) memset(stream_buffer + copy_len,0,DSP_STREAMBUFFER_SIZE - copy_len);
182 DCFlushRange(stream_buffer,DSP_STREAMBUFFER_SIZE);
183 ARQ_PostRequestAsync(&arq_request[pb->voiceno],pb->voiceno,ARQ_MRAMTOARAM,ARQ_PRIO_HI,buf_addr,(u32)MEM_VIRTUAL_TO_PHYSICAL(stream_buffer),DSP_STREAMBUFFER_SIZE,NULL);
185 pb->mram_curr += copy_len;
188 static __inline__ void __aesndhandlerequest(AESNDPB *pb)
190 register u32 buf_addr;
191 register u32 copy_len;
193 if(pb->mram_curr>=pb->mram_end) {
194 if(pb->flags&VOICE_ONCE) {
195 pb->flags |= VOICE_STOPPED;
196 return;
197 } else if(pb->flags&VOICE_LOOP) pb->mram_curr = pb->mram_start;
198 else if(pb->cb) pb->cb(pb,VOICE_STATE_STREAM);
201 if(pb->buf_start) {
202 register u32 curr_pos = pb->buf_curr;
203 if(curr_pos<pb->stream_last)
204 __aesndfillbuffer(pb,1);
205 if(curr_pos>=(pb->buf_start + (DSP_STREAMBUFFER_SIZE>>pb->shift)) &&
206 pb->stream_last<(pb->buf_start + (DSP_STREAMBUFFER_SIZE>>pb->shift)))
207 __aesndfillbuffer(pb,0);
209 pb->stream_last = curr_pos;
210 return;
213 buf_addr = __aesndaramblocks[pb->voiceno];
214 pb->buf_start = buf_addr>>pb->shift;
215 pb->buf_end = (buf_addr + (DSP_STREAMBUFFER_SIZE*2) - (1<<pb->shift))>>pb->shift;
216 pb->buf_curr = pb->buf_start;
218 copy_len = (pb->mram_end - pb->mram_curr);
219 if(copy_len>(DSP_STREAMBUFFER_SIZE*2)) copy_len = (DSP_STREAMBUFFER_SIZE*2);
221 memcpy(stream_buffer,(void*)pb->mram_curr,copy_len);
222 if(copy_len<(DSP_STREAMBUFFER_SIZE*2)) memset(stream_buffer + copy_len,0,(DSP_STREAMBUFFER_SIZE*2) - copy_len);
224 DCFlushRange(stream_buffer,(DSP_STREAMBUFFER_SIZE*2));
225 ARQ_PostRequestAsync(&arq_request[pb->voiceno],pb->voiceno,ARQ_MRAMTOARAM,ARQ_PRIO_HI,buf_addr,(u32)MEM_VIRTUAL_TO_PHYSICAL(stream_buffer),(DSP_STREAMBUFFER_SIZE*2),__aesndarqcallback);
227 pb->mram_curr += copy_len;
229 #elif defined(HW_RVL)
230 static u8 stream_buffer[MAX_VOICES][DSP_STREAMBUFFER_SIZE*2] ATTRIBUTE_ALIGN(32);
232 static void __aesndfillbuffer(AESNDPB *pb,u32 buffer)
234 register u32 copy_len;
235 register u32 buf_addr;
237 buf_addr = (u32)stream_buffer[pb->voiceno];
238 if(buffer) buf_addr += DSP_STREAMBUFFER_SIZE;
240 copy_len = (pb->mram_end - pb->mram_curr);
241 if(copy_len>DSP_STREAMBUFFER_SIZE) copy_len = DSP_STREAMBUFFER_SIZE;
243 memcpy((void*)buf_addr,(void*)pb->mram_curr,copy_len);
244 if(copy_len<DSP_STREAMBUFFER_SIZE) memset((void*)(buf_addr + copy_len),0,DSP_STREAMBUFFER_SIZE - copy_len);
246 DCFlushRange((void*)buf_addr,DSP_STREAMBUFFER_SIZE);
248 pb->mram_curr += copy_len;
251 static __inline__ void __aesndhandlerequest(AESNDPB *pb)
253 register u32 buf_addr;
254 register u32 copy_len;
256 if(pb->mram_curr>=pb->mram_end) {
257 if(pb->flags&VOICE_ONCE) {
258 pb->buf_start = 0;
259 pb->flags |= VOICE_STOPPED;
260 return;
261 } else if(pb->flags&VOICE_LOOP) pb->mram_curr = pb->mram_start;
262 else if(pb->cb) pb->cb(pb,VOICE_STATE_STREAM);
265 if(pb->buf_start) {
266 register u32 curr_pos = pb->buf_curr;
267 if(curr_pos<pb->stream_last)
268 __aesndfillbuffer(pb,1);
269 if(curr_pos>=(pb->buf_start + (DSP_STREAMBUFFER_SIZE>>pb->shift)) &&
270 pb->stream_last<(pb->buf_start + (DSP_STREAMBUFFER_SIZE>>pb->shift)))
271 __aesndfillbuffer(pb,0);
273 pb->stream_last = curr_pos;
274 return;
277 buf_addr = (u32)MEM_VIRTUAL_TO_PHYSICAL(stream_buffer[pb->voiceno]);
278 pb->buf_start = buf_addr>>pb->shift;
279 pb->buf_end = (buf_addr + (DSP_STREAMBUFFER_SIZE*2) - (1<<pb->shift))>>pb->shift;
280 pb->buf_curr = pb->buf_start;
282 copy_len = (pb->mram_end - pb->mram_curr);
283 if(copy_len>(DSP_STREAMBUFFER_SIZE*2)) copy_len = (DSP_STREAMBUFFER_SIZE*2);
285 memcpy(stream_buffer,(void*)pb->mram_curr,copy_len);
286 if(copy_len<(DSP_STREAMBUFFER_SIZE*2)) memset(stream_buffer + copy_len,0,(DSP_STREAMBUFFER_SIZE*2) - copy_len);
288 DCFlushRange(stream_buffer,(DSP_STREAMBUFFER_SIZE*2));
290 pb->mram_curr += copy_len;
291 pb->flags |= VOICE_RUNNING;
293 #endif
295 static void __dsp_initcallback(dsptask_t *task)
297 DSP_SendMailTo(0xface0080);
298 while(DSP_CheckMailTo());
300 DSP_SendMailTo(MEM_VIRTUAL_TO_PHYSICAL(&__aesndcommand));
301 while(DSP_CheckMailTo());
303 __aesnddspinit = 1;
304 __aesnddspcomplete = 1;
307 static void __dsp_resumecallback(dsptask_t *task)
311 static void __dsp_requestcallback(dsptask_t *task)
313 if(__aesnddspabrequested==1) {
314 __aesnddspprocesstime = (gettime() - __aesnddspstarttime);
315 __aesnddspabrequested = 0;
316 __aesnddspcomplete = 1;
317 return;
320 DCInvalidateRange(&__aesndcommand,PB_STRUCT_SIZE);
322 if(__aesndcommand.flags&VOICE_FINISHED) {
323 __aesndcommand.flags &= ~VOICE_FINISHED;
325 __aesndhandlerequest(&__aesndcommand);
327 if(__aesndcommand.flags&VOICE_STOPPED && __aesndcommand.cb) __aesndcommand.cb(&__aesndcommand,VOICE_STATE_STOPPED);
329 __aesndcopycommand(&__aesndvoicepb[__aesndcurrvoice],&__aesndcommand);
331 __aesndcurrvoice++;
332 while(__aesndcurrvoice<MAX_VOICES && (!(__aesndvoicepb[__aesndcurrvoice].flags&VOICE_USED) || (__aesndvoicepb[__aesndcurrvoice].flags&VOICE_STOPPED))) __aesndcurrvoice++;
333 if(__aesndcurrvoice<MAX_VOICES) {
334 __aesndcopycommand(&__aesndcommand,&__aesndvoicepb[__aesndcurrvoice]);
336 if(__aesndcommand.cb) __aesndcommand.cb(&__aesndcommand,VOICE_STATE_RUNNING);
338 DCFlushRange(&__aesndcommand,PB_STRUCT_SIZE);
339 DSP_SendMailTo(0xface0020);
340 while(DSP_CheckMailTo());
341 return;
345 if(__aesndcurrvoice>=MAX_VOICES) {
346 DSP_SendMailTo(0xface0100);
347 while(DSP_CheckMailTo());
349 __aesnddspabrequested = 1;
353 static void __dsp_donecallback(dsptask_t *task)
355 __aesnddspinit = 0;
356 __aesnddspcomplete = 0;
357 __aesnddspabrequested = 0;
360 static void __audio_dma_callback()
362 void *ptr;
364 __aesndcurrab ^= 1;
365 if(__aesndglobalpause==true || __aesndvoicesstopped==true)
366 ptr = mute_buffer;
367 else
368 ptr = audio_buffer[__aesndcurrab];
370 if(__aesndcommand.audioCB) __aesndcommand.audioCB(ptr,SND_BUFFERSIZE);
371 AUDIO_InitDMA((u32)ptr,SND_BUFFERSIZE);
373 if(__aesndglobalpause==true) return;
374 if(!__aesnddspcomplete || !__aesnddspinit) return;
376 __aesndcurrvoice = 0;
377 __aesnddspprocesstime = 0;
378 while(__aesndcurrvoice<MAX_VOICES && (!(__aesndvoicepb[__aesndcurrvoice].flags&VOICE_USED) || (__aesndvoicepb[__aesndcurrvoice].flags&VOICE_STOPPED))) __aesndcurrvoice++;
379 if(__aesndcurrvoice>=MAX_VOICES) {
380 __aesndvoicesstopped = true;
381 return;
384 __aesnddspcomplete = 0;
385 __aesndvoicesstopped = false;
386 __aesndcopycommand(&__aesndcommand,&__aesndvoicepb[__aesndcurrvoice]);
388 if(__aesndcommand.cb) __aesndcommand.cb(&__aesndcommand,VOICE_STATE_RUNNING);
390 __aesndcommand.out_buf = (u32)MEM_VIRTUAL_TO_PHYSICAL(audio_buffer[__aesndcurrab]);
391 DCFlushRange(&__aesndcommand,PB_STRUCT_SIZE);
393 __aesnddspstarttime = gettime();
394 DSP_SendMailTo(0xface0010);
395 while(DSP_CheckMailTo());
399 static void __aesndloaddsptask(dsptask_t *task,const void *dsp_code,u32 dsp_code_size,const void *dram_image,u32 dram_size)
401 task->prio = 255;
402 task->iram_maddr = (void*)MEM_VIRTUAL_TO_PHYSICAL(dsp_code);
403 task->iram_len = dsp_code_size;
404 task->iram_addr = 0x0000;
405 task->dram_maddr = (void*)MEM_VIRTUAL_TO_PHYSICAL(dram_image);
406 task->dram_len = dram_size;
407 task->dram_addr = 0x0000;
408 task->init_vec = 0x0010;
409 task->res_cb = __dsp_resumecallback;
410 task->req_cb = __dsp_requestcallback;
411 task->init_cb = __dsp_initcallback;
412 task->done_cb = __dsp_donecallback;
413 DSP_AddTask(task);
416 void AESND_Init()
418 u32 i,level;
420 #if defined(HW_DOL)
421 __aesndarambase = AR_Init(__aesndarammemory,MAX_VOICES);
422 ARQ_Init();
423 #endif
424 DSP_Init();
425 AUDIO_Init(NULL);
426 AUDIO_StopDMA();
427 AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ);
429 _CPU_ISR_Disable(level);
430 if(!__aesndinit) {
431 __aesndinit = 1;
432 __aesndcurrab = 0;
433 __aesnddspinit = 0;
434 __aesnddspcomplete = 0;
435 __aesndglobalpause = false;
436 __aesndvoicesstopped = true;
438 #if defined(HW_DOL)
439 for(i=0;i<MAX_VOICES;i++) __aesndaramblocks[i] = AR_Alloc(DSP_STREAMBUFFER_SIZE*2);
440 #endif
441 snd_set0w((int*)mute_buffer,SND_BUFFERSIZE>>2);
442 snd_set0w((int*)stream_buffer,SND_BUFFERSIZE>>1);
443 snd_set0w((int*)audio_buffer[0],SND_BUFFERSIZE>>2);
444 snd_set0w((int*)audio_buffer[1],SND_BUFFERSIZE>>2);
445 DCFlushRange(mute_buffer,SND_BUFFERSIZE);
446 DCFlushRange(audio_buffer[0],SND_BUFFERSIZE);
447 DCFlushRange(audio_buffer[1],SND_BUFFERSIZE);
449 snd_set0w((int*)&__aesndcommand,sizeof(struct aesndpb_t)>>2);
450 for(i=0;i<MAX_VOICES;i++)
451 snd_set0w((int*)&__aesndvoicepb[i],sizeof(struct aesndpb_t)>>2);
453 __aesndloaddsptask(&__aesnddsptask,dspmixer,dspmixer_size,__dspdram,DSP_DRAMSIZE);
456 AUDIO_RegisterDMACallback(__audio_dma_callback);
457 AUDIO_InitDMA((u32)audio_buffer[__aesndcurrab],SND_BUFFERSIZE);
458 AUDIO_StartDMA();
460 _CPU_ISR_Restore(level);
463 void AESND_Reset()
465 u32 level;
467 _CPU_ISR_Disable(level);
468 if(__aesndinit) {
469 AUDIO_StopDMA();
470 AUDIO_RegisterDMACallback(NULL);
472 DSP_SendMailTo(0xfacedead);
473 while(DSP_CheckMailTo());
475 do {
476 _CPU_ISR_Flash(level);
477 } while(__aesnddspinit);
479 __aesndinit = 0;
481 _CPU_ISR_Restore(level);
484 void AESND_Pause(bool pause)
486 u32 level;
488 _CPU_ISR_Disable(level);
489 __aesndglobalpause = pause;
490 _CPU_ISR_Restore(level);
493 u32 AESND_GetDSPProcessTime()
495 u32 level;
496 u32 time = 0;
498 _CPU_ISR_Disable(level);
499 time = ticks_to_microsecs(__aesnddspprocesstime);
500 _CPU_ISR_Restore(level);
502 return time;
505 f32 AESND_GetDSPProcessUsage()
507 u32 level;
508 f32 usage = 0.0f;
510 _CPU_ISR_Disable(level);
511 usage = (ticks_to_microsecs(__aesnddspprocesstime)*100)/2000.0f;
512 _CPU_ISR_Restore(level);
514 return usage;
517 AESNDAudioCallback AESND_RegisterAudioCallback(AESNDAudioCallback cb)
519 u32 level;
520 AESNDAudioCallback aCB;
522 _CPU_ISR_Disable(level);
523 aCB = __aesndcommand.audioCB;
524 __aesndcommand.audioCB = cb;
525 _CPU_ISR_Restore(level);
527 return aCB;
530 AESNDPB* AESND_AllocateVoice(AESNDVoiceCallback cb)
532 u32 i,level;
533 AESNDPB *pb = NULL;
535 _CPU_ISR_Disable(level);
536 for(i=0;i<MAX_VOICES;i++) {
537 pb = &__aesndvoicepb[i];
538 if(!(pb->flags&VOICE_USED)) {
539 pb->voiceno = i;
540 pb->flags = (VOICE_USED|VOICE_STOPPED);
541 pb->pds = pb->yn1 = pb->yn2 = 0;
542 pb->buf_start = 0;
543 pb->buf_curr = 0;
544 pb->buf_end = 0;
545 pb->counter = 0;
546 pb->volume_l = 255;
547 pb->volume_r = 255;
548 pb->freq_h = 0x0001;
549 pb->freq_l = 0x0000;
550 pb->cb = cb;
551 break;
554 _CPU_ISR_Restore(level);
556 return pb;
559 void AESND_FreeVoice(AESNDPB *pb)
561 u32 level;
563 _CPU_ISR_Disable(level);
564 snd_set0w((int*)pb,sizeof(struct aesndpb_t)>>2);
565 _CPU_ISR_Restore(level);
568 void AESND_PlayVoice(AESNDPB *pb,u32 format,const void *buffer,u32 len,u32 freq,u32 delay,bool looped)
570 u32 level;
571 void *ptr = (void*)buffer;
573 _CPU_ISR_Disable(level);
574 __aesndsetvoiceformat(pb,format);
575 __aesndsetvoicefreq(pb,freq);
576 __aesndsetvoicebuffer(pb,ptr,len);
578 pb->flags &= ~(VOICE_RUNNING|VOICE_STOPPED|VOICE_LOOP|VOICE_ONCE);
579 if(looped==true)
580 pb->flags |= VOICE_LOOP;
581 else
582 pb->flags |= VOICE_ONCE;
584 pb->buf_start = pb->buf_curr = pb->buf_end = pb->stream_last = 0;
585 pb->delay = (delay*48);
586 pb->pds = pb->yn1 = pb->yn2 = 0;
587 pb->counter = 0;
588 _CPU_ISR_Restore(level);
591 void AESND_SetVoiceBuffer(AESNDPB *pb,const void *buffer,u32 len)
593 u32 level;
594 void *ptr = (void*)buffer;
596 _CPU_ISR_Disable(level);
597 __aesndsetvoicebuffer(pb,ptr,len);
598 _CPU_ISR_Restore(level);
601 void AESND_SetVoiceFormat(AESNDPB *pb,u32 format)
603 u32 level;
605 _CPU_ISR_Disable(level);
606 __aesndsetvoiceformat(pb,format);
607 _CPU_ISR_Restore(level);
610 void AESND_SetVoiceVolume(AESNDPB *pb,u16 volume_l,u16 volume_r)
612 u32 level;
614 _CPU_ISR_Disable(level);
615 pb->volume_l = volume_l;
616 pb->volume_r = volume_r;
617 _CPU_ISR_Restore(level);
620 void AESND_SetVoiceFrequency(AESNDPB *pb,u32 freq)
622 u32 level;
624 _CPU_ISR_Disable(level);
625 __aesndsetvoicefreq(pb,freq);
626 _CPU_ISR_Restore(level);
629 void AESND_SetVoiceStream(AESNDPB *pb,bool stream)
631 u32 level;
633 _CPU_ISR_Disable(level);
634 if(stream==true)
635 pb->flags |= VOICE_STREAM;
636 else
637 pb->flags &= ~VOICE_STREAM;
638 _CPU_ISR_Restore(level);
641 void AESND_SetVoiceLoop(AESNDPB *pb,bool loop)
643 u32 level;
645 _CPU_ISR_Disable(level);
646 if(loop==true)
647 pb->flags |= VOICE_LOOP;
648 else
649 pb->flags &= ~VOICE_LOOP;
650 _CPU_ISR_Restore(level);
653 void AESND_SetVoiceMute(AESNDPB *pb,bool mute)
655 u32 level;
657 _CPU_ISR_Disable(level);
658 if(mute==true)
659 pb->flags |= VOICE_PAUSE;
660 else
661 pb->flags &= ~VOICE_PAUSE;
662 _CPU_ISR_Restore(level);
665 void AESND_SetVoiceStop(AESNDPB *pb,bool stop)
667 u32 level;
669 _CPU_ISR_Disable(level);
670 if(stop==true)
671 pb->flags |= VOICE_STOPPED;
672 else
673 pb->flags &= ~VOICE_STOPPED;
674 _CPU_ISR_Restore(level);
677 AESNDVoiceCallback AESND_RegisterVoiceCallback(AESNDPB *pb,AESNDVoiceCallback cb)
679 u32 level;
680 AESNDVoiceCallback rcb = NULL;
682 _CPU_ISR_Disable(level);
683 rcb = pb->cb;
684 pb->cb = cb;
685 _CPU_ISR_Restore(level);
687 return rcb;