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 #include <system/audio.h> 23 24 namespace android { 25 26 // AUDIO_RESAMPLER_DOWN_RATIO_MAX is the maximum ratio between the original 27 // audio sample rate and the target rate when downsampling, 28 // as permitted in the audio framework, e.g. AudioTrack and AudioFlinger. 29 // In practice, it is not recommended to downsample more than 6:1 30 // for best audio quality, even though the audio framework permits a larger 31 // downsampling ratio. 32 // TODO: replace with an API 33 #define AUDIO_RESAMPLER_DOWN_RATIO_MAX 256 34 35 // AUDIO_RESAMPLER_UP_RATIO_MAX is the maximum suggested ratio between the original 36 // audio sample rate and the target rate when upsampling. It is loosely enforced by 37 // the system. One issue with large upsampling ratios is the approximation by 38 // an int32_t of the phase increments, making the resulting sample rate inexact. 39 #define AUDIO_RESAMPLER_UP_RATIO_MAX 65536 40 41 //Determines the current algorithm used for stretching 42 using AudioTimestretchStretchMode = ::audio_timestretch_stretch_mode_t; 43 44 //Determines behavior of Timestretch if current algorithm can't perform 45 //with current parameters. 46 using AudioTimestretchFallbackMode = ::audio_timestretch_fallback_mode_t; 47 48 using AudioPlaybackRate = ::audio_playback_rate_t; 49 50 static const AudioPlaybackRate AUDIO_PLAYBACK_RATE_DEFAULT = ::AUDIO_PLAYBACK_RATE_INITIALIZER; 51 52 static inline bool isAudioPlaybackRateEqual(const AudioPlaybackRate &pr1, 53 const AudioPlaybackRate &pr2) { 54 return fabs(pr1.mSpeed - pr2.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA && 55 fabs(pr1.mPitch - pr2.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA && 56 pr1.mStretchMode == pr2.mStretchMode && 57 pr1.mFallbackMode == pr2.mFallbackMode; 58 } 59 60 static inline bool isAudioPlaybackRateValid(const AudioPlaybackRate &playbackRate) { 61 if (playbackRate.mFallbackMode == AUDIO_TIMESTRETCH_FALLBACK_FAIL && 62 (playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_VOICE || 63 playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_DEFAULT)) { 64 //test sonic specific constraints 65 return playbackRate.mSpeed >= TIMESTRETCH_SONIC_SPEED_MIN && 66 playbackRate.mSpeed <= TIMESTRETCH_SONIC_SPEED_MAX && 67 playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN && 68 playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX; 69 } else { 70 return playbackRate.mSpeed >= AUDIO_TIMESTRETCH_SPEED_MIN && 71 playbackRate.mSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX && 72 playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN && 73 playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX; 74 } 75 } 76 77 // TODO: Consider putting these inlines into a class scope 78 79 // Returns the source frames needed to resample to destination frames. This is not a precise 80 // value and depends on the resampler (and possibly how it handles rounding internally). 81 // Nevertheless, this should be an upper bound on the requirements of the resampler. 82 // If srcSampleRate and dstSampleRate are equal, then it returns destination frames, which 83 // may not be true if the resampler is asynchronous. 84 static inline size_t sourceFramesNeeded( 85 uint32_t srcSampleRate, size_t dstFramesRequired, uint32_t dstSampleRate) { 86 // +1 for rounding - always do this even if matched ratio (resampler may use phases not ratio) 87 // +1 for additional sample needed for interpolation 88 return srcSampleRate == dstSampleRate ? dstFramesRequired : 89 size_t((uint64_t)dstFramesRequired * srcSampleRate / dstSampleRate + 1 + 1); 90 } 91 92 // An upper bound for the number of destination frames possible from srcFrames 93 // after sample rate conversion. This may be used for buffer sizing. 94 static inline size_t destinationFramesPossible(size_t srcFrames, uint32_t srcSampleRate, 95 uint32_t dstSampleRate) { 96 if (srcSampleRate == dstSampleRate) { 97 return srcFrames; 98 } 99 uint64_t dstFrames = (uint64_t)srcFrames * dstSampleRate / srcSampleRate; 100 return dstFrames > 2 ? dstFrames - 2 : 0; 101 } 102 103 static inline size_t sourceFramesNeededWithTimestretch( 104 uint32_t srcSampleRate, size_t dstFramesRequired, uint32_t dstSampleRate, 105 float speed) { 106 // required is the number of input frames the resampler needs 107 size_t required = sourceFramesNeeded(srcSampleRate, dstFramesRequired, dstSampleRate); 108 // to deliver this, the time stretcher requires: 109 return required * (double)speed + 1 + 1; // accounting for rounding dependencies 110 } 111 112 // Identifies sample rates that we associate with music 113 // and thus eligible for better resampling and fast capture. 114 // This is somewhat less than 44100 to allow for pitch correction 115 // involving resampling as well as asynchronous resampling. 116 #define AUDIO_PROCESSING_MUSIC_RATE 40000 117 118 static inline bool isMusicRate(uint32_t sampleRate) { 119 return sampleRate >= AUDIO_PROCESSING_MUSIC_RATE; 120 } 121 122 } // namespace android 123 124 // --------------------------------------------------------------------------- 125 126 #endif // ANDROID_AUDIO_RESAMPLER_PUBLIC_H 127