📄 audlinux_alsa.cpp
字号:
// frontRightVolume = 0; // // if( snd_mixer_selem_get_playback_volume( mixer_elements2, // // SND_MIXER_SCHN_FRONT_CENTER, &frontCenterVolume) < 0) // // 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 + -