1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_AUDIO_RESAMPLER_PUBLIC_H 18 #define ANDROID_AUDIO_RESAMPLER_PUBLIC_H 19 20 #include <stdint.h> 21 #include <math.h> 22 23 namespace android { 24 25 // AUDIO_RESAMPLER_DOWN_RATIO_MAX is the maximum ratio between the original 26 // audio sample rate and the target rate when downsampling, 27 // as permitted in the audio framework, e.g. AudioTrack and AudioFlinger. 28 // In practice, it is not recommended to downsample more than 6:1 29 // for best audio quality, even though the audio framework permits a larger 30 // downsampling ratio. 31 // TODO: replace with an API 32 #define AUDIO_RESAMPLER_DOWN_RATIO_MAX 256 33 34 // AUDIO_RESAMPLER_UP_RATIO_MAX is the maximum suggested ratio between the original 35 // audio sample rate and the target rate when upsampling. It is loosely enforced by 36 // the system. One issue with large upsampling ratios is the approximation by 37 // an int32_t of the phase increments, making the resulting sample rate inexact. 38 #define AUDIO_RESAMPLER_UP_RATIO_MAX 65536 39 40 // AUDIO_TIMESTRETCH_SPEED_MIN and AUDIO_TIMESTRETCH_SPEED_MAX define the min and max time stretch 41 // speeds supported by the system. These are enforced by the system and values outside this range 42 // will result in a runtime error. 43 // Depending on the AudioPlaybackRate::mStretchMode, the effective limits might be narrower than 44 // the ones specified here 45 // AUDIO_TIMESTRETCH_SPEED_MIN_DELTA is the minimum absolute speed difference that might trigger a 46 // parameter update 47 #define AUDIO_TIMESTRETCH_SPEED_MIN 0.01f 48 #define AUDIO_TIMESTRETCH_SPEED_MAX 20.0f 49 #define AUDIO_TIMESTRETCH_SPEED_NORMAL 1.0f 50 #define AUDIO_TIMESTRETCH_SPEED_MIN_DELTA 0.0001f 51 52 // AUDIO_TIMESTRETCH_PITCH_MIN and AUDIO_TIMESTRETCH_PITCH_MAX define the min and max time stretch 53 // pitch shifting supported by the system. These are not enforced by the system and values 54 // outside this range might result in a pitch different than the one requested. 55 // Depending on the AudioPlaybackRate::mStretchMode, the effective limits might be narrower than 56 // the ones specified here. 57 // AUDIO_TIMESTRETCH_PITCH_MIN_DELTA is the minimum absolute pitch difference that might trigger a 58 // parameter update 59 #define AUDIO_TIMESTRETCH_PITCH_MIN 0.25f 60 #define AUDIO_TIMESTRETCH_PITCH_MAX 4.0f 61 #define AUDIO_TIMESTRETCH_PITCH_NORMAL 1.0f 62 #define AUDIO_TIMESTRETCH_PITCH_MIN_DELTA 0.0001f 63 64 65 //Determines the current algorithm used for stretching 66 enum AudioTimestretchStretchMode : int32_t { 67 AUDIO_TIMESTRETCH_STRETCH_DEFAULT = 0, 68 AUDIO_TIMESTRETCH_STRETCH_SPEECH = 1, 69 //TODO: add more stretch modes/algorithms 70 }; 71 72 //Limits for AUDIO_TIMESTRETCH_STRETCH_SPEECH mode 73 #define TIMESTRETCH_SONIC_SPEED_MIN 0.1f 74 #define TIMESTRETCH_SONIC_SPEED_MAX 6.0f 75 76 //Determines behavior of Timestretch if current algorithm can't perform 77 //with current parameters. 78 // FALLBACK_CUT_REPEAT: (internal only) for speed <1.0 will truncate frames 79 // for speed > 1.0 will repeat frames 80 // FALLBACK_MUTE: will set all processed frames to zero 81 // FALLBACK_FAIL: will stop program execution and log a fatal error 82 enum AudioTimestretchFallbackMode : int32_t { 83 AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT = -1, 84 AUDIO_TIMESTRETCH_FALLBACK_DEFAULT = 0, 85 AUDIO_TIMESTRETCH_FALLBACK_MUTE = 1, 86 AUDIO_TIMESTRETCH_FALLBACK_FAIL = 2, 87 }; 88 89 struct AudioPlaybackRate { 90 float mSpeed; 91 float mPitch; 92 enum AudioTimestretchStretchMode mStretchMode; 93 enum AudioTimestretchFallbackMode mFallbackMode; 94 }; 95 96 static const AudioPlaybackRate AUDIO_PLAYBACK_RATE_DEFAULT = { 97 AUDIO_TIMESTRETCH_SPEED_NORMAL, 98 AUDIO_TIMESTRETCH_PITCH_NORMAL, 99 AUDIO_TIMESTRETCH_STRETCH_DEFAULT, 100 AUDIO_TIMESTRETCH_FALLBACK_DEFAULT 101 }; 102 103 static inline bool isAudioPlaybackRateEqual(const AudioPlaybackRate &pr1, 104 const AudioPlaybackRate &pr2) { 105 return fabs(pr1.mSpeed - pr2.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA && 106 fabs(pr1.mPitch - pr2.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA && 107 pr1.mStretchMode == pr2.mStretchMode && 108 pr1.mFallbackMode == pr2.mFallbackMode; 109 } 110 111 static inline bool isAudioPlaybackRateValid(const AudioPlaybackRate &playbackRate) { 112 if (playbackRate.mFallbackMode == AUDIO_TIMESTRETCH_FALLBACK_FAIL && 113 (playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_SPEECH || 114 playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_DEFAULT)) { 115 //test sonic specific constraints 116 return playbackRate.mSpeed >= TIMESTRETCH_SONIC_SPEED_MIN && 117 playbackRate.mSpeed <= TIMESTRETCH_SONIC_SPEED_MAX && 118 playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN && 119 playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX; 120 } else { 121 return playbackRate.mSpeed >= AUDIO_TIMESTRETCH_SPEED_MIN && 122 playbackRate.mSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX && 123 playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN && 124 playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX; 125 } 126 } 127 128 // TODO: Consider putting these inlines into a class scope 129 130 // Returns the source frames needed to resample to destination frames. This is not a precise 131 // value and depends on the resampler (and possibly how it handles rounding internally). 132 // Nevertheless, this should be an upper bound on the requirements of the resampler. 133 // If srcSampleRate and dstSampleRate are equal, then it returns destination frames, which 134 // may not be true if the resampler is asynchronous. 135 static inline size_t sourceFramesNeeded( 136 uint32_t srcSampleRate, size_t dstFramesRequired, uint32_t dstSampleRate) { 137 // +1 for rounding - always do this even if matched ratio (resampler may use phases not ratio) 138 // +1 for additional sample needed for interpolation 139 return srcSampleRate == dstSampleRate ? dstFramesRequired : 140 size_t((uint64_t)dstFramesRequired * srcSampleRate / dstSampleRate + 1 + 1); 141 } 142 143 // An upper bound for the number of destination frames possible from srcFrames 144 // after sample rate conversion. This may be used for buffer sizing. 145 static inline size_t destinationFramesPossible(size_t srcFrames, uint32_t srcSampleRate, 146 uint32_t dstSampleRate) { 147 if (srcSampleRate == dstSampleRate) { 148 return srcFrames; 149 } 150 uint64_t dstFrames = (uint64_t)srcFrames * dstSampleRate / srcSampleRate; 151 return dstFrames > 2 ? dstFrames - 2 : 0; 152 } 153 154 static inline size_t sourceFramesNeededWithTimestretch( 155 uint32_t srcSampleRate, size_t dstFramesRequired, uint32_t dstSampleRate, 156 float speed) { 157 // required is the number of input frames the resampler needs 158 size_t required = sourceFramesNeeded(srcSampleRate, dstFramesRequired, dstSampleRate); 159 // to deliver this, the time stretcher requires: 160 return required * (double)speed + 1 + 1; // accounting for rounding dependencies 161 } 162 163 // Identifies sample rates that we associate with music 164 // and thus eligible for better resampling and fast capture. 165 // This is somewhat less than 44100 to allow for pitch correction 166 // involving resampling as well as asynchronous resampling. 167 #define AUDIO_PROCESSING_MUSIC_RATE 40000 168 169 static inline bool isMusicRate(uint32_t sampleRate) { 170 return sampleRate >= AUDIO_PROCESSING_MUSIC_RATE; 171 } 172 173 } // namespace android 174 175 // --------------------------------------------------------------------------- 176 177 #endif // ANDROID_AUDIO_RESAMPLER_PUBLIC_H 178