⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio_class.c

📁 最新版IAR FOR ARM(EWARM)5.11中的代码例子
💻 C
📖 第 1 页 / 共 2 页
字号:
  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 + -