You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

317 lines
5.4KB

  1. /* SpiralLoops
  2. * Copyleft (C) 2000 David Griffiths <dave@pawfal.org>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include <string.h>
  19. #include "Sample.h"
  20. #include <iostream>
  21. Sample::Sample(int Len) :
  22. m_IsEmpty(true),
  23. m_DataGranularity(1),//512),
  24. m_Data(NULL),
  25. m_Length(0)
  26. {
  27. if (Len)
  28. {
  29. Allocate(Len);
  30. }
  31. }
  32. Sample::Sample(const Sample &rhs):
  33. m_IsEmpty(true),
  34. m_DataGranularity(512),
  35. m_Data(NULL),
  36. m_Length(0)
  37. {
  38. *this=rhs;
  39. }
  40. Sample::Sample(const float *S, int Len):
  41. m_IsEmpty(false),
  42. m_DataGranularity(512),
  43. m_Data(NULL),
  44. m_Length(0)
  45. {
  46. assert(S);
  47. Allocate(Len);
  48. memcpy(m_Data,S,GetLengthInBytes());
  49. }
  50. Sample::~Sample()
  51. {
  52. Clear();
  53. }
  54. bool Sample::Allocate(int Size)
  55. {
  56. Clear();
  57. m_Data = new float[Size];
  58. m_Length=Size;
  59. memset(m_Data,0,GetLengthInBytes());
  60. return (m_Data);
  61. }
  62. void Sample::Clear()
  63. {
  64. m_IsEmpty=true;
  65. if (m_Data)
  66. {
  67. delete[] m_Data;
  68. m_Length=0;
  69. m_Data=NULL;
  70. }
  71. }
  72. void Sample::Zero()
  73. {
  74. m_IsEmpty=true;
  75. memset(m_Data,0,GetLengthInBytes());
  76. }
  77. void Sample::Set(float Val)
  78. {
  79. m_IsEmpty=false;
  80. for (int n=0; n<m_Length; n++)
  81. {
  82. m_Data[n]=Val;
  83. }
  84. }
  85. void Sample::Insert(const Sample &S, int Pos)
  86. {
  87. // do some checking
  88. assert(Pos<=GetLength());
  89. int NewLen = GetLength()+S.GetLength();
  90. float *NewBuf = new float [NewLen];
  91. int FromPos=0, ToPos=0, TempBufPos=0;
  92. while (FromPos<=GetLength())
  93. {
  94. if (FromPos==Pos)
  95. {
  96. for (TempBufPos=0; TempBufPos<S.GetLength(); TempBufPos++)
  97. {
  98. NewBuf[ToPos]=S[TempBufPos];
  99. ToPos++;
  100. }
  101. }
  102. else
  103. {
  104. // this test is needed so the loop can deal
  105. // with samples being "inserted" on to the
  106. // very end of the buffer
  107. if (FromPos<GetLength())
  108. {
  109. NewBuf[ToPos]=m_Data[FromPos];
  110. }
  111. }
  112. FromPos++;
  113. ToPos++;
  114. }
  115. Clear();
  116. m_Data=NewBuf;
  117. m_Length=NewLen;
  118. }
  119. void Sample::Add(const Sample &S)
  120. {
  121. Insert(S,GetLength());
  122. }
  123. void Sample::Mix(const Sample &S, int Pos)
  124. {
  125. // do some checking
  126. assert(Pos<GetLength());
  127. int ToPos=Pos;
  128. for (int FromPos=0; FromPos<S.GetLength(); FromPos++)
  129. {
  130. m_Data[ToPos]=m_Data[ToPos]+S[FromPos];
  131. if (ToPos>GetLength()) ToPos=0;
  132. ToPos++;
  133. }
  134. }
  135. void Sample::Remove(int Start, int End)
  136. {
  137. // do some checking
  138. assert(End<GetLength() && Start<GetLength());
  139. assert(Start<=End);
  140. // check the range
  141. if (End>GetLength()) End=GetLength();
  142. if (Start<0) Start=0;
  143. // calc lengths and allocate memory
  144. int CutLen = End - Start;
  145. // has to be granulated by the buffer size
  146. CutLen-=CutLen % m_DataGranularity;
  147. int NewLen = GetLength()-CutLen;
  148. float *TempBuf = new float[NewLen];
  149. int ToPos=0;
  150. for (int FromPos=0; FromPos<GetLength(); FromPos++)
  151. {
  152. // copy the areas outside of the cut range
  153. if (FromPos<Start || FromPos>End)
  154. {
  155. TempBuf[ToPos]=m_Data[FromPos];
  156. ToPos++;
  157. // check the position is in range of the calculated length
  158. assert(ToPos<=NewLen);
  159. }
  160. }
  161. Clear();
  162. m_Data=TempBuf;
  163. m_Length=NewLen;
  164. }
  165. void Sample::Reverse(int Start, int End)
  166. {
  167. // do some checking
  168. assert(End<GetLength() && Start<GetLength());
  169. assert(Start<=End);
  170. // check the range
  171. if (End>GetLength()) End=GetLength();
  172. int NewLen = End-Start;
  173. float *TempBuf = new float[NewLen];
  174. int ToPos=0;
  175. int FromPos=0;
  176. // get the reversed sample
  177. for (FromPos=End; FromPos>Start; FromPos--)
  178. {
  179. TempBuf[ToPos]=m_Data[FromPos];
  180. ToPos++;
  181. assert(ToPos<=NewLen);
  182. }
  183. FromPos=0;
  184. // overwrite back into place
  185. for (ToPos=Start; ToPos<End; ToPos++)
  186. {
  187. m_Data[ToPos]=TempBuf[FromPos];
  188. FromPos++;
  189. }
  190. }
  191. void Sample::Move(int Dist)
  192. {
  193. int Length=GetLength();
  194. float *TempBuf = new float[Length];
  195. int ToPos=0;
  196. int FromPos=Dist;
  197. if (FromPos<0) FromPos+=Length;
  198. if (FromPos>Length) FromPos-=Length;
  199. // get the offset sample
  200. for (ToPos=0; ToPos<Length; ToPos++)
  201. {
  202. TempBuf[ToPos]=m_Data[FromPos];
  203. FromPos++;
  204. if (FromPos>=Length) FromPos=0;
  205. }
  206. Clear();
  207. m_Data=TempBuf;
  208. m_Length=Length;
  209. }
  210. void Sample::GetRegion(Sample &S, int Start, int End)
  211. {
  212. // do some checking
  213. assert(End<GetLength() && Start<GetLength());
  214. assert(Start<=End);
  215. int Length=End-Start;
  216. Length-=Length % m_DataGranularity;
  217. S.Allocate(Length);
  218. int FromPos=Start;
  219. for (int ToPos=0; ToPos<Length; ToPos++)
  220. {
  221. S.Set(ToPos,m_Data[FromPos]);
  222. FromPos++;
  223. }
  224. }
  225. void Sample::CropTo(int NewLength)
  226. {
  227. assert (NewLength<GetLength());
  228. float *temp = new float[NewLength];
  229. for(int n=0; n<NewLength; n++)
  230. {
  231. temp[n]=m_Data[n];
  232. }
  233. Clear();
  234. m_Data=temp;
  235. m_Length=NewLength;
  236. }
  237. // adds length amount of blank space
  238. void Sample::Expand(int Length)
  239. {
  240. Sample Temp(Length);
  241. Temp.Zero();
  242. Add(Temp);
  243. }
  244. // shrink the samle by length amount
  245. void Sample::Shrink(int Length)
  246. {
  247. int NewLength=GetLength()-Length;
  248. assert(NewLength>0 && NewLength<=GetLength());
  249. float *temp = new float[NewLength];
  250. for(int n=0; n<NewLength; n++)
  251. {
  252. temp[n]=m_Data[n];
  253. }
  254. Clear();
  255. m_Data=temp;
  256. m_Length=NewLength;
  257. }