今天来看看playback rate相关的接口。包括set和get。


*****************************************源码*************************************************
    //Test case 6: setPlaybackRate() accepts values twice the output sample rate    @LargeTest    public void testSetPlaybackRateTwiceOutputSR() throws Exception {        // constants for test        final String TEST_NAME = "testSetPlaybackRateTwiceOutputSR";        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];        int outputSR = AudioTrack.getNativeOutputSampleRate(TEST_STREAM_TYPE);        //--------    test        --------------        track.write(data, 0, data.length);        track.write(data, 0, data.length);        assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);        track.play();        assertTrue(TEST_NAME, track.setPlaybackRate(2*outputSR) == AudioTrack.SUCCESS);        //-------- tear down      --------------        track.release();    }

**********************************************************************************************
源码路径:
frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioTrackTest.java


#######################说明################################
    //Test case 6: setPlaybackRate() accepts values twice the output sample rate    @LargeTest    public void testSetPlaybackRateTwiceOutputSR() throws Exception {        // constants for test        final String TEST_NAME = "testSetPlaybackRateTwiceOutputSR";        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];        int outputSR = AudioTrack.getNativeOutputSampleRate(TEST_STREAM_TYPE);// +++++++++++++++++++++++++++++getNativeOutputSampleRate+++++++++++++++++++++++++++++++++++    /**     *  Returns the hardware output sample rate     */    static public int getNativeOutputSampleRate(int streamType) {        return native_get_output_sample_rate(streamType);// +++++++++++++++++++++++++++++android_media_AudioTrack_get_playback_rate+++++++++++++++++++++++++++++++++++static jint android_media_AudioTrack_get_playback_rate(JNIEnv *env,  jobject thiz) {    AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(                thiz, javaAudioTrackFields.nativeTrackInJavaObj);    if (lpTrack) {        return (jint) lpTrack->getSampleRate();   // ++++++++++++++++++++++++++++AudioTrack::getSampleRate++++++++++++++++++++++++++++++++++++uint32_t AudioTrack::getSampleRate(){// 直接返回了audio_track_cblk_t中的sample rate。// audio_track_cblk_t对象在AudioFlinger::ThreadBase::TrackBase::TrackBase的构造函数中被创建:new(mCblk) audio_track_cblk_t();// 创建audio_track_cblk_t对象后,即对其成员变量sampleRate进行了赋值:mCblk->sampleRate = sampleRate;// 此处的sampleRate其实是创建AudioTrack对象时传入的sampleRate。    return mCblk->sampleRate;}// ----------------------------AudioTrack::getSampleRate------------------------------------    } else {        jniThrowException(env, "java/lang/IllegalStateException",            "Unable to retrieve AudioTrack pointer for getSampleRate()");        return AUDIOTRACK_ERROR;    }}// -----------------------------android_media_AudioTrack_get_playback_rate-----------------------------------    }// -----------------------------getNativeOutputSampleRate-----------------------------------        //--------    test        --------------        track.write(data, 0, data.length);        track.write(data, 0, data.length);        assumeTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);        track.play();        assertTrue(TEST_NAME, track.setPlaybackRate(2*outputSR) == AudioTrack.SUCCESS);// ++++++++++++++++++++++++++++setPlaybackRate+++++++++++++++++++++++++++++++++++    /**     * Sets the playback sample rate for this track. This sets the sampling rate at which     * the audio data will be consumed and played back, not the original sampling rate of the     * content. Setting it to half the sample rate of the content will cause the playback to     * last twice as long, but will also result in a negative pitch shift.     * The valid sample rate range if from 1Hz to twice the value returned by     * {@link #getNativeOutputSampleRate(int)}.     * @param sampleRateInHz the sample rate expressed in Hz     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},     *    {@link #ERROR_INVALID_OPERATION}     */// 看看这段注释// 此处改变的rate,只是播放时的rate,并不是数据本身的rate。// 例如,如果将rate设置为原来的一半,则播放时间将变为原来的2倍。// 所设rate的范围是1Hz到原来rate的2倍。    public int setPlaybackRate(int sampleRateInHz) {        if (mState != STATE_INITIALIZED) {            return ERROR_INVALID_OPERATION;        }        if (sampleRateInHz <= 0) {            return ERROR_BAD_VALUE;        }        return native_set_playback_rate(sampleRateInHz);// ++++++++++++++++++++++++++++android_media_AudioTrack_set_playback_rate++++++++++++++++++++++++++++++++++++static jint android_media_AudioTrack_set_playback_rate(JNIEnv *env,  jobject thiz,        jint sampleRateInHz) {    AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(                thiz, javaAudioTrackFields.nativeTrackInJavaObj);    if (lpTrack) {        return android_media_translateErrorCode(lpTrack->setSampleRate(sampleRateInHz));// +++++++++++++++++++++++++++AudioTrack::setSampleRate+++++++++++++++++++++++++++++++++++++status_t AudioTrack::setSampleRate(int rate){    int afSamplingRate;    if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) {        return NO_INIT;// +++++++++++++++++++++++++++++AudioSystem::getOutputSamplingRate+++++++++++++++++++++++++++++++++++// 感觉这么熟悉!// 原来已见过多次!status_t AudioSystem::getOutputSamplingRate(int* samplingRate, int streamType){    OutputDescriptor *outputDesc;    audio_io_handle_t output;    if (streamType == DEFAULT) {        streamType = MUSIC;    }    output = getOutput((stream_type)streamType);    if (output == 0) {        return PERMISSION_DENIED;    }    gLock.lock();// AudioSystem::AudioFlingerClient::ioConfigChanged函数有往gOutputs中添加成员    outputDesc = AudioSystem::gOutputs.valueFor(output);    if (outputDesc == 0) {        LOGV("getOutputSamplingRate() no output descriptor for output %d in gOutputs", output);        gLock.unlock();        const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();        if (af == 0) return PERMISSION_DENIED;        *samplingRate = af->sampleRate(output);// +++++++++++++++++++++++++AudioFlinger::sampleRate+++++++++++++++++++++++++++++++++++++++uint32_t AudioFlinger::sampleRate(int output) const{    Mutex::Autolock _l(mLock);    PlaybackThread *thread = checkPlaybackThread_l(output);    if (thread == NULL) {        LOGW("sampleRate() unknown thread %d", output);        return 0;    }    return thread->sampleRate();// +++++++++++++++++++++++++++AudioFlinger::ThreadBase::sampleRate+++++++++++++++++++++++++++++++++++++uint32_t AudioFlinger::ThreadBase::sampleRate() const{// 函数AudioFlinger::PlaybackThread::readOutputParameters中会给mSampleRate赋值: mSampleRate = mOutput->sampleRate();    return mSampleRate;}// ---------------------------AudioFlinger::ThreadBase::sampleRate-------------------------------------}// -------------------------AudioFlinger::sampleRate---------------------------------------    } else {        LOGV("getOutputSamplingRate() reading from output desc");        *samplingRate = outputDesc->samplingRate;        gLock.unlock();    }    LOGV("getOutputSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output, *samplingRate);    return NO_ERROR;}// -----------------------------AudioSystem::getOutputSamplingRate-----------------------------------    }    // Resampler implementation limits input sampling rate to 2 x output sampling rate.    if (rate <= 0 || rate > afSamplingRate*2 ) return BAD_VALUE;// 将rate设置到audio_track_cblk_t对象中    mCblk->sampleRate = rate;    return NO_ERROR;}// ---------------------------AudioTrack::setSampleRate-------------------------------------    } else {        jniThrowException(env, "java/lang/IllegalStateException",            "Unable to retrieve AudioTrack pointer for setSampleRate()");        return AUDIOTRACK_ERROR;    }}// ----------------------------android_media_AudioTrack_set_playback_rate------------------------------------    }// ----------------------------setPlaybackRate------------------------------------        //-------- tear down      --------------        track.release();    }

###########################################################


&&&&&&&&&&&&&&&&&&&&&&&总结&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
set rate改变的只是播放时的rate,而不是数据本身的rate。
也就是说,set rate若与原来的rate不同的话,播放时间会改变。
函数AudioFlinger::MixerThread::threadLoop中会根据rate计算max period。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

更多相关文章

  1. 箭头函数的基础使用
  2. 类和 Json对象
  3. Python技巧匿名函数、回调函数和高阶函数
  4. 浅析android通过jni控制service服务程序的简易流程
  5. android“设置”里的版本号
  6. Android(安卓)bluetooth介绍(四): a2dp connect流程分析
  7. Android中文API(144) —— JsonWriter
  8. Android之Handler用法总结
  9. Android架构分析之使用自定义硬件抽象层(HAL)模块

随机推荐

  1. Glide的with()方法和生命周期的源码分析
  2. Android(安卓)事件中 OnTouch 事件
  3. Android稳定性优化--概括
  4. Android-BLE低功耗蓝牙开发
  5. android获取屏幕大小
  6. 通过Setters方式对日期属性及日期格式进
  7. 仿PHP中文网右侧部分
  8. 留言板功能
  9. 常用的函数类型和常用的数据类型
  10. 留言板与自动客服