ParamCurve.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /* ParamCurve.cpp
  2. *
  3. * Copyright (C) 1992-2012,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 "ParamCurve.h"
  19. #include "oo_DESTROY.h"
  20. #include "ParamCurve_def.h"
  21. #include "oo_COPY.h"
  22. #include "ParamCurve_def.h"
  23. #include "oo_EQUAL.h"
  24. #include "ParamCurve_def.h"
  25. #include "oo_DESCRIPTION.h"
  26. #include "ParamCurve_def.h"
  27. #include "oo_CAN_WRITE_AS_ENCODING.h"
  28. #include "ParamCurve_def.h"
  29. Thing_implement (ParamCurve, Function, 2);
  30. void structParamCurve :: v_info () {
  31. double xvalmin = 1e308, xvalmax = -1e308, yvalmin = 1e308, yvalmax = -1e308;
  32. for (integer i = 1; i <= our x -> nx; i ++) {
  33. double value = our x -> z [1] [i];
  34. if (value < xvalmin) xvalmin = value;
  35. if (value > xvalmax) xvalmax = value;
  36. }
  37. for (integer i = 1; i <= y -> nx; i ++) {
  38. double value = our y -> z [1] [i];
  39. if (value < yvalmin) yvalmin = value;
  40. if (value > yvalmax) yvalmax = value;
  41. }
  42. structDaata :: v_info ();
  43. MelderInfo_writeLine (U"Domain:");
  44. MelderInfo_writeLine (U" tmin: ", our xmin);
  45. MelderInfo_writeLine (U" tmax: ", our xmax);
  46. MelderInfo_writeLine (U"x sampling:");
  47. MelderInfo_writeLine (U" Number of values of t in x: ", our x -> nx);
  48. MelderInfo_writeLine (U" t step in x: ", our x -> dx, U" (sampling rate ", 1.0 / our x -> dx, U")");
  49. MelderInfo_writeLine (U" First t in x: ", our x -> x1);
  50. MelderInfo_writeLine (U"x values:");
  51. MelderInfo_writeLine (U" Minimum x: ", xvalmin);
  52. MelderInfo_writeLine (U" Maximum x: ", xvalmax);
  53. MelderInfo_writeLine (U"y sampling:");
  54. MelderInfo_writeLine (U" Number of values of t in y: ", our y -> nx);
  55. MelderInfo_writeLine (U" t step in y: ", our y -> dx, U" (sampling rate ", 1.0 / our y -> dx, U")");
  56. MelderInfo_writeLine (U" First t in y: ", our y -> x1);
  57. MelderInfo_writeLine (U"y values:");
  58. MelderInfo_writeLine (U" Minimum y: ", yvalmin);
  59. MelderInfo_writeLine (U" Maximum y: ", yvalmax);
  60. }
  61. void structParamCurve :: v_writeText (MelderFile file) {
  62. Data_writeText (our x.get(), file);
  63. Data_writeText (our y.get(), file);
  64. }
  65. void structParamCurve :: v_readText (MelderReadText text, int formatVersion) {
  66. our x = Thing_new (Sound);
  67. our y = Thing_new (Sound);
  68. Data_readText (our x.get(), text, formatVersion);
  69. Data_readText (our y.get(), text, formatVersion);
  70. our xmin = our x -> xmin > our y -> xmin ? our x -> xmin : our y -> xmin;
  71. our xmax = our x -> xmax < our y -> xmax ? our x -> xmax : our y -> xmax;
  72. }
  73. void structParamCurve :: v_writeBinary (FILE *f) {
  74. Data_writeBinary (x.get(), f);
  75. Data_writeBinary (y.get(), f);
  76. }
  77. void structParamCurve :: v_readBinary (FILE *f, int /*formatVersion*/) {
  78. our x = Thing_new (Sound);
  79. our y = Thing_new (Sound);
  80. Data_readBinary (our x.get(), f, 2);
  81. Data_readBinary (our y.get(), f, 2);
  82. our xmin = our x -> xmin > our y -> xmin ? our x -> xmin : our y -> xmin;
  83. our xmax = our x -> xmax < our y -> xmax ? our x -> xmax : our y -> xmax;
  84. }
  85. void ParamCurve_init (ParamCurve me, Sound x, Sound y) {
  86. if (x -> xmax <= y -> xmin || x -> xmin >= y -> xmax)
  87. Melder_throw (U"Domains do not overlap.");
  88. my x = Data_copy (x);
  89. my y = Data_copy (y);
  90. my xmin = x -> xmin > y -> xmin ? x -> xmin : y -> xmin;
  91. my xmax = x -> xmax < y -> xmax ? x -> xmax : y -> xmax;
  92. }
  93. autoParamCurve ParamCurve_create (Sound x, Sound y) {
  94. try {
  95. autoParamCurve me = Thing_new (ParamCurve);
  96. ParamCurve_init (me.get(), x, y);
  97. return me;
  98. } catch (MelderError) {
  99. Melder_throw (U"ParamCurve not created.");
  100. }
  101. }
  102. void ParamCurve_draw (ParamCurve me, Graphics g, double t1, double t2, double dt,
  103. double x1, double x2, double y1, double y2, bool garnish)
  104. {
  105. if (t2 <= t1) {
  106. double tx1 = my x -> x1;
  107. double ty1 = my y -> x1;
  108. double tx2 = my x -> x1 + (my x -> nx - 1) * my x -> dx;
  109. double ty2 = my y -> x1 + (my y -> nx - 1) * my y -> dx;
  110. t1 = tx1 > ty1 ? tx1 : ty1;
  111. t2 = tx2 < ty2 ? tx2 : ty2;
  112. }
  113. if (x2 <= x1) Matrix_getWindowExtrema (my x.get(), 0, 0, 1, 1, & x1, & x2);
  114. if (x1 == x2) { x1 -= 1.0; x2 += 1.0; }
  115. if (y2 <= y1) Matrix_getWindowExtrema (my y.get(), 0, 0, 1, 1, & y1, & y2);
  116. if (y1 == y2) { y1 -= 1.0; y2 += 1.0; }
  117. if (dt <= 0.0)
  118. dt = my x -> dx < my y -> dx ? my x -> dx : my y -> dx;
  119. integer numberOfPoints = Melder_iceiling ((t2 - t1) / dt) + 1;
  120. if (numberOfPoints > 0) {
  121. autoNUMvector <double> x (1, numberOfPoints);
  122. autoNUMvector <double> y (1, numberOfPoints);
  123. for (integer i = 1; i <= numberOfPoints; i ++) {
  124. double t = i == numberOfPoints ? t2 : t1 + (i - 1) * dt;
  125. double index = Sampled_xToIndex (my x.get(), t);
  126. x [i] = NUM_interpolate_sinc (my x -> z [1], my x -> nx, index, 50);
  127. index = Sampled_xToIndex (my y.get(), t);
  128. y [i] = NUM_interpolate_sinc (my y -> z [1], my y -> nx, index, 50);
  129. }
  130. Graphics_setWindow (g, x1, x2, y1, y2);
  131. Graphics_setInner (g);
  132. Graphics_polyline (g, numberOfPoints, & x [1], & y [1]);
  133. Graphics_unsetInner (g);
  134. }
  135. if (garnish) {
  136. Graphics_drawInnerBox (g);
  137. Graphics_marksBottom (g, 2, true, true, false);
  138. Graphics_marksLeft (g, 2, true, true, false);
  139. }
  140. }
  141. void ParamCurve_swapXY (ParamCurve me) {
  142. autoSound help = my x.move();
  143. my x = my y.move();
  144. my y = help.move();
  145. }
  146. /* End of file ParamCurve.cpp */