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

Commit d4adbdb7 authored by Kuowei Li's avatar Kuowei Li Committed by Andy Hung
Browse files

audio: add implementation for TV related API

1. TunerConfiguration.
2. AudioDescriptionMixLevel getter/setter.
3. DualMonoMode getter/setter.
4. PlaybackRate getter/setter.

Test: TIS player with instrumented HAL
Test: atest AudioTrackTest#testTunerConfiguration
Test: atest AudioTrackTest#testDualMonoMode
Test: atest AudioTrackTest#testAudioDescriptionMixLevel
Test: atest AudioManagerTest#testGetAdditionalOutputDeviceDelay
Bug: 173482792
Change-Id: Idb22ce6714fa240b2b4b3b8637b16d3a51228fa1
parent 07f14e30
Loading
Loading
Loading
Loading
+74 −0
Original line number Diff line number Diff line
@@ -2127,4 +2127,78 @@ legacy2aidl_product_strategy_t_int32_t(product_strategy_t legacy) {
    return convertReinterpret<int32_t>(legacy);
}

ConversionResult<audio_dual_mono_mode_t>
aidl2legacy_AudioDualMonoMode_audio_dual_mono_mode_t(media::AudioDualMonoMode aidl) {
    switch (aidl) {
        case media::AudioDualMonoMode::OFF:
            return AUDIO_DUAL_MONO_MODE_OFF;
        case media::AudioDualMonoMode::LR:
            return AUDIO_DUAL_MONO_MODE_LR;
        case media::AudioDualMonoMode::LL:
            return AUDIO_DUAL_MONO_MODE_LL;
        case media::AudioDualMonoMode::RR:
            return AUDIO_DUAL_MONO_MODE_RR;
    }
    return unexpected(BAD_VALUE);
}

ConversionResult<media::AudioDualMonoMode>
legacy2aidl_audio_dual_mono_mode_t_AudioDualMonoMode(audio_dual_mono_mode_t legacy) {
    switch (legacy) {
        case AUDIO_DUAL_MONO_MODE_OFF:
            return media::AudioDualMonoMode::OFF;
        case AUDIO_DUAL_MONO_MODE_LR:
            return media::AudioDualMonoMode::LR;
        case AUDIO_DUAL_MONO_MODE_LL:
            return media::AudioDualMonoMode::LL;
        case AUDIO_DUAL_MONO_MODE_RR:
            return media::AudioDualMonoMode::RR;
    }
    return unexpected(BAD_VALUE);
}

ConversionResult<audio_timestretch_fallback_mode_t>
aidl2legacy_int32_t_audio_timestretch_fallback_mode_t(int32_t aidl) {
    return convertReinterpret<audio_timestretch_fallback_mode_t>(aidl);
}

ConversionResult<int32_t>
legacy2aidl_audio_timestretch_fallback_mode_t_int32_t(audio_timestretch_fallback_mode_t legacy) {
    return convertReinterpret<int32_t>(legacy);
}

ConversionResult<audio_timestretch_stretch_mode_t>
aidl2legacy_int32_t_audio_timestretch_stretch_mode_t(int32_t aidl) {
    return convertReinterpret<audio_timestretch_stretch_mode_t>(aidl);
}

ConversionResult<int32_t>
legacy2aidl_audio_timestretch_stretch_mode_t_int32_t(audio_timestretch_stretch_mode_t legacy) {
    return convertReinterpret<int32_t>(legacy);
}

ConversionResult<audio_playback_rate_t>
aidl2legacy_AudioPlaybackRate_audio_playback_rate_t(const media::AudioPlaybackRate& aidl) {
    audio_playback_rate_t legacy;
    legacy.mSpeed = aidl.speed;
    legacy.mPitch = aidl.pitch;
    legacy.mFallbackMode = VALUE_OR_RETURN(
            aidl2legacy_int32_t_audio_timestretch_fallback_mode_t(aidl.fallbackMode));
    legacy.mStretchMode = VALUE_OR_RETURN(
            aidl2legacy_int32_t_audio_timestretch_stretch_mode_t(aidl.stretchMode));
    return legacy;
}

ConversionResult<media::AudioPlaybackRate>
legacy2aidl_audio_playback_rate_t_AudioPlaybackRate(const audio_playback_rate_t& legacy) {
    media::AudioPlaybackRate aidl;
    aidl.speed = legacy.mSpeed;
    aidl.pitch = legacy.mPitch;
    aidl.fallbackMode = VALUE_OR_RETURN(
            legacy2aidl_audio_timestretch_fallback_mode_t_int32_t(legacy.mFallbackMode));
    aidl.stretchMode = VALUE_OR_RETURN(
            legacy2aidl_audio_timestretch_stretch_mode_t_int32_t(legacy.mStretchMode));
    return aidl;
}

}  // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -295,6 +295,7 @@ aidl_interface {
        "aidl/android/media/AudioConfigBase.aidl",
        "aidl/android/media/AudioContentType.aidl",
        "aidl/android/media/AudioDevice.aidl",
        "aidl/android/media/AudioDualMonoMode.aidl",
        "aidl/android/media/AudioEncapsulationMode.aidl",
        "aidl/android/media/AudioEncapsulationMetadataType.aidl",
        "aidl/android/media/AudioFlag.aidl",
