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.

485 lines
15KB

  1. /*
  2. Copyright (C) 2009 Rory Walsh
  3. Cabbage is free software; you can redistribute it
  4. and/or modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. Cabbage is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with Csound; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  14. 02111-1307 USA
  15. */
  16. #ifndef __PLUGINPROCESSOR_H_FE85D052__
  17. #define __PLUGINPROCESSOR_H_FE85D052__
  18. #include "../JuceHeader.h"
  19. #include "../CabbageUtils.h"
  20. #include "../CabbageGUIClass.h"
  21. #include "../Editor/CodeEditor.h"
  22. #include "../XYPadAutomation.h"
  23. #include "../CabbageMessageSystem.h"
  24. #include "../Soundfiler.h"
  25. #include "CabbageGenericAudioProcessorEditor.h"
  26. #include "../CabbageLookAndFeel.h"
  27. #ifndef Cabbage_No_Csound
  28. #include <csound.hpp>
  29. #include "cwindow.h"
  30. #include "../csPerfThread.hpp"
  31. #endif
  32. //#ifndef Cabbage_Build_Standalone
  33. //#include "../Editor/CabbageEditorWindow.h"
  34. //#endif
  35. #define CABBAGE_VERSION "Cabbage v0.5.07 Alpha"
  36. #define AUDIO_PLUGIN 1
  37. #define EXTERNAL_PLUGIN 2
  38. #define AUTOMATION_PLUGIN 3
  39. #ifdef Cabbage_Build_Standalone
  40. class CsoundCodeEditor;
  41. #endif
  42. extern CabbageLookAndFeel* lookAndFeel;
  43. extern CabbageLookAndFeelBasic* lookAndFeelBasic;
  44. //==============================================================================
  45. // CabbagePluginAudioProcessor definition
  46. //==============================================================================
  47. class CabbagePluginAudioProcessor : public AudioProcessor,
  48. public CabbageUtils,
  49. public ChangeBroadcaster,
  50. public Timer,
  51. public ActionBroadcaster,
  52. public ChangeListener
  53. {
  54. //==============================================================================
  55. protected:
  56. File csdFile;
  57. int masterCounter;
  58. String filename;
  59. String pluginName;
  60. bool csoundStatus;
  61. int csCompileResult;
  62. void timerCallback();
  63. String csoundOutput;
  64. void changeListenerCallback(ChangeBroadcaster *source);
  65. String changeMessageType;
  66. bool guiON;
  67. int currentLine;
  68. bool xyAutosCreated;
  69. bool updateTable;
  70. Array<int> tableNumbers;
  71. AudioSourceChannelInfo soundfilerChannelData;
  72. AudioPlayHead::CurrentPositionInfo hostInfo;
  73. int soundFileIndex;
  74. //ScopedPointer<FileLogger> fileLogger;
  75. File logFile;
  76. bool isAutomator;
  77. bool isNativeThreadRunning;
  78. //============== Csound related variables/methods ==============================
  79. #ifndef Cabbage_No_Csound
  80. ScopedPointer<CSOUND_PARAMS> csoundParams;
  81. ScopedPointer<CsoundPerformanceThread> csoundPerfThread;
  82. PVSDATEXT* dataout;
  83. MYFLT cs_scale;
  84. ScopedPointer<Csound> csound; //Csound instance
  85. MYFLT *CSspin, *CSspout; //Csound audio IO pointers
  86. int csndIndex; //Csound sample counter
  87. int csdKsmps;
  88. MYFLT *soundFilerTempVector;
  89. int CSCompResult; //result of Csound performKsmps
  90. controlChannelInfo_s* csoundChanList;
  91. int numCsoundChannels; //number of Csound channels
  92. static void messageCallback(CSOUND *csound, int attr, const char *fmt, va_list args); //message callback function
  93. int pos;
  94. //Csound API functions for deailing with midi input
  95. static int OpenMidiInputDevice(CSOUND * csnd, void **userData, const char *devName);
  96. static int OpenMidiOutputDevice(CSOUND * csnd, void **userData, const char *devName);
  97. static int ReadMidiData(CSOUND *csound, void *userData, unsigned char *mbuf, int nbytes);
  98. static int WriteMidiData(CSOUND *csound, void *userData, const unsigned char *mbuf, int nbytes);
  99. int getNumberCsoundOutChannels(){
  100. return csound->GetNchnls();
  101. }
  102. int getNumberCsoundInChannels(){
  103. //return csound->GetInNchnls();
  104. }
  105. int getCsoundSamplingRate(){
  106. return csound->GetSr();
  107. }
  108. int getCsoundKsmpsSize(){
  109. return csound->GetKsmps();
  110. }
  111. #endif
  112. static void YieldCallback(void* data);
  113. void updateCabbageControls();
  114. void sendOutgoingMessagesToCsound();
  115. void sendAudioToCsoundFromSoundFilers(int numSamples);
  116. StringArray debugInfo;
  117. //basic classes that hold all information regarding GUI objects
  118. //guiLayoutControls are not used to send data to Csound, and don't show
  119. //as parameters in a host, guiCtrls do show are parameters, and can send
  120. //channel messages to Csound.
  121. Array<CabbageGUIClass, CriticalSection> guiLayoutCtrls;
  122. Array<CabbageGUIClass, CriticalSection> guiCtrls;
  123. String plantFlag, presetFlag;
  124. String debugMessage;
  125. StringArray debugMessageArray;
  126. String currentLineText;
  127. bool editorReOpened;
  128. OwnedArray<XYPadAutomation, CriticalSection> xyAutomation;
  129. void updateGUIControlsKsmps(int speed);
  130. int guiRefreshRate;
  131. public:
  132. //==============================================================================
  133. #if defined(Cabbage_Build_Standalone) || (Cabbage_Plugin_Host)
  134. CabbagePluginAudioProcessor(String inputfile, bool guiOnOff, int pluginType);
  135. #else
  136. CabbagePluginAudioProcessor();
  137. #endif
  138. ~CabbagePluginAudioProcessor();
  139. #ifdef Cabbage_Build_Standalone
  140. CsoundCodeEditor* codeEditor;
  141. #endif
  142. bool haveXYAutosBeenCreated(){
  143. return xyAutosCreated;
  144. }
  145. void setHaveXYAutoBeenCreated(bool val){
  146. xyAutosCreated = val;
  147. }
  148. double getTailLengthSeconds(void) const {
  149. return 1;
  150. }
  151. int performEntireScore();
  152. void reCompileCsound(File file);
  153. void setupNativePluginEditor();
  154. //==============================================================================
  155. void prepareToPlay (double sampleRate, int samplesPerBlock);
  156. void releaseResources();
  157. virtual void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
  158. //==============================================================================
  159. AudioProcessorEditor* createEditor();
  160. bool hasEditor() const;
  161. //==============================================================================
  162. const String getName() const;
  163. int getNumParameters();
  164. float getParameter (int index);
  165. void setParameter (int index, float newValue);
  166. const String getParameterName (int index);
  167. const String getParameterText (int index);
  168. const String getInputChannelName (int channelIndex) const;
  169. const String getOutputChannelName (int channelIndex) const;
  170. bool isInputChannelStereoPair (int index) const;
  171. bool isOutputChannelStereoPair (int index) const;
  172. bool acceptsMidi() const;
  173. bool producesMidi() const;
  174. Array<CabbagePatternMatrixStepData> patStepMatrix;
  175. StringArray patternNames;
  176. Array<CabbagePatternMatrixPfieldData> patPfieldMatrix;
  177. //Array<int> pField4, pField5, pField6, pField7;
  178. int noSteps;
  179. int noPatterns;
  180. int timeCounter;
  181. int beat;
  182. int patMatrixActive;
  183. float bpm;
  184. //==============================================================================
  185. int getNumPrograms();
  186. int getCurrentProgram();
  187. void setCurrentProgram (int index);
  188. const String getProgramName (int index);
  189. void changeProgramName (int index, const String& newName);
  190. //==============================================================================
  191. void getStateInformation (MemoryBlock& destData);
  192. void setStateInformation (const void* data, int sizeInBytes);
  193. const Array<double, CriticalSection> getTable(int tableNum);
  194. void createGUI(String source, bool refresh);
  195. MidiKeyboardState keyboardState;
  196. //midiBuffers
  197. MidiBuffer midiBuffer;
  198. MidiBuffer midiOutputBuffer;
  199. MidiBuffer ccBuffer;
  200. bool showMIDI;
  201. bool yieldCallbackBool;
  202. int yieldCounter;
  203. bool nativePluginEditor;
  204. CabbageMessageQueue messageQueue;
  205. OwnedArray<CabbageAudioSource, CriticalSection> audioSourcesArray;
  206. void addSoundfilerSource(String filename, StringArray channels);
  207. StringArray scoreEvents;
  208. int averageSampleIndex;
  209. float outputNo1;
  210. int pluginType;
  211. float automationAmp;
  212. int automationParamID;
  213. int pluginCalls, csoundCalls;
  214. //==============================================================================
  215. File getCsoundInputFile(){
  216. return csdFile;
  217. }
  218. inline String getCsoundInputFileText(){
  219. String ret="";
  220. #ifdef Cabbage_Build_Standalone
  221. if(codeEditor)
  222. ret = codeEditor->getAllText();
  223. else
  224. ret = csdFile.loadFileAsString();
  225. #endif
  226. return ret;
  227. }
  228. void updateCsoundFile(String text){
  229. //csdFile.replaceWithText(text);
  230. #ifdef Cabbage_Build_Standalone
  231. //codeEditor->textChanged = true;
  232. codeEditor->setAllText(text);
  233. #endif
  234. }
  235. bool hasTextChanged(){
  236. #ifdef Cabbage_Build_Standalone
  237. if(codeEditor)
  238. return codeEditor->textChanged;
  239. else return false;
  240. #else
  241. return false;
  242. #endif
  243. }
  244. void saveText(){
  245. #ifdef Cabbage_Build_Standalone
  246. codeEditor->textChanged = false;
  247. #endif
  248. }
  249. void setOpcodeDirEnv(){
  250. #ifdef WIN32
  251. //showMessage(getenv("OPCODE6DIR64"));
  252. String opcodeDir = File::getSpecialLocation(File::currentExecutableFile).getParentDirectory().getFullPathName()+"\\CsoundPlugins";
  253. //showMessage(opcodeDir);
  254. if(File(opcodeDir).exists()){
  255. String env = "OPCODE6DIR64="+opcodeDir;
  256. _putenv(env.toUTF8().getAddress());
  257. //showMessage(getenv("OPCODE6DIR64"));
  258. }
  259. #endif
  260. }
  261. void highlightLine(String text){
  262. #ifdef Cabbage_Build_Standalone
  263. codeEditor->highlightLine(text);
  264. #endif
  265. }
  266. String getDebugMessage(){
  267. return debugMessage;
  268. }
  269. void addDebugMessage(String message){
  270. debugMessageArray.add(message);;
  271. }
  272. StringArray getDebugMessageArray(){
  273. return debugMessageArray;
  274. }
  275. void clearDebugMessageArray(){
  276. debugMessageArray.clear();
  277. }
  278. int getCompileStatus(){
  279. return csCompileResult;
  280. }
  281. void clearDebugMessage(){
  282. debugMessage="";
  283. }
  284. void setPluginName(String name){
  285. pluginName = name;
  286. }
  287. String getPluginName(){
  288. return pluginName;
  289. }
  290. Array<Array <float > > tableArrays;
  291. Array<float> getTableArray(int index){
  292. return tableArrays[index];
  293. }
  294. void setMidiDebug(bool val){
  295. showMIDI=val;
  296. }
  297. bool getMidiDebug(){
  298. return showMIDI;
  299. }
  300. //======== log information about GUI controls ===============
  301. StringArray logGUIAttributes(CabbageGUIClass cAttr, String type){
  302. StringArray arr;
  303. /*
  304. arr.add(String("----------- ")+type+String(" -----------"));
  305. arr.add(String("Name:")+cAttr.getStringProp("name")+String(", Type:")+cAttr.getStringProp("type")+String(", Caption:")+cAttr.getStringProp("caption")+String(", RelToPlant:")+cAttr.getStringProp("reltoplant")+String(", Plant:")+cAttr.getStringProp("plant"));
  306. arr.add(String("PosX:")+String(cAttr.getNumProp("left"))+String(", PosY:")+String(cAttr.getNumProp("top"))+String(", Width:")+String(cAttr.getNumProp("width"))+String(", Height:")+String(cAttr.getNumProp("height")));
  307. */
  308. arr.add(String(" "));
  309. //Logger::writeToLog(String("----------- ")+type+String(" -----------"));
  310. //Logger::writeToLog(String("Name:")+cAttr.getStringProp("name")+String(", Type:")+cAttr.getStringProp("type")+String(", Caption:")+cAttr.getStringProp("caption")+String(", RelToPlant:")+cAttr.getStringProp("reltoplant")+String(", Plant:")+cAttr.getStringProp("plant"));
  311. //Logger::writeToLog(String("PosX:")+String(cAttr.getNumProp("left"))+String(", PosY:")+String(cAttr.getNumProp("top"))+String(", Width:")+String(cAttr.getNumProp("width"))+String(", Height:")+String(cAttr.getNumProp("height")));
  312. //Logger::writeToLog(" ");
  313. return arr;
  314. }
  315. inline bool getCsoundStatus(){
  316. return csoundStatus;
  317. }
  318. //===========================================================
  319. inline int getGUICtrlsSize(){
  320. return (int)guiCtrls.size();
  321. }
  322. inline int getGUILayoutCtrlsSize(){
  323. return (int)guiLayoutCtrls.size();
  324. }
  325. inline CabbageGUIClass &getGUILayoutCtrls(int index){
  326. return guiLayoutCtrls.getReference(index);
  327. }
  328. inline CabbageGUIClass &getGUICtrls(int index){
  329. return guiCtrls.getReference(index);
  330. }
  331. inline String getChangeMessageType(){
  332. return changeMessageType;
  333. }
  334. inline String getCsoundOutput(){
  335. return csoundOutput;
  336. }
  337. inline void setChangeMessageType(String text){
  338. changeMessageType = text;
  339. }
  340. inline int getCurrentLine(){
  341. return currentLine;
  342. }
  343. inline void setCurrentLine(int line){
  344. currentLine = line;
  345. }
  346. inline void setCurrentLineText(String lineText){
  347. currentLineText = lineText;
  348. }
  349. String getCurrentLineText(){
  350. return currentLineText;
  351. }
  352. void removeGUIComponent(int index, String type);
  353. #ifndef Cabbage_No_Csound
  354. Csound* getCsound(){
  355. return csound;
  356. }
  357. CSOUND* getCsoundStruct(){
  358. return csound->GetCsound();
  359. }
  360. MYFLT getCSScale(){
  361. return cs_scale;
  362. }
  363. PVSDATEXT* getPVSDataOut(){
  364. return dataout;
  365. }
  366. #endif
  367. void addLayoutCtrl(CabbageGUIClass cAttr){
  368. guiLayoutCtrls.add(cAttr);
  369. }
  370. void addGUICtrl(CabbageGUIClass cAttr){
  371. guiCtrls.add(cAttr);
  372. }
  373. bool isGuiEnabled(){
  374. return guiON;
  375. }
  376. void setGuiEnabled(bool val);
  377. void addXYAutomater(XYPadAutomation* xyAuto){
  378. xyAutomation.add(xyAuto);
  379. }
  380. XYPadAutomation* getXYAutomater(int index){
  381. return xyAutomation[index];
  382. }
  383. int getXYAutomaterSize(){
  384. return xyAutomation.size();
  385. }
  386. void removeXYAutomaters(){
  387. xyAutomation.clear();
  388. }
  389. bool silenceInProducesSilenceOut() const{
  390. return true;
  391. }
  392. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CabbagePluginAudioProcessor);
  393. };
  394. //pecial auotmation only plugin type. Does not output any audio.
  395. #ifdef Cabbage_Host
  396. class CabbagePluginAutomationProcessor : public CabbagePluginAudioProcessor
  397. {
  398. public:
  399. CabbagePluginAutomationProcessor(AudioProcessor* filter, String inputfile, int pluginType):
  400. CabbagePluginAudioProcessor(inputfile, false, pluginType)
  401. {}
  402. ~CabbagePluginAutomationProcessor(){}
  403. };
  404. #endif
  405. #endif // __PLUGINPROCESSOR_H_FE85D052__