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.

300 lines
10KB

  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. #include <QtCore/QDir>
  19. #include <QtCore/QFileInfo>
  20. //#define __STDC_LIMIT_MACROS
  21. //#include <cstdint>
  22. CARLA_BACKEND_USE_NAMESPACE
  23. // ------------------------------------------------------------------------------------------------
  24. // Carla Host object
  25. CarlaHostObject Carla;
  26. // ------------------------------------------------------------------------------------------------------------
  27. // Carla XML helpers
  28. const CarlaSaveState* getSaveStateDictFromXML(const QDomNode& xmlNode)
  29. {
  30. static CarlaSaveState saveState;
  31. saveState.reset();
  32. QDomNode node(xmlNode.firstChild());
  33. while (! node.isNull())
  34. {
  35. // ------------------------------------------------------
  36. // Info
  37. if (node.toElement().tagName() == "Info")
  38. {
  39. QDomNode xmlInfo(node.toElement().firstChild());
  40. while (! xmlInfo.isNull())
  41. {
  42. const QString tag = xmlInfo.toElement().tagName();
  43. const QString text = xmlInfo.toElement().text(); //.strip();
  44. if (tag == "Type")
  45. saveState.type = text;
  46. else if (tag == "Name")
  47. saveState.name = xmlSafeString(text, false);
  48. else if (tag == "Label" || tag == "URI")
  49. saveState.label = xmlSafeString(text, false);
  50. else if (tag == "Binary")
  51. saveState.binary = xmlSafeString(text, false);
  52. else if (tag == "UniqueID")
  53. {
  54. bool ok;
  55. long uniqueID = text.toLong(&ok);
  56. if (ok) saveState.uniqueID = uniqueID;
  57. }
  58. xmlInfo = xmlInfo.nextSibling();
  59. }
  60. }
  61. // ------------------------------------------------------
  62. // Data
  63. else if (node.toElement().tagName() == "Data")
  64. {
  65. QDomNode xmlData(node.toElement().firstChild());
  66. while (! xmlData.isNull())
  67. {
  68. const QString tag = xmlData.toElement().tagName();
  69. const QString text = xmlData.toElement().text(); //.strip();
  70. // ----------------------------------------------
  71. // Internal Data
  72. if (tag == "Active")
  73. {
  74. saveState.active = bool(text == "Yes");
  75. }
  76. else if (tag == "DryWet")
  77. {
  78. bool ok;
  79. double value = text.toDouble(&ok);
  80. if (ok) saveState.dryWet = value;
  81. }
  82. else if (tag == "Volume")
  83. {
  84. bool ok;
  85. double value = text.toDouble(&ok);
  86. if (ok) saveState.volume = value;
  87. }
  88. else if (tag == "Balance-Left")
  89. {
  90. bool ok;
  91. double value = text.toDouble(&ok);
  92. if (ok) saveState.balanceLeft = value;
  93. }
  94. else if (tag == "Balance-Right")
  95. {
  96. bool ok;
  97. double value = text.toDouble(&ok);
  98. if (ok) saveState.balanceRight = value;
  99. }
  100. // ----------------------------------------------
  101. // Program (current)
  102. else if (tag == "CurrentProgramIndex")
  103. {
  104. bool ok;
  105. int value = text.toInt(&ok);
  106. if (ok) saveState.currentProgramIndex = value;
  107. }
  108. else if (tag == "CurrentProgramName")
  109. {
  110. saveState.currentProgramName = xmlSafeString(text, false);
  111. }
  112. // ----------------------------------------------
  113. // Midi Program (current)
  114. else if (tag == "CurrentMidiBank")
  115. {
  116. bool ok;
  117. int value = text.toInt(&ok);
  118. if (ok) saveState.currentMidiBank = value;
  119. }
  120. else if (tag == "CurrentMidiProgram")
  121. {
  122. bool ok;
  123. int value = text.toInt(&ok);
  124. if (ok) saveState.currentMidiProgram = value;
  125. }
  126. // ----------------------------------------------
  127. // Parameters
  128. else if (tag == "Parameter")
  129. {
  130. CarlaStateParameter stateParameter;
  131. QDomNode xmlSubData(xmlData.toElement().firstChild());
  132. while (! xmlSubData.isNull())
  133. {
  134. const QString pTag = xmlSubData.toElement().tagName();
  135. const QString pText = xmlSubData.toElement().text(); //.strip();
  136. if (pTag == "index")
  137. {
  138. bool ok;
  139. uint index = pText.toUInt(&ok);
  140. if (ok) stateParameter.index = index;
  141. }
  142. else if (pTag == "name")
  143. {
  144. stateParameter.name = xmlSafeString(pText, false);
  145. }
  146. else if (pTag == "symbol")
  147. {
  148. stateParameter.symbol = xmlSafeString(pText, false);
  149. }
  150. else if (pTag == "value")
  151. {
  152. bool ok;
  153. double value = pText.toDouble(&ok);
  154. if (ok) stateParameter.value = value;
  155. }
  156. else if (pTag == "midiChannel")
  157. {
  158. bool ok;
  159. uint channel = pText.toUInt(&ok);
  160. if (ok && channel < 16)
  161. stateParameter.midiChannel = channel;
  162. }
  163. else if (pTag == "midiCC")
  164. {
  165. bool ok;
  166. int cc = pText.toInt(&ok);
  167. if (ok && cc < INT16_MAX)
  168. stateParameter.midiCC = cc;
  169. }
  170. xmlSubData = xmlSubData.nextSibling();
  171. }
  172. saveState.parameters.append(stateParameter);
  173. }
  174. // ----------------------------------------------
  175. // Custom Data
  176. else if (tag == "CustomData")
  177. {
  178. CarlaStateCustomData stateCustomData;
  179. QDomNode xmlSubData(xmlData.toElement().firstChild());
  180. while (! xmlSubData.isNull())
  181. {
  182. const QString cTag = xmlSubData.toElement().tagName();
  183. const QString cText = xmlSubData.toElement().text(); //.strip();
  184. if (cTag == "type")
  185. stateCustomData.type = xmlSafeString(cText, false);
  186. else if (cTag == "key")
  187. stateCustomData.key = xmlSafeString(cText, false);
  188. else if (cTag == "value")
  189. stateCustomData.value = xmlSafeString(cText, false);
  190. xmlSubData = xmlSubData.nextSibling();
  191. }
  192. saveState.customData.append(stateCustomData);
  193. }
  194. // ----------------------------------------------
  195. // Chunk
  196. else if (tag == "Chunk")
  197. {
  198. saveState.chunk = xmlSafeString(text, false);
  199. }
  200. // ----------------------------------------------
  201. xmlData = xmlData.nextSibling();
  202. }
  203. }
  204. // ------------------------------------------------------
  205. node = node.nextSibling();
  206. }
  207. return &saveState;
  208. }
  209. QString xmlSafeString(QString string, const bool toXml)
  210. {
  211. if (toXml)
  212. return string.replace("&", "&amp;").replace("<","&lt;").replace(">","&gt;").replace("'","&apos;").replace("\"","&quot;");
  213. else
  214. return string.replace("&amp;", "&").replace("&lt;","<").replace("&gt;",">").replace("&apos;","'").replace("&quot;","\"");
  215. }
  216. // ------------------------------------------------------------------------------------------------------------
  217. // Plugin Query (helper functions)
  218. char* findDSSIGUI(const char* const filename, const char* const name, const char* const label)
  219. {
  220. static QString guiFilename;
  221. guiFilename.clear();
  222. QString pluginDir(filename);
  223. pluginDir.resize(pluginDir.lastIndexOf("."));
  224. QString shortName = QFileInfo(pluginDir).baseName();
  225. QString checkName = QString(name).replace(" ", "_");
  226. QString checkLabel = QString(label);
  227. QString checkSName = shortName;
  228. if (! checkName.endsWith("_")) checkName += "_";
  229. if (! checkLabel.endsWith("_")) checkLabel += "_";
  230. if (! checkSName.endsWith("_")) checkSName += "_";
  231. QStringList guiFiles = QDir(pluginDir).entryList();
  232. foreach (const QString& gui, guiFiles)
  233. {
  234. if (gui.startsWith(checkName) || gui.startsWith(checkLabel) || gui.startsWith(checkSName))
  235. {
  236. QFileInfo finalname(pluginDir + QDir::separator() + gui);
  237. guiFilename = finalname.absoluteFilePath();
  238. break;
  239. }
  240. }
  241. if (guiFilename.isEmpty())
  242. return nullptr;
  243. return strdup(guiFilename.toUtf8().constData());
  244. }