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.

368 lines
10KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCETICE project - Copyright 2009 by Lucio Asnaghi.
  4. JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions"
  5. Copyright 2007 by Julian Storer.
  6. ------------------------------------------------------------------------------
  7. JUCE and JUCETICE can be redistributed and/or modified under the terms of
  8. the GNU General Public License, as published by the Free Software Foundation;
  9. either version 2 of the License, or (at your option) any later version.
  10. JUCE and JUCETICE are distributed in the hope that they will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to
  16. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  17. Boston, MA 02111-1307 USA
  18. ==============================================================================
  19. This file is based around Niall Moody's OSC/UDP library, but was modified to
  20. be more independent and modularized, using the best practices from JUCE.
  21. ==============================================================================
  22. */
  23. #ifdef WIN32
  24. #include <winsock.h>
  25. #else
  26. #include <netinet/in.h>
  27. #endif
  28. BEGIN_JUCE_NAMESPACE
  29. #include "jucetice_OpenSoundMessage.h"
  30. //------------------------------------------------------------------------------
  31. OpenSoundBundle::OpenSoundBundle()
  32. : OpenSoundBase(),
  33. bufferSize(0),
  34. outgoingSize(0),
  35. dataBuffer(0)
  36. {
  37. }
  38. //------------------------------------------------------------------------------
  39. OpenSoundBundle::OpenSoundBundle (char *data, const int size)
  40. : OpenSoundBase(),
  41. bufferSize(0),
  42. outgoingSize(0),
  43. dataBuffer(0)
  44. {
  45. int i;
  46. int32 tempSize;
  47. TimeTag *tempTag;
  48. OpenSoundMessage *newMessage;
  49. OpenSoundBundle *newBundle;
  50. //Start at 8, because we don't care about the first '#bundle' string.
  51. for (i = 8; i < size; ++i)
  52. {
  53. if (i < 16)
  54. {
  55. //Get timeTag.
  56. tempTag = new TimeTag(data+i);
  57. timeTag = *tempTag;
  58. delete tempTag;
  59. i += 7;
  60. }
  61. else
  62. {
  63. tempSize = ntohl(*(reinterpret_cast<int32 *>(data+i)));
  64. i += 4;
  65. if(isBundle((data+i), tempSize))
  66. {
  67. newBundle = new OpenSoundBundle((data+i), tempSize);
  68. addElement(newBundle);
  69. i += (tempSize-1); //-1 because it gets incremented at the end of the loop.
  70. }
  71. else if(OpenSoundMessage::isMessage((data+i), tempSize))
  72. {
  73. newMessage = new OpenSoundMessage((data+i), tempSize);
  74. addElement(newMessage);
  75. i += (tempSize-1); //-1 because it gets incremented at the end of the loop.
  76. }
  77. }
  78. }
  79. }
  80. //------------------------------------------------------------------------------
  81. OpenSoundBundle::~OpenSoundBundle()
  82. {
  83. clearElements();
  84. if(dataBuffer)
  85. {
  86. delete [] dataBuffer;
  87. dataBuffer = 0;
  88. }
  89. }
  90. //------------------------------------------------------------------------------
  91. int32 OpenSoundBundle::getSize()
  92. {
  93. std::vector<OpenSoundMessage *>::iterator itM;
  94. std::vector<OpenSoundBundle *>::iterator itB;
  95. int32 retval = 0;
  96. retval += 8; //'#bundle'
  97. retval += 8; //timeTag
  98. for(itM=messageArray.begin();itM!=messageArray.end();++itM)
  99. {
  100. retval += 4; //For the size of the message.
  101. retval += (*itM)->getSize();
  102. }
  103. for(itB=bundleArray.begin();itB!=bundleArray.end();++itB)
  104. {
  105. retval += 4; //For the size of the bundle.
  106. retval += (*itB)->getSize();
  107. }
  108. outgoingSize = retval;
  109. if(outgoingSize > bufferSize)
  110. {
  111. //This shouldn't ever happen, but just in case...
  112. if(outgoingSize < 16)
  113. outgoingSize = 16;
  114. bufferSize = outgoingSize;
  115. if(dataBuffer)
  116. {
  117. delete [] dataBuffer;
  118. dataBuffer = 0;
  119. }
  120. dataBuffer = new char[bufferSize];
  121. }
  122. return retval;
  123. }
  124. //------------------------------------------------------------------------------
  125. char *OpenSoundBundle::getData()
  126. {
  127. int32 i, j;
  128. int32 tempInt;
  129. unsigned long tempL;
  130. GetTheBytes *tempBytes;
  131. char *tempBuffer;
  132. int32 messageCount = 0;
  133. int32 bundleCount = 0;
  134. int32 messageArraySize = static_cast<int32>(messageArray.size());
  135. if(!dataBuffer)
  136. return 0;
  137. for(i=0;i<outgoingSize;++i)
  138. {
  139. //'#bundle'
  140. if(i < 8)
  141. {
  142. //dataBuffer = "#bundle";
  143. dataBuffer[0] = '#';
  144. dataBuffer[1] = 'b';
  145. dataBuffer[2] = 'u';
  146. dataBuffer[3] = 'n';
  147. dataBuffer[4] = 'd';
  148. dataBuffer[5] = 'l';
  149. dataBuffer[6] = 'e';
  150. dataBuffer[7] = static_cast<char>(NULL);
  151. i += 7;
  152. }
  153. //timeTag
  154. else if(i < 16)
  155. {
  156. tempL = timeTag.getSeconds();
  157. tempInt = htonl(tempL);
  158. tempBytes = reinterpret_cast<GetTheBytes *>(&tempInt);
  159. dataBuffer[i] = tempBytes->a;
  160. ++i;
  161. dataBuffer[i] = tempBytes->b;
  162. ++i;
  163. dataBuffer[i] = tempBytes->c;
  164. ++i;
  165. dataBuffer[i] = tempBytes->d;
  166. ++i;
  167. tempL = timeTag.getFraction();
  168. tempInt = htonl(tempL);
  169. tempBytes = reinterpret_cast<GetTheBytes *>(&tempInt);
  170. dataBuffer[i] = tempBytes->a;
  171. ++i;
  172. dataBuffer[i] = tempBytes->b;
  173. ++i;
  174. dataBuffer[i] = tempBytes->c;
  175. ++i;
  176. dataBuffer[i] = tempBytes->d;
  177. }
  178. //Do the messages first.
  179. else if(messageCount < messageArraySize)
  180. {
  181. tempInt = htonl(messageArray[messageCount]->getSize());
  182. tempBytes = reinterpret_cast<GetTheBytes *>(&tempInt);
  183. dataBuffer[i] = tempBytes->a;
  184. ++i;
  185. dataBuffer[i] = tempBytes->b;
  186. ++i;
  187. dataBuffer[i] = tempBytes->c;
  188. ++i;
  189. dataBuffer[i] = tempBytes->d;
  190. ++i;
  191. tempBuffer = messageArray[messageCount]->getData();
  192. for(j=0;j<static_cast<int32>(ntohl(tempInt));++j)
  193. dataBuffer[i+j] = tempBuffer[j];
  194. i += (j-1);
  195. ++messageCount;
  196. }
  197. //Now the bundles.
  198. else if(bundleCount < static_cast<int32>(bundleArray.size()))
  199. {
  200. tempInt = htonl(bundleArray[bundleCount]->getSize());
  201. tempBytes = reinterpret_cast<GetTheBytes *>(&tempInt);
  202. dataBuffer[i] = tempBytes->a;
  203. ++i;
  204. dataBuffer[i] = tempBytes->b;
  205. ++i;
  206. dataBuffer[i] = tempBytes->c;
  207. ++i;
  208. dataBuffer[i] = tempBytes->d;
  209. ++i;
  210. tempBuffer = bundleArray[bundleCount]->getData();
  211. for(j=0;j<static_cast<int32>(ntohl(tempInt));++j)
  212. dataBuffer[i+j] = tempBuffer[j];
  213. i += (j-1);
  214. ++bundleCount;
  215. }
  216. }
  217. return dataBuffer;
  218. }
  219. //------------------------------------------------------------------------------
  220. void OpenSoundBundle::addElement(OpenSoundBase *entry, bool deleteWhenUsed)
  221. {
  222. int32 size;
  223. size = entry->getSize();
  224. if(isBundle(entry->getData(), size))
  225. {
  226. bundleArray.push_back(static_cast<OpenSoundBundle *>(entry));
  227. bundleShouldBeDeleted.push_back(deleteWhenUsed);
  228. }
  229. else if(OpenSoundMessage::isMessage(entry->getData(), size))
  230. {
  231. messageArray.push_back(static_cast<OpenSoundMessage *>(entry));
  232. messageShouldBeDeleted.push_back(deleteWhenUsed);
  233. }
  234. }
  235. //------------------------------------------------------------------------------
  236. void OpenSoundBundle::addMessage(OpenSoundMessage *message, bool deleteWhenUsed)
  237. {
  238. messageArray.push_back(message);
  239. messageShouldBeDeleted.push_back(deleteWhenUsed);
  240. }
  241. //------------------------------------------------------------------------------
  242. void OpenSoundBundle::clearElements()
  243. {
  244. std::vector<OpenSoundMessage *>::iterator itM;
  245. std::vector<OpenSoundBundle *>::iterator itB;
  246. std::vector<bool>::iterator itD;
  247. for(itM=messageArray.begin(), itD=messageShouldBeDeleted.begin();
  248. itM!=messageArray.end();
  249. ++itM, ++itD)
  250. {
  251. if(*itD)
  252. delete (*itM);
  253. }
  254. for(itB=bundleArray.begin(), itD=bundleShouldBeDeleted.begin();
  255. itB!=bundleArray.end();
  256. ++itB, ++itD)
  257. {
  258. if(*itD)
  259. delete (*itB);
  260. }
  261. messageArray.clear();
  262. messageShouldBeDeleted.clear();
  263. bundleArray.clear();
  264. bundleShouldBeDeleted.clear();
  265. }
  266. //------------------------------------------------------------------------------
  267. void OpenSoundBundle::setTimeTag(const TimeTag& val)
  268. {
  269. timeTag = val;
  270. }
  271. //------------------------------------------------------------------------------
  272. long OpenSoundBundle::getNumElements() const
  273. {
  274. return messageArray.size() + bundleArray.size();
  275. }
  276. //------------------------------------------------------------------------------
  277. OpenSoundMessage *OpenSoundBundle::getMessage(const long index)
  278. {
  279. OpenSoundMessage *retval = 0;
  280. if(index < static_cast<int32>(messageArray.size()))
  281. retval = messageArray[index];
  282. return retval;
  283. }
  284. //------------------------------------------------------------------------------
  285. OpenSoundBundle *OpenSoundBundle::getBundle(const long index)
  286. {
  287. OpenSoundBundle *retval = 0;
  288. if(index < static_cast<int32>(bundleArray.size()))
  289. retval = bundleArray[index];
  290. return retval;
  291. }
  292. //------------------------------------------------------------------------------
  293. bool OpenSoundBundle::isBundle(char *data, const int size)
  294. {
  295. bool retval = false;
  296. if(size > 8)
  297. {
  298. //Should only need to check for the '#bundle' string...
  299. if((data[0] == '#') &&
  300. (data[1] == 'b') &&
  301. (data[2] == 'u') &&
  302. (data[3] == 'n') &&
  303. (data[4] == 'd') &&
  304. (data[5] == 'l') &&
  305. (data[6] == 'e'))
  306. retval = true;
  307. }
  308. return retval;
  309. }
  310. END_JUCE_NAMESPACE