/*---------------------------------------------------------------------------* Project: Mixer application for Remote Speakers File: remote.c Copyright (C)2006 Nintendo All Rights Reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Log: remote.c,v $ Revision 1.6 2006/10/23 01:52:27 aka Added __s_MIXRmtChannel[]. Revision 1.5 2006/10/06 08:05:55 aka Changed __MIXRmtChannel. Revision 1.4 2006/07/24 10:33:27 aka Revised initial value of mode. Revision 1.3 2006/07/24 10:15:07 aka Removed test functions. Revision 1.2 2006/07/24 09:12:54 aka Changed in ration to modification of AX lib. Revision 1.1 2006/07/19 07:52:33 aka Initial check-in. $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #include "mixprivate.h" /*---------------------------------------------------------------------------* Internal variables for the mixer *---------------------------------------------------------------------------*/ MIXRmtChannel* __MIXRmtChannel = NULL; MIXRmtChannel __s_MIXRmtChannel[AX_MAX_VOICES]; /*---------------------------------------------------------------------------* Exposed functions *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* Name: MIXRmtSetVolumes Description: Set volumes for remote speakers. Arguments: axvpb ointer to acquired voice mode aux0,1,2,3 modes fade0 initial fader0 atten / gain fade1 initial fader1 atten / gain fade2 initial fader2 atten / gain fade3 initial fader3 atten / gain aux0 initial aux0 atten / gain aux1 initial aux1 atten / gain aux2 initial aux2 atten / gain aux3 initial aux3 atten / gain Returns: None *---------------------------------------------------------------------------*/ void MIXRmtSetVolumes( AXVPB *axvpb, // pointer to voice u32 mode, // aux0,1,2,3 modes int fader0, // initial fader0 atten / gain int fader1, // initial fader1 atten / gain int fader2, // initial fader2 atten / gain int fader3, // initial fader3 atten / gain int aux0, // initial aux0 atten / gain int aux1, // initial aux1 atten / gain int aux2, // initial aux2 atten / gain int aux3 // initial aux3 atten / gain ) { MIXRmtChannel *channel; ASSERT(axvpb); channel = &__MIXRmtChannel[axvpb->index]; channel->mode |= mode & (MIX_MODE_AUX0_PREFADER | MIX_MODE_AUX1_PREFADER | MIX_MODE_AUX2_PREFADER | MIX_MODE_AUX3_PREFADER); channel->fader0 = fader0; channel->fader1 = fader1; channel->fader2 = fader2; channel->fader3 = fader3; channel->aux0 = aux0; channel->aux1 = aux1; channel->aux2 = aux2; channel->aux3 = aux3; channel->mode |= MIX_MODE_UPDATE_MIX; } /*---------------------------------------------------------------------------* Name: MIXRmtAuxPostFader Description: Set Aux 0..3 control to post fader mode for the specified voice. Arguments: p Pointer to voice num Controller number Returns: None *---------------------------------------------------------------------------*/ void MIXRmtAuxPostFader(AXVPB *p, int num) { MIXRmtChannel *channel = &__MIXRmtChannel[p->index]; ASSERT((num >= 0) && (num < 4)); channel->mode &= ~(MIX_MODE_AUX0_PREFADER << num); channel->mode |= MIX_MODE_UPDATE_MIX; } /*---------------------------------------------------------------------------* Name: MIXRmtAuxPreFader Description: Set Aux 0..3 control to pre fader mode for the specified voice. Arguments: p Pointer to voice num Controller number Returns: None *---------------------------------------------------------------------------*/ void MIXRmtAuxPreFader(AXVPB *p, int num) { MIXRmtChannel *channel = &__MIXRmtChannel[p->index]; ASSERT((num >= 0) && (num < 4)); channel->mode |= MIX_MODE_AUX0_PREFADER << num; channel->mode |= MIX_MODE_UPDATE_MIX; } /*---------------------------------------------------------------------------* Name: MIXRmtAuxIsPostFader Description: Check to see if Aux 0..3 is in post fader mode for the specified voice. Arguments: p Pointer to voice num Controller number Returns: TRUE if Aux 0..3 is in post fader mode, else FALSE. *---------------------------------------------------------------------------*/ BOOL MIXRmtAuxIsPostFader(AXVPB *p, int num) { MIXRmtChannel *channel = &__MIXRmtChannel[p->index]; ASSERT((num >= 0) && (num < 4)); if (channel->mode & (MIX_MODE_AUX0_PREFADER << num)) { return FALSE; } return TRUE; } /*---------------------------------------------------------------------------* Name: MIXRmtSetAux Description: Set the attenuation for the Aux 0..3 control for the specified voice. Arguments: p Pointer to voice num Controller number dB Attenuation to set Returns: None *---------------------------------------------------------------------------*/ void MIXRmtSetAux(AXVPB *p, int num, int dB) { MIXRmtChannel *channel = &__MIXRmtChannel[p->index]; ASSERT((num >= 0) && (num < 4)); switch (num) { case 0: channel->aux0 = dB; break; case 1: channel->aux1 = dB; break; case 2: channel->aux2 = dB; break; case 3: channel->aux3 = dB; break; } channel->mode |= MIX_MODE_UPDATE_MIX; } /*---------------------------------------------------------------------------* Name: MIXRmtAdjustAux Description: Add the specified amount of attenuation to the Aux 0..3 control for the specified voice. Arguments: p Pointer to voice num Controller number dB Attenuation to add Returns: None *---------------------------------------------------------------------------*/ void MIXRmtAdjustAux(AXVPB *p, int num, int dB) { MIXRmtChannel *channel = &__MIXRmtChannel[p->index]; ASSERT((num >= 0) && (num < 4)); switch (num) { case 0: channel->aux0 += dB; break; case 1: channel->aux1 += dB; break; case 2: channel->aux2 += dB; break; case 3: channel->aux3 += dB; break; } channel->mode |= MIX_MODE_UPDATE_MIX; } /*---------------------------------------------------------------------------* Name: MIXRmtGetAux Description: Returns attenuation for the Aux 0..3 control for the specified voice. Arguments: p Pointer to voice num Controller number Returns: Attenuation for Aux 0..3. *---------------------------------------------------------------------------*/ int MIXRmtGetAux(AXVPB *p, int num) { MIXRmtChannel *channel = &__MIXRmtChannel[p->index]; ASSERT((num >= 0) && (num < 4)); switch (num) { case 0: return channel->aux0; break; case 1: return channel->aux1; break; case 2: return channel->aux2; break; } return channel->aux3; } /*---------------------------------------------------------------------------* Name: MIXRmtSetFader Description: Set fader attenuation for specified voice. Arguments: p Pointer to voice num Controller number dB Attenuation to set Returns: None *---------------------------------------------------------------------------*/ void MIXRmtSetFader(AXVPB *p, int num, int dB) { MIXRmtChannel *channel = &__MIXRmtChannel[p->index]; ASSERT((num >= 0) && (num < 4)); switch (num) { case 0: channel->fader0 = dB; break; case 1: channel->fader1 = dB; break; case 2: channel->fader2 = dB; break; case 3: channel->fader3 = dB; break; } channel->mode |= MIX_MODE_UPDATE_MIX; } /*---------------------------------------------------------------------------* Name: MIXRmtAdjustFader Description: Adjust fader for specified voice Arguments: p Pointer to voice num Controller number dB Attenuation to add Returns: None *---------------------------------------------------------------------------*/ void MIXRmtAdjustFader(AXVPB *p, int num, int dB) { MIXRmtChannel *channel = &__MIXRmtChannel[p->index]; ASSERT((num >= 0) && (num < 4)); switch (num) { case 0: channel->fader0 += dB; break; case 1: channel->fader1 += dB; break; case 2: channel->fader2 += dB; break; case 3: channel->fader3 += dB; break; } channel->mode |= MIX_MODE_UPDATE_MIX; } /*---------------------------------------------------------------------------* Name: MIXRmtGetFader Description: Returns fader attenuation for the specified voice. Arguments: p Pointer to voice num Controller number Returns: Attenuation for fader. *---------------------------------------------------------------------------*/ int MIXRmtGetFader(AXVPB *p, int num) { MIXRmtChannel *channel = &__MIXRmtChannel[p->index]; ASSERT((num >= 0) && (num < 4)); switch (num) { case 0: return channel->fader0; break; case 1: return channel->fader1; break; case 2: return channel->fader2; break; } return channel->fader3; } /*---------------------------------------------------------------------------* Name: __MIXRmtUpdateSettings Description: Updates user settings to AX, this function should be called from the audio frame callback for AX to update the mixer settings every audio frame. Arguments: chan number of channel to update Returns: None *---------------------------------------------------------------------------*/ void __MIXRmtUpdateSettings(s32 chan, AXVPB* axvpb) { MIXRmtChannel *channel = &__MIXRmtChannel[chan]; u16 mixerCtrl; u16 *p; if (!(channel->mode & (MIX_MODE_UPDATE_MIX | MIX_MODE_UPDATE_MIX1))) { return; } // take care of mix ramp that might have been set for last frame if (channel->mode & MIX_MODE_UPDATE_MIX1) { // set the vX1 values to vX channel->vMain0 = channel->vMain0_1; channel->vAux0 = channel->vAux0_1; channel->vMain1 = channel->vMain1_1; channel->vAux1 = channel->vAux1_1; channel->vMain2 = channel->vMain2_1; channel->vAux2 = channel->vAux2_1; channel->vMain3 = channel->vMain3_1; channel->vAux3 = channel->vAux3_1; // clear the mix1 update flag for next frame channel->mode &= ~MIX_MODE_UPDATE_MIX1; } // see if any mixer settings need to be updated if (channel->mode & MIX_MODE_UPDATE_MIX) { // volume updates in the DSP will always happen over 1 audio frame // this is so we can ramp differences larger than AX_IN_SAMPLES_PER_FRAME ... // to do this we place the new target value in vX1 and assert // the bit for that buss in the ramp, on the following frame the // vX1 value will be places into vX // // main buss volume // channel->vMain0_1 = __MIXGetVolume(channel->fader0); // fader0 channel->vMain1_1 = __MIXGetVolume(channel->fader1); // fader1 channel->vMain2_1 = __MIXGetVolume(channel->fader2); // fader2 channel->vMain3_1 = __MIXGetVolume(channel->fader3); // fader3 // // aux buss volume // if (channel->mode & MIX_MODE_AUX0_PREFADER) { channel->vAux0_1 = __MIXGetVolume(channel->aux0); } else { channel->vAux0_1 = __MIXGetVolume(channel->fader0 + channel->aux0); } if (channel->mode & MIX_MODE_AUX1_PREFADER) { channel->vAux1_1 = __MIXGetVolume(channel->aux1); } else { channel->vAux1_1 = __MIXGetVolume(channel->fader1 + channel->aux1); } if (channel->mode & MIX_MODE_AUX2_PREFADER) { channel->vAux2_1 = __MIXGetVolume(channel->aux2); } else { channel->vAux2_1 = __MIXGetVolume(channel->fader2 + channel->aux2); } if (channel->mode & MIX_MODE_AUX3_PREFADER) { channel->vAux3_1 = __MIXGetVolume(channel->aux3); } else { channel->vAux3_1 = __MIXGetVolume(channel->fader3 + channel->aux3); } // clear the update mix bit channel->mode &= ~MIX_MODE_UPDATE_MIX; // assert the update for next frame channel->mode |= MIX_MODE_UPDATE_MIX1; } // // update the new levels to the AX // mixerCtrl = 0; p = (u16*)&axvpb->pb.rmtMix; // main0 if((*p++ = channel->vMain0) != 0) mixerCtrl |= AX_PB_MIXCTRL_MAIN0; if((*p++ = (u16)((channel->vMain0_1 - channel->vMain0) / AX_RMT_SAMPLES_PER_FRAME)) != 0) mixerCtrl |= AX_PB_MIXCTRL_MAIN0_RAMP; // aux0 if((*p++ = channel->vAux0) != 0) mixerCtrl |= AX_PB_MIXCTRL_AUX0; if((*p++ = (u16)((channel->vAux0_1 - channel->vAux0) / AX_RMT_SAMPLES_PER_FRAME)) != 0) mixerCtrl |= AX_PB_MIXCTRL_AUX0_RAMP; // main1 if((*p++ = channel->vMain1) != 0) mixerCtrl |= AX_PB_MIXCTRL_MAIN1; if((*p++ = (u16)((channel->vMain1_1 - channel->vMain1) / AX_RMT_SAMPLES_PER_FRAME)) != 0) mixerCtrl |= AX_PB_MIXCTRL_MAIN1_RAMP; // aux1 if((*p++ = channel->vAux1) != 0) mixerCtrl |= AX_PB_MIXCTRL_AUX1; if((*p++ = (u16)((channel->vAux1_1 - channel->vAux1) / AX_RMT_SAMPLES_PER_FRAME)) != 0) mixerCtrl |= AX_PB_MIXCTRL_AUX1_RAMP; // main2 if((*p++ = channel->vMain2) != 0) mixerCtrl |= AX_PB_MIXCTRL_MAIN2; if((*p++ = (u16)((channel->vMain2_1 - channel->vMain2) / AX_RMT_SAMPLES_PER_FRAME)) != 0) mixerCtrl |= AX_PB_MIXCTRL_MAIN2_RAMP; // aux2 if((*p++ = channel->vAux2) != 0) mixerCtrl |= AX_PB_MIXCTRL_AUX2; if((*p++ = (u16)((channel->vAux2_1 - channel->vAux2) / AX_RMT_SAMPLES_PER_FRAME)) != 0) mixerCtrl |= AX_PB_MIXCTRL_AUX2_RAMP; // main3 if((*p++ = channel->vMain3) != 0) mixerCtrl |= AX_PB_MIXCTRL_MAIN3; if((*p++ = (u16)((channel->vMain3_1 - channel->vMain3) / AX_RMT_SAMPLES_PER_FRAME)) != 0) mixerCtrl |= AX_PB_MIXCTRL_MAIN3_RAMP; // aux3 if((*p++ = channel->vAux3) != 0) mixerCtrl |= AX_PB_MIXCTRL_AUX3; if((*p++ = (u16)((channel->vAux3_1 - channel->vAux3) / AX_RMT_SAMPLES_PER_FRAME)) != 0) mixerCtrl |= AX_PB_MIXCTRL_AUX3_RAMP; axvpb->pb.rmtMixerCtrl = mixerCtrl; axvpb->sync |= AX_SYNC_USER_RMTMIX | AX_SYNC_USER_RMTMIXCTRL; } /*---------------------------------------------------------------------------* Name: __MIXRmtResetChannel Description: Reset specified channel on the mixer to initial values. Arguments: chan number of channel to reset Returns: None *---------------------------------------------------------------------------*/ void __MIXRmtResetChannel(s32 chan) { MIXRmtChannel *channel = &__MIXRmtChannel[chan]; channel->mode = 0; channel->fader0 = 0; // fader at 0 channel->fader1 = 0; // fader at 0 channel->fader2 = 0; // fader at 0 channel->fader3 = 0; // fader at 0 channel->aux0 = -960; // -96.0 dB on AUX 0 channel->aux1 = -960; // -96.0 dB on AUX 1 channel->aux2 = -960; // -96.0 dB on AUX 2 channel->aux3 = -960; // -96.0 dB on AUX 3 channel->vMain0 = channel->vAux0 = channel->vMain1 = channel->vAux1 = channel->vMain2 = channel->vAux2 = channel->vMain3 = channel->vAux3 = 0; }