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