Spectrum_to_Excitation.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /* Spectrum_to_Excitation.cpp
  2. *
  3. * Copyright (C) 1992-2011,2014,2015,2016,2017 Paul Boersma
  4. *
  5. * This code is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This code is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. * See the GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "Spectrum_to_Excitation.h"
  19. autoExcitation Spectrum_to_Excitation (Spectrum me, double dbark) {
  20. try {
  21. integer nbark = Melder_iround (25.6 / dbark);
  22. double *re = my z [1], *im = my z [2];
  23. autoNUMvector <double> auditoryFilter (1, nbark);
  24. double filterArea = 0.0;
  25. for (integer i = 1; i <= nbark; i ++) {
  26. double bark = dbark * (i - nbark/2) + 0.474;
  27. filterArea += auditoryFilter [i] = pow (10, (1.581 + 0.75 * bark - 1.75 * sqrt (1 + bark * bark)));
  28. }
  29. /*for (integer i = 1; i <= nbark; i ++)
  30. auditoryFilter [i] /= filterArea;*/
  31. autoNUMvector <double> rFreqs (1, nbark + 1);
  32. autoNUMvector <integer> iFreqs (1, nbark + 1);
  33. for (integer i = 1; i <= nbark + 1; i ++) {
  34. rFreqs [i] = Excitation_barkToHertz (dbark * (i - 1));
  35. iFreqs [i] = Sampled_xToNearestIndex (me, rFreqs [i]);
  36. }
  37. autoNUMvector <double> inSig (1, nbark);
  38. for (integer i = 1; i <= nbark; i ++) {
  39. integer low = iFreqs [i], high = iFreqs [i + 1] - 1;
  40. if (low < 1) low = 1;
  41. if (high > my nx) high = my nx;
  42. for (integer j = low; j <= high; j ++) {
  43. inSig [i] += re [j] * re [j] + im [j] * im [j]; // Pa2 s2
  44. }
  45. /* An anti-undersampling correction. */
  46. if (high >= low)
  47. inSig [i] *= 2.0 * (rFreqs [i + 1] - rFreqs [i]) / (high - low + 1) * my dx; // Pa2: power density in this band
  48. }
  49. /* Convolution with auditory (masking) filter. */
  50. autoNUMvector <double> outSig (1, 2 * nbark);
  51. for (integer i = 1; i <= nbark; i ++) {
  52. for (integer j = 1; j <= nbark; j ++) {
  53. outSig [i + j] += inSig [i] * auditoryFilter [j];
  54. }
  55. }
  56. autoExcitation thee = Excitation_create (dbark, nbark);
  57. for (integer i = 1; i <= nbark; i ++) {
  58. thy z [1] [i] = Excitation_soundPressureToPhon (sqrt (outSig [i + nbark/2]), Sampled_indexToX (thee.get(), i));
  59. }
  60. return thee;
  61. } catch (MelderError) {
  62. Melder_throw (me, U": not converted to Excitation.");
  63. }
  64. }
  65. /* End of file Spectrum_to_Excitation.cpp */