1cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung/*
2cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung * Copyright (C) 2014 The Android Open Source Project
3cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung *
4cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung * Licensed under the Apache License, Version 2.0 (the "License");
5cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung * you may not use this file except in compliance with the License.
6cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung * You may obtain a copy of the License at
7cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung *
8cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung *      http://www.apache.org/licenses/LICENSE-2.0
9cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung *
10cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung * Unless required by applicable law or agreed to in writing, software
11cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung * distributed under the License is distributed on an "AS IS" BASIS,
12cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung * See the License for the specific language governing permissions and
14cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung * limitations under the License.
15cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung */
16cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung
17cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung#ifndef ANDROID_AUDIO_RESAMPLER_PUBLIC_H
18cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung#define ANDROID_AUDIO_RESAMPLER_PUBLIC_H
19cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung
206770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung#include <stdint.h>
215a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia#include <math.h>
225a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia
235a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcianamespace android {
246770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung
25cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung// AUDIO_RESAMPLER_DOWN_RATIO_MAX is the maximum ratio between the original
26cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung// audio sample rate and the target rate when downsampling,
27cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung// as permitted in the audio framework, e.g. AudioTrack and AudioFlinger.
28cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung// In practice, it is not recommended to downsample more than 6:1
29cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung// for best audio quality, even though the audio framework permits a larger
30cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung// downsampling ratio.
31cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung// TODO: replace with an API
32cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung#define AUDIO_RESAMPLER_DOWN_RATIO_MAX 256
33cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung
346770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung// AUDIO_RESAMPLER_UP_RATIO_MAX is the maximum suggested ratio between the original
356770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung// audio sample rate and the target rate when upsampling.  It is loosely enforced by
366770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung// the system. One issue with large upsampling ratios is the approximation by
376770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung// an int32_t of the phase increments, making the resulting sample rate inexact.
386770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung#define AUDIO_RESAMPLER_UP_RATIO_MAX 65536
396770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung
405a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// AUDIO_TIMESTRETCH_SPEED_MIN and AUDIO_TIMESTRETCH_SPEED_MAX define the min and max time stretch
415a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// speeds supported by the system. These are enforced by the system and values outside this range
425a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// will result in a runtime error.
435a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// Depending on the AudioPlaybackRate::mStretchMode, the effective limits might be narrower than
445a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// the ones specified here
455a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// AUDIO_TIMESTRETCH_SPEED_MIN_DELTA is the minimum absolute speed difference that might trigger a
465a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// parameter update
475a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia#define AUDIO_TIMESTRETCH_SPEED_MIN    0.01f
485a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia#define AUDIO_TIMESTRETCH_SPEED_MAX    20.0f
49c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung#define AUDIO_TIMESTRETCH_SPEED_NORMAL 1.0f
505a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia#define AUDIO_TIMESTRETCH_SPEED_MIN_DELTA 0.0001f
51c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung
525a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// AUDIO_TIMESTRETCH_PITCH_MIN and AUDIO_TIMESTRETCH_PITCH_MAX define the min and max time stretch
535a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// pitch shifting supported by the system. These are not enforced by the system and values
545a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// outside this range might result in a pitch different than the one requested.
555a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// Depending on the AudioPlaybackRate::mStretchMode, the effective limits might be narrower than
565a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// the ones specified here.
575a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// AUDIO_TIMESTRETCH_PITCH_MIN_DELTA is the minimum absolute pitch difference that might trigger a
585a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// parameter update
595a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia#define AUDIO_TIMESTRETCH_PITCH_MIN    0.25f
605a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia#define AUDIO_TIMESTRETCH_PITCH_MAX    4.0f
61c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung#define AUDIO_TIMESTRETCH_PITCH_NORMAL 1.0f
625a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia#define AUDIO_TIMESTRETCH_PITCH_MIN_DELTA 0.0001f
635a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia
645a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia
655a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia//Determines the current algorithm used for stretching
665a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garciaenum AudioTimestretchStretchMode : int32_t {
675a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    AUDIO_TIMESTRETCH_STRETCH_DEFAULT            = 0,
685a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    AUDIO_TIMESTRETCH_STRETCH_SPEECH             = 1,
695a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    //TODO: add more stretch modes/algorithms
705a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia};
715a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia
725a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia//Limits for AUDIO_TIMESTRETCH_STRETCH_SPEECH mode
735a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia#define TIMESTRETCH_SONIC_SPEED_MIN 0.1f
745a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia#define TIMESTRETCH_SONIC_SPEED_MAX 6.0f
755a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia
765a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia//Determines behavior of Timestretch if current algorithm can't perform
775a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia//with current parameters.
785a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// FALLBACK_CUT_REPEAT: (internal only) for speed <1.0 will truncate frames
795a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia//    for speed > 1.0 will repeat frames
805a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// FALLBACK_MUTE: will set all processed frames to zero
815a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// FALLBACK_FAIL:  will stop program execution and log a fatal error
825a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garciaenum AudioTimestretchFallbackMode : int32_t {
835a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT     = -1,
845a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    AUDIO_TIMESTRETCH_FALLBACK_DEFAULT        = 0,
855a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    AUDIO_TIMESTRETCH_FALLBACK_MUTE           = 1,
865a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    AUDIO_TIMESTRETCH_FALLBACK_FAIL           = 2,
875a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia};
885a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia
895a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garciastruct AudioPlaybackRate {
905a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    float mSpeed;
915a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    float mPitch;
925a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    enum AudioTimestretchStretchMode  mStretchMode;
935a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    enum AudioTimestretchFallbackMode mFallbackMode;
945a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia};
955a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia
965a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garciastatic const AudioPlaybackRate AUDIO_PLAYBACK_RATE_DEFAULT = {
975a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia        AUDIO_TIMESTRETCH_SPEED_NORMAL,
985a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia        AUDIO_TIMESTRETCH_PITCH_NORMAL,
995a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia        AUDIO_TIMESTRETCH_STRETCH_DEFAULT,
1005a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia        AUDIO_TIMESTRETCH_FALLBACK_DEFAULT
1015a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia};
1025a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia
1035a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garciastatic inline bool isAudioPlaybackRateEqual(const AudioPlaybackRate &pr1,
1045a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia        const AudioPlaybackRate &pr2) {
1055a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia    return fabs(pr1.mSpeed - pr2.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
1065a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia           fabs(pr1.mPitch - pr2.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA &&
1075a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia           pr2.mStretchMode == pr2.mStretchMode &&
1085a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia           pr2.mFallbackMode == pr2.mFallbackMode;
1095a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia}
110c5656cc900aeb4a705e27508dd82c70030a97709Andy Hung
1116c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garciastatic inline bool isAudioPlaybackRateValid(const AudioPlaybackRate &playbackRate) {
1126c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia    if (playbackRate.mFallbackMode == AUDIO_TIMESTRETCH_FALLBACK_FAIL &&
1136c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia            (playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_SPEECH ||
1146c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia                    playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_DEFAULT)) {
1156c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia        //test sonic specific constraints
1166c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia        return playbackRate.mSpeed >= TIMESTRETCH_SONIC_SPEED_MIN &&
1176c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia                playbackRate.mSpeed <= TIMESTRETCH_SONIC_SPEED_MAX &&
1186c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia                playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN &&
1196c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia                playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX;
1206c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia    } else {
1216c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia        return playbackRate.mSpeed >= AUDIO_TIMESTRETCH_SPEED_MIN &&
1226c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia                playbackRate.mSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX &&
1236c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia                playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN &&
1246c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia                playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX;
1256c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia    }
1266c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia}
1276c7f062d3149d6890daaee64828959ad6f61ea54Ricardo Garcia
1288edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung// TODO: Consider putting these inlines into a class scope
1298edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung
1300e48d25606c82def035ad10a5b3923767a765cddAndy Hung// Returns the source frames needed to resample to destination frames.  This is not a precise
1310e48d25606c82def035ad10a5b3923767a765cddAndy Hung// value and depends on the resampler (and possibly how it handles rounding internally).
1320e48d25606c82def035ad10a5b3923767a765cddAndy Hung// Nevertheless, this should be an upper bound on the requirements of the resampler.
1330e48d25606c82def035ad10a5b3923767a765cddAndy Hung// If srcSampleRate and dstSampleRate are equal, then it returns destination frames, which
1340e48d25606c82def035ad10a5b3923767a765cddAndy Hung// may not be true if the resampler is asynchronous.
1350e48d25606c82def035ad10a5b3923767a765cddAndy Hungstatic inline size_t sourceFramesNeeded(
1360e48d25606c82def035ad10a5b3923767a765cddAndy Hung        uint32_t srcSampleRate, size_t dstFramesRequired, uint32_t dstSampleRate) {
1370e48d25606c82def035ad10a5b3923767a765cddAndy Hung    // +1 for rounding - always do this even if matched ratio (resampler may use phases not ratio)
1380e48d25606c82def035ad10a5b3923767a765cddAndy Hung    // +1 for additional sample needed for interpolation
1390e48d25606c82def035ad10a5b3923767a765cddAndy Hung    return srcSampleRate == dstSampleRate ? dstFramesRequired :
1400e48d25606c82def035ad10a5b3923767a765cddAndy Hung            size_t((uint64_t)dstFramesRequired * srcSampleRate / dstSampleRate + 1 + 1);
1410e48d25606c82def035ad10a5b3923767a765cddAndy Hung}
1420e48d25606c82def035ad10a5b3923767a765cddAndy Hung
1436770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung// An upper bound for the number of destination frames possible from srcFrames
1446770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung// after sample rate conversion.  This may be used for buffer sizing.
1456770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hungstatic inline size_t destinationFramesPossible(size_t srcFrames, uint32_t srcSampleRate,
1466770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung        uint32_t dstSampleRate) {
1476770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung    if (srcSampleRate == dstSampleRate) {
1486770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung        return srcFrames;
1496770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung    }
1506770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung    uint64_t dstFrames = (uint64_t)srcFrames * dstSampleRate / srcSampleRate;
1516770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung    return dstFrames > 2 ? dstFrames - 2 : 0;
1526770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung}
1536770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung
1548edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hungstatic inline size_t sourceFramesNeededWithTimestretch(
1558edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung        uint32_t srcSampleRate, size_t dstFramesRequired, uint32_t dstSampleRate,
1568edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung        float speed) {
1578edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung    // required is the number of input frames the resampler needs
1588edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung    size_t required = sourceFramesNeeded(srcSampleRate, dstFramesRequired, dstSampleRate);
1598edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung    // to deliver this, the time stretcher requires:
1608edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung    return required * (double)speed + 1 + 1; // accounting for rounding dependencies
1618edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung}
1628edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung
163db4c031f518ae5806af73756273ff32cd8d0e4f8Andy Hung// Identifies sample rates that we associate with music
164db4c031f518ae5806af73756273ff32cd8d0e4f8Andy Hung// and thus eligible for better resampling and fast capture.
165db4c031f518ae5806af73756273ff32cd8d0e4f8Andy Hung// This is somewhat less than 44100 to allow for pitch correction
166db4c031f518ae5806af73756273ff32cd8d0e4f8Andy Hung// involving resampling as well as asynchronous resampling.
167db4c031f518ae5806af73756273ff32cd8d0e4f8Andy Hung#define AUDIO_PROCESSING_MUSIC_RATE 40000
168db4c031f518ae5806af73756273ff32cd8d0e4f8Andy Hung
169db4c031f518ae5806af73756273ff32cd8d0e4f8Andy Hungstatic inline bool isMusicRate(uint32_t sampleRate) {
170db4c031f518ae5806af73756273ff32cd8d0e4f8Andy Hung    return sampleRate >= AUDIO_PROCESSING_MUSIC_RATE;
171db4c031f518ae5806af73756273ff32cd8d0e4f8Andy Hung}
172db4c031f518ae5806af73756273ff32cd8d0e4f8Andy Hung
1735a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia} // namespace android
1745a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia
1755a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia// ---------------------------------------------------------------------------
1765a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia
177cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung#endif // ANDROID_AUDIO_RESAMPLER_PUBLIC_H
178