Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 76d94691 authored by jiabin's avatar jiabin
Browse files

Volume control for bit-perfect thread.

When there is a track play bit-perfectly, the framework will no longer
apply software volume control in the mixer. In that case, the audio
framework need to send the volume command down to the HAL.

Bug: 262578034
Test: adjust volume while play bit-perfectly
Change-Id: I927a9bd20b7fcce841a133c2786bdc4b352afa30
parent 8e22898f
Loading
Loading
Loading
Loading
+10 −2
Original line number Original line Diff line number Diff line
@@ -116,6 +116,9 @@ bool AudioMixer::setChannelMasks(int name,
        track->mKeepContractedChannels = false;
        track->mKeepContractedChannels = false;
    }
    }


    track->mInputFrameSize = audio_bytes_per_frame(
            track->channelCount + track->mHapticChannelCount, track->mFormat);

    // channel masks have changed, does this track need a downmixer?
    // channel masks have changed, does this track need a downmixer?
    // update to try using our desired format (if we aren't already using it)
    // update to try using our desired format (if we aren't already using it)
    const status_t status = track->prepareForDownmix();
    const status_t status = track->prepareForDownmix();
@@ -309,9 +312,8 @@ status_t AudioMixer::Track::prepareForTee() {
    ALOGV("AudioMixer::%s(%p) teeBuffer=%p", __func__, this, teeBuffer);
    ALOGV("AudioMixer::%s(%p) teeBuffer=%p", __func__, this, teeBuffer);
    unprepareForTee();
    unprepareForTee();
    if (teeBuffer != nullptr) {
    if (teeBuffer != nullptr) {
        const size_t frameSize = audio_bytes_per_frame(channelCount + mHapticChannelCount, mFormat);
        mTeeBufferProvider.reset(new TeeBufferProvider(
        mTeeBufferProvider.reset(new TeeBufferProvider(
                frameSize, frameSize, kCopyBufferFrameCount,
                mInputFrameSize, mInputFrameSize, kCopyBufferFrameCount,
                (uint8_t*)teeBuffer, mTeeBufferFrameCount));
                (uint8_t*)teeBuffer, mTeeBufferFrameCount));
        reconfigureBufferProviders();
        reconfigureBufferProviders();
    }
    }
@@ -590,6 +592,8 @@ status_t AudioMixer::postCreateTrack(TrackBase *track)
    t->mAdjustInChannelCount = t->channelCount + t->mHapticChannelCount;
    t->mAdjustInChannelCount = t->channelCount + t->mHapticChannelCount;
    t->mAdjustOutChannelCount = t->channelCount;
    t->mAdjustOutChannelCount = t->channelCount;
    t->mKeepContractedChannels = false;
    t->mKeepContractedChannels = false;
    t->mInputFrameSize = audio_bytes_per_frame(
            t->channelCount + t->mHapticChannelCount, t->mFormat);
    // Check the downmixing (or upmixing) requirements.
    // Check the downmixing (or upmixing) requirements.
    status_t status = t->prepareForDownmix();
    status_t status = t->prepareForDownmix();
    if (status != OK) {
    if (status != OK) {
@@ -641,6 +645,10 @@ void AudioMixer::postProcess()
                }
                }
                break;
                break;
            }
            }
            if (t->teeBuffer != nullptr && t->volumeRL == 0) {
                // Need to mute tee
                memset(t->teeBuffer, 0, t->mTeeBufferFrameCount * t->mInputFrameSize);
            }
        }
        }
    }
    }
}
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -152,6 +152,7 @@ status_t AudioMixerBase::create(
                AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
                AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
        t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
        t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
        t->mTeeBufferFrameCount = 0;
        t->mTeeBufferFrameCount = 0;
        t->mInputFrameSize = audio_bytes_per_frame(t->channelCount, t->mFormat);
        status_t status = postCreateTrack(t.get());
        status_t status = postCreateTrack(t.get());
        if (status != OK) return status;
        if (status != OK) return status;
        mTracks[name] = t;
        mTracks[name] = t;
@@ -178,6 +179,7 @@ bool AudioMixerBase::setChannelMasks(int name,
    track->channelCount = trackChannelCount;
    track->channelCount = trackChannelCount;
    track->mMixerChannelMask = mixerChannelMask;
    track->mMixerChannelMask = mixerChannelMask;
    track->mMixerChannelCount = mixerChannelCount;
    track->mMixerChannelCount = mixerChannelCount;
    track->mInputFrameSize = audio_bytes_per_frame(track->channelCount, track->mFormat);


    // Resampler channels may have changed.
    // Resampler channels may have changed.
    track->recreateResampler(mSampleRate);
    track->recreateResampler(mSampleRate);
+2 −0
Original line number Original line Diff line number Diff line
@@ -297,6 +297,8 @@ public:


        int32_t        mTeeBufferFrameCount;
        int32_t        mTeeBufferFrameCount;


        uint32_t       mInputFrameSize; // The track input frame size, used for tee buffer

      protected:
      protected:


        // hooks
        // hooks
+9 −1
Original line number Original line Diff line number Diff line
@@ -148,8 +148,12 @@ public:
    sp<media::VolumeHandler>   getVolumeHandler() { return mVolumeHandler; }
    sp<media::VolumeHandler>   getVolumeHandler() { return mVolumeHandler; }
    /** Set the computed normalized final volume of the track.
    /** Set the computed normalized final volume of the track.
     * !masterMute * masterVolume * streamVolume * averageLRVolume */
     * !masterMute * masterVolume * streamVolume * averageLRVolume */
    void                setFinalVolume(float volume);
    void                setFinalVolume(float volumeLeft, float volumeRight);
    float               getFinalVolume() const { return mFinalVolume; }
    float               getFinalVolume() const { return mFinalVolume; }
    void                getFinalVolume(float* left, float* right) const {
                            *left = mFinalVolumeLeft;
                            *right = mFinalVolumeRight;
    }


    using SourceMetadatas = std::vector<playback_track_metadata_v7_t>;
    using SourceMetadatas = std::vector<playback_track_metadata_v7_t>;
    using MetadataInserter = std::back_insert_iterator<SourceMetadatas>;
    using MetadataInserter = std::back_insert_iterator<SourceMetadatas>;
@@ -355,6 +359,10 @@ private:
                                        // 'volatile' means accessed without lock or
                                        // 'volatile' means accessed without lock or
                                        // barrier, but is read/written atomically
                                        // barrier, but is read/written atomically
    float               mFinalVolume; // combine master volume, stream type volume and track volume
    float               mFinalVolume; // combine master volume, stream type volume and track volume
    float               mFinalVolumeLeft; // combine master volume, stream type volume and track
                                          // volume
    float               mFinalVolumeRight; // combine master volume, stream type volume and track
                                           // volume
    sp<AudioTrackServerProxy>  mAudioTrackServerProxy;
    sp<AudioTrackServerProxy>  mAudioTrackServerProxy;
    bool                mResumeToStopping; // track was paused in stopping state.
    bool                mResumeToStopping; // track was paused in stopping state.
    bool                mFlushHwPending; // track requests for thread flush
    bool                mFlushHwPending; // track requests for thread flush
+11 −3
Original line number Original line Diff line number Diff line
@@ -5513,7 +5513,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
                vlf *= volume;
                vlf *= volume;
                vrf *= volume;
                vrf *= volume;


                track->setFinalVolume((vlf + vrf) / 2.f);
                track->setFinalVolume(vlf, vrf);
                ++fastTracks;
                ++fastTracks;
            } else {
            } else {
                // was it previously active?
                // was it previously active?
@@ -5712,7 +5712,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
                vaf = v * sendLevel * (1. / MAX_GAIN_INT);
                vaf = v * sendLevel * (1. / MAX_GAIN_INT);
            }
            }


            track->setFinalVolume((vrf + vlf) / 2.f);
            track->setFinalVolume(vrf, vlf);


            // Delegate volume control to effect in track effect chain if needed
            // Delegate volume control to effect in track effect chain if needed
            if (chain != 0 && chain->setVolume_l(&vl, &vr)) {
            if (chain != 0 && chain->setVolume_l(&vl, &vr)) {
@@ -6320,7 +6320,7 @@ void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTr
                       shaperVolume == 0.f});
                       shaperVolume == 0.f});


    if (lastTrack) {
    if (lastTrack) {
        track->setFinalVolume((left + right) / 2.f);
        track->setFinalVolume(left, right);
        if (left != mLeftVolFloat || right != mRightVolFloat) {
        if (left != mLeftVolFloat || right != mRightVolFloat) {
            mLeftVolFloat = left;
            mLeftVolFloat = left;
            mRightVolFloat = right;
            mRightVolFloat = right;
@@ -10804,6 +10804,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::BitPerfectThread::prepar
        Vector<sp<Track>> *tracksToRemove) {
        Vector<sp<Track>> *tracksToRemove) {
    mixer_state result = MixerThread::prepareTracks_l(tracksToRemove);
    mixer_state result = MixerThread::prepareTracks_l(tracksToRemove);
    // If there is only one active track and it is bit-perfect, enable tee buffer.
    // If there is only one active track and it is bit-perfect, enable tee buffer.
    float volumeLeft = 1.0f;
    float volumeRight = 1.0f;
    if (mActiveTracks.size() == 1 && mActiveTracks[0]->isBitPerfect()) {
    if (mActiveTracks.size() == 1 && mActiveTracks[0]->isBitPerfect()) {
        const int trackId = mActiveTracks[0]->id();
        const int trackId = mActiveTracks[0]->id();
        mAudioMixer->setParameter(
        mAudioMixer->setParameter(
@@ -10811,6 +10813,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::BitPerfectThread::prepar
        mAudioMixer->setParameter(
        mAudioMixer->setParameter(
                    trackId, AudioMixer::TRACK, AudioMixer::TEE_BUFFER_FRAME_COUNT,
                    trackId, AudioMixer::TRACK, AudioMixer::TEE_BUFFER_FRAME_COUNT,
                    (void *)(uintptr_t)mNormalFrameCount);
                    (void *)(uintptr_t)mNormalFrameCount);
        mActiveTracks[0]->getFinalVolume(&volumeLeft, &volumeRight);
        mIsBitPerfect = true;
        mIsBitPerfect = true;
    } else {
    } else {
        mIsBitPerfect = false;
        mIsBitPerfect = false;
@@ -10822,6 +10825,11 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::BitPerfectThread::prepar
                        trackId, AudioMixer::TRACK, AudioMixer::TEE_BUFFER, nullptr);
                        trackId, AudioMixer::TRACK, AudioMixer::TEE_BUFFER, nullptr);
        }
        }
    }
    }
    if (mVolumeLeft != volumeLeft || mVolumeRight != volumeRight) {
        mVolumeLeft = volumeLeft;
        mVolumeRight = volumeRight;
        setVolumeForOutput_l(volumeLeft, volumeRight);
    }
    return result;
    return result;
}
}


Loading