The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

335 lines
10KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-10 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #include "../../core/juce_StandardHeader.h"
  19. BEGIN_JUCE_NAMESPACE
  20. #include "juce_AudioProcessor.h"
  21. #include "../../threads/juce_ScopedLock.h"
  22. #include "../../text/juce_XmlDocument.h"
  23. //==============================================================================
  24. AudioProcessor::AudioProcessor()
  25. : playHead (0),
  26. activeEditor (0),
  27. sampleRate (0),
  28. blockSize (0),
  29. numInputChannels (0),
  30. numOutputChannels (0),
  31. latencySamples (0),
  32. suspended (false),
  33. nonRealtime (false)
  34. {
  35. }
  36. AudioProcessor::~AudioProcessor()
  37. {
  38. // ooh, nasty - the editor should have been deleted before the filter
  39. // that it refers to is deleted..
  40. jassert (activeEditor == 0);
  41. #ifdef JUCE_DEBUG
  42. // This will fail if you've called beginParameterChangeGesture() for one
  43. // or more parameters without having made a corresponding call to endParameterChangeGesture...
  44. jassert (changingParams.countNumberOfSetBits() == 0);
  45. #endif
  46. }
  47. void AudioProcessor::setPlayHead (AudioPlayHead* const newPlayHead) throw()
  48. {
  49. playHead = newPlayHead;
  50. }
  51. void AudioProcessor::addListener (AudioProcessorListener* const newListener) throw()
  52. {
  53. const ScopedLock sl (listenerLock);
  54. listeners.addIfNotAlreadyThere (newListener);
  55. }
  56. void AudioProcessor::removeListener (AudioProcessorListener* const listenerToRemove) throw()
  57. {
  58. const ScopedLock sl (listenerLock);
  59. listeners.removeValue (listenerToRemove);
  60. }
  61. void AudioProcessor::setPlayConfigDetails (const int numIns,
  62. const int numOuts,
  63. const double sampleRate_,
  64. const int blockSize_) throw()
  65. {
  66. numInputChannels = numIns;
  67. numOutputChannels = numOuts;
  68. sampleRate = sampleRate_;
  69. blockSize = blockSize_;
  70. }
  71. void AudioProcessor::setNonRealtime (const bool nonRealtime_) throw()
  72. {
  73. nonRealtime = nonRealtime_;
  74. }
  75. void AudioProcessor::setLatencySamples (const int newLatency)
  76. {
  77. if (latencySamples != newLatency)
  78. {
  79. latencySamples = newLatency;
  80. updateHostDisplay();
  81. }
  82. }
  83. void AudioProcessor::setParameterNotifyingHost (const int parameterIndex,
  84. const float newValue)
  85. {
  86. setParameter (parameterIndex, newValue);
  87. sendParamChangeMessageToListeners (parameterIndex, newValue);
  88. }
  89. void AudioProcessor::sendParamChangeMessageToListeners (const int parameterIndex, const float newValue)
  90. {
  91. jassert (((unsigned int) parameterIndex) < (unsigned int) getNumParameters());
  92. for (int i = listeners.size(); --i >= 0;)
  93. {
  94. AudioProcessorListener* l;
  95. {
  96. const ScopedLock sl (listenerLock);
  97. l = (AudioProcessorListener*) listeners [i];
  98. }
  99. if (l != 0)
  100. l->audioProcessorParameterChanged (this, parameterIndex, newValue);
  101. }
  102. }
  103. void AudioProcessor::beginParameterChangeGesture (int parameterIndex)
  104. {
  105. jassert (((unsigned int) parameterIndex) < (unsigned int) getNumParameters());
  106. #ifdef JUCE_DEBUG
  107. // This means you've called beginParameterChangeGesture twice in succession without a matching
  108. // call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it.
  109. jassert (! changingParams [parameterIndex]);
  110. changingParams.setBit (parameterIndex);
  111. #endif
  112. for (int i = listeners.size(); --i >= 0;)
  113. {
  114. AudioProcessorListener* l;
  115. {
  116. const ScopedLock sl (listenerLock);
  117. l = (AudioProcessorListener*) listeners [i];
  118. }
  119. if (l != 0)
  120. l->audioProcessorParameterChangeGestureBegin (this, parameterIndex);
  121. }
  122. }
  123. void AudioProcessor::endParameterChangeGesture (int parameterIndex)
  124. {
  125. jassert (((unsigned int) parameterIndex) < (unsigned int) getNumParameters());
  126. #ifdef JUCE_DEBUG
  127. // This means you've called endParameterChangeGesture without having previously called
  128. // endParameterChangeGesture. That might be fine in most hosts, but better to keep the
  129. // calls matched correctly.
  130. jassert (changingParams [parameterIndex]);
  131. changingParams.clearBit (parameterIndex);
  132. #endif
  133. for (int i = listeners.size(); --i >= 0;)
  134. {
  135. AudioProcessorListener* l;
  136. {
  137. const ScopedLock sl (listenerLock);
  138. l = (AudioProcessorListener*) listeners [i];
  139. }
  140. if (l != 0)
  141. l->audioProcessorParameterChangeGestureEnd (this, parameterIndex);
  142. }
  143. }
  144. void AudioProcessor::updateHostDisplay()
  145. {
  146. for (int i = listeners.size(); --i >= 0;)
  147. {
  148. AudioProcessorListener* l;
  149. {
  150. const ScopedLock sl (listenerLock);
  151. l = (AudioProcessorListener*) listeners [i];
  152. }
  153. if (l != 0)
  154. l->audioProcessorChanged (this);
  155. }
  156. }
  157. bool AudioProcessor::isParameterAutomatable (int /*parameterIndex*/) const
  158. {
  159. return true;
  160. }
  161. bool AudioProcessor::isMetaParameter (int /*parameterIndex*/) const
  162. {
  163. return false;
  164. }
  165. void AudioProcessor::suspendProcessing (const bool shouldBeSuspended)
  166. {
  167. const ScopedLock sl (callbackLock);
  168. suspended = shouldBeSuspended;
  169. }
  170. void AudioProcessor::reset()
  171. {
  172. }
  173. //==============================================================================
  174. void AudioProcessor::editorBeingDeleted (AudioProcessorEditor* const editor) throw()
  175. {
  176. const ScopedLock sl (callbackLock);
  177. jassert (activeEditor == editor);
  178. if (activeEditor == editor)
  179. activeEditor = 0;
  180. }
  181. AudioProcessorEditor* AudioProcessor::createEditorIfNeeded()
  182. {
  183. if (activeEditor != 0)
  184. return activeEditor;
  185. AudioProcessorEditor* const ed = createEditor();
  186. if (ed != 0)
  187. {
  188. // you must give your editor comp a size before returning it..
  189. jassert (ed->getWidth() > 0 && ed->getHeight() > 0);
  190. const ScopedLock sl (callbackLock);
  191. activeEditor = ed;
  192. }
  193. return ed;
  194. }
  195. //==============================================================================
  196. void AudioProcessor::getCurrentProgramStateInformation (JUCE_NAMESPACE::MemoryBlock& destData)
  197. {
  198. getStateInformation (destData);
  199. }
  200. void AudioProcessor::setCurrentProgramStateInformation (const void* data, int sizeInBytes)
  201. {
  202. setStateInformation (data, sizeInBytes);
  203. }
  204. //==============================================================================
  205. // magic number to identify memory blocks that we've stored as XML
  206. const uint32 magicXmlNumber = 0x21324356;
  207. void AudioProcessor::copyXmlToBinary (const XmlElement& xml,
  208. JUCE_NAMESPACE::MemoryBlock& destData)
  209. {
  210. const String xmlString (xml.createDocument (String::empty, true, false));
  211. const int stringLength = xmlString.getNumBytesAsUTF8();
  212. destData.setSize (stringLength + 10);
  213. char* const d = (char*) destData.getData();
  214. *(uint32*) d = ByteOrder::swapIfBigEndian ((const uint32) magicXmlNumber);
  215. *(uint32*) (d + 4) = ByteOrder::swapIfBigEndian ((const uint32) stringLength);
  216. xmlString.copyToUTF8 (d + 8, stringLength + 1);
  217. }
  218. XmlElement* AudioProcessor::getXmlFromBinary (const void* data,
  219. const int sizeInBytes)
  220. {
  221. if (sizeInBytes > 8
  222. && ByteOrder::littleEndianInt (data) == magicXmlNumber)
  223. {
  224. const int stringLength = (int) ByteOrder::littleEndianInt (((const char*) data) + 4);
  225. if (stringLength > 0)
  226. {
  227. XmlDocument doc (String::fromUTF8 (((const char*) data) + 8,
  228. jmin ((sizeInBytes - 8), stringLength)));
  229. return doc.getDocumentElement();
  230. }
  231. }
  232. return 0;
  233. }
  234. //==============================================================================
  235. void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int)
  236. {
  237. }
  238. void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor*, int)
  239. {
  240. }
  241. //==============================================================================
  242. bool AudioPlayHead::CurrentPositionInfo::operator== (const CurrentPositionInfo& other) const throw()
  243. {
  244. return timeInSeconds == other.timeInSeconds
  245. && ppqPosition == other.ppqPosition
  246. && editOriginTime == other.editOriginTime
  247. && ppqPositionOfLastBarStart == other.ppqPositionOfLastBarStart
  248. && frameRate == other.frameRate
  249. && isPlaying == other.isPlaying
  250. && isRecording == other.isRecording
  251. && bpm == other.bpm
  252. && timeSigNumerator == other.timeSigNumerator
  253. && timeSigDenominator == other.timeSigDenominator;
  254. }
  255. bool AudioPlayHead::CurrentPositionInfo::operator!= (const CurrentPositionInfo& other) const throw()
  256. {
  257. return ! operator== (other);
  258. }
  259. void AudioPlayHead::CurrentPositionInfo::resetToDefault()
  260. {
  261. zerostruct (*this);
  262. timeSigNumerator = 4;
  263. timeSigDenominator = 4;
  264. bpm = 120;
  265. }
  266. END_JUCE_NAMESPACE