@@ -310,6 +311,7 @@ aidl_interface {
        "aidl/android/media/AudioOffloadInfo.aidl",
        "aidl/android/media/AudioOutputFlags.aidl",
        "aidl/android/media/AudioPatch.aidl",
        "aidl/android/media/AudioPlaybackRate.aidl",
        "aidl/android/media/AudioPort.aidl",
        "aidl/android/media/AudioPortConfig.aidl",
        "aidl/android/media/AudioPortConfigType.aidl",
+73 −2
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@
#define WAIT_STREAM_END_TIMEOUT_SEC     120
static const int kMaxLoopCountNotifications = 32;

using ::android::aidl_utils::statusTFromBinderStatus;

namespace android {
// ---------------------------------------------------------------------------

@@ -1096,6 +1098,53 @@ uint32_t AudioTrack::getOriginalSampleRate() const
    return mOriginalSampleRate;
}

status_t AudioTrack::setDualMonoMode(audio_dual_mono_mode_t mode)
{
    AutoMutex lock(mLock);
    return setDualMonoMode_l(mode);
}

status_t AudioTrack::setDualMonoMode_l(audio_dual_mono_mode_t mode)
{
    const status_t status = statusTFromBinderStatus(
        mAudioTrack->setDualMonoMode(VALUE_OR_RETURN_STATUS(
            legacy2aidl_audio_dual_mono_mode_t_AudioDualMonoMode(mode))));
    if (status == NO_ERROR) mDualMonoMode = mode;
    return status;
}

status_t AudioTrack::getDualMonoMode(audio_dual_mono_mode_t* mode) const
{
    AutoMutex lock(mLock);
    media::AudioDualMonoMode mediaMode;
    const status_t status = statusTFromBinderStatus(mAudioTrack->getDualMonoMode(&mediaMode));
    if (status == NO_ERROR) {
        *mode = VALUE_OR_RETURN_STATUS(
                aidl2legacy_AudioDualMonoMode_audio_dual_mono_mode_t(mediaMode));
    }
    return status;
}

status_t AudioTrack::setAudioDescriptionMixLevel(float leveldB)
{
    AutoMutex lock(mLock);
    return setAudioDescriptionMixLevel_l(leveldB);
}

status_t AudioTrack::setAudioDescriptionMixLevel_l(float leveldB)
{
    const status_t status = statusTFromBinderStatus(
             mAudioTrack->setAudioDescriptionMixLevel(leveldB));
    if (status == NO_ERROR) mAudioDescriptionMixLeveldB = leveldB;
    return status;
}

status_t AudioTrack::getAudioDescriptionMixLevel(float* leveldB) const
{
    AutoMutex lock(mLock);
    return statusTFromBinderStatus(mAudioTrack->getAudioDescriptionMixLevel(leveldB));
}

status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate)
{
    AutoMutex lock(mLock);
@@ -1103,7 +1152,13 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate)
        return NO_ERROR;
    }
    if (isOffloadedOrDirect_l()) {
        return INVALID_OPERATION;
        const status_t status = statusTFromBinderStatus(mAudioTrack->setPlaybackRateParameters(
                VALUE_OR_RETURN_STATUS(
                        legacy2aidl_audio_playback_rate_t_AudioPlaybackRate(playbackRate))));
        if (status == NO_ERROR) {
            mPlaybackRate = playbackRate;
        }
        return status;
    }
    if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
        return INVALID_OPERATION;
@@ -1168,9 +1223,18 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate)
    return NO_ERROR;
}

const AudioPlaybackRate& AudioTrack::getPlaybackRate() const
const AudioPlaybackRate& AudioTrack::getPlaybackRate()
{
    AutoMutex lock(mLock);
    if (isOffloadedOrDirect_l()) {
        media::AudioPlaybackRate playbackRateTemp;
        const status_t status = statusTFromBinderStatus(
                mAudioTrack->getPlaybackRateParameters(&playbackRateTemp));
        if (status == NO_ERROR) { // update local version if changed.
            mPlaybackRate =
                    aidl2legacy_AudioPlaybackRate_audio_playback_rate_t(playbackRateTemp).value();
        }
    }
    return mPlaybackRate;
}

@@ -1771,6 +1835,13 @@ status_t AudioTrack::createTrack_l()
    mProxy->setPlaybackRate(playbackRateTemp);
    mProxy->setMinimum(mNotificationFramesAct);

    if (mDualMonoMode != AUDIO_DUAL_MONO_MODE_OFF) {
        setDualMonoMode_l(mDualMonoMode);
    }
    if (mAudioDescriptionMixLeveldB != -std::numeric_limits<float>::infinity()) {
        setAudioDescriptionMixLevel_l(mAudioDescriptionMixLeveldB);
    }

    mDeathNotifier = new DeathNotifier(this);
    IInterface::asBinder(mAudioTrack)->linkToDeath(mDeathNotifier, this);

+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.media;

// TODO(b/175167149): Reconcile AudioDualMonoMode with framework-media-sources

@Backing(type="int")
enum AudioDualMonoMode {
    OFF = 0,
    LR = 1,
    LL = 2,
    RR = 3,
}
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;

/**
 * The AudioPlaybackRate.
 *
 * See https://developer.android.com/reference/android/media/PlaybackParams.
 * TODO(b/175166815): Reconcile with framework-media-sources PlaybackParams.aidl.
 *       As this is used for native wire serialization, no need to define
 *       audio_timestretch_stretch_mode_t and audio_timestretch_fallback_mode_t enums
 *       until we attempt to unify with PlaybackParams.
 *
 * {@hide}
 */
parcelable AudioPlaybackRate {
    /** Speed of audio playback, >= 0.f, 1.f nominal (system limits are further restrictive) */
    float speed;
    /** Pitch of audio, >= 0.f, 1.f nominal (system limits are further restrictive) */
    float pitch;
    /** Interpreted as audio_timestretch_stretch_mode_t */
    int stretchMode;
    /** Interpreted as audio_timestretch_fallback_mode_t */
    int fallbackMode;
}
Loading