NUMear.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /* NUMear.cpp
  2. *
  3. * Copyright (C) 1992-2011,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 "melder.h"
  19. double NUMhertzToBark (double hertz) {
  20. double r = hertz / 650.0;
  21. return hertz < 0.0 ? undefined : 7.0 * log (r + sqrt (1.0 + r * r));
  22. }
  23. double NUMbarkToHertz (double bark) {
  24. return bark < 0.0 ? undefined : 650.0 * sinh (bark / 7.0);
  25. }
  26. double NUMphonToDifferenceLimens (double phon) {
  27. return phon < 0.0 ? undefined : 30.0 * (pow (61.0 / 60.0, phon) - 1.0);
  28. }
  29. double NUMdifferenceLimensToPhon (double ndli) {
  30. return ndli < 0.0 ? undefined : log (1.0 + ndli / 30.0) / log (61.0 / 60.0);
  31. }
  32. double NUMsoundPressureToPhon (double soundPressure, double bark) {
  33. double result = 0.0, dum;
  34. if (soundPressure <= 0.0 || bark < 0.0) return undefined;
  35. /* dB = 20 * log10 (soundPressure / threshold) */
  36. if (soundPressure > 0.0)
  37. result = 20.0 * log10 (soundPressure / 2.0e-5); /* First approximation: phon = dB */
  38. /* Phones from dB */
  39. if (result < 90.0 && bark < 8.0) {
  40. dum = (90.0 - result) * (8.0 - bark);
  41. result -= dum * dum / 2500.0;
  42. }
  43. dum = bark / 3.6 - 5.0;
  44. result += 5.0 * exp (- dum * dum);
  45. if (bark > 20.0) { dum = bark - 20.0; result -= 0.5 * dum * dum; }
  46. if (result < 0.0) result = 0.0;
  47. return result;
  48. }
  49. double NUMhertzToMel (double hertz) {
  50. return hertz < 0.0 ? undefined : 550.0 * log (1.0 + hertz / 550.0);
  51. }
  52. double NUMmelToHertz (double mel) {
  53. return mel < 0.0 ? undefined : 550.0 * (exp (mel / 550.0) - 1.0);
  54. }
  55. double NUMhertzToSemitones (double hertz) {
  56. return hertz <= 0.0 ? undefined : 12.0 * log (hertz / 100.0) / NUMln2;
  57. }
  58. double NUMsemitonesToHertz (double semitones) {
  59. return isundef (semitones) ? undefined : 100.0 * exp (semitones * (NUMln2 / 12.0));
  60. }
  61. /* Moore & Glasberg 1983 JASA 74: 750 */
  62. double NUMerb (double f) {
  63. return 6.23e-6 * f * f + 0.09339 * f + 28.52;
  64. }
  65. double NUMhertzToErb (double hertz) {
  66. return hertz < 0.0 ? undefined : 11.17 * log ((hertz + 312.0) / (hertz + 14680.0)) + 43.0;
  67. }
  68. double NUMerbToHertz (double erb) {
  69. double dum = exp ((erb - 43.0) / 11.17);
  70. return erb < 0.0 ? undefined : (14680.0 * dum - 312.0) / (1.0 - dum);
  71. }
  72. /* End of file NUMear.cpp */