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