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

Commit 973e4d33 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audio: Add playback rate parameters to IStreamOut

Playback rate parameters allow changing the playback speed
of audio streams optionally preserving the pitch (this is
often referred to as "timestretch"). HALs can apply these
parameters when decoding of streams is done in hardware.

Bug: 133526565
Test: atest VtsHalAudioV6_0TargetTest
Change-Id: Ie78cd924bd034b57bf5b6a74affd62641ffc0aba
parent 0a675fcc
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -333,4 +333,33 @@ interface IStreamOut extends IStream {
     * @return retval operation completion status.
     */
    setAudioDescriptionMixLevel(float leveldB) generates (Result retval);

    /**
     * Retrieves current playback rate parameters.
     *
     * Optional method
     *
     * @return retval operation completion status.
     * @return playbackRate current playback parameters
     */
    getPlaybackRateParameters()
            generates (Result retval, PlaybackRate playbackRate);

    /**
     * Sets the playback rate parameters that control playback behavior.
     * This is normally used when playing encoded content and decoding
     * is performed in hardware. Otherwise, the framework can apply
     * necessary transformations.
     *
     * Optional method
     *
     * If the HAL supports setting the playback rate, it is recommended
     * to support speed and pitch values at least in the range
     * from 0.5f to 2.0f, inclusive (see the definition of PlaybackRate struct).
     *
     * @param playbackRate playback parameters
     * @return retval operation completion status.
     */
    setPlaybackRateParameters(PlaybackRate playbackRate)
            generates (Result retval);
};
+58 −0
Original line number Diff line number Diff line
@@ -297,3 +297,61 @@ enum DualMonoMode : int32_t {
     */
    RR = 3,
};

/**
 * Algorithms used for timestretching (preserving pitch while playing audio
 * content at different speed).
 */
@export(name="audio_timestretch_stretch_mode_t", value_prefix="AUDIO_TIMESTRETCH_STRETCH_")
enum TimestretchMode : int32_t {
    // Need to be in sync with AUDIO_STRETCH_MODE_* constants in
    // frameworks/base/media/java/android/media/PlaybackParams.java
    DEFAULT = 0,
    /** Selects timestretch algorithm best suitable for voice (speech) content. */
    VOICE = 1,
};

/**
 * Behavior when the values for speed and / or pitch are out
 * of applicable range.
 */
@export(name="audio_timestretch_fallback_mode_t", value_prefix="AUDIO_TIMESTRETCH_FALLBACK_")
enum TimestretchFallbackMode : int32_t {
    // Need to be in sync with AUDIO_FALLBACK_MODE_* constants in
    // frameworks/base/media/java/android/media/PlaybackParams.java
    /** Play silence for parameter values that are out of range. */
    MUTE = 1,
    /** Return an error while trying to set the parameters. */
    FAIL = 2,
};

/**
 * Parameters determining playback behavior. They are used to speed up or
 * slow down playback and / or change the tonal frequency of the audio content
 * (pitch).
 */
struct PlaybackRate {
    /**
     * Speed factor (multiplier). Normal speed has the value of 1.0f.
     * Values less than 1.0f slow down playback, value greater than 1.0f
     * speed it up.
     */
    float speed;
    /**
     * Pitch factor (multiplier). Setting pitch value to 1.0f together
     * with changing playback speed preserves the pitch, this is often
     * called "timestretching." Setting the pitch value equal to speed produces
     * the same effect as playing audio content at different sampling rate.
     */
    float pitch;
    /**
     * Selects the algorithm used for timestretching (preserving pitch while
     * playing audio at different speed).
     */
    TimestretchMode timestretchMode;
    /**
     * Selects the behavior when the specified values for speed and / or pitch
     * are out of applicable range.
     */
    TimestretchFallbackMode fallbackMode;
};
+12 −0
Original line number Diff line number Diff line
@@ -600,6 +600,18 @@ Return<void> StreamOut::getAudioDescriptionMixLevel(getAudioDescriptionMixLevel_
Return<Result> StreamOut::setAudioDescriptionMixLevel(float /*leveldB*/) {
    return Result::NOT_SUPPORTED;
}

Return<void> StreamOut::getPlaybackRateParameters(getPlaybackRateParameters_cb _hidl_cb) {
    _hidl_cb(Result::NOT_SUPPORTED,
             // Same as AUDIO_PLAYBACK_RATE_INITIALIZER
             PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::FAIL});
    return Void();
}

