LPC.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /* LPC.cpp
  2. *
  3. * Copyright (C) 1994-2018 David Weenink
  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. See the GNU
  13. * 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. /*
  19. djmw 20020812 GPL header
  20. djmw 20030612 Removed LPC_Frame_free
  21. djmw 20060510 LPC_drawPoles error cleared if something goes wrong.
  22. djmw 20061212 Changed info to Melder_writeLine<x> format.
  23. djmw 20071017 oo_CAN_WRITE_AS_ENCODING.h
  24. djmw 20080122 float -> double
  25. djmw 20081223 Corrected a bug in Matrix LPC_to_Matrix (last coefficient was not copied)
  26. djmw 20110304 Thing_new
  27. */
  28. #include "LPC_and_Polynomial.h"
  29. #include "NUM2.h"
  30. #include "oo_DESTROY.h"
  31. #include "LPC_def.h"
  32. #include "oo_COPY.h"
  33. #include "LPC_def.h"
  34. #include "oo_EQUAL.h"
  35. #include "LPC_def.h"
  36. #include "oo_CAN_WRITE_AS_ENCODING.h"
  37. #include "LPC_def.h"
  38. #include "oo_WRITE_TEXT.h"
  39. #include "LPC_def.h"
  40. #include "oo_WRITE_BINARY.h"
  41. #include "LPC_def.h"
  42. #include "oo_READ_TEXT.h"
  43. #include "LPC_def.h"
  44. #include "oo_READ_BINARY.h"
  45. #include "LPC_def.h"
  46. #include "oo_DESCRIPTION.h"
  47. #include "LPC_def.h"
  48. Thing_implement (LPC, Sampled, 1);
  49. void structLPC :: v_info () {
  50. structDaata :: v_info ();
  51. MelderInfo_writeLine (U"Time domain: ", xmin, U" to ", xmax, U" (s).");
  52. MelderInfo_writeLine (U"Prediction order: ", maxnCoefficients);
  53. MelderInfo_writeLine (U"Number of frames: ", nx);
  54. MelderInfo_writeLine (U"Time step: ", dx, U" (s).");
  55. MelderInfo_writeLine (U"First frame at: ", x1, U" (s).");
  56. }
  57. void LPC_Frame_init (LPC_Frame me, integer nCoefficients) {
  58. if (nCoefficients != 0) {
  59. my a = VECzero (nCoefficients);
  60. }
  61. my nCoefficients = nCoefficients;
  62. }
  63. void LPC_init (LPC me, double tmin, double tmax, integer nt, double dt, double t1, integer predictionOrder, double samplingPeriod) {
  64. my samplingPeriod = samplingPeriod;
  65. my maxnCoefficients = predictionOrder;
  66. Sampled_init (me, tmin, tmax, nt, dt, t1);
  67. my d_frames = NUMvector<structLPC_Frame> (1, nt);
  68. }
  69. autoLPC LPC_create (double tmin, double tmax, integer nt, double dt, double t1, integer predictionOrder, double samplingPeriod) {
  70. try {
  71. autoLPC me = Thing_new (LPC);
  72. LPC_init (me.get(), tmin, tmax, nt, dt, t1, predictionOrder, samplingPeriod);
  73. return me;
  74. } catch (MelderError) {
  75. Melder_throw (U"LPC not created.");
  76. }
  77. }
  78. void LPC_drawGain (LPC me, Graphics g, double tmin, double tmax, double gmin, double gmax, bool garnish) {
  79. if (tmax <= tmin) {
  80. tmin = my xmin;
  81. tmax = my xmax;
  82. }
  83. integer itmin, itmax;
  84. if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) {
  85. return;
  86. }
  87. autoNUMvector<double> gain (itmin, itmax);
  88. for (integer iframe = itmin; iframe <= itmax; iframe ++) {
  89. gain [iframe] = my d_frames [iframe]. gain;
  90. }
  91. if (gmax <= gmin) {
  92. NUMvector_extrema (gain.peek(), itmin, itmax, & gmin, & gmax);
  93. }
  94. if (gmax == gmin) {
  95. gmin = 0;
  96. gmax += 0.5;
  97. }
  98. Graphics_setInner (g);
  99. Graphics_setWindow (g, tmin, tmax, gmin, gmax);
  100. for (integer iframe = itmin; iframe <= itmax; iframe ++) {
  101. double x = Sampled_indexToX (me, iframe);
  102. Graphics_speckle (g, x, gain[iframe]);
  103. }
  104. Graphics_unsetInner (g);
  105. if (garnish) {
  106. Graphics_drawInnerBox (g);
  107. Graphics_textBottom (g, true, U"Time (seconds)");
  108. Graphics_textLeft (g, true, U"Gain");
  109. Graphics_marksBottom (g, 2, true, true, false);
  110. Graphics_marksLeft (g, 2, true, true, false);
  111. }
  112. }
  113. void LPC_drawPoles (LPC me, Graphics g, double time, bool garnish) {
  114. autoPolynomial p = LPC_to_Polynomial (me, time);
  115. autoRoots r = Polynomial_to_Roots (p.get());
  116. Roots_draw (r.get(), g, -1.0, 1.0, -1.0, 1.0, U"+", 12, garnish);
  117. }
  118. autoMatrix LPC_downto_Matrix_lpc (LPC me) {
  119. try {
  120. autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 0.5, 0.5 + my maxnCoefficients, my maxnCoefficients, 1.0, 1.0);
  121. for (integer j = 1; j <= my nx; j ++) {
  122. LPC_Frame lpc = & my d_frames [j];
  123. for (integer i = 1; i <= lpc -> nCoefficients; i ++) {
  124. thy z [i] [j] = lpc -> a [i];
  125. }
  126. }
  127. return thee;
  128. } catch (MelderError) {
  129. Melder_throw (me, U": no Matrix with linear prediction coefficients created.");
  130. }
  131. }
  132. autoMatrix LPC_downto_Matrix_rc (LPC me) {
  133. try {
  134. autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 0.5, 0.5 + my maxnCoefficients, my maxnCoefficients, 1.0, 1.0);
  135. autoNUMvector<double> rc (1, my maxnCoefficients);
  136. for (integer j = 1; j <= my nx; j ++) {
  137. LPC_Frame lpc = & my d_frames [j];
  138. NUMlpc_lpc_to_rc (lpc -> a.at, lpc -> nCoefficients, rc.peek());
  139. for (integer i = 1; i <= lpc -> nCoefficients; i ++) {
  140. thy z [i] [j] = rc [i];
  141. }
  142. }
  143. return thee;
  144. } catch (MelderError) {
  145. Melder_throw (me, U": no Matrix with relection coefficients created.");
  146. }
  147. }
  148. autoMatrix LPC_downto_Matrix_area (LPC me) {
  149. try {
  150. autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 0.5, 0.5 + my maxnCoefficients, my maxnCoefficients, 1.0, 1.0);
  151. autoNUMvector<double> rc (1, my maxnCoefficients);
  152. autoNUMvector<double> area (1, my maxnCoefficients);
  153. for (integer j = 1; j <= my nx; j ++) {
  154. LPC_Frame lpc = & my d_frames [j];
  155. NUMlpc_lpc_to_rc (lpc -> a.at, lpc -> nCoefficients, rc.peek());
  156. NUMlpc_rc_to_area (rc.peek(), lpc -> nCoefficients, area.peek());
  157. for (integer i = 1; i <= lpc -> nCoefficients; i ++) {
  158. thy z [i] [j] = area [i];
  159. }
  160. }
  161. return thee;
  162. } catch (MelderError) {
  163. Melder_throw (me, U": no Matrix with areas created.");
  164. }
  165. }
  166. /* End of file LPC.cpp */