AudioEqualizer.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /*
  2. * Copyright 2009, 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. #define LOG_TAG "AudioEqualizer"
  17. #include <assert.h>
  18. #include <stdlib.h>
  19. #include <new>
  20. #include <utils/Log.h>
  21. #include "AudioEqualizer.h"
  22. #include "AudioPeakingFilter.h"
  23. #include "AudioShelvingFilter.h"
  24. #include "EffectsMath.h"
  25. namespace android {
  26. size_t AudioEqualizer::GetInstanceSize(int nBands) {
  27. assert(nBands >= 2);
  28. return sizeof(AudioEqualizer) +
  29. sizeof(AudioShelvingFilter) * 2 +
  30. sizeof(AudioPeakingFilter) * (nBands - 2);
  31. }
  32. AudioEqualizer * AudioEqualizer::CreateInstance(void * pMem, int nBands,
  33. int nChannels, int sampleRate,
  34. const PresetConfig * presets,
  35. int nPresets) {
  36. ALOGV("AudioEqualizer::CreateInstance(pMem=%p, nBands=%d, nChannels=%d, "
  37. "sampleRate=%d, nPresets=%d)",
  38. pMem, nBands, nChannels, sampleRate, nPresets);
  39. assert(nBands >= 2);
  40. bool ownMem = false;
  41. if (pMem == NULL) {
  42. pMem = malloc(GetInstanceSize(nBands));
  43. if (pMem == NULL) {
  44. return NULL;
  45. }
  46. ownMem = true;
  47. }
  48. return new (pMem) AudioEqualizer(pMem, nBands, nChannels, sampleRate,
  49. ownMem, presets, nPresets);
  50. }
  51. void AudioEqualizer::configure(int nChannels, int sampleRate) {
  52. ALOGV("AudioEqualizer::configure(nChannels=%d, sampleRate=%d)", nChannels,
  53. sampleRate);
  54. mpLowShelf->configure(nChannels, sampleRate);
  55. for (int i = 0; i < mNumPeaking; ++i) {
  56. mpPeakingFilters[i].configure(nChannels, sampleRate);
  57. }
  58. mpHighShelf->configure(nChannels, sampleRate);
  59. }
  60. void AudioEqualizer::clear() {
  61. ALOGV("AudioEqualizer::clear()");
  62. mpLowShelf->clear();
  63. for (int i = 0; i < mNumPeaking; ++i) {
  64. mpPeakingFilters[i].clear();
  65. }
  66. mpHighShelf->clear();
  67. }
  68. void AudioEqualizer::free() {
  69. ALOGV("AudioEqualizer::free()");
  70. if (mpMem != NULL) {
  71. ::free(mpMem);
  72. }
  73. }
  74. void AudioEqualizer::reset() {
  75. ALOGV("AudioEqualizer::reset()");
  76. const int32_t bottom = Effects_log2(kMinFreq);
  77. const int32_t top = Effects_log2(mSampleRate * 500);
  78. const int32_t jump = (top - bottom) / (mNumPeaking + 2);
  79. int32_t centerFreq = bottom + jump/2;
  80. mpLowShelf->reset();
  81. mpLowShelf->setFrequency(Effects_exp2(centerFreq));
  82. centerFreq += jump;
  83. for (int i = 0; i < mNumPeaking; ++i) {
  84. mpPeakingFilters[i].reset();
  85. mpPeakingFilters[i].setFrequency(Effects_exp2(centerFreq));
  86. centerFreq += jump;
  87. }
  88. mpHighShelf->reset();
  89. mpHighShelf->setFrequency(Effects_exp2(centerFreq));
  90. commit(true);
  91. mCurPreset = PRESET_CUSTOM;
  92. }
  93. void AudioEqualizer::setGain(int band, int32_t millibel) {
  94. ALOGV("AudioEqualizer::setGain(band=%d, millibel=%d)", band, millibel);
  95. assert(band >= 0 && band < mNumPeaking + 2);
  96. if (band == 0) {
  97. mpLowShelf->setGain(millibel);
  98. } else if (band == mNumPeaking + 1) {
  99. mpHighShelf->setGain(millibel);
  100. } else {
  101. mpPeakingFilters[band - 1].setGain(millibel);
  102. }
  103. mCurPreset = PRESET_CUSTOM;
  104. }
  105. void AudioEqualizer::setFrequency(int band, uint32_t millihertz) {
  106. ALOGV("AudioEqualizer::setFrequency(band=%d, millihertz=%d)", band,
  107. millihertz);
  108. assert(band >= 0 && band < mNumPeaking + 2);
  109. if (band == 0) {
  110. mpLowShelf->setFrequency(millihertz);
  111. } else if (band == mNumPeaking + 1) {
  112. mpHighShelf->setFrequency(millihertz);
  113. } else {
  114. mpPeakingFilters[band - 1].setFrequency(millihertz);
  115. }
  116. mCurPreset = PRESET_CUSTOM;
  117. }
  118. void AudioEqualizer::setBandwidth(int band, uint32_t cents) {
  119. ALOGV("AudioEqualizer::setBandwidth(band=%d, cents=%d)", band, cents);
  120. assert(band >= 0 && band < mNumPeaking + 2);
  121. if (band > 0 && band < mNumPeaking + 1) {
  122. mpPeakingFilters[band - 1].setBandwidth(cents);
  123. mCurPreset = PRESET_CUSTOM;
  124. }
  125. }
  126. int32_t AudioEqualizer::getGain(int band) const {
  127. assert(band >= 0 && band < mNumPeaking + 2);
  128. if (band == 0) {
  129. return mpLowShelf->getGain();
  130. } else if (band == mNumPeaking + 1) {
  131. return mpHighShelf->getGain();
  132. } else {
  133. return mpPeakingFilters[band - 1].getGain();
  134. }
  135. }
  136. uint32_t AudioEqualizer::getFrequency(int band) const {
  137. assert(band >= 0 && band < mNumPeaking + 2);
  138. if (band == 0) {
  139. return mpLowShelf->getFrequency();
  140. } else if (band == mNumPeaking + 1) {
  141. return mpHighShelf->getFrequency();
  142. } else {
  143. return mpPeakingFilters[band - 1].getFrequency();
  144. }
  145. }
  146. uint32_t AudioEqualizer::getBandwidth(int band) const {
  147. assert(band >= 0 && band < mNumPeaking + 2);
  148. if (band == 0 || band == mNumPeaking + 1) {
  149. return 0;
  150. } else {
  151. return mpPeakingFilters[band - 1].getBandwidth();
  152. }
  153. }
  154. void AudioEqualizer::getBandRange(int band, uint32_t & low,
  155. uint32_t & high) const {
  156. assert(band >= 0 && band < mNumPeaking + 2);
  157. if (band == 0) {
  158. low = 0;
  159. high = mpLowShelf->getFrequency();
  160. } else if (band == mNumPeaking + 1) {
  161. low = mpHighShelf->getFrequency();
  162. high = mSampleRate * 500;
  163. } else {
  164. mpPeakingFilters[band - 1].getBandRange(low, high);
  165. }
  166. }
  167. const char * AudioEqualizer::getPresetName(int preset) const {
  168. assert(preset < mNumPresets && preset >= PRESET_CUSTOM);
  169. if (preset == PRESET_CUSTOM) {
  170. return "Custom";
  171. } else {
  172. return mpPresets[preset].name;
  173. }
  174. }
  175. int AudioEqualizer::getNumPresets() const {
  176. return mNumPresets;
  177. }
  178. int AudioEqualizer::getPreset() const {
  179. return mCurPreset;
  180. }
  181. void AudioEqualizer::setPreset(int preset) {
  182. ALOGV("AudioEqualizer::setPreset(preset=%d)", preset);
  183. assert(preset < mNumPresets && preset >= 0);
  184. const PresetConfig &presetCfg = mpPresets[preset];
  185. for (int band = 0; band < (mNumPeaking + 2); ++band) {
  186. const BandConfig & bandCfg = presetCfg.bandConfigs[band];
  187. setGain(band, bandCfg.gain);
  188. setFrequency(band, bandCfg.freq);
  189. setBandwidth(band, bandCfg.bandwidth);
  190. }
  191. mCurPreset = preset;
  192. }
  193. void AudioEqualizer::commit(bool immediate) {
  194. ALOGV("AudioEqualizer::commit(immediate=%d)", immediate);
  195. mpLowShelf->commit(immediate);
  196. for (int i = 0; i < mNumPeaking; ++i) {
  197. mpPeakingFilters[i].commit(immediate);
  198. }
  199. mpHighShelf->commit(immediate);
  200. }
  201. void AudioEqualizer::process(const audio_sample_t * pIn,
  202. audio_sample_t * pOut,
  203. int frameCount) {
  204. // ALOGV("AudioEqualizer::process(frameCount=%d)", frameCount);
  205. mpLowShelf->process(pIn, pOut, frameCount);
  206. for (int i = 0; i < mNumPeaking; ++i) {
  207. mpPeakingFilters[i].process(pIn, pOut, frameCount);
  208. }
  209. mpHighShelf->process(pIn, pOut, frameCount);
  210. }
  211. void AudioEqualizer::enable(bool immediate) {
  212. ALOGV("AudioEqualizer::enable(immediate=%d)", immediate);
  213. mpLowShelf->enable(immediate);
  214. for (int i = 0; i < mNumPeaking; ++i) {
  215. mpPeakingFilters[i].enable(immediate);
  216. }
  217. mpHighShelf->enable(immediate);
  218. }
  219. void AudioEqualizer::disable(bool immediate) {
  220. ALOGV("AudioEqualizer::disable(immediate=%d)", immediate);
  221. mpLowShelf->disable(immediate);
  222. for (int i = 0; i < mNumPeaking; ++i) {
  223. mpPeakingFilters[i].disable(immediate);
  224. }
  225. mpHighShelf->disable(immediate);
  226. }
  227. int AudioEqualizer::getMostRelevantBand(uint32_t targetFreq) const {
  228. // First, find the two bands that the target frequency is between.
  229. uint32_t low = mpLowShelf->getFrequency();
  230. if (targetFreq <= low) {
  231. return 0;
  232. }
  233. uint32_t high = mpHighShelf->getFrequency();
  234. if (targetFreq >= high) {
  235. return mNumPeaking + 1;
  236. }
  237. int band = mNumPeaking;
  238. for (int i = 0; i < mNumPeaking; ++i) {
  239. uint32_t freq = mpPeakingFilters[i].getFrequency();
  240. if (freq >= targetFreq) {
  241. high = freq;
  242. band = i;
  243. break;
  244. }
  245. low = freq;
  246. }
  247. // Now, low is right below the target and high is right above. See which one
  248. // is closer on a log scale.
  249. low = Effects_log2(low);
  250. high = Effects_log2(high);
  251. targetFreq = Effects_log2(targetFreq);
  252. if (high - targetFreq < targetFreq - low) {
  253. return band + 1;
  254. } else {
  255. return band;
  256. }
  257. }
  258. AudioEqualizer::AudioEqualizer(void * pMem, int nBands, int nChannels,
  259. int sampleRate, bool ownMem,
  260. const PresetConfig * presets, int nPresets)
  261. : mSampleRate(sampleRate)
  262. , mpPresets(presets)
  263. , mNumPresets(nPresets) {
  264. assert(pMem != NULL);
  265. assert(nPresets == 0 || nPresets > 0 && presets != NULL);
  266. mpMem = ownMem ? pMem : NULL;
  267. pMem = (char *) pMem + sizeof(AudioEqualizer);
  268. mpLowShelf = new (pMem) AudioShelvingFilter(AudioShelvingFilter::kLowShelf,
  269. nChannels, sampleRate);
  270. pMem = (char *) pMem + sizeof(AudioShelvingFilter);
  271. mpHighShelf = new (pMem) AudioShelvingFilter(AudioShelvingFilter::kHighShelf,
  272. nChannels, sampleRate);
  273. pMem = (char *) pMem + sizeof(AudioShelvingFilter);
  274. mNumPeaking = nBands - 2;
  275. if (mNumPeaking > 0) {
  276. mpPeakingFilters = reinterpret_cast<AudioPeakingFilter *>(pMem);
  277. for (int i = 0; i < mNumPeaking; ++i) {
  278. new (&mpPeakingFilters[i]) AudioPeakingFilter(nChannels,
  279. sampleRate);
  280. }
  281. }
  282. reset();
  283. }
  284. }