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

📄 audlinux_alsa.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  // //                   frontCenterVolume = 0;
           
  // //               if( snd_mixer_selem_get_playback_volume( mixer_elements2,
  // //                                                        SND_MIXER_SCHN_REAR_RIGHT, &rearRightVolume) < 0)
  // //                   rearRightVolume = 0;
              
  // //               if( snd_mixer_selem_get_playback_volume( mixer_elements2,
  // //                                                        SND_MIXER_SCHN_REAR_LEFT, &rearLeftVolume) < 0)
  // //                   rearLeftVolume = 0;
           
  // //               if( snd_mixer_selem_get_playback_volume( mixer_elements2,
  // //                                                        SND_MIXER_SCHN_WOOFER, &wooferVolume) < 0)
  // //                   wooferVolume = 0;
                
  //               long range = pmax - pmin;
  //               long val = frontLeftVolume;
  //               frontRightVolume =  frontLeftVolume;
  //               val -= pmin;

  //               percentage = (long)rint(val / range * 100);
        
  //                 //            printf("min %d, max %d, range %d\n", pmin, pmax, range);

  //               printf("fleft %ld, fright %ld, center %ld, rleft %ld, rright %ld, woofer %ld, percent %d\n",
  //                      frontLeftVolume, frontRightVolume, frontCenterVolume, rearLeftVolume,
  //                      rearRightVolume, percentage);
  //           }
  // //         snd_mixer_selem_get_playback_volume_range( mixer_elements2, &pmin, &pmax);
  //       }
  //     }
  

  //    nLeftVolume  = (nVolume & 0x000000ff); 
  //    nRightVolume = (nVolume & 0x0000ff00) >> 8;

  nRetVolume  = (UINT16)frontLeftVolume;

  //    printf("nRetVolume is %ld\n",nRetVolume);

  return nRetVolume;
}


HX_RESULT CAudioOutLinuxAlsa::_SetVolume(UINT16 unVolume)
{
  HX_RESULT retCode = RA_AOE_NOERR;
  ///////////////////////// FIXME: 
  long pmin = 0, pmax = 0;
  long percentage = 0;
  
  long frontLeftVolume = 0;
  long frontRightVolume = 0;
  
  /*  long frontCenterVolume = 0;

  long rearLeftVolume = 0;
  long rearRightVolume = 0;
  
  long wooferVolume = 0;

  snd_mixer_selem_id_t *sid;
  snd_mixer_selem_id_alloca(&sid);
  */
  snd_mixer_elem_t *mixer_elements;

  frontLeftVolume = frontRightVolume = unVolume;
  //    nNewVolume = (unVolume & 0xff) | ((unVolume &0xff) << 8);

  mixer_elements = snd_mixer_first_elem( mixer_handle); //just grab first elem for now

  if (snd_mixer_selem_has_playback_volume( mixer_elements)) {

    // do this as the volume range in alsa might be more or less than 100
    // act like its a percentage, the vol range for rmedigi96 is 16383, and my pci128 is 16
    snd_mixer_selem_get_playback_volume_range( mixer_elements, &pmin, &pmax);

    int range = pmax - pmin;
    int val = frontLeftVolume;

    //percent to volume
    frontLeftVolume = rint((double)range * ((double)val*.01)) + pmin; 
  
    frontRightVolume = frontLeftVolume;
  
    if( snd_mixer_selem_set_playback_volume( mixer_elements,
                                             SND_MIXER_SCHN_FRONT_LEFT,
                                             frontLeftVolume) < 0)
      frontLeftVolume = 0;

    if( snd_mixer_selem_set_playback_volume( mixer_elements,
                                             SND_MIXER_SCHN_FRONT_RIGHT,
                                             frontRightVolume) < 0)
      frontRightVolume = 0;
  }              
#ifdef _DEBUG
  printf("setting volume left %ld, right %ld %ld\%\n", frontLeftVolume, frontRightVolume, unVolume );
#endif




  // Save for future use, demonstrates multichannel mixer access.

 
  //     for ( mixer_elements = snd_mixer_first_elem( mixer_handle); //ramble through elems
  //           mixer_elements; 
  //           mixer_elements = snd_mixer_elem_next( mixer_elements) )
  //       {
    
  //           snd_mixer_selem_get_id( mixer_elements, sid);
    
  //           printf("mixer control '%s',%i\n", 
  //                  snd_mixer_selem_id_get_name( sid), 
  //                  snd_mixer_selem_id_get_index( sid));

  //           if ( snd_mixer_selem_has_common_volume( mixer_elements)) //is mono
  //             {
  // //          // check for playback vol mixer         
  //                 if (snd_mixer_selem_has_playback_volume( mixer_elements)) {
  //                     snd_mixer_selem_get_playback_volume_range( mixer_elements, &pmin, &pmax);

  //                     int range = pmax - pmin;
  //                     int val = frontLeftVolume;

  //                     val -= pmin;
  //                     frontLeftVolume  =  rint((double)range * ((double)val*.01)) + pmin; //percent to volume
  //                       //frontLeftVolume  = rint((double)val/(double)range * 100);
  //                       // frontLeftVolume = (long) ( unVolume & 0x000000ff);
  //                     frontRightVolume = frontLeftVolume;
  //                       //  frontRightVolume = (long) ( unVolume & 0x0000ff00);
  //                       //score!       
  //                     if( snd_mixer_selem_set_playback_volume( mixer_elements,
  //                                                              SND_MIXER_SCHN_MONO,
  //                                                              frontLeftVolume) < 0)
  //                         frontLeftVolume = 0;
  //                     val -= pmin;
  //                     percentage = (long)rint((double)val/(double)range * 100);
  //                 }
  //             }
  //           else //is stereo
  //             {
  // //        if (snd_mixer_selem_has_playback_volume( mixer_elements)) {
  //                 snd_mixer_selem_get_playback_volume_range( mixer_elements, &pmin, &pmax);
  //                 printf("vol min %d, max %d\n", pmin, pmax);
  //                 int range = pmax - pmin;
  //                 int tmp;
  //                 int val = frontLeftVolume;
  //                 frontLeftVolume  =  rint((double)range * ((double)val*.01)) + pmin; //percent to volume
  //                   //rint((double)val/(double)range * 100);
  
  // //  frontLeftVolume = (long) ( unVolume & 0x000000ff);
  //                 frontRightVolume = frontLeftVolume;
  // //  frontRightVolume = (long) ( unVolume & 0x0000ff00);

  
  //                 if( snd_mixer_selem_set_playback_volume( mixer_elements,
  //                                                          SND_MIXER_SCHN_FRONT_LEFT,
  //                                                          frontLeftVolume) < 0)
  //                     frontLeftVolume = 0;

  //                 if( snd_mixer_selem_set_playback_volume( mixer_elements,
  //                                                          SND_MIXER_SCHN_FRONT_RIGHT,
  //                                                          frontRightVolume) < 0)
  //                     frontRightVolume = 0;
              
  // //              if( snd_mixer_selem_set_playback_volume( mixer_elements,
  // //                SND_MIXER_SCHN_FRONT_CENTER, &frontCenterVolume) < 0)
  // //               frontCenterVolume = 0;
           
  // //               if( snd_mixer_selem_set_playback_volume( mixer_elements,
  // //                  SND_MIXER_SCHN_REAR_RIGHT, &rearRightVolume) < 0)
  // //                  rearRightVolume = 0;
              
  // //              if( snd_mixer_selem_set_playback_volume( mixer_elements,
  // //                SND_MIXER_SCHN_REAR_LEFT, &rearLeftVolume) < 0)
  // //               rearLeftVolume = 0;
           
  // //               if( snd_mixer_selem_set_playback_volume( mixer_elements,
  // //                    SND_MIXER_SCHN_WOOFER, &wooferVolume) < 0)
  // //                   wooferVolume = 0;
  // //        }
  //                 int range2 = pmax - pmin;
  //                 int val2 = frontLeftVolume;
  //                 val2 -= pmin;
  //                 percentage = (long)rint((double)val2/(double)range2 * 100);
        
  //             }
  //       }

  //     printf("fleft %d, fright %d, center %d, rleft %d, rright %d, woofer %d, percent %d\n",
  //            frontLeftVolume, frontRightVolume, frontCenterVolume, rearLeftVolume, 
  //            rearRightVolume, percentage);

  m_wLastError = retCode;
  return m_wLastError;
}


//Device specific method to drain a device. This should play the remaining
//bytes in the devices buffer and then return.
HX_RESULT CAudioOutLinuxAlsa::_Drain()
{
  HX_RESULT retCode = RA_AOE_NOERR;
  if ( pcm_handle < 0 )
    {
      retCode = RA_AOE_DEVNOTOPEN;
    }
  // Stop PCM device after pending frames have been played
  if( snd_pcm_drain( pcm_handle) < 0)
    retCode = RA_AOE_GENERAL;
    

  m_wLastError = retCode;
  return m_wLastError;
}


//Device specific method to reset device and return it to a state that it
//can accept new sample rates, num channels, etc.
HX_RESULT CAudioOutLinuxAlsa::_Reset()
{
  HX_RESULT retCode = RA_AOE_NOERR;
  m_ulPausePosition = 0;

  if( pcm_handle > 0 )
    //    if (snd_pcm_state( pcm_handle) == SND_PCM_STATE_OPEN)
    {
      if( snd_pcm_reset( pcm_handle) < 0)
        {
          retCode = RA_AOE_GENERAL;
        }
    }
  else
    {
      retCode = RA_AOE_DEVNOTOPEN;
    }

  m_wLastError = retCode;
  return m_wLastError;
}

HX_RESULT CAudioOutLinuxAlsa::_CheckFormat( const HXAudioFormat* pFormat )
{
  int   nBitsPerSample = pFormat->uBitsPerSample;
  int   ulTmp          = pFormat->ulSamplesPerSec;
  int   nNumChannels   = pFormat->uChannels;
  float fTmp           = 0.0;
  int err=0;
  snd_pcm_format_t m_format;
  HX_RESULT retCode = RA_AOE_NOERR;

  if( nBitsPerSample = 16)
    {
      m_format = SND_PCM_FORMAT_S16;
    }
  else
    {
      m_format =  SND_PCM_FORMAT_U8;
    }

  //Is the device already open?
  if( pcm_handle > 0 ||  RA_AOE_NOERR != _OpenAudio() )
    {
      retCode = RA_AOE_DEVBUSY;
      return retCode;
    }

  //See if the sample rate is supported.
  if( snd_pcm_hw_params_test_rate ( pcm_handle, hwparams, ulTmp  ,0) < 0)
    {
#ifdef _DEBUG
      fprintf (stderr, "cannot set sample rate (%s)\n",
               snd_strerror (err));
#endif
      //Not quite the real error, but it is what we need to return.
      retCode = RA_AOE_BADFORMAT;
      goto donechecking;
    }

  //Check num channels.
  if(snd_pcm_hw_params_test_channels ( pcm_handle, hwparams, nNumChannels) < 0)
    {
      retCode = RA_AOE_BADFORMAT;
      goto donechecking;
    }

  if ( snd_pcm_hw_params_test_format( pcm_handle, hwparams, m_format  /*SND_PCM_FORMAT_S16*/ ) < 0)
    {
      retCode = RA_AOE_BADFORMAT;
      goto donechecking;
    }

  //Close the audio device.
 donechecking:
  _CloseAudio();
  m_wLastError = retCode;
  return retCode;
}


HX_RESULT CAudioOutLinuxAlsa::_CheckSampleRate( ULONG32 ulSampleRate )
{
  ULONG32 ulTmp = ulSampleRate;

  m_wLastError = RA_AOE_NOERR;
  //Is the device already open?
  if( pcm_handle > 0 || RA_AOE_NOERR != _OpenAudio() )
    {
      m_wLastError = RA_AOE_DEVBUSY;
    }
  else
    {
      //See if the sample rate is supported.
      if( snd_pcm_hw_params_test_rate ( pcm_handle, hwparams, (uint)ulTmp, 0) != 1)
        {
          //Not quite the real error, but it is what we need to return.
          m_wLastError = RA_AOE_DEVBUSY;
        }
      else if( ulSampleRate != ulTmp )
        {
          //It is NOT supported
          m_wLastError = RA_AOE_BADFORMAT;
        }

      _CloseAudio();
    }

  return m_wLastError;
}


HX_RESULT CAudioOutLinuxAlsa::_Pause()
{
  m_wLastError = HXR_OK;
  m_ulPausePosition = m_ulTotalWritten;
  m_ulTickCount = 0;
  m_ulLastTimeStamp   = 0;
  int err=0;
  if( m_bHasHardwarePause)
    {
      if((err = snd_pcm_pause( pcm_handle, 1)) < 0)
        {
#ifdef _DEBUG
          fprintf(stderr, "Error : cannot pause (%s)\n", snd_strerror (err));
#endif
          m_wLastError = RA_AOE_NOTSUPPORTED;
        }
    }
  else
    {
      m_wLastError = RA_AOE_NOTSUPPORTED;
    }

  return m_wLastError;
}

HX_RESULT CAudioOutLinuxAlsa::_Resume()
{
  m_wLastError = HXR_OK;

  if( m_ulTotalWritten > 0 )
    {
      m_ulTickCount = GetTickCount();
      m_ulLastTimeStamp = m_ulTickCount;
    }

  if( m_bHasHardwarePause &&  m_bHasHardwareResume)
    {
      int err=0;
      if((err = snd_pcm_resume( pcm_handle)) < 0)
        {
#ifdef _DEBUG
          fprintf (stderr, "Error: cannot resume (%s)\n",
                   snd_strerror (err));
#endif
          m_wLastError = RA_AOE_NOTSUPPORTED;
        }
    }
  else
    {
      m_wLastError = RA_AOE_NOTSUPPORTED;
    }
    
  return m_wLastError;
}

BOOL CAudioOutLinuxAlsa::_HardwarePauseSupported() const
{
    
  if( snd_pcm_hw_params_can_resume( hwparams) == 1)
    {
      m_bHasHardwareResume = true;
    }
  else
    {
      m_bHasHardwareResume = false;
    }

  if( snd_pcm_hw_params_can_pause( hwparams) == 1)
    {
      m_bHasHardwarePause = true;
      return TRUE;
    }
  else
    {
      m_bHasHardwarePause = false;
    }
  return FALSE;
}

⌨️ 快捷键说明

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