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

📄 audlinux_alsa.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  m_unNumChannels = channels = numChannels;  if ( numChannels != pFormat->uChannels )    {      ((HXAudioFormat*)pFormat)->uChannels = numChannels;    }  int periods = 2;       // Number of periods   snd_pcm_uframes_t periodsize = 2048; // FIXME  int direct=0;  snd_pcm_uframes_t period = 0;  // The period size == fragment size.  // Note that this in frames (frame = nr_channels * sample_width)  // So a value of 1024 means 4096 bytes (1024 x 2 x 16-bits)          //     if((err = snd_pcm_hw_params_get_period_size_max( hwparams, &period,& direct) ) < 0)  //       {  // #ifdef _DEBUG  //           printf("Unable to get period size %ld : %s\n", period,  snd_strerror(err));  // #endif  //       }  //     direct=0;  if((err = snd_pcm_hw_params_set_period_size_near( pcm_handle, hwparams, &periodsize, &direct) ) < 0)    {#ifdef _DEBUG      printf("Set period size failed %ld : %s\n", periodsize,  snd_strerror(err));#endif    }  //////////////////////////////////// set periods  //      printf("set periods\n");  //      if ((err = snd_pcm_hw_params_set_periods_near( pcm_handle, hwparams, &periods, &direct ))  < 0 )  //        {  //            printf("Error setting periods  %s\n", snd_strerror(err));  //        }   /*     if(( err =snd_pcm_hw_params_get_period_size( hwparams, &period_size, NULL)) < 0)         {         printf("unable to get peroidsize:\n") ;         }  */    //     snd_pcm_hw_params_get_period_size( hwparams, &val);  //     if((err = snd_pcm_hw_params_set_buffer_size( pcm_handle, hwparams, bufferSz )) < 0)  //      if((err = snd_pcm_hw_params_set_buffer_size_near( pcm_handle, hwparams, bufferSz )) < 0)  //        {  //            printf("Unable to set buffer size %li : %s\n", bufferSz, snd_strerror(err));  //        }  //     printf("get buffer size\n");  ////////////////////////// Get buffer size in frames   //  m_wBlockSize = m_ulBytesPerGran;  if((err = snd_pcm_hw_params_get_buffer_size_max( hwparams, &bufferSz)) < 0)     {#ifdef _DEBUG      printf("Get buffer size failed:\n") ;#endif      if(  m_ulDeviceBufferSize <= 0)        blocksize = m_wBlockSize = m_ulDeviceBufferSize = 8192 * 2;    }  else    {      blocksize = bufferSz;      m_wBlockSize = blocksize;      m_ulDeviceBufferSize  = blocksize *  samplesize * channels;    }  //    printf("blocksize %d, samplesize %d, channels %d\n", blocksize, samplesize, channels );  //    printf("m_ulDeviceBufferSize %ld\n",  m_ulDeviceBufferSize);    if (snd_pcm_hw_params( pcm_handle, hwparams) < 0) //write device    {#ifdef _DEBUG      fprintf(stderr, "Error setting HW params.\n");#endif      return ( m_wLastError = RA_AOE_NOTENABLED );    }  snd_pcm_sw_params_alloca(&swparams);  if((err = snd_pcm_sw_params_current( pcm_handle, swparams)) <0)    {#ifdef _DEBUG      printf("Current SW params failed: %s\n", snd_strerror(err));#endif    }  //  if ((err = snd_pcm_sw_params_set_avail_min ( pcm_handle, swparams, 2048)) < 0) {  //       fprintf (stderr, "cannot set minimum available count (%s)\n",  //                snd_strerror (err));  //   }  if((err = snd_pcm_sw_params_set_start_threshold( pcm_handle, swparams, bufferSz )) < 0)    {#ifdef _DEBUG      printf("Set start threshold mode failed: %s\n", snd_strerror(err));#endif    }  if((err = snd_pcm_sw_params_set_xfer_align( pcm_handle, swparams, 1)) < 0)    {#ifdef _DEBUG      printf("Set transfer align failed: %s\n", snd_strerror(err));#endif    }   if((err = snd_pcm_sw_params_set_tstamp_mode( pcm_handle, swparams,SND_PCM_TSTAMP_MMAP )) < 0 )    {#ifdef _DEBUG      printf("Set sw params time stamp mode failed: %s\n", snd_strerror(err));#endif    }  if((err = snd_pcm_sw_params( pcm_handle, swparams)) < 0)    {#ifdef _DEBUG      printf("Set sw params failed: %s\n", snd_strerror(err));#endif    }  if ((err=snd_pcm_prepare ( pcm_handle)) < 0)    {#ifdef _DEBUG      fprintf (stderr, "Prepare audio interface failed %s\n",               snd_strerror (err));#endif      return  retCode = RA_AOE_NOTENABLED;    }       #ifdef _DEBUG  snd_output_t *output = NULL;  snd_output_stdio_attach(&output, stdout, 0);  printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");  snd_pcm_dump( pcm_handle, output);  printf("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");  snd_pcm_hw_params_dump( hwparams, output);  printf("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");  snd_pcm_sw_params_dump( swparams, output);   printf("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");  //     snd_pcm_status_dump( status, output);  //     printf("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");  fprintf( stdout, "Device Configured:\n");  fprintf( stdout, "         Sample Rate: %d\n",  m_unSampleRate);  fprintf( stdout, "        Sample Width: %d\n",  nSampleWidth);  fprintf( stdout , "        Num channels: %d\n",  m_unNumChannels);  fprintf( stdout, "          Block size: %d\n",  m_wBlockSize);  fprintf( stdout, "  Device buffer size: %lu\n", m_ulDeviceBufferSize);#endif  //     snd_pcm_sw_params_free( swparams);  return RA_AOE_NOERR;}void CAudioOutLinuxAlsa::_SyncUpTimeStamps(ULONG32 writeCount){  snd_pcm_hwsync( pcm_handle);  int bytes2  = 0;  int err = 0;  snd_pcm_sframes_t framedelay;  if((err = snd_pcm_delay( pcm_handle, &framedelay)) < 0)    {#ifdef _DEBUG      fprintf (stderr, "cannot get delay %s\n", snd_strerror (err));#endif    }  bytes2 = snd_pcm_frames_to_bytes( pcm_handle, framedelay);               if( bytes2 > 0)    {      m_ulLastBytesPlayed = (UINT64)( m_ulTotalWritten + writeCount - bytes2);      m_ulLastTimeStamp   = GetTickCount();    }}//Device specific method to write bytes out to the audiodevice and return a//count of bytes written.HX_RESULT CAudioOutLinuxAlsa::_WriteBytes( UCHAR* buffer, ULONG32 ulBuffLength, LONG32& lCount ){  LONG32 writeCount;  HX_RESULT retCode = RA_AOE_NOERR;  int err=0;  if( m_ulTickCount == 0 )    m_ulTickCount = GetTickCount();  snd_pcm_sframes_t num_frames, size;  lCount = 0;  num_frames = snd_pcm_bytes_to_frames( pcm_handle, ulBuffLength); //alsa in frames  // Returns the number of frames actually written.   size = snd_pcm_writei( pcm_handle, buffer, num_frames );  if(size < 0)    {      switch (size)        {        case -EBADFD:          {#ifdef _DEBUG            printf("EBADFD: Device not in the right state \n");#endif            retCode = RA_AOE_DEVBUSY;          }          break;        case -EPIPE: //lets handle underruns          {            if(( size = snd_pcm_prepare( pcm_handle) ) < 0 )              {#ifdef _DEBUG                printf("EPIPE: Recovery from underrun is difficult: %s\n", snd_strerror( size));#endif                retCode = RA_AOE_DEVBUSY;              }          }          break;        case -ESTRPIPE:          {            while (( size = snd_pcm_resume( pcm_handle)) == -EAGAIN)              sleep(1);            if ( size < 0)              {                size = snd_pcm_prepare( pcm_handle);                if ( size < 0)                  {#ifdef _DEBUG                    printf("ESTRPIPE: Recover from suspend is difficult: %s\n", snd_strerror( size));#endif                    retCode = RA_AOE_DEVBUSY;                  }              }          }          break;        };    }//  printf("frames written = %d\n", size);  writeCount = snd_pcm_frames_to_bytes( pcm_handle, size );  if( writeCount < 0 )    {      if( errno == EAGAIN )        retCode = RA_AOE_NOERR;      if( errno == EINTR )        retCode = RA_AOE_DEVBUSY;    }  else    {      _SyncUpTimeStamps( writeCount);      // XXXRGG: Figure out why writeCount != ulBuffLength      // lCount = writeCount;      lCount = ulBuffLength;    }  return retCode;}UINT64 CAudioOutLinuxAlsa::_GetBytesActualyPlayed(void) const{  // Get current playback position in device DMA.   int     bytes2 = 0;  UINT64  ulTheAnswer = 0;  if( m_ulTotalWritten > 0 )    {      HX_ASSERT( m_unSampleRate!=0 && m_uSampFrameSize!=0 );      ULONG32 ulTick = GetTickCount();      //We need to update the timestamps every so often.      //This make sure that if the XServer was blocked, and      //we ran dry, that we re-sync up.      if( (ulTick - m_ulLastTimeStamp) > 200 )        {          ((CAudioOutLinuxAlsa*)this)->_SyncUpTimeStamps();          ulTick = GetTickCount();        }      ulTheAnswer = (UINT64)(m_ulLastBytesPlayed+                             ((float)(ulTick-m_ulLastTimeStamp)*                              (float)m_unNumChannels/1000.0*                              m_unSampleRate*m_uSampFrameSize) +0.5 );    }  //    printf("BytesActualyPlayed %ld\n", ulTheAnswer);  return  ulTheAnswer;}//this must return the number of bytes that can be written without blocking.HX_RESULT CAudioOutLinuxAlsa::_GetRoomOnDevice(ULONG32& ulBytes) const{  HX_RESULT  retCode = RA_AOE_NOERR;  // FIXME  ulBytes = m_ulDeviceBufferSize - ( m_ulTotalWritten - _GetBytesActualyPlayed() );  //    printf("RoomOnDevice %ld\n", ulBytes);  m_wLastError = retCode;  return m_wLastError;}//Device specific method to get/set the devices current volume.UINT16 CAudioOutLinuxAlsa::_GetVolume() const{  UINT16 nRetVolume   = 0;  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_elements2;  mixer_elements2 = snd_mixer_first_elem( mixer_handle);  // grab first elem of mixer  if (snd_mixer_selem_has_playback_volume( mixer_elements2)) {                if( snd_mixer_selem_get_playback_volume( mixer_elements2,                                             SND_MIXER_SCHN_FRONT_LEFT, &frontLeftVolume) < 0)      frontLeftVolume = 0;               if( snd_mixer_selem_get_playback_volume( mixer_elements2,                                             SND_MIXER_SCHN_FRONT_RIGHT, &frontRightVolume) < 0)      frontRightVolume = 0;  }  /*    snd_mixer_selem_get_playback_volume_range( mixer_elements2, &pmin, &pmax);        int range = pmax - pmin;        int val = frontLeftVolume;        frontRightVolume =  frontLeftVolume;        val -= pmin;        //    printf("min %d, max %d, range %d, val %d\n", pmin, pmax, range, val );        percentage = (long)rint((double)val / (double)range * 100);  */        //    printf("fleft %ld, fright %ld, percent %d\n",  //           frontLeftVolume, frontRightVolume, percentage);  // Save for future use, demonstrates multichannel mixer access.    //   for ( mixer_elements2 = snd_mixer_first_elem( mixer_handle);  //         mixer_elements2;  //         mixer_elements2 = snd_mixer_elem_next( mixer_elements2) )  {      //     snd_mixer_selem_get_id( mixer_elements2, sid);      // //     if ( !snd_mixer_selem_is_active( mixer_elements2))  // //       continue;      //     printf("mixer control '%s',%i\n",   //     snd_mixer_selem_id_get_name( sid),   //     snd_mixer_selem_id_get_index( sid));    //        snd_mixer_selem_get_playback_volume_range( mixer_elements2, &pmin, &pmax);  //         // if its got mono mixer  //        if ( snd_mixer_selem_has_common_volume( mixer_elements2)) //mono  //      {  //            // check for playback vol mixer           //          if (snd_mixer_selem_has_playback_volume( mixer_elements2)) {  //                //score!          // //           if( snd_mixer_find_selem( mixer_handle,mixer_elements2) == SND_MIXER_SCHN_MONO)  // //             {  //              snd_mixer_selem_get_playback_volume( mixer_elements2,  //                                                   SND_MIXER_SCHN_MONO, &frontLeftVolume);  //                //for finding percentage                  //              int range = pmax - pmin;  //              int val = frontLeftVolume;  //              frontRightVolume =  frontLeftVolume;  //              val -= pmin;  //              percentage = (long)rint((double)val / (double)range * 100);  //              printf("common min %d, max %d, range %d\n", pmin, pmax, range);     //          }  //      }  //        else //stereo  //       {  // //          printf("get seperate r and l volumes\n");         //           if (snd_mixer_selem_has_playback_volume( mixer_elements2)) {              //               if( snd_mixer_selem_get_playback_volume( mixer_elements2,  //                                                        SND_MIXER_SCHN_FRONT_LEFT, &frontLeftVolume) < 0)  //                   frontLeftVolume = 0;             //               if( snd_mixer_selem_get_playback_volume( mixer_elements2,  //                                                        SND_MIXER_SCHN_FRONT_RIGHT, &frontRightVolume) < 0)

⌨️ 快捷键说明

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