📄 audio_class.c
字号:
MicEna = TRUE;
// Set pointer to free buffer
if(++MicCurrBuffer & 1)
{
PacketLength = (Int32U)pMicData - (Int32U)AudioMicData1;
pMicData = AudioMicData2;
}
else
{
PacketLength = (Int32U)pMicData - (Int32U)AudioMicData2;
pMicData = AudioMicData1;
}
EXT_CRT_SECTION();
// Send microphone output buffer
USB_IO_Data( MicEp,
(pInt8U)((MicCurrBuffer & 1)?AudioMicData1:AudioMicData2),
PacketLength,
(void*)AudioOutHadler);
}
/*************************************************************************
* Function Name: Tim2Handler
* Parameters: none
*
* Return: none
*
* Description: Timer 2 interrupt handler
*
*************************************************************************/
void Tim2Handler (void)
{
union _Val MicTemp;
if (SempEna)
{
if(Delta > 1)
{
// Get next input sample
Val.Data = AudioSpkData[SempCount++];
Delta -= 2;
// Correct pointer to sample buffer
if(SempCount >= sizeof(AudioSpkData)/sizeof(Int16U))
{
SempCount = 0;
}
if(!AudioFeat1Mute && AudioSpkVolMul)
{
// Apply volume
Val.Data *= AudioSpkVolMul;
// Add offset
Val.DataHi += 0x200;
// Check for overflow and correct value
if(Val.DataHi < 50)
{
Val.DataHi = 50;
}
else if(Val.DataHi > 975)
{
Val.DataHi = 975;
}
}
else
{
// set middle of range
Val.DataHi = 0x200;
}
}
else
{
// Disable output stream after emptying the buffer
SempEna = FALSE;
SempPerCurrHold = SempPeriod;
}
}
else
{
SempPerCurrHold = SempPeriod;
}
// reload PWM
TIM1->CCR1 = Val.DataHi;
if(MicEna)
{
if(!AudioFeat2Mute && AudioMicVolMul)
{
// Get ADC sample and remove offset
MicTemp.Data = (ADC1->DR>>2) - 0x200;
// Start the conversion
ADC1->CR2 |= ((Int32U)0x00500000);
// Add volume
MicTemp.Data *= AudioMicVolMul;
// check for overflow and correct the result
if(MicTemp.DataHi < -511)
{
MicTemp.Data = -511 * 65536;
}
else if(MicTemp.DataHi > 511)
{
MicTemp.Data = 511 * 65536;
}
// Scale to 16bit
MicTemp.Data <<= 6;
}
else
{
// set middle of range
MicTemp.DataHi = 0;
}
// write to output buffer
*pMicData++ = MicTemp.DataHi;
if(MicCurrBuffer & 1)
{
if (pMicData >= (AudioMicData2 + (SampRerFrame * 2)))
{
MicEna = FALSE;
}
}
else
{
if (pMicData >= (AudioMicData1+(SampRerFrame * 2)))
{
MicEna = FALSE;
}
}
}
TIM2->ARR = SempPerCurrHold; // reload output compare
TIM2->SR &= (Int16U)~TIM1_FLAG_Update;
}
/*************************************************************************
* Function Name: AudioFeatureGetReg
* Parameters: Int32U CS, Int32U Id
*
* Return: Boolean
*
* Description:
*
*************************************************************************/
static
Boolean AudioFeatureGetReg (Int32U CS, Int32U Id)
{
switch (CS)
{
case REQUEST_GET_CUR:
// Load current value of Volume in the transmit buffer
if (Id == FeatUnit1Id)
{
AudioBuf[1] = (AudioFeat1Vol>>8)& 0xFF;
AudioBuf[0] = AudioFeat1Vol & 0xFF;
}
else if (Id == FeatUnit2Id)
{
AudioBuf[1] = (AudioFeat2Vol>>8)& 0xFF;
AudioBuf[0] = AudioFeat2Vol & 0xFF;
}
else
{
return(FALSE);
}
break;
case REQUEST_GET_MIN:
// Load minimum value of Volume in the transmit buffer
if (Id == FeatUnit1Id)
{
AudioBuf[1] = (Feat1MinVol>>8) & 0xFF;
AudioBuf[0] = Feat1MinVol & 0xFF;
}
else if (Id == FeatUnit2Id)
{
AudioBuf[1] = (Feat2MinVol>>8) & 0xFF;
AudioBuf[0] = Feat2MinVol & 0xFF;
}
else
{
return(FALSE);
}
break;
case REQUEST_GET_MAX:
// Load maximum value of Volume in the transmit buffer
if (Id == FeatUnit1Id)
{
AudioBuf[1] = (Feat1MaxVol>>8) & 0xFF;
AudioBuf[0] = Feat1MaxVol & 0xFF;
}
else if (Id == FeatUnit2Id)
{
AudioBuf[1] = (Feat2MaxVol>>8) & 0xFF;
AudioBuf[0] = Feat2MaxVol & 0xFF;
}
else
{
return(FALSE);
}
break;
case REQUEST_GET_RES:
// Load resolution value of Volume in the transmit buffer
if (Id == FeatUnit1Id)
{
AudioBuf[1] = (Feat1ResVol>>8) & 0xFF;
AudioBuf[0] = Feat1ResVol & 0xFF;
}
else if (Id == FeatUnit2Id)
{
AudioBuf[1] = (Feat2ResVol>>8) & 0xFF;
AudioBuf[0] = Feat2ResVol & 0xFF;
}
else
{
return(FALSE);
}
break;
default:
return(FALSE);
}
return(TRUE);
}
/*************************************************************************
* Function Name: UsbClassAudioRequest
* Parameters: pUsbSetupPacket_t pSetup
*
* Return: UsbCommStatus_t
*
* Description: USB Class Audio Requests
*
*************************************************************************/
UsbCommStatus_t UsbClassAudioRequest (pUsbSetupPacket_t pSetup)
{
// Validate Request
switch (pSetup->mRequestType.Recipient)
{
case UsbRecipientInterface:
// Feature Unit requests only Imlement for interface 0
if ((pSetup->wIndex.Word == (FeatUnit1Id << 8)) ||
(pSetup->wIndex.Word == (FeatUnit2Id << 8)))
{
// Request type
switch (pSetup->wValue.Hi)
{
case FU_MUTE_CONTROL:
if ((pSetup->bRequest == REQUEST_SET_CUR) &&
(pSetup->wLength.Word == 1))
{
// Set mute flag
AudioRequest = pSetup->bRequest;
AudioId = pSetup->wIndex.Hi;
AudioCS = pSetup->wValue.Hi;
AudioCN = pSetup->wValue.Lo;
AudioDataSize = pSetup->wLength.Word;
USB_IO_Data(CTRL_ENP_OUT,
AudioBuf,
USB_T9_Size(1,pSetup->wLength.Word),
(void *)UsbClassAudioData);
return(UsbPass);
}
else if ((pSetup->bRequest == REQUEST_GET_CUR) &&
(pSetup->wLength.Word == 1))
{
// Read mute flag
if(pSetup->wIndex.Hi == FeatUnit1Id)
{
AudioBuf[0] = AudioFeat1Mute;
}
else
{
AudioBuf[0] = AudioFeat2Mute;
}
USB_IO_Data(CTRL_ENP_IN,
AudioBuf,
USB_T9_Size(1,pSetup->wLength.Word),
(void *)USB_StatusHandler);
return(UsbPass);
}
break;
case FU_VOLUME_CONTROL:
if(pSetup->bRequest & 0x80)
{
// Read different volume values
if((pSetup->wLength.Word == 2) &&
AudioFeatureGetReg(pSetup->bRequest,pSetup->wIndex.Hi))
{
USB_IO_Data(CTRL_ENP_IN,
AudioBuf,
USB_T9_Size(2,pSetup->wLength.Word),
(void *)USB_StatusHandler);
return(UsbPass);
}
}
else if((pSetup->bRequest == REQUEST_SET_CUR) &&
(pSetup->wLength.Word == 2))
{
// Set volume value
AudioRequest = pSetup->bRequest;
AudioId = pSetup->wIndex.Hi;
AudioCS = pSetup->wValue.Hi;
AudioCN = pSetup->wValue.Lo;
AudioDataSize = pSetup->wLength.Word;
USB_IO_Data(CTRL_ENP_OUT,
AudioBuf,
USB_T9_Size(2,pSetup->wLength.Word),
(void *)UsbClassAudioData);
return(UsbPass);
}
break;
}
}
// Selector Unit requests only Imlement for interface 0
else if (pSetup->wIndex.Word == (SelUnit1ID << 8))
{
if(pSetup->wValue.Word == 0)
{
// Read different selector unit values
if(pSetup->bRequest & 0x80)
{
if(pSetup->wLength.Word == 1)
{
AudioBuf[0] = 1;
USB_IO_Data(CTRL_ENP_IN,
AudioBuf,
USB_T9_Size(1,pSetup->wLength.Word),
(void *)USB_StatusHandler);
return(UsbPass);
}
}
else
{
// Set channel
AudioRequest = pSetup->bRequest;
AudioId = pSetup->wIndex.Hi;
AudioDataSize = pSetup->wLength.Word;
USB_IO_Data(CTRL_ENP_OUT,
AudioBuf,
USB_T9_Size(1,pSetup->wLength.Word),
(void *)UsbClassAudioData);
return(UsbPass);
}
}
}
return(UsbFault);
case UsbRecipientEndpoint:
return(UsbFault);
}
return(UsbFault);
}
/*************************************************************************
* Function Name: UsbClassAudioData
* Parameters: USB_Endpoint_t EP
*
* Return: none
*
* Description: USB Class Audio Data receive
*
*************************************************************************/
static
void UsbClassAudioData (USB_Endpoint_t EP)
{
if (EpCnfg[EP].Status != COMPLETE)
{
USB_StallCtrlEP();
return;
}
if((AudioId == FeatUnit1Id) ||
(AudioId == FeatUnit2Id))
{
switch (AudioCS)
{
case FU_MUTE_CONTROL:
// Set mute flag
if (AudioId == FeatUnit1Id)
{
AudioFeat1Mute = AudioBuf[0];
}
else if (AudioId == FeatUnit2Id)
{
AudioFeat2Mute = AudioBuf[0];
}
else
{
USB_StallCtrlEP();
return;
}
break;
case FU_VOLUME_CONTROL:
// Set volume value
if (AudioId == FeatUnit1Id)
{
AudioFeat1Vol = AudioBuf[0] + ((Int16U)AudioBuf[1]<<8);
if((Int16U)AudioFeat1Vol == MinVol)
{
AudioSpkVolMul = 0;
}
else
{
if (AudioFeat1Vol < (Int16S)Feat1MinVol)
{
AudioFeat1Vol = Feat1MinVol;
}
else if(AudioFeat1Vol > (Int16S)Feat1MaxVol)
{
AudioFeat1Vol = Feat1MaxVol;
}
// -48dB - +6dB multiply
AudioSpkVolMul = (VolumeMul[((AudioFeat1Vol>>8)+0x30) & 0x3F]) >> 6;
}
}
else if (AudioId == FeatUnit2Id)
{
AudioFeat2Vol = AudioBuf[0] + ((Int16U)AudioBuf[1]<<8);
if((Int16U)AudioFeat2Vol == MinVol)
{
AudioMicVolMul = 0;
}
else
{
if (AudioFeat2Vol < (Int16S)Feat2MinVol)
{
AudioFeat2Vol = Feat2MinVol;
}
else if(AudioFeat2Vol > (Int16S)Feat2MaxVol)
{
AudioFeat2Vol = Feat2MaxVol;
}
// -48dB - +6dB multiply
AudioMicVolMul = VolumeMul[((AudioFeat2Vol>>8)+0x30) & 0x3F];
}
}
else
{
USB_StallCtrlEP();
return;
}
break;
default:
USB_StallCtrlEP();
return;
}
}
else if (AudioId == SelUnit1ID)
{
// empty
}
else
{
USB_StallCtrlEP();
return;
}
USB_StatusHandler(CTRL_ENP_IN);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -