AudioResamplerPublic.h 7.8 KB

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