1 /*---------------------------------------------------------------------------*
2   Project:  Mixer application for Remote Speakers
3   File:     remote.c
4 
5   Copyright (C)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: remote.c,v $
14   Revision 1.4  07/24/2006 10:33:27  aka
15   Revised initial value of mode.
16 
17   Revision 1.3  07/24/2006 10:15:07  aka
18   Removed test functions.
19 
20   Revision 1.2  07/24/2006 09:12:54  aka
21   Changed in ration to modification of AX lib.
22 
23   Revision 1.1  07/19/2006 07:52:33  aka
24   Initial check-in.
25 
26   $NoKeywords: $
27  *---------------------------------------------------------------------------*/
28 
29 #include <revolution.h>
30 #include <revolution/mix.h>
31 #include "mixprivate.h"
32 
33 /*---------------------------------------------------------------------------*
34     Internal variables for the mixer
35  *---------------------------------------------------------------------------*/
36 static MIXRmtChannel __MIXRmtChannel[AX_MAX_VOICES];
37 
38 /*---------------------------------------------------------------------------*
39     Exposed functions
40  *---------------------------------------------------------------------------*/
41 
42  /*---------------------------------------------------------------------------*
43      Name:           MIXRmtSetVolumes
44 
45      Description:    Set volumes for remote speakers.
46 
47 
48      Arguments:      axvpb   pointer to acquired voice
49                      mode    aux0,1,2,3 modes
50                      fade0   initial fader0 atten / gain
51                      fade1   initial fader1 atten / gain
52                      fade2   initial fader2 atten / gain
53                      fade3   initial fader3 atten / gain
54                      aux0    initial aux0   atten / gain
55                      aux1    initial aux1   atten / gain
56                      aux2    initial aux2   atten / gain
57                      aux3    initial aux3   atten / gain
58 
59      Returns:        None
60  *---------------------------------------------------------------------------*/
MIXRmtSetVolumes(AXVPB * axvpb,u32 mode,int fader0,int fader1,int fader2,int fader3,int aux0,int aux1,int aux2,int aux3)61 void MIXRmtSetVolumes(
62                       AXVPB *axvpb,   // pointer to voice
63                       u32    mode,    // aux0,1,2,3 modes
64                       int    fader0,  // initial fader0 atten / gain
65                       int    fader1,  // initial fader1 atten / gain
66                       int    fader2,  // initial fader2 atten / gain
67                       int    fader3,  // initial fader3 atten / gain
68                       int    aux0,    // initial aux0   atten / gain
69                       int    aux1,    // initial aux1   atten / gain
70                       int    aux2,    // initial aux2   atten / gain
71                       int    aux3     // initial aux3   atten / gain
72                      )
73 {
74     MIXRmtChannel *channel;
75 
76     ASSERT(axvpb);
77 
78     channel = &__MIXRmtChannel[axvpb->index];
79 
80     channel->mode  |= mode & (MIX_MODE_AUX0_PREFADER
81                               | MIX_MODE_AUX1_PREFADER
82                               | MIX_MODE_AUX2_PREFADER
83                               | MIX_MODE_AUX3_PREFADER);
84 
85     channel->fader0 = fader0;
86     channel->fader1 = fader1;
87     channel->fader2 = fader2;
88     channel->fader3 = fader3;
89 
90     channel->aux0   = aux0;
91     channel->aux1   = aux1;
92     channel->aux2   = aux2;
93     channel->aux3   = aux3;
94 
95     channel->mode |= MIX_MODE_UPDATE_MIX;
96 }
97 
98 
99 /*---------------------------------------------------------------------------*
100     Name:           MIXRmtAuxPostFader
101 
102     Description:    Set Aux 0..3 control to post fader mode for the specified
103                     voice.
104 
105     Arguments:      p   Pointer to voice
106                     num  Controller number
107 
108     Returns:        None
109  *---------------------------------------------------------------------------*/
MIXRmtAuxPostFader(AXVPB * p,int num)110 void MIXRmtAuxPostFader(AXVPB *p, int num)
111 {
112     MIXRmtChannel *channel = &__MIXRmtChannel[p->index];
113 
114     ASSERT((num >= 0) && (num < 4));
115 
116     channel->mode &= ~(MIX_MODE_AUX0_PREFADER << num);
117     channel->mode |= MIX_MODE_UPDATE_MIX;
118 }
119 
120 
121 /*---------------------------------------------------------------------------*
122     Name:           MIXRmtAuxPreFader
123 
124     Description:    Set Aux 0..3 control to pre fader mode for the specified
125                     voice.
126 
127     Arguments:      p   Pointer to voice
128                     num  Controller number
129 
130     Returns:        None
131  *---------------------------------------------------------------------------*/
MIXRmtAuxPreFader(AXVPB * p,int num)132 void MIXRmtAuxPreFader(AXVPB *p, int num)
133 {
134     MIXRmtChannel *channel = &__MIXRmtChannel[p->index];
135 
136     ASSERT((num >= 0) && (num < 4));
137 
138     channel->mode |= MIX_MODE_AUX0_PREFADER << num;
139     channel->mode |= MIX_MODE_UPDATE_MIX;
140 }
141 
142 
143 /*---------------------------------------------------------------------------*
144     Name:           MIXRmtAuxIsPostFader
145 
146     Description:    Check to see if Aux 0..3 is in post fader mode for the
147                     specified voice.
148 
149     Arguments:      p   Pointer to voice
150                     num  Controller number
151 
152     Returns:        TRUE if Aux 0..3 is in post fader mode, else FALSE.
153  *---------------------------------------------------------------------------*/
MIXRmtAuxIsPostFader(AXVPB * p,int num)154 BOOL MIXRmtAuxIsPostFader(AXVPB *p, int num)
155 {
156     MIXRmtChannel *channel = &__MIXRmtChannel[p->index];
157 
158     ASSERT((num >= 0) && (num < 4));
159 
160     if (channel->mode & (MIX_MODE_AUX0_PREFADER << num))
161     {
162         return FALSE;
163     }
164 
165     return TRUE;
166 }
167 
168 
169 /*---------------------------------------------------------------------------*
170     Name:           MIXRmtSetAux
171 
172     Description:    Set the attenuation for the Aux 0..3 control for the
173                     specified voice.
174 
175     Arguments:      p   Pointer to voice
176                     num  Controller number
177                     dB  Attenuation to set
178 
179     Returns:        None
180  *---------------------------------------------------------------------------*/
MIXRmtSetAux(AXVPB * p,int num,int dB)181 void MIXRmtSetAux(AXVPB *p, int num, int dB)
182 {
183     MIXRmtChannel *channel = &__MIXRmtChannel[p->index];
184 
185     ASSERT((num >= 0) && (num < 4));
186 
187     switch (num)
188     {
189         case 0:
190             channel->aux0 = dB;
191             break;
192         case 1:
193             channel->aux1 = dB;
194             break;
195         case 2:
196             channel->aux2 = dB;
197             break;
198         case 3:
199             channel->aux3 = dB;
200             break;
201     }
202 
203     channel->mode |= MIX_MODE_UPDATE_MIX;
204 }
205 
206 
207 /*---------------------------------------------------------------------------*
208     Name:           MIXRmtAdjustAux
209 
210     Description:    Add the specified amount of attenuation to the Aux 0..3
211                     control for the specified voice.
212 
213     Arguments:      p   Pointer to voice
214                     num  Controller number
215                     dB  Attenuation to add
216 
217     Returns:        None
218  *---------------------------------------------------------------------------*/
MIXRmtAdjustAux(AXVPB * p,int num,int dB)219 void MIXRmtAdjustAux(AXVPB *p, int num, int dB)
220 {
221     MIXRmtChannel *channel = &__MIXRmtChannel[p->index];
222 
223     ASSERT((num >= 0) && (num < 4));
224 
225     switch (num)
226     {
227         case 0:
228             channel->aux0 += dB;
229             break;
230         case 1:
231             channel->aux1 += dB;
232             break;
233         case 2:
234             channel->aux2 += dB;
235             break;
236         case 3:
237             channel->aux3 += dB;
238             break;
239     }
240 
241     channel->mode |= MIX_MODE_UPDATE_MIX;
242 }
243 
244 
245 /*---------------------------------------------------------------------------*
246     Name:           MIXRmtGetAux
247 
248     Description:    Returns attenuation for the Aux 0..3 control for the
249                     specified voice.
250 
251     Arguments:      p   Pointer to voice
252                     num  Controller number
253 
254     Returns:        Attenuation for Aux 0..3.
255  *---------------------------------------------------------------------------*/
MIXRmtGetAux(AXVPB * p,int num)256 int MIXRmtGetAux(AXVPB *p, int num)
257 {
258     MIXRmtChannel *channel = &__MIXRmtChannel[p->index];
259 
260     ASSERT((num >= 0) && (num < 4));
261 
262     switch (num)
263     {
264         case 0:
265             return channel->aux0;
266             break;
267         case 1:
268             return channel->aux1;
269             break;
270         case 2:
271             return channel->aux2;
272             break;
273     }
274 
275     return channel->aux3;
276 }
277 
278 
279 /*---------------------------------------------------------------------------*
280     Name:           MIXRmtSetFader
281 
282     Description:    Set fader attenuation for specified voice.
283 
284     Arguments:      p   Pointer to voice
285                     num  Controller number
286                     dB  Attenuation to set
287 
288     Returns:        None
289  *---------------------------------------------------------------------------*/
MIXRmtSetFader(AXVPB * p,int num,int dB)290 void MIXRmtSetFader(AXVPB *p, int num, int dB)
291 {
292     MIXRmtChannel *channel = &__MIXRmtChannel[p->index];
293 
294     ASSERT((num >= 0) && (num < 4));
295 
296     switch (num)
297     {
298         case 0:
299             channel->fader0 = dB;
300             break;
301         case 1:
302             channel->fader1 = dB;
303             break;
304         case 2:
305             channel->fader2 = dB;
306             break;
307         case 3:
308             channel->fader3 = dB;
309             break;
310     }
311 
312     channel->mode |= MIX_MODE_UPDATE_MIX;
313 }
314 
315 
316 /*---------------------------------------------------------------------------*
317     Name:           MIXRmtAdjustFader
318 
319     Description:    Adjust fader for specified voice
320 
321     Arguments:      p   Pointer to voice
322                     num  Controller number
323                     dB  Attenuation to add
324 
325     Returns:        None
326  *---------------------------------------------------------------------------*/
MIXRmtAdjustFader(AXVPB * p,int num,int dB)327 void MIXRmtAdjustFader(AXVPB *p, int num, int dB)
328 {
329     MIXRmtChannel *channel = &__MIXRmtChannel[p->index];
330 
331     ASSERT((num >= 0) && (num < 4));
332 
333     switch (num)
334     {
335         case 0:
336             channel->fader0 += dB;
337             break;
338         case 1:
339             channel->fader1 += dB;
340             break;
341         case 2:
342             channel->fader2 += dB;
343             break;
344         case 3:
345             channel->fader3 += dB;
346             break;
347     }
348 
349     channel->mode |= MIX_MODE_UPDATE_MIX;
350 }
351 
352 
353 /*---------------------------------------------------------------------------*
354     Name:           MIXRmtGetFader
355 
356     Description:    Returns fader attenuation for the specified voice.
357 
358     Arguments:      p   Pointer to voice
359                     num  Controller number
360 
361     Returns:        Attenuation for fader.
362  *---------------------------------------------------------------------------*/
MIXRmtGetFader(AXVPB * p,int num)363 int MIXRmtGetFader(AXVPB *p, int num)
364 {
365     MIXRmtChannel *channel = &__MIXRmtChannel[p->index];
366 
367     ASSERT((num >= 0) && (num < 4));
368 
369     switch (num)
370     {
371         case 0:
372             return channel->fader0;
373             break;
374         case 1:
375             return channel->fader1;
376             break;
377         case 2:
378             return channel->fader2;
379             break;
380     }
381 
382     return channel->fader3;
383 }
384 
385 
386 /*---------------------------------------------------------------------------*
387     Name:           __MIXRmtUpdateSettings
388 
389     Description:    Updates user settings to AX, this function should be
390                     called from the audio frame callback for AX to update the
391                     mixer settings every audio frame.
392 
393     Arguments:      chan  number of channel to update
394 
395     Returns:        None
396  *---------------------------------------------------------------------------*/
__MIXRmtUpdateSettings(s32 chan,AXVPB * axvpb)397 void __MIXRmtUpdateSettings(s32 chan, AXVPB* axvpb)
398 {
399     MIXRmtChannel *channel = &__MIXRmtChannel[chan];
400 
401     u16  mixerCtrl;
402     u16  *p;
403 
404     if (!(channel->mode & (MIX_MODE_UPDATE_MIX | MIX_MODE_UPDATE_MIX1)))
405     {
406         return;
407     }
408 
409     // take care of mix ramp that might have been set for last frame
410     if (channel->mode & MIX_MODE_UPDATE_MIX1)
411     {
412         // set the vX1 values to vX
413         channel->vMain0 = channel->vMain0_1;
414         channel->vAux0  = channel->vAux0_1;
415         channel->vMain1 = channel->vMain1_1;
416         channel->vAux1  = channel->vAux1_1;
417         channel->vMain2 = channel->vMain2_1;
418         channel->vAux2  = channel->vAux2_1;
419         channel->vMain3 = channel->vMain3_1;
420         channel->vAux3  = channel->vAux3_1;
421 
422         // clear the mix1 update flag for next frame
423         channel->mode &= ~MIX_MODE_UPDATE_MIX1;
424     }
425 
426     // see if any mixer settings need to be updated
427     if (channel->mode & MIX_MODE_UPDATE_MIX)
428     {
429         // volume updates in the DSP will always happen over 1 audio frame
430         // this is so we can ramp differences larger than AX_IN_SAMPLES_PER_FRAME ...
431         // to do this we place the new target value in vX1 and assert
432         // the bit for that buss in the ramp, on the following frame the
433         // vX1 value will be places into vX
434 
435         //
436         // main buss volume
437         //
438 
439         channel->vMain0_1 = __MIXGetVolume(channel->fader0); // fader0
440         channel->vMain1_1 = __MIXGetVolume(channel->fader1); // fader1
441         channel->vMain2_1 = __MIXGetVolume(channel->fader2); // fader2
442         channel->vMain3_1 = __MIXGetVolume(channel->fader3); // fader3
443 
444         //
445         // aux buss volume
446         //
447 
448         if (channel->mode & MIX_MODE_AUX0_PREFADER)
449         {
450             channel->vAux0_1 = __MIXGetVolume(channel->aux0);
451         }
452         else
453         {
454             channel->vAux0_1 = __MIXGetVolume(channel->fader0 + channel->aux0);
455         }
456 
457         if (channel->mode & MIX_MODE_AUX1_PREFADER)
458         {
459             channel->vAux1_1 = __MIXGetVolume(channel->aux1);
460 
461         }
462         else
463         {
464             channel->vAux1_1 = __MIXGetVolume(channel->fader1 + channel->aux1);
465         }
466 
467         if (channel->mode & MIX_MODE_AUX2_PREFADER)
468         {
469             channel->vAux2_1 = __MIXGetVolume(channel->aux2);
470         }
471         else
472         {
473             channel->vAux2_1 = __MIXGetVolume(channel->fader2 + channel->aux2);
474         }
475 
476         if (channel->mode & MIX_MODE_AUX3_PREFADER)
477         {
478             channel->vAux3_1 = __MIXGetVolume(channel->aux3);
479         }
480         else
481         {
482             channel->vAux3_1 = __MIXGetVolume(channel->fader3  + channel->aux3);
483         }
484 
485         // clear the update mix bit
486         channel->mode &= ~MIX_MODE_UPDATE_MIX;
487 
488         // assert the update for next frame
489         channel->mode |= MIX_MODE_UPDATE_MIX1;
490     }
491 
492     //
493     // update the new levels to the AX
494     //
495 
496     mixerCtrl  = 0;
497     p          = (u16*)&axvpb->pb.rmtMix;
498 
499     // main0
500     if((*p++ = channel->vMain0) != 0)
501         mixerCtrl |= AX_PB_MIXCTRL_MAIN0;
502     if((*p++ = (u16)((channel->vMain0_1 - channel->vMain0) / AX_RMT_SAMPLES_PER_FRAME)) != 0)
503         mixerCtrl |= AX_PB_MIXCTRL_MAIN0_RAMP;
504 
505     // aux0
506     if((*p++ = channel->vAux0) != 0)
507         mixerCtrl |= AX_PB_MIXCTRL_AUX0;
508     if((*p++ = (u16)((channel->vAux0_1 - channel->vAux0) / AX_RMT_SAMPLES_PER_FRAME)) != 0)
509         mixerCtrl |= AX_PB_MIXCTRL_AUX0_RAMP;
510 
511     // main1
512     if((*p++ = channel->vMain1) != 0)
513         mixerCtrl |= AX_PB_MIXCTRL_MAIN1;
514     if((*p++ = (u16)((channel->vMain1_1 - channel->vMain1) / AX_RMT_SAMPLES_PER_FRAME)) != 0)
515         mixerCtrl |= AX_PB_MIXCTRL_MAIN1_RAMP;
516 
517     // aux1
518     if((*p++ = channel->vAux1) != 0)
519         mixerCtrl |= AX_PB_MIXCTRL_AUX1;
520     if((*p++ = (u16)((channel->vAux1_1 - channel->vAux1) / AX_RMT_SAMPLES_PER_FRAME)) != 0)
521         mixerCtrl |= AX_PB_MIXCTRL_AUX1_RAMP;
522 
523     // main2
524     if((*p++ = channel->vMain2) != 0)
525         mixerCtrl |= AX_PB_MIXCTRL_MAIN2;
526     if((*p++ = (u16)((channel->vMain2_1 - channel->vMain2) / AX_RMT_SAMPLES_PER_FRAME)) != 0)
527         mixerCtrl |= AX_PB_MIXCTRL_MAIN2_RAMP;
528 
529     // aux2
530     if((*p++ = channel->vAux2) != 0)
531         mixerCtrl |= AX_PB_MIXCTRL_AUX2;
532     if((*p++ = (u16)((channel->vAux2_1 - channel->vAux2) / AX_RMT_SAMPLES_PER_FRAME)) != 0)
533         mixerCtrl |= AX_PB_MIXCTRL_AUX2_RAMP;
534 
535     // main3
536     if((*p++ = channel->vMain3) != 0)
537         mixerCtrl |= AX_PB_MIXCTRL_MAIN3;
538     if((*p++ = (u16)((channel->vMain3_1 - channel->vMain3) / AX_RMT_SAMPLES_PER_FRAME)) != 0)
539         mixerCtrl |= AX_PB_MIXCTRL_MAIN3_RAMP;
540 
541     // aux3
542     if((*p++ = channel->vAux3) != 0)
543         mixerCtrl |= AX_PB_MIXCTRL_AUX3;
544     if((*p++ = (u16)((channel->vAux3_1 - channel->vAux3) / AX_RMT_SAMPLES_PER_FRAME)) != 0)
545         mixerCtrl |= AX_PB_MIXCTRL_AUX3_RAMP;
546 
547     axvpb->pb.rmtMixerCtrl = mixerCtrl;
548 
549     axvpb->sync |= AX_SYNC_USER_RMTMIX | AX_SYNC_USER_RMTMIXCTRL;
550 }
551 
552 
553 /*---------------------------------------------------------------------------*
554     Name:           __MIXRmtResetChannel
555 
556     Description:    Reset specified channel on the mixer to initial values.
557 
558     Arguments:      chan  number of channel to reset
559 
560     Returns:        None
561  *---------------------------------------------------------------------------*/
__MIXRmtResetChannel(s32 chan)562 void __MIXRmtResetChannel(s32 chan)
563 {
564     MIXRmtChannel *channel = &__MIXRmtChannel[chan];
565 
566     channel->mode   = 0;
567 
568     channel->fader0 = 0;                // fader at 0
569     channel->fader1 = 0;                // fader at 0
570     channel->fader2 = 0;                // fader at 0
571     channel->fader3 = 0;                // fader at 0
572 
573     channel->aux0   = -960;             // -96.0 dB on AUX 0
574     channel->aux1   = -960;             // -96.0 dB on AUX 1
575     channel->aux2   = -960;             // -96.0 dB on AUX 2
576     channel->aux3   = -960;             // -96.0 dB on AUX 3
577 
578     channel->vMain0 =
579     channel->vAux0  =
580     channel->vMain1 =
581     channel->vAux1  =
582     channel->vMain2 =
583     channel->vAux2  =
584     channel->vMain3 =
585     channel->vAux3  = 0;
586 }
587