Android Audio代码分析17 - setvolume函数
2011-10-19 15:50
465 查看
下面来看看音量设置相关的接口。
*****************************************源码*************************************************
**********************************************************************************************
源码路径:
frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioTrackTest.java
#######################说明################################
###########################################################
&&&&&&&&&&&&&&&&&&&&&&&总结&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
函数setStereoVolume最终设置的是软音量。
类AudioMixer中将数据从audio_track_cblk_t copy 到main buffer时,会使用音量对数据进行处理。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
*****************************************源码*************************************************
//Test case 1: setStereoVolume() with max volume returns SUCCESS @LargeTest public void testSetStereoVolumeMax() throws Exception { // constants for test final String TEST_NAME = "testSetStereoVolumeMax"; final int TEST_SR = 22050; final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO; final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT; final int TEST_MODE = AudioTrack.MODE_STREAM; final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC; //-------- initialization -------------- int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT); AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT, minBuffSize, TEST_MODE); byte data[] = new byte[minBuffSize/2]; //-------- test -------------- track.write(data, 0, data.length); track.write(data, 0, data.length); track.play(); float maxVol = AudioTrack.getMaxVolume(); assertTrue(TEST_NAME, track.setStereoVolume(maxVol, maxVol) == AudioTrack.SUCCESS); //-------- tear down -------------- track.release(); }
**********************************************************************************************
源码路径:
frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioTrackTest.java
#######################说明################################
//Test case 1: setStereoVolume() with max volume returns SUCCESS @LargeTest public void testSetStereoVolumeMax() throws Exception { // constants for test final String TEST_NAME = "testSetStereoVolumeMax"; final int TEST_SR = 22050; final int TEST_CONF = AudioFormat.CHANNEL_OUT_STEREO; final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT; final int TEST_MODE = AudioTrack.MODE_STREAM; final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC; //-------- initialization -------------- int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT); AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT, minBuffSize, TEST_MODE); byte data[] = new byte[minBuffSize/2]; //-------- test -------------- track.write(data, 0, data.length); track.write(data, 0, data.length); track.play(); float maxVol = AudioTrack.getMaxVolume(); // ++++++++++++++++++++++++++++++getMaxVolume++++++++++++++++++++++++++++++++++ /** * Returns the maximum valid volume value. Volume values set above this one will * be clamped at this value. * @return the maximum volume expressed as a linear attenuation. */ static public float getMaxVolume() { return AudioTrack.VOLUME_MAX; } // ------------------------------getMaxVolume---------------------------------- assertTrue(TEST_NAME, track.setStereoVolume(maxVol, maxVol) == AudioTrack.SUCCESS); // ++++++++++++++++++++++++++++++setStereoVolume++++++++++++++++++++++++++++++++++ /** * Sets the specified left/right output volume values on the AudioTrack. Values are clamped * to the ({@link #getMinVolume()}, {@link #getMaxVolume()}) interval if outside this range. * @param leftVolume output attenuation for the left channel. A value of 0.0f is silence, * a value of 1.0f is no attenuation. * @param rightVolume output attenuation for the right channel * @return error code or success, see {@link #SUCCESS}, * {@link #ERROR_INVALID_OPERATION} */ public int setStereoVolume(float leftVolume, float rightVolume) { if (mState != STATE_INITIALIZED) { return ERROR_INVALID_OPERATION; } // 确保音量在[min, max]范围之内。 // clamp the volumes if (leftVolume < getMinVolume()) { leftVolume = getMinVolume(); } if (leftVolume > getMaxVolume()) { leftVolume = getMaxVolume(); } if (rightVolume < getMinVolume()) { rightVolume = getMinVolume(); } if (rightVolume > getMaxVolume()) { rightVolume = getMaxVolume(); } native_setVolume(leftVolume, rightVolume); // ++++++++++++++++++++++++++++android_media_AudioTrack_set_volume++++++++++++++++++++++++++++++++++++ static void android_media_AudioTrack_set_volume(JNIEnv *env, jobject thiz, jfloat leftVol, jfloat rightVol ) { AudioTrack *lpTrack = (AudioTrack *)env->GetIntField( thiz, javaAudioTrackFields.nativeTrackInJavaObj); if (lpTrack == NULL ) { jniThrowException(env, "java/lang/IllegalStateException", "Unable to retrieve AudioTrack pointer for setVolume()"); return; } lpTrack->setVolume(leftVol, rightVol); // +++++++++++++++++++++++++++++AudioTrack::setVolume++++++++++++++++++++++++++++++++++ status_t AudioTrack::setVolume(float left, float right) { // 范围检查 if (left > 1.0f || right > 1.0f) { return BAD_VALUE; } // 将音量保存到成员变量中 // 函数AudioTrack::set中会将这两个音量初始化为1.0f // 函数AudioTrack::getVolume会取出这两个音量值 // 函数AudioTrack::createTrack中会将这两个值赋值给mCblk->volumeLR mVolume[LEFT] = left; mVolume[RIGHT] = right; // write must be atomic // 从audio_track_cblk_t的定义可知,volume的信息其实是一个union,这儿是作为volumeLR存入的, // 用的时候其实是作为uint16_t volume[2]数组来使用的。 // +++++++++++++++++++++++++++++union+++++++++++++++++++++++++++++++++++ volatile union { uint16_t volume[2]; uint32_t volumeLR; }; // -----------------------------union----------------------------------- // 类AudioMixer中,将数据从audio_track_cblk_t copy 到main buffer时,会根据音量对数据进行处理。 // 如以前我们看过的process__OneTrack16BitsStereoNoResampling函数。 mCblk->volumeLR = (uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000); return NO_ERROR; } // -----------------------------AudioTrack::setVolume---------------------------------- } // ----------------------------android_media_AudioTrack_set_volume------------------------------------ return SUCCESS; } // ------------------------------setStereoVolume---------------------------------- //-------- tear down -------------- track.release(); }
###########################################################
&&&&&&&&&&&&&&&&&&&&&&&总结&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
函数setStereoVolume最终设置的是软音量。
类AudioMixer中将数据从audio_track_cblk_t copy 到main buffer时,会使用音量对数据进行处理。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
相关文章推荐
- Android Audio代码分析17 - setvolume函数
- Android Audio 代码分析- Audio Strategy
- Android Audio代码分析3 - 创建AudioTrack对象
- Android Audio代码分析8 - AudioHardwareALSA::openOutputStream函数
- Android Audio代码分析26 - Audio Strategy
- Android Audio代码分析8 - AudioHardwareALSA::openOutputStream函数
- Android Audio代码分析15 - testPlaybackHeadPositionAfterFlush
- Android Audio代码分析26 - Audio Strategy
- Android Audio代码分析=>Stream=>Strateg优先级
- Android Audio代码分析15 - testPlaybackHeadPositionAfterFlush
- Android Audio代码分析11 - AudioStreamOutALSA::write函数
- Android Audio代码分析27 - Strategy 优先级
- Android Audio代码分析16 - testPlaybackHeadPositionAfterPause函数
- Android Audio代码分析23 - attachAuxEffect函数
- Android Audio代码分析8 - AudioHardwareALSA::openOutputStream函数(下)
- Android Audio代码分析9 - AudioTrack::write函数
- Android Audio代码分析11 - AudioStreamOutALSA::write函数
- Android Audio代码分析27 - Strategy 优先级
- Android Audio代码分析16 - testPlaybackHeadPositionAfterPause函数
- Android Audio代码分析22 - AudioEffect::getEnabled函数