Return<Result> StreamOut::setPlaybackRateParameters(const PlaybackRate& /*playbackRate*/) {
    return Result::NOT_SUPPORTED;
}

#endif

}  // namespace implementation
+2 −0
Original line number Diff line number Diff line
@@ -126,6 +126,8 @@ struct StreamOut : public IStreamOut {
    Return<Result> setDualMonoMode(DualMonoMode mode) override;
    Return<void> getAudioDescriptionMixLevel(getAudioDescriptionMixLevel_cb _hidl_cb) override;
    Return<Result> setAudioDescriptionMixLevel(float leveldB) override;
    Return<void> getPlaybackRateParameters(getPlaybackRateParameters_cb _hidl_cb) override;
    Return<Result> setPlaybackRateParameters(const PlaybackRate& playbackRate) override;
#endif

    static Result getPresentationPositionImpl(audio_stream_out_t* stream, uint64_t* frames,
+34 −0
Original line number Diff line number Diff line
@@ -217,3 +217,37 @@ TEST_P(AudioDescriptionMixLevelHidlTest, AudioDescriptionMixLevelTest) {
INSTANTIATE_TEST_CASE_P(AudioDescriptionMixLevelHidl, AudioDescriptionMixLevelHidlTest,
                        ::testing::ValuesIn(getOutputDeviceConfigParameters()),
                        &DeviceConfigParameterToString);

using PlaybackRateParametersHidlTest = AccessorHidlTest<PlaybackRate, OutputStreamTest>;
TEST_P(PlaybackRateParametersHidlTest, PlaybackRateParametersTest) {
    doc::test("Check that playback rate parameters can be set and retrieved");
    testAccessors<OPTIONAL>(
            &OutputStreamTest::getStream, "playback rate parameters",
            Initial{PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT,
                                 TimestretchFallbackMode::FAIL}},
            {// Speed and pitch values in the range from 0.5f to 2.0f must be supported
             // (see the definition of IStreamOut::setPlaybackRateParameters).
             PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::MUTE},
             PlaybackRate{2.0f, 2.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::MUTE},
             PlaybackRate{0.5f, 0.5f, TimestretchMode::DEFAULT, TimestretchFallbackMode::MUTE},
             // Gross speed / pitch values must not be rejected if the fallback mode is "mute"
             PlaybackRate{1000.0f, 1000.0f, TimestretchMode::DEFAULT,
                          TimestretchFallbackMode::MUTE},
             // Default speed / pitch values must not be rejected in "fail" fallback mode
             PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::FAIL},
             // Same for "voice" mode
             PlaybackRate{1.0f, 1.0f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
             PlaybackRate{2.0f, 2.0f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
             PlaybackRate{0.5f, 0.5f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
             PlaybackRate{1000.0f, 1000.0f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
             PlaybackRate{1.0f, 1.0f, TimestretchMode::VOICE, TimestretchFallbackMode::FAIL}},
            &IStreamOut::setPlaybackRateParameters, &IStreamOut::getPlaybackRateParameters,
            {PlaybackRate{1000.0f, 1000.0f, TimestretchMode::DEFAULT,
                          TimestretchFallbackMode::FAIL},
             PlaybackRate{1000.0f, 1000.0f, TimestretchMode::VOICE,
                          TimestretchFallbackMode::FAIL}});
}

INSTANTIATE_TEST_CASE_P(PlaybackRateParametersHidl, PlaybackRateParametersHidlTest,
                        ::testing::ValuesIn(getOutputDeviceConfigParameters()),
                        &DeviceConfigParameterToString);
Loading