AnyTier.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /* AnyTier.cpp
  2. *
  3. * Copyright (C) 1992-2005,2007,2008,2011,2015-2018 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 "AnyTier.h"
  19. /*
  20. #include "oo_DESTROY.h"
  21. #include "AnyTier_def.h"
  22. #include "oo_COPY.h"
  23. #include "AnyTier_def.h"
  24. #include "oo_EQUAL.h"
  25. #include "AnyTier_def.h"
  26. #include "oo_CAN_WRITE_AS_ENCODING.h"
  27. #include "AnyTier_def.h"
  28. #include "oo_WRITE_TEXT.h"
  29. #include "AnyTier_def.h"
  30. #include "oo_READ_TEXT.h"
  31. #include "AnyTier_def.h"
  32. #include "oo_WRITE_BINARY.h"
  33. #include "AnyTier_def.h"
  34. #include "oo_READ_BINARY.h"
  35. #include "AnyTier_def.h"
  36. #include "oo_DESCRIPTION.h"
  37. #include "AnyTier_def.h"
  38. */
  39. Thing_implement (AnyPoint, SimpleDouble, 0);
  40. Thing_implement (AnyTier, Function, 0);
  41. void structAnyTier :: v_shiftX (double xfrom, double xto) {
  42. AnyTier_Parent :: v_shiftX (xfrom, xto);
  43. for (integer i = 1; i <= our points.size; i ++) {
  44. AnyPoint point = our points.at [i];
  45. NUMshift (& point -> number, xfrom, xto);
  46. }
  47. }
  48. void structAnyTier :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) {
  49. AnyTier_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto);
  50. for (integer i = 1; i <= our points.size; i ++) {
  51. AnyPoint point = our points.at [i];
  52. NUMscale (& point -> number, xminfrom, xmaxfrom, xminto, xmaxto);
  53. }
  54. }
  55. integer AnyTier_timeToLowIndex (AnyTier me, double time) {
  56. if (my points.size == 0) return 0; // undefined
  57. integer ileft = 1, iright = my points.size;
  58. double tleft = my points.at [ileft] -> number;
  59. if (time < tleft) return 0; // offleft
  60. double tright = my points.at [iright] -> number;
  61. if (time >= tright) return iright;
  62. Melder_assert (time >= tleft && time < tright);
  63. Melder_assert (iright > ileft);
  64. while (iright > ileft + 1) {
  65. integer imid = (ileft + iright) / 2;
  66. double tmid = my points.at [imid] -> number;
  67. if (time < tmid) {
  68. iright = imid;
  69. tright = tmid;
  70. } else {
  71. ileft = imid;
  72. tleft = tmid;
  73. }
  74. }
  75. Melder_assert (iright == ileft + 1);
  76. Melder_assert (ileft >= 1);
  77. Melder_assert (iright <= my points.size);
  78. Melder_assert (time >= my points.at [ileft] -> number);
  79. Melder_assert (time <= my points.at [iright] -> number);
  80. return ileft;
  81. }
  82. integer AnyTier_timeToHighIndex (AnyTier me, double time) {
  83. if (my points.size == 0) return 0; // undefined; is this right?
  84. integer ileft = 1, iright = my points.size;
  85. double tleft = my points.at [ileft] -> number;
  86. if (time <= tleft) return 1;
  87. double tright = my points.at [iright] -> number;
  88. if (time > tright) return iright + 1; // offright
  89. Melder_assert (time > tleft && time <= tright);
  90. Melder_assert (iright > ileft);
  91. while (iright > ileft + 1) {
  92. integer imid = (ileft + iright) / 2;
  93. double tmid = my points.at [imid] -> number;
  94. if (time <= tmid) {
  95. iright = imid;
  96. tright = tmid;
  97. } else {
  98. ileft = imid;
  99. tleft = tmid;
  100. }
  101. }
  102. Melder_assert (iright == ileft + 1);
  103. Melder_assert (ileft >= 1);
  104. Melder_assert (iright <= my points.size);
  105. Melder_assert (time >= my points.at [ileft] -> number);
  106. Melder_assert (time <= my points.at [iright] -> number);
  107. return iright;
  108. }
  109. integer AnyTier_getWindowPoints (AnyTier me, double tmin, double tmax, integer *imin, integer *imax) {
  110. if (my points.size == 0) return 0;
  111. *imin = AnyTier_timeToHighIndex (me, tmin);
  112. *imax = AnyTier_timeToLowIndex (me, tmax);
  113. if (*imax < *imin) return 0;
  114. return *imax - *imin + 1;
  115. }
  116. integer AnyTier_timeToNearestIndex (AnyTier me, double time) {
  117. if (my points.size == 0) return 0; // undefined
  118. integer ileft = 1, iright = my points.size;
  119. double tleft = my points.at [ileft] -> number;
  120. if (time <= tleft) return 1;
  121. double tright = my points.at [iright] -> number;
  122. if (time >= tright) return iright;
  123. Melder_assert (time > tleft && time < tright);
  124. Melder_assert (iright > ileft);
  125. while (iright > ileft + 1) {
  126. integer imid = (ileft + iright) / 2;
  127. double tmid = my points.at [imid] -> number;
  128. if (time < tmid) {
  129. iright = imid;
  130. tright = tmid;
  131. } else {
  132. ileft = imid;
  133. tleft = tmid;
  134. }
  135. }
  136. Melder_assert (iright == ileft + 1);
  137. Melder_assert (ileft >= 1);
  138. Melder_assert (iright <= my points.size);
  139. Melder_assert (time >= my points.at [ileft] -> number);
  140. Melder_assert (time <= my points.at [iright] -> number);
  141. return time - tleft <= tright - time ? ileft : iright;
  142. }
  143. integer AnyTier_hasPoint (AnyTier me, double t) {
  144. if (my points.size == 0) return 0; // point not found
  145. integer ileft = 1, iright = my points.size;
  146. double tleft = my points.at [ileft] -> number;
  147. if (t < tleft) return 0; // offleft
  148. double tright = my points.at [iright] -> number;
  149. if (t > tright) return 0; // offright
  150. if (t == tleft) return 1;
  151. if (t == tright) return iright;
  152. Melder_assert (t > tleft && t < tright);
  153. Melder_assert (iright > ileft);
  154. while (iright > ileft + 1) {
  155. integer imid = (ileft + iright) / 2;
  156. double tmid = my points.at [imid] -> number;
  157. if (t < tmid) {
  158. iright = imid;
  159. tright = tmid;
  160. } else if (t == tmid) {
  161. return imid; // point found
  162. } else {
  163. ileft = imid;
  164. tleft = tmid;
  165. }
  166. }
  167. Melder_assert (iright == ileft + 1);
  168. Melder_assert (ileft >= 1);
  169. Melder_assert (iright <= my points.size);
  170. Melder_assert (t > my points.at [ileft] -> number);
  171. Melder_assert (t < my points.at [iright] -> number);
  172. return 0; // point not found
  173. }
  174. void AnyTier_addPoint_move (AnyTier me, autoAnyPoint point) {
  175. try {
  176. my points. addItem_move (point.move());
  177. } catch (MelderError) {
  178. Melder_throw (me, U": point not added.");
  179. }
  180. }
  181. void AnyTier_removePoint (AnyTier me, integer i) {
  182. if (i >= 1 && i <= my points.size) my points. removeItem (i);
  183. }
  184. void AnyTier_removePointNear (AnyTier me, double time) {
  185. integer ipoint = AnyTier_timeToNearestIndex (me, time);
  186. if (ipoint) my points.removeItem (ipoint);
  187. }
  188. void AnyTier_removePointsBetween (AnyTier me, double tmin, double tmax) {
  189. if (my points.size == 0) return;
  190. integer ileft = AnyTier_timeToHighIndex (me, tmin);
  191. integer iright = AnyTier_timeToLowIndex (me, tmax);
  192. for (integer i = iright; i >= ileft; i --)
  193. my points. removeItem (i);
  194. }
  195. autoPointProcess AnyTier_downto_PointProcess (AnyTier me) {
  196. try {
  197. integer numberOfPoints = my points.size;
  198. autoPointProcess thee = PointProcess_create (my xmin, my xmax, numberOfPoints);
  199. for (integer i = 1; i <= numberOfPoints; i ++)
  200. PointProcess_addPoint (thee.get(), my points.at [i] -> number);
  201. return thee;
  202. } catch (MelderError) {
  203. Melder_throw (me, U": not converted to PointProcess.");
  204. }
  205. }
  206. /* End of file AnyTier.cpp */