Collection of tools useful for audio production
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.

258 lines
8.9KB

  1. /*
  2. * Carla (frontend)
  3. * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program 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
  8. * any later version.
  9. *
  10. * This program is distributed in the hope that it 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. *
  15. * For a full copy of the GNU General Public License see the COPYING file
  16. */
  17. #include "Shared.hpp"
  18. //#define __STDC_LIMIT_MACROS
  19. //#include <cstdint>
  20. CARLA_BACKEND_USE_NAMESPACE
  21. // ------------------------------------------------------------------------------------------------
  22. // Carla Host object
  23. CarlaHostObject Carla;
  24. // ------------------------------------------------------------------------------------------------------------
  25. // Carla XML helpers
  26. const CarlaSaveState* getSaveStateDictFromXML(const QDomNode& xmlNode)
  27. {
  28. static CarlaSaveState saveState;
  29. saveState.reset();
  30. QDomNode node(xmlNode.firstChild());
  31. while (! node.isNull())
  32. {
  33. // ------------------------------------------------------
  34. // Info
  35. if (node.toElement().tagName() == "Info")
  36. {
  37. QDomNode xmlInfo(node.toElement().firstChild());
  38. while (! xmlInfo.isNull())
  39. {
  40. const QString tag = xmlInfo.toElement().tagName();
  41. const QString text = xmlInfo.toElement().text(); //.strip();
  42. if (tag == "Type")
  43. saveState.type = text;
  44. else if (tag == "Name")
  45. saveState.name = xmlSafeString(text, false);
  46. else if (tag == "Label" || tag == "URI")
  47. saveState.label = xmlSafeString(text, false);
  48. else if (tag == "Binary")
  49. saveState.binary = xmlSafeString(text, false);
  50. else if (tag == "UniqueID")
  51. {
  52. bool ok;
  53. long uniqueID = text.toLong(&ok);
  54. if (ok) saveState.uniqueID = uniqueID;
  55. }
  56. xmlInfo = xmlInfo.nextSibling();
  57. }
  58. }
  59. // ------------------------------------------------------
  60. // Data
  61. else if (node.toElement().tagName() == "Data")
  62. {
  63. QDomNode xmlData(node.toElement().firstChild());
  64. while (! xmlData.isNull())
  65. {
  66. const QString tag = xmlData.toElement().tagName();
  67. const QString text = xmlData.toElement().text(); //.strip();
  68. // ----------------------------------------------
  69. // Internal Data
  70. if (tag == "Active")
  71. {
  72. saveState.active = bool(text == "Yes");
  73. }
  74. else if (tag == "DryWet")
  75. {
  76. bool ok;
  77. double value = text.toDouble(&ok);
  78. if (ok) saveState.dryWet = value;
  79. }
  80. else if (tag == "Volume")
  81. {
  82. bool ok;
  83. double value = text.toDouble(&ok);
  84. if (ok) saveState.volume = value;
  85. }
  86. else if (tag == "Balance-Left")
  87. {
  88. bool ok;
  89. double value = text.toDouble(&ok);
  90. if (ok) saveState.balanceLeft = value;
  91. }
  92. else if (tag == "Balance-Right")
  93. {
  94. bool ok;
  95. double value = text.toDouble(&ok);
  96. if (ok) saveState.balanceRight = value;
  97. }
  98. // ----------------------------------------------
  99. // Program (current)
  100. else if (tag == "CurrentProgramIndex")
  101. {
  102. bool ok;
  103. int value = text.toInt(&ok);
  104. if (ok) saveState.currentProgramIndex = value;
  105. }
  106. else if (tag == "CurrentProgramName")
  107. {
  108. saveState.currentProgramName = xmlSafeString(text, false);
  109. }
  110. // ----------------------------------------------
  111. // Midi Program (current)
  112. else if (tag == "CurrentMidiBank")
  113. {
  114. bool ok;
  115. int value = text.toInt(&ok);
  116. if (ok) saveState.currentMidiBank = value;
  117. }
  118. else if (tag == "CurrentMidiProgram")
  119. {
  120. bool ok;
  121. int value = text.toInt(&ok);
  122. if (ok) saveState.currentMidiProgram = value;
  123. }
  124. // ----------------------------------------------
  125. // Parameters
  126. else if (tag == "Parameter")
  127. {
  128. CarlaStateParameter stateParameter;
  129. QDomNode xmlSubData(xmlData.toElement().firstChild());
  130. while (! xmlSubData.isNull())
  131. {
  132. const QString pTag = xmlSubData.toElement().tagName();
  133. const QString pText = xmlSubData.toElement().text(); //.strip();
  134. if (pTag == "index")
  135. {
  136. bool ok;
  137. uint index = pText.toUInt(&ok);
  138. if (ok) stateParameter.index = index;
  139. }
  140. else if (pTag == "name")
  141. {
  142. stateParameter.name = xmlSafeString(pText, false);
  143. }
  144. else if (pTag == "symbol")
  145. {
  146. stateParameter.symbol = xmlSafeString(pText, false);
  147. }
  148. else if (pTag == "value")
  149. {
  150. bool ok;
  151. double value = pText.toDouble(&ok);
  152. if (ok) stateParameter.value = value;
  153. }
  154. else if (pTag == "midiChannel")
  155. {
  156. bool ok;
  157. uint channel = pText.toUInt(&ok);
  158. if (ok && channel < 16)
  159. stateParameter.midiChannel = channel;
  160. }
  161. else if (pTag == "midiCC")
  162. {
  163. bool ok;
  164. int cc = pText.toInt(&ok);
  165. if (ok && cc < INT16_MAX)
  166. stateParameter.midiCC = cc;
  167. }
  168. xmlSubData = xmlSubData.nextSibling();
  169. }
  170. saveState.parameters.append(stateParameter);
  171. }
  172. // ----------------------------------------------
  173. // Custom Data
  174. else if (tag == "CustomData")
  175. {
  176. CarlaStateCustomData stateCustomData;
  177. QDomNode xmlSubData(xmlData.toElement().firstChild());
  178. while (! xmlSubData.isNull())
  179. {
  180. const QString cTag = xmlSubData.toElement().tagName();
  181. const QString cText = xmlSubData.toElement().text(); //.strip();
  182. if (cTag == "type")
  183. stateCustomData.type = xmlSafeString(cText, false);
  184. else if (cTag == "key")
  185. stateCustomData.key = xmlSafeString(cText, false);
  186. else if (cTag == "value")
  187. stateCustomData.value = xmlSafeString(cText, false);
  188. xmlSubData = xmlSubData.nextSibling();
  189. }
  190. saveState.customData.append(stateCustomData);
  191. }
  192. // ----------------------------------------------
  193. // Chunk
  194. else if (tag == "Chunk")
  195. {
  196. saveState.chunk = xmlSafeString(text, false);
  197. }
  198. // ----------------------------------------------
  199. xmlData = xmlData.nextSibling();
  200. }
  201. }
  202. // ------------------------------------------------------
  203. node = node.nextSibling();
  204. }
  205. return &saveState;
  206. }
  207. QString xmlSafeString(QString string, const bool toXml)
  208. {
  209. if (toXml)
  210. return string.replace("&", "&amp;").replace("<","&lt;").replace(">","&gt;").replace("'","&apos;").replace("\"","&quot;");
  211. else
  212. return string.replace("&amp;", "&").replace("&lt;","<").replace("&gt;",">").replace("&apos;","'").replace("&quot;","\"");
  213. }