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

📄 es1371.cpp

📁 此代码为WCE5.0下声卡的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:

}  

void
CES1371::SetDMAVolume(ULONG ulChannelIndex, USHORT usLeftVal, USHORT usRightVal)
{
      switch(ulChannelIndex)
      {
      case ES1371_DAC0:
            SRCRegWrite(SRC_DAC0_VOL_L, usLeftVal);
            SRCRegWrite(SRC_DAC0_VOL_R, usRightVal);
            break;

      case ES1371_DAC1:
            SRCRegWrite(SRC_DAC1_VOL_L, usLeftVal);
            SRCRegWrite(SRC_DAC1_VOL_R, usRightVal);
            break;
 
      case ES1371_ADC:
            SRCRegWrite(SRC_ADC_VOL_L, usLeftVal);
            SRCRegWrite(SRC_ADC_VOL_R, usRightVal);
          break;
      }
 
}

//--------------------------------------------------------------------------
//
//  Name: SetDMAChannelFormat
//
//  Description: Set the Format of a particular DMA channel.
//
//  Parameters: ULONG ulChannelIndex : Index of the DMA channel to init
//              ULONG ulChannels   : Number of audio channels 1=mono 2=stereo
//              ULONG ulSampleSize : Sample size - 8bit or 16bit
//              ULONG ulSampleRate : actual number of samples/second.
//
//  Returns: none   
//
//  Note:
//
//--------------------------------------------------------------------------
void
CES1371::SetDMAChannelFormat( ULONG ulChannelIndex,
                              ULONG ulChannels,
                              ULONG ulSampleSize,
                              ULONG ulSampleRate )
{
  UCHAR ucFormatBits;
  UCHAR ucSkipCount;

  // save off the info for power managment
  m_dmachannel[ulChannelIndex].ulChannels   = ulChannels;
  m_dmachannel[ulChannelIndex].ulSampleSize = ulSampleSize;
  m_dmachannel[ulChannelIndex].ulSampleRate = ulSampleRate;

  // first set the new sample rate
  SRCSetRate ( ulChannelIndex, (USHORT) ulSampleRate );

  switch ( ulChannelIndex )
  {
    case ES1371_DAC0 :
      // set format bits for DAC0 ... 
      ucFormatBits = 0x00;
      if( 2 == ulChannels )
          ucFormatBits |= ES1371_PCM_DAC0_STEREO ;
      if( 16 == ulSampleSize )
          ucFormatBits |= ES1371_PCM_DAC0_16BIT ;

      HwRegRMW( ES1371_bSERFMT_OFF, 
                ES1371_PCM_DAC0_STEREO|ES1371_PCM_DAC0_16BIT,
                ucFormatBits ); 
      break;

    case ES1371_DAC1 :
      // set format bits for DAC1 ... 
      ucFormatBits = 0x00;
      if( 2 == ulChannels )
          ucFormatBits |= ES1371_PCM_DAC1_STEREO ;
      if( 16 == ulSampleSize )
      {
          ucFormatBits |= ES1371_PCM_DAC1_16BIT ;
          // set the SKIP register for proper playback
          ucSkipCount = 0x10;
          HwRegRMW( ES1371_bSKIPC_OFF, (UCHAR)0x18, ucSkipCount ); 
      }
      else
      {   // set the SKIP register for proper playback
          ucSkipCount = 0x08;
          HwRegRMW( ES1371_bSKIPC_OFF, (UCHAR)0x18, ucSkipCount ); 
      }

      HwRegRMW( ES1371_bSERFMT_OFF, 
                ES1371_PCM_DAC1_STEREO|ES1371_PCM_DAC1_16BIT,
                ucFormatBits ); 
      break;

    case ES1371_ADC :
      // set format bits for ADC ... 
      ucFormatBits = 0x00;
      if( 2 == ulChannels )
          ucFormatBits |= ES1371_PCM_ADC_STEREO ;
      if( 16 == ulSampleSize )
          ucFormatBits |= ES1371_PCM_ADC_16BIT ;
 
      HwRegRMW( ES1371_bSERFMT_OFF, 
                ES1371_PCM_ADC_STEREO|ES1371_PCM_ADC_16BIT,
                ucFormatBits ); 
      break;
  }
}

//--------------------------------------------------------------------------
//
//  Name: SetDMAChannelBuffer
//
//  Description: Set the buffer sizes of a particular DMA channel.
//
//  Parameters: ULONG ulChannelIndex    : Index of the DMA channel to init
//              ULONG ulBufferLength  : Size in bytes of the whole DMA buffer
//              ULONG ulSamplesPerInt : Count of samples before interrupting
//
//  Returns: none   
//
//  Note:
//
//--------------------------------------------------------------------------
void
CES1371::SetDMAChannelBuffer( ULONG ulChannelIndex,
                              ULONG ulBufferLength,
                              ULONG ulSamplesPerInt )
{
  ULONG ulDesiredBufferSize =  m_dmachannel[ulChannelIndex].ulBufferSize;
  USHORT usInterruptCount = (USHORT) (ulSamplesPerInt - 1);

  m_dmachannel[ulChannelIndex].ulBufferLength  = ulBufferLength;
  m_dmachannel[ulChannelIndex].ulSamplesPerInt = ulSamplesPerInt;

  // buffer can't be bigger than half the physical buffer
  // convert to dwords and subtract one to get register value
  ulDesiredBufferSize = MIN( ulDesiredBufferSize, ulBufferLength )/4 - 1;
  ULONG ulPrevCount;

  switch ( ulChannelIndex )
  {
    case ES1371_DAC0 :
      // set the DAC0 DWORD frame count
      ulPrevCount = HwPagedIORead( ES1371_DAC0CTL_PAGE, ES1371_wDAC0FC_OFF);
      HwPagedIOWrite( ES1371_DAC0CTL_PAGE, 
                      ES1371_wDAC0FC_OFF, 
                      (ulPrevCount & 0xffff0000) | (ulDesiredBufferSize & 0x0000ffff) );  

      // Write DAC0 interrupt count - sample frames per half-buffer (n-1).
      HwRegRMW( ES1371_wDAC0IC_OFF, 0xffff, usInterruptCount );
      break;

    case ES1371_DAC1 :
      // set the DAC1 DWORD frame count
      ulPrevCount = HwPagedIORead( ES1371_DAC1CTL_PAGE, ES1371_wDAC1FC_OFF);
      HwPagedIOWrite( ES1371_DAC1CTL_PAGE, 
                      ES1371_wDAC1FC_OFF, 
                      (ulPrevCount & 0xffff0000) | (ulDesiredBufferSize & 0x0000ffff) );  

      // Write DAC1 interrupt count - sample frames per half-buffer (n-1).
      HwRegRMW( ES1371_wDAC1IC_OFF, 0xffff, usInterruptCount );
      break;

    case ES1371_ADC :
      ulPrevCount = HwPagedIORead( ES1371_ADCCTL_PAGE, ES1371_wADCFC_OFF);
      // set the ADC DWORD frame count
      HwPagedIOWrite( ES1371_ADCCTL_PAGE, 
                      ES1371_wADCFC_OFF, 
                      (ulPrevCount & 0xffff0000) | (ulDesiredBufferSize & 0x0000ffff) );  

      // Write ADC interrupt count - sample frames per half-buffer (n-1).
      HwRegRMW( ES1371_wADCIC_OFF, 0xffff, usInterruptCount );
      break;
  }
}

//--------------------------------------------------------------------------
//
//  Name: StartDMAChannel
//
//  Description: Start a particular DMA channel running.
//
//  Parameters: ULONG ulChannelIndex : Index of the DMA channel to start
//
//  Returns: none   
//
//  Note:
//
//--------------------------------------------------------------------------
void
CES1371::StartDMAChannel( ULONG ulChannelIndex )
{
  UCHAR ucIOVal;

  switch ( ulChannelIndex )
  {
    case ES1371_DAC0 :
      if ( DMA_PAUSED == m_dmachannel[ulChannelIndex].ulDMAChannelState )
      {
        // modify pause bit for DAC0
        ucIOVal = 0;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC0PAUSE, ucIOVal );
      }
      else
      {
        // enable the DAC0 interrupt
        ucIOVal = ES1371_SERCTL_DAC0IE;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC0IE,
                  ucIOVal ); 

        // start DAC0
        ucIOVal = ES1371_DEVCTL_DAC0_EN;
        HwRegRMW( ES1371_bDEVCTL_OFF,
                  ES1371_DEVCTL_DAC0_EN,
                  ucIOVal ); 
      }

      // save the state
      m_dmachannel[ulChannelIndex].ulDMAChannelState = DMA_RUNNING;
      break;

    case ES1371_DAC1 :
      if ( DMA_PAUSED == m_dmachannel[ulChannelIndex].ulDMAChannelState )
      {
        // modify pause bit for DAC1
        ucIOVal = 0;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC1PAUSE, ucIOVal );
      }
      else
      {
        // enable the DAC1 interrupt
        ucIOVal = ES1371_SERCTL_DAC1IE;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC1IE,
                  ucIOVal ); 

        // start DAC1
        ucIOVal = ES1371_DEVCTL_DAC1_EN;
        HwRegRMW( ES1371_bDEVCTL_OFF,
                  ES1371_DEVCTL_DAC1_EN,
                  ucIOVal ); 
      }

      // save the state
      m_dmachannel[ulChannelIndex].ulDMAChannelState = DMA_RUNNING;
      break;

    case ES1371_ADC :
      // enable the ADC interrupt
      ucIOVal = ES1371_SERCTL_ADCIE;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_ADCIE,
                ucIOVal ); 

      // start ADC
      ucIOVal = ES1371_DEVCTL_ADC_EN;
      HwRegRMW( ES1371_bDEVCTL_OFF,
                ES1371_DEVCTL_ADC_EN,
                ucIOVal ); 

      // save the state
      m_dmachannel[ulChannelIndex].ulDMAChannelState = DMA_RUNNING;
      break;
  }
  return;
}

//--------------------------------------------------------------------------
//
//  Name: StopDMAChannel
//
//  Description: Stop a particular DMA channel.
//
//  Parameters: ULONG ulChannelIndex : Index of the DMA channel to stop
//
//  Returns: none   
//
//  Note:
//
//--------------------------------------------------------------------------
void
CES1371::StopDMAChannel( ULONG ulChannelIndex )
{
  UCHAR ucIOVal;

  switch ( ulChannelIndex )
  {
    case ES1371_DAC0 :
      // Stop DAC0
      ucIOVal = 0;
      HwRegRMW( ES1371_bDEVCTL_OFF,
                ES1371_DEVCTL_DAC0_EN, ucIOVal );

      // disable the DAC0 interrupt
      ucIOVal = 0;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_DAC0IE, ucIOVal );

      if ( DMA_PAUSED == m_dmachannel[ulChannelIndex].ulDMAChannelState )
      {
        // modify pause bit for DAC0
        ucIOVal = 0;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC0PAUSE, ucIOVal );
      }

      // save the state
      m_dmachannel[ulChannelIndex].ulDMAChannelState = DMA_STOPPED;
      break;

    case ES1371_DAC1 :
      // Stop DAC1
      ucIOVal = 0;
      HwRegRMW( ES1371_bDEVCTL_OFF,
                ES1371_DEVCTL_DAC1_EN, ucIOVal);

      // disable the DAC1 interrupt
      ucIOVal = 0;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_DAC1IE, ucIOVal);

      if ( DMA_PAUSED == m_dmachannel[ulChannelIndex].ulDMAChannelState )
      {
        // modify pause bit for DAC0
        ucIOVal = 0;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC1PAUSE, ucIOVal );
      }

      // save the state
      m_dmachannel[ulChannelIndex].ulDMAChannelState = DMA_STOPPED;
      break;

    case ES1371_ADC :
      // Stop ADC
      ucIOVal = 0;
      HwRegRMW( ES1371_bDEVCTL_OFF,
                ES1371_DEVCTL_ADC_EN, ucIOVal);

      // disable the ADC interrupt
      ucIOVal = 0;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_ADCIE, ucIOVal);

      // save the state
      m_dmachannel[ulChannelIndex].ulDMAChannelState = DMA_STOPPED;
      break;
  }
}

//--------------------------------------------------------------------------
//
//  Name: PauseDMAChannel
//
//  Description: Pause a particular DMA channel.
//
//  Parameters: ULONG ulChannelIndex : Index of the DMA channel to pause
//
//  Returns: none   
//
//  Note:
//
//--------------------------------------------------------------------------
void
CES1371::PauseDMAChannel( ULONG ulChannelIndex )
{
  UCHAR ucIOVal;

  switch ( ulChannelIndex )
  {
    case ES1371_DAC0 :
      // wait until interrupt count is non-zero
//      while ( !HwPagedIORead( ES1371_DAC0CTL_PAGE, ES1371_wDAC0CIC_OFF)); 

      // modify pause bit for DAC0
      ucIOVal = ES1371_SERCTL_DAC0PAUSE;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_DAC0PAUSE, ucIOVal );
      // save the state
      m_dmachannel[ulChannelIndex].ulDMAChannelState = DMA_PAUSED;
      break;

    case ES1371_DAC1 :
      // wait until interrupt count is non-zero
//      while ( !HwPagedIORead( ES1371_DAC1CTL_PAGE, ES1371_wDAC1CIC_OFF)); 

      // modify pause bit for DAC1
      ucIOVal = ES1371_SERCTL_DAC1PAUSE;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_DAC1PAUSE, ucIOVal);
      // save the state
      m_dmachannel[ulChannelIndex].ulDMAChannelState = DMA_PAUSED;
      break;

    case ES1371_ADC :
      break;
  }
}

//--------------------------------------------------------------------------
//
//  Name: GetDMAPosition
//
//  Description: reads the current position of a DMA channel.
//
//  Parameters: ULONG ulChannelIndex : Index of the DMA channel
//
//  Returns: ULONG current DMA position in bytes  
//
//  Note: This function returns the DMA position NOT the sample play
//        cursor.  It appears that this will be used for buffer filling.
//
//--------------------------------------------------------------------------
ULONG
CES1371::GetDMAPosition( ULONG ulChannelIndex )
{
  ULONG ulCurrentPos = 0;

  switch ( ulChannelIndex )
  {
    case ES1371_DAC0 :
      // read the Frame register
      ulCurrentPos = HwPagedIORead( ES1371_DAC0CTL_PAGE, ES1371_wDAC0FC_OFF); 
      // the current frame count is in the upper WORD
      ulCurrentPos >>= 16;

      // multiply the DWORD count by 4 to get a BYTE count to return
      ulCurrentPos *= 4;
      break;

    case ES1371_DAC1 :
      // read the Frame register
      ulCurrentPos = HwPagedIORead( ES1371_DAC1CTL_PAGE, ES1371_wDAC1FC_OFF); 
      // the current frame count is in the upper WORD
      ulCurrentPos >>= 16;

      // multiply the DWORD count by 4 to get a BYTE count to return
      ulCurrentPos *= 4;
      break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -