1 /*---------------------------------------------------------------------------*
2   Project:  Sound Pipeline (SP) for AX
3   File:     sp.c
4 
5   Copyright (C)1998-2006 Nintendo  All Rights Reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: sp.c,v $
14   Revision 1.3  2006/11/21 04:26:28  aka
15   Removed #ifndef HOLLYWOOD_REV - #else - #endif.
16   Removed assertion of the zero buffer.
17   Changed not to use the zero buffer.
18 
19   Revision 1.2  2006/01/31 07:12:23  aka
20   Changed arguments of SPInitSoundTable().
21   Added #ifndef HOLLYWOOD_REV - #else - #endif.
22 
23   Revision 1.1.1.1  2005/05/12 02:15:50  yasuh-to
24   Imported from dolphin tree.
25 
26     1     8/15/01 11:16a Billyjack
27     created
28 
29   $NoKeywords: $
30  *---------------------------------------------------------------------------*/
31 #include <revolution.h>
32 #include <revolution/sp.h>
33 
34 
35 /*---------------------------------------------------------------------------*
36  *---------------------------------------------------------------------------*/
SPInitSoundTable(SPSoundTable * table,u8 * samples,u8 * zerobuffer)37 void SPInitSoundTable(SPSoundTable *table, u8 *samples, u8 *zerobuffer)
38 {
39 #pragma unused(zerobuffer)
40 
41     int             i;
42     SPSoundEntry    *sound;
43     SPAdpcmEntry    *adpcm;
44     u32             mramBase, mramBase4, mramBase8, mramBase16;
45 
46     ASSERT(table);
47     ASSERT(samples);
48     //ASSERT(zerobuffer);
49 
50     // pre compute base addresses
51     mramBase   = OSCachedToPhysical(samples);
52     mramBase4  = mramBase << 1;
53     mramBase8  = mramBase;
54     mramBase16 = mramBase >> 1;
55 
56     // initialize pointers to objects
57     sound = &table->sound[0];
58     adpcm = (SPAdpcmEntry*)&table->sound[table->entries];
59 
60     // intialize objects
61     for (i = 0; i < table->entries; i++)
62     {
63         switch (sound->type)
64         {
65         case SP_TYPE_ADPCM_ONESHOT:
66 
67             sound->loopAddr     = mramBase4 + sound->currentAddr; // dummy
68             sound->loopEndAddr  = 0;                              // not used
69             sound->endAddr      = mramBase4 + sound->endAddr;
70             sound->currentAddr  = mramBase4 + sound->currentAddr;
71             sound->adpcm        = adpcm;
72 
73             adpcm++;
74 
75             break;
76 
77         case SP_TYPE_ADPCM_LOOPED:
78 
79             sound->loopAddr     = mramBase4 + sound->loopAddr;
80             sound->loopEndAddr  = mramBase4 + sound->loopEndAddr;
81             sound->endAddr      = mramBase4 + sound->endAddr;
82             sound->currentAddr  = mramBase4 + sound->currentAddr;
83             sound->adpcm        = adpcm;
84 
85             adpcm++;
86 
87             break;
88 
89         case SP_TYPE_PCM16_ONESHOT:
90 
91             sound->loopAddr     = mramBase16 + sound->currentAddr; // dummy
92             sound->loopEndAddr  = 0;                               // not used
93             sound->endAddr      = mramBase16 + sound->endAddr;
94             sound->currentAddr  = mramBase16 + sound->currentAddr;
95 
96             break;
97 
98         case SP_TYPE_PCM16_LOOPED:
99 
100             sound->loopAddr     = mramBase16 + sound->loopAddr;
101             sound->loopEndAddr  = mramBase16 + sound->loopEndAddr;
102             sound->endAddr      = mramBase16 + sound->endAddr;
103             sound->currentAddr  = mramBase16 + sound->currentAddr;
104 
105             break;
106 
107         case SP_TYPE_PCM8_ONESHOT:
108 
109             sound->loopAddr     = mramBase8 + sound->currentAddr; // dummy
110             sound->loopEndAddr  = 0;                              // not used
111             sound->endAddr      = mramBase8 + sound->endAddr;
112             sound->currentAddr  = mramBase8 + sound->currentAddr;
113 
114             break;
115 
116         case SP_TYPE_PCM8_LOOPED:
117 
118             sound->loopAddr     = mramBase8 + sound->loopAddr;
119             sound->loopEndAddr  = mramBase8 + sound->loopEndAddr;
120             sound->endAddr      = mramBase8 + sound->endAddr;
121             sound->currentAddr  = mramBase8 + sound->currentAddr;
122 
123             break;
124         }
125 
126         sound++;
127     }
128 }
129 
130 
131 /*---------------------------------------------------------------------------*
132  *---------------------------------------------------------------------------*/
SPGetSoundEntry(SPSoundTable * table,u32 index)133 SPSoundEntry * SPGetSoundEntry(SPSoundTable *table, u32 index)
134 {
135     ASSERT(table);
136 
137     if (table->entries > index)
138         return &table->sound[index];
139 
140     return NULL;
141 }
142 
143 
144 /*---------------------------------------------------------------------------*
145  *---------------------------------------------------------------------------*/
SPPrepareSound(SPSoundEntry * sound,AXVPB * axvpb,u32 sampleRate)146 void SPPrepareSound(SPSoundEntry *sound, AXVPB *axvpb, u32 sampleRate)
147 {
148     int old;
149     u32 srcBits, loopAddr, endAddr, currentAddr;
150     u16 *p, *p1;
151 
152     ASSERT(sound);
153     ASSERT(axvpb);
154 
155     srcBits = (u32)(0x00010000 * ((f32)sampleRate / AX_IN_SAMPLES_PER_SEC));
156 
157     switch (sound->type)
158     {
159     case SP_TYPE_ADPCM_ONESHOT:
160 
161         loopAddr    = sound->loopAddr;
162         endAddr     = sound->endAddr;
163         currentAddr = sound->currentAddr;
164 
165         p   = (u16*)&axvpb->pb.addr;
166         p1  = (u16*)sound->adpcm;
167 
168         old = OSDisableInterrupts();
169 
170         // addr bits
171         *p++    = AXPBADDR_LOOP_OFF;
172         *p++    = AX_PB_FORMAT_ADPCM;
173         *p++    = (u16)(loopAddr >> 16);
174         *p++    = (u16)(loopAddr & 0xffff);
175         *p++    = (u16)(endAddr >> 16);
176         *p++    = (u16)(endAddr & 0xffff);
177         *p++    = (u16)(currentAddr >> 16);
178         *p++    = (u16)(currentAddr & 0xffff);
179         // adpcm bits
180         *p++    = *p1++;
181         *p++    = *p1++;
182         *p++    = *p1++;
183         *p++    = *p1++;
184         *p++    = *p1++;
185         *p++    = *p1++;
186         *p++    = *p1++;
187         *p++    = *p1++;
188         *p++    = *p1++;
189         *p++    = *p1++;
190         *p++    = *p1++;
191         *p++    = *p1++;
192         *p++    = *p1++;
193         *p++    = *p1++;
194         *p++    = *p1++;
195         *p++    = *p1++;
196         *p++    = *p1++;
197         *p++    = *p1++;
198         *p++    = *p1++;
199         *p++    = *p1++;
200         // src bits
201         *p++    = (u16)(srcBits >> 16);
202         *p++    = (u16)(srcBits & 0xFFFF);
203         *p++    = 0;
204         *p++    = 0;
205         *p++    = 0;
206         *p++    = 0;
207         *p++    = 0;
208         // don't need ADPCM loop context
209 
210         axvpb->sync |= AX_SYNC_USER_ADDR | AX_SYNC_USER_ADPCM | AX_SYNC_USER_SRC;
211 
212         OSRestoreInterrupts(old);
213 
214         break;
215 
216     case SP_TYPE_ADPCM_LOOPED:
217 
218         loopAddr    = sound->loopAddr;
219         endAddr     = sound->loopEndAddr;
220         currentAddr = sound->currentAddr;
221 
222         p   = (u16*)&axvpb->pb.addr;
223         p1  = (u16*)sound->adpcm;
224 
225         old = OSDisableInterrupts();
226 
227         // addr bits
228         *p++    = AXPBADDR_LOOP_ON;
229         *p++    = AX_PB_FORMAT_ADPCM;
230         *p++    = (u16)(loopAddr >> 16);
231         *p++    = (u16)(loopAddr & 0xffff);
232         *p++    = (u16)(endAddr >> 16);
233         *p++    = (u16)(endAddr & 0xffff);
234         *p++    = (u16)(currentAddr >> 16);
235         *p++    = (u16)(currentAddr & 0xffff);
236         // adpcm bits
237         *p++    = *p1++;
238         *p++    = *p1++;
239         *p++    = *p1++;
240         *p++    = *p1++;
241         *p++    = *p1++;
242         *p++    = *p1++;
243         *p++    = *p1++;
244         *p++    = *p1++;
245         *p++    = *p1++;
246         *p++    = *p1++;
247         *p++    = *p1++;
248         *p++    = *p1++;
249         *p++    = *p1++;
250         *p++    = *p1++;
251         *p++    = *p1++;
252         *p++    = *p1++;
253         *p++    = *p1++;
254         *p++    = *p1++;
255         *p++    = *p1++;
256         *p++    = *p1++;
257         // src bits
258         *p++    = (u16)(srcBits >> 16);
259         *p++    = (u16)(srcBits & 0xFFFF);
260         *p++    = 0;
261         *p++    = 0;
262         *p++    = 0;
263         *p++    = 0;
264         *p++    = 0;
265         // ADPCM loop bits
266         *p++    = *p1++;
267         *p++    = *p1++;
268         *p++    = *p1++;
269 
270         axvpb->sync |= AX_SYNC_USER_ADDR | AX_SYNC_USER_ADPCM | AX_SYNC_USER_SRC | AX_SYNC_USER_ADPCMLOOP;
271 
272         OSRestoreInterrupts(old);
273 
274         break;
275 
276     case SP_TYPE_PCM16_ONESHOT:
277 
278         loopAddr    = sound->loopAddr;
279         endAddr     = sound->endAddr;
280         currentAddr = sound->currentAddr;
281 
282         p   = (u16*)&axvpb->pb.addr;
283 
284         old = OSDisableInterrupts();
285 
286         // addr bits
287         *p++    = AXPBADDR_LOOP_OFF;
288         *p++    = AX_PB_FORMAT_PCM16;
289         *p++    = (u16)(loopAddr >> 16);
290         *p++    = (u16)(loopAddr & 0xffff);
291         *p++    = (u16)(endAddr >> 16);
292         *p++    = (u16)(endAddr & 0xffff);
293         *p++    = (u16)(currentAddr >> 16);
294         *p++    = (u16)(currentAddr & 0xffff);
295         // adpcm bits
296         *p++    = 0;
297         *p++    = 0;
298         *p++    = 0;
299         *p++    = 0;
300         *p++    = 0;
301         *p++    = 0;
302         *p++    = 0;
303         *p++    = 0;
304         *p++    = 0;
305         *p++    = 0;
306         *p++    = 0;
307         *p++    = 0;
308         *p++    = 0;
309         *p++    = 0;
310         *p++    = 0;
311         *p++    = 0;
312         *p++    = 0x0800;
313         *p++    = 0;
314         *p++    = 0;
315         *p++    = 0;
316         // src bits
317         *p++    = (u16)(srcBits >> 16);
318         *p++    = (u16)(srcBits & 0xFFFF);
319         *p++    = 0;
320         *p++    = 0;
321         *p++    = 0;
322         *p++    = 0;
323         *p++    = 0;
324         // don't need ADPCM loop context
325 
326         axvpb->sync |= AX_SYNC_USER_ADDR | AX_SYNC_USER_ADPCM | AX_SYNC_USER_SRC;
327 
328         OSRestoreInterrupts(old);
329 
330         break;
331 
332     case SP_TYPE_PCM16_LOOPED:
333 
334         loopAddr    = sound->loopAddr;
335         endAddr     = sound->loopEndAddr;
336         currentAddr = sound->currentAddr;
337 
338         p   = (u16*)&axvpb->pb.addr;
339 
340         old = OSDisableInterrupts();
341 
342         // addr bits
343         *p++    = AXPBADDR_LOOP_ON;
344         *p++    = AX_PB_FORMAT_PCM16;
345         *p++    = (u16)(loopAddr >> 16);
346         *p++    = (u16)(loopAddr & 0xffff);
347         *p++    = (u16)(endAddr >> 16);
348         *p++    = (u16)(endAddr & 0xffff);
349         *p++    = (u16)(currentAddr >> 16);
350         *p++    = (u16)(currentAddr & 0xffff);
351         // adpcm bits
352         *p++    = 0;
353         *p++    = 0;
354         *p++    = 0;
355         *p++    = 0;
356         *p++    = 0;
357         *p++    = 0;
358         *p++    = 0;
359         *p++    = 0;
360         *p++    = 0;
361         *p++    = 0;
362         *p++    = 0;
363         *p++    = 0;
364         *p++    = 0;
365         *p++    = 0;
366         *p++    = 0;
367         *p++    = 0;
368         *p++    = 0x0800;
369         *p++    = 0;
370         *p++    = 0;
371         *p++    = 0;
372         // src bits
373         *p++    = (u16)(srcBits >> 16);
374         *p++    = (u16)(srcBits & 0xFFFF);
375         *p++    = 0;
376         *p++    = 0;
377         *p++    = 0;
378         *p++    = 0;
379         *p++    = 0;
380         // don't need ADPCM loop context
381 
382         axvpb->sync |= AX_SYNC_USER_ADDR | AX_SYNC_USER_ADPCM | AX_SYNC_USER_SRC;
383 
384         OSRestoreInterrupts(old);
385 
386         break;
387 
388     case SP_TYPE_PCM8_ONESHOT:
389 
390         loopAddr    = sound->loopAddr;
391         endAddr     = sound->endAddr;
392         currentAddr = sound->currentAddr;
393 
394         p   = (u16*)&axvpb->pb.addr;
395 
396         old = OSDisableInterrupts();
397 
398         // addr bits
399         *p++    = AXPBADDR_LOOP_OFF;
400         *p++    = AX_PB_FORMAT_PCM8;
401         *p++    = (u16)(loopAddr >> 16);
402         *p++    = (u16)(loopAddr & 0xffff);
403         *p++    = (u16)(endAddr >> 16);
404         *p++    = (u16)(endAddr & 0xffff);
405         *p++    = (u16)(currentAddr >> 16);
406         *p++    = (u16)(currentAddr & 0xffff);
407         // adpcm bits
408         *p++    = 0;
409         *p++    = 0;
410         *p++    = 0;
411         *p++    = 0;
412         *p++    = 0;
413         *p++    = 0;
414         *p++    = 0;
415         *p++    = 0;
416         *p++    = 0;
417         *p++    = 0;
418         *p++    = 0;
419         *p++    = 0;
420         *p++    = 0;
421         *p++    = 0;
422         *p++    = 0;
423         *p++    = 0;
424         *p++    = 0x0100;
425         *p++    = 0;
426         *p++    = 0;
427         *p++    = 0;
428         // src bits
429         *p++    = (u16)(srcBits >> 16);
430         *p++    = (u16)(srcBits & 0xFFFF);
431         *p++    = 0;
432         *p++    = 0;
433         *p++    = 0;
434         *p++    = 0;
435         *p++    = 0;
436         // don't need ADPCM loop context
437 
438         axvpb->sync |= AX_SYNC_USER_ADDR | AX_SYNC_USER_ADPCM | AX_SYNC_USER_SRC;
439 
440         OSRestoreInterrupts(old);
441 
442         break;
443 
444     case SP_TYPE_PCM8_LOOPED:
445 
446         loopAddr    = sound->loopAddr;
447         endAddr     = sound->loopEndAddr;
448         currentAddr = sound->currentAddr;
449 
450         p   = (u16*)&axvpb->pb.addr;
451 
452         old = OSDisableInterrupts();
453 
454         // addr bits
455         *p++    = AXPBADDR_LOOP_ON;
456         *p++    = AX_PB_FORMAT_PCM8;
457         *p++    = (u16)(loopAddr >> 16);
458         *p++    = (u16)(loopAddr & 0xffff);
459         *p++    = (u16)(endAddr >> 16);
460         *p++    = (u16)(endAddr & 0xffff);
461         *p++    = (u16)(currentAddr >> 16);
462         *p++    = (u16)(currentAddr & 0xffff);
463         // adpcm bits
464         *p++    = 0;
465         *p++    = 0;
466         *p++    = 0;
467         *p++    = 0;
468         *p++    = 0;
469         *p++    = 0;
470         *p++    = 0;
471         *p++    = 0;
472         *p++    = 0;
473         *p++    = 0;
474         *p++    = 0;
475         *p++    = 0;
476         *p++    = 0;
477         *p++    = 0;
478         *p++    = 0;
479         *p++    = 0;
480         *p++    = 0x0100;
481         *p++    = 0;
482         *p++    = 0;
483         *p++    = 0;
484         // src bits
485         *p++    = (u16)(srcBits >> 16);
486         *p++    = (u16)(srcBits & 0xFFFF);
487         *p++    = 0;
488         *p++    = 0;
489         *p++    = 0;
490         *p++    = 0;
491         *p++    = 0;
492         // don't need ADPCM loop context
493 
494         axvpb->sync |= AX_SYNC_USER_ADDR | AX_SYNC_USER_ADPCM | AX_SYNC_USER_SRC;
495 
496         OSRestoreInterrupts(old);
497 
498         break;
499         }
500 }
501 
502 
503 /*---------------------------------------------------------------------------*
504  *---------------------------------------------------------------------------*/
SPPrepareEnd(SPSoundEntry * sound,AXVPB * axvpb)505 void SPPrepareEnd(SPSoundEntry *sound, AXVPB *axvpb)
506 {
507     int old;
508 
509     ASSERT(sound);
510     ASSERT(axvpb);
511 
512     old = OSDisableInterrupts();
513 
514     axvpb->pb.addr.loopFlag     = AXPBADDR_LOOP_OFF;
515     axvpb->pb.addr.endAddressHi = (u16)(sound->endAddr >> 16);
516     axvpb->pb.addr.endAddressLo = (u16)(sound->endAddr & 0xFFFF);
517 
518     axvpb->sync |= AX_SYNC_USER_LOOP | AX_SYNC_USER_ENDADDR;
519 
520     OSRestoreInterrupts(old);
521 }
522