|
|
@@ -70,8 +70,10 @@ pluginType(_pluginType), |
|
|
|
automationAmp(0),
|
|
|
|
isAutomator(false),
|
|
|
|
automationParamID(-1),
|
|
|
|
debugMessage("")
|
|
|
|
debugMessage(""),
|
|
|
|
guiRefreshRate(20)
|
|
|
|
{
|
|
|
|
//suspendProcessing(true);
|
|
|
|
codeEditor = nullptr;
|
|
|
|
#ifdef Cabbage_Logger
|
|
|
|
logFile = File((appProperties->getCommonSettings(true)->getFile().getParentDirectory().getFullPathName()+"/CabbageLog.txt"));
|
|
|
@@ -98,7 +100,7 @@ csound->SetHostImplementedMIDIIO(true); |
|
|
|
csound->Reset();
|
|
|
|
//Logger::writeToLog(csound->GetEnv("OPCODEDIR64"));
|
|
|
|
#ifdef CSOUND5
|
|
|
|
csound->PreCompile();
|
|
|
|
csound->PreCompile();
|
|
|
|
#endif
|
|
|
|
csound->SetHostData(this);
|
|
|
|
csound->SetMessageCallback(CabbagePluginAudioProcessor::messageCallback);
|
|
|
@@ -107,7 +109,6 @@ csound->SetExternalMidiReadCallback(ReadMidiData); |
|
|
|
csound->SetExternalMidiOutOpenCallback(OpenMidiOutputDevice);
|
|
|
|
csound->SetExternalMidiWriteCallback(WriteMidiData);
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef Cabbage_Plugin_Host
|
|
|
|
if(!getPreference(appProperties, "UseCabbageIO")){
|
|
|
|
csoundPerfThread = new CsoundPerformanceThread(csound);
|
|
|
@@ -125,7 +126,7 @@ csndIndex = 32; |
|
|
|
//set up PVS struct
|
|
|
|
dataout = new PVSDATEXT;
|
|
|
|
|
|
|
|
if(!inputfile.isEmpty()){
|
|
|
|
if(inputfile.isNotEmpty()){
|
|
|
|
File(inputfile).setAsCurrentWorkingDirectory();
|
|
|
|
#ifdef CSOUND6
|
|
|
|
csoundParams = new CSOUND_PARAMS();
|
|
|
@@ -136,6 +137,7 @@ csCompileResult = csound->Compile(const_cast<char*>(inputfile.toUTF8().getAddres |
|
|
|
|
|
|
|
if(csCompileResult==0){
|
|
|
|
|
|
|
|
//send root directory path to Csound.
|
|
|
|
setPlayConfigDetails(getNumberCsoundOutChannels(),
|
|
|
|
getNumberCsoundOutChannels(),
|
|
|
|
getCsoundSamplingRate(),
|
|
|
@@ -145,8 +147,13 @@ if(csCompileResult==0){ |
|
|
|
csound->PerformKsmps();
|
|
|
|
csound->SetScoreOffsetSeconds(0);
|
|
|
|
csound->RewindScore();
|
|
|
|
#ifdef WIN32
|
|
|
|
csound->SetChannel("CSD_PATH", File(inputfile).getParentDirectory().getFullPathName().replace("\\", "\\\\").toUTF8().getAddress());
|
|
|
|
#else
|
|
|
|
csound->SetChannel("CSD_PATH", File(inputfile).getParentDirectory().getFullPathName().toUTF8().getAddress());
|
|
|
|
#endif
|
|
|
|
Logger::writeToLog("Csound compiled your file");
|
|
|
|
|
|
|
|
|
|
|
|
//csound->SetYieldCallback(CabbagePluginAudioProcessor::yieldCallback);
|
|
|
|
if(csound->GetSpout()==nullptr);
|
|
|
|
CSspout = csound->GetSpout();
|
|
|
@@ -159,6 +166,9 @@ if(csCompileResult==0){ |
|
|
|
csoundStatus = true;
|
|
|
|
debugMessageArray.add(CABBAGE_VERSION);
|
|
|
|
debugMessageArray.add(String("\n"));
|
|
|
|
this->setLatencySamples(csound->GetKsmps());
|
|
|
|
updateHostDisplay();
|
|
|
|
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
Logger::writeToLog("Csound couldn't compile your file");
|
|
|
@@ -263,9 +273,12 @@ csoundParams->nchnls_override =2; |
|
|
|
csound->SetParams(csoundParams);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
csdFile.setAsCurrentWorkingDirectory();
|
|
|
|
|
|
|
|
csCompileResult = csound->Compile(const_cast<char*>(csdFile.getFullPathName().toUTF8().getAddress()));
|
|
|
|
csdFile.setAsCurrentWorkingDirectory();
|
|
|
|
if(csCompileResult==0){
|
|
|
|
|
|
|
|
Logger::writeToLog("compiled Ok");
|
|
|
|
keyboardState.allNotesOff(0);
|
|
|
|
keyboardState.reset();
|
|
|
@@ -283,10 +296,30 @@ if(csCompileResult==0){ |
|
|
|
cs_scale = csound->Get0dBFS();
|
|
|
|
numCsoundChannels = csoundListChannels(csound->GetCsound(), &csoundChanList);
|
|
|
|
csndIndex = csound->GetKsmps();
|
|
|
|
this->setLatencySamples(csound->GetKsmps());
|
|
|
|
updateHostDisplay();
|
|
|
|
//soundFilerVector = new MYFLT[csdKsmps];
|
|
|
|
csoundStatus = true;
|
|
|
|
debugMessageArray.add(VERSION);
|
|
|
|
debugMessageArray.add(String("\n"));
|
|
|
|
#ifdef WIN32
|
|
|
|
csound->SetChannel("CSD_PATH", File(csdFile).getParentDirectory().getFullPathName().replace("\\", "\\\\").toUTF8().getAddress());
|
|
|
|
#else
|
|
|
|
csound->SetChannel("CSD_PATH", File(csdFile).getParentDirectory().getFullPathName().toUTF8().getAddress());
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//send host info before performance..
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(CabbageIDs::hostbpm.toUTF8(), hostInfo.bpm);
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(CabbageIDs::timeinseconds.toUTF8(), hostInfo.timeInSeconds);
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(CabbageIDs::isplaying.toUTF8(), hostInfo.isPlaying);
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(CabbageIDs::isrecording.toUTF8(), hostInfo.isRecording);
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(CabbageIDs::hostppqpos.toUTF8(), hostInfo.ppqPosition);
|
|
|
|
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
Logger::writeToLog("Csound couldn't compile your file");
|
|
|
@@ -367,12 +400,12 @@ void CabbagePluginAudioProcessor::YieldCallback(void* data){ |
|
|
|
void CabbagePluginAudioProcessor::reCompileCsound(File file)
|
|
|
|
{
|
|
|
|
#ifndef Cabbage_No_Csound
|
|
|
|
this->suspendProcessing(true);
|
|
|
|
suspendProcessing(true);
|
|
|
|
soundFileIndex = 0;
|
|
|
|
midiOutputBuffer.clear();
|
|
|
|
getCallbackLock().enter();
|
|
|
|
csound->DeleteChannelList(csoundChanList);
|
|
|
|
//csound->SetHostImplementedMIDIIO(true);
|
|
|
|
csound->SetHostImplementedMIDIIO(true);
|
|
|
|
|
|
|
|
csound->Reset();
|
|
|
|
xyAutosCreated = false;
|
|
|
@@ -394,6 +427,7 @@ if(csCompileResult==0){ |
|
|
|
//simple hack to allow tables to be set up correctly.
|
|
|
|
keyboardState.allNotesOff(0);
|
|
|
|
keyboardState.reset();
|
|
|
|
csndIndex = 0;
|
|
|
|
CSspout = csound->GetSpout();
|
|
|
|
CSspin = csound->GetSpin();
|
|
|
|
csound->PerformKsmps();
|
|
|
@@ -405,17 +439,24 @@ if(csCompileResult==0){ |
|
|
|
csoundStatus = true;
|
|
|
|
debugMessageArray.add(CABBAGE_VERSION);
|
|
|
|
debugMessageArray.add(String("\n"));
|
|
|
|
removeAllChangeListeners();
|
|
|
|
//removeAllChangeListeners();
|
|
|
|
getCallbackLock().exit();
|
|
|
|
|
|
|
|
//init all channels with their init val
|
|
|
|
for(int i=0;i<guiCtrls.size();i++)
|
|
|
|
{
|
|
|
|
csound->SetChannel( guiCtrls.getReference(i).getStringProp("channel").toUTF8(),
|
|
|
|
guiCtrls.getReference(i).getNumProp("value"));
|
|
|
|
csound->SetChannel( guiCtrls.getReference(i).getStringProp(CabbageIDs::channel).toUTF8(),
|
|
|
|
guiCtrls.getReference(i).getNumProp(CabbageIDs::value));
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
csound->SetChannel("CSD_PATH", file.getParentDirectory().getFullPathName().replace("\\", "\\\\").toUTF8().getAddress());
|
|
|
|
#else
|
|
|
|
csound->SetChannel("CSD_PATH", file.getParentDirectory().getFullPathName().toUTF8().getAddress());
|
|
|
|
#endif
|
|
|
|
|
|
|
|
this->suspendProcessing(false);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else{
|
|
|
@@ -431,6 +472,7 @@ getCallbackLock().exit(); |
|
|
|
// GUI OBJECTS ARE CREATED ON THE FLY IN THE CABBAGE PLUGIN
|
|
|
|
// EDITOR FROM INFORMATION HELD IN THE GUICONTROLS VECTOR
|
|
|
|
//===========================================================
|
|
|
|
//maybe this should only be done at the end of a k-rate cycle..
|
|
|
|
void CabbagePluginAudioProcessor::createGUI(String source, bool refresh)
|
|
|
|
{
|
|
|
|
//clear arrays if refresh is set
|
|
|
@@ -551,6 +593,8 @@ bool multiLine = false; |
|
|
|
nativePluginEditor = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(cAttr.getNumProp(CabbageIDs::guirefresh)>1)
|
|
|
|
guiRefreshRate = cAttr.getNumProp(CabbageIDs::guirefresh);
|
|
|
|
|
|
|
|
//showMessage(cAttr.getStringProp("type"));
|
|
|
|
csdLine = "";
|
|
|
@@ -564,11 +608,11 @@ bool multiLine = false; |
|
|
|
|
|
|
|
//set up stuff for tables
|
|
|
|
if(tokes[0].equalsIgnoreCase(String("table"))){
|
|
|
|
if(cAttr.getStringArrayProp("channel").size()==0)
|
|
|
|
if(cAttr.getStringArrayProp(CabbageIDs::channel).size()==0)
|
|
|
|
for(int i=0;i<cAttr.getIntArrayProp("tablenumber").size();i++)
|
|
|
|
cAttr.addDummyChannel("dummy"+String(i));
|
|
|
|
|
|
|
|
for(int i=0;i<cAttr.getStringArrayProp("channel").size();i++)
|
|
|
|
for(int i=0;i<cAttr.getStringArrayProp(CabbageIDs::channel).size();i++)
|
|
|
|
cAttr.addTableChannelValues();
|
|
|
|
|
|
|
|
|
|
|
@@ -614,7 +658,7 @@ bool multiLine = false; |
|
|
|
||tokes[0].equalsIgnoreCase(String("xypad"))
|
|
|
|
||tokes[0].equalsIgnoreCase(String("button"))){
|
|
|
|
CabbageGUIClass cAttr(csdLine.trimEnd(), guiID);
|
|
|
|
Logger::writeToLog(csdLine.trimEnd());
|
|
|
|
//Logger::writeToLog(csdLine.trimEnd());
|
|
|
|
csdLine = "";
|
|
|
|
//Logger::writeToLog(tokes[0]);
|
|
|
|
//attach widget to plant if need be
|
|
|
@@ -631,29 +675,29 @@ bool multiLine = false; |
|
|
|
//to our contorl vector so that plugin hosts display two sliders. We name one of the xypad pads
|
|
|
|
// 'dummy' so that our editor doesn't display it. Our editor only needs to show one xypad.
|
|
|
|
if(tokes[0].equalsIgnoreCase(String("xypad"))){
|
|
|
|
cAttr.setStringProp(String("xychannel"), String("X"));
|
|
|
|
cAttr.setNumProp("range", cAttr.getNumProp("rangex"));
|
|
|
|
cAttr.setNumProp("min", cAttr.getNumProp("minx"));
|
|
|
|
cAttr.setNumProp("max", cAttr.getNumProp("maxx"));
|
|
|
|
cAttr.setNumProp("value", cAttr.getNumProp("valuex"));
|
|
|
|
cAttr.setStringProp(String("channel"), cAttr.getStringProp("xchannel"));
|
|
|
|
cAttr.setStringProp(CabbageIDs::xychannel, String("X"));
|
|
|
|
cAttr.setNumProp(CabbageIDs::range, cAttr.getNumProp(CabbageIDs::rangex));
|
|
|
|
cAttr.setNumProp(CabbageIDs::min, cAttr.getNumProp(CabbageIDs::minx));
|
|
|
|
cAttr.setNumProp(CabbageIDs::max, cAttr.getNumProp(CabbageIDs::maxx));
|
|
|
|
cAttr.setNumProp(CabbageIDs::value, cAttr.getNumProp(CabbageIDs::valuex));
|
|
|
|
cAttr.setStringProp(String(CabbageIDs::channel), cAttr.getStringProp(CabbageIDs::xchannel));
|
|
|
|
guiCtrls.add(cAttr);
|
|
|
|
|
|
|
|
cAttr.setStringProp(String("xychannel"), String("Y"));
|
|
|
|
cAttr.setNumProp("range", cAttr.getNumProp("rangey"));
|
|
|
|
cAttr.setNumProp("min", cAttr.getNumProp("miny"));
|
|
|
|
cAttr.setNumProp("max", cAttr.getNumProp("maxy"));
|
|
|
|
cAttr.setNumProp("value", cAttr.getNumProp("valuey"));
|
|
|
|
cAttr.setStringProp(String("channel"), cAttr.getStringProp("ychannel"));
|
|
|
|
cAttr.setStringProp(CabbageIDs::xychannel, String("Y"));
|
|
|
|
cAttr.setNumProp(CabbageIDs::range, cAttr.getNumProp(CabbageIDs::rangey));
|
|
|
|
cAttr.setNumProp(CabbageIDs::min, cAttr.getNumProp(CabbageIDs::miny));
|
|
|
|
cAttr.setNumProp(CabbageIDs::max, cAttr.getNumProp(CabbageIDs::maxy));
|
|
|
|
cAttr.setNumProp(CabbageIDs::value, cAttr.getNumProp(CabbageIDs::valuey));
|
|
|
|
cAttr.setStringProp(String(CabbageIDs::channel), cAttr.getStringProp(CabbageIDs::ychannel));
|
|
|
|
//append 'dummy' to name so the editor know not to display the
|
|
|
|
//second xypad
|
|
|
|
cAttr.setStringProp("name", cAttr.getStringProp("name")+String("dummy"));
|
|
|
|
cAttr.setStringProp("name", cAttr.getStringProp(CabbageIDs::name)+String("dummy"));
|
|
|
|
guiCtrls.add(cAttr);
|
|
|
|
guiID++;
|
|
|
|
startTimer(10);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
Logger::writeToLog("Value:"+String(cAttr.getNumProp("value")));
|
|
|
|
//Logger::writeToLog("Value:"+String(cAttr.getNumProp(CabbageIDs::value)));
|
|
|
|
guiCtrls.add(cAttr);
|
|
|
|
guiID++;
|
|
|
|
}
|
|
|
@@ -697,12 +741,14 @@ bool multiLine = false; |
|
|
|
//init all channels with their init val, and set parameters
|
|
|
|
for(int i=0;i<guiCtrls.size();i++)
|
|
|
|
{
|
|
|
|
// Logger::writeToLog(guiCtrls.getReference(i).getStringProp("channel")+": "+String(guiCtrls[i].getNumProp("value")));
|
|
|
|
// Logger::writeToLog(guiCtrls.getReference(i).getStringProp(CabbageIDs::channel)+": "+String(guiCtrls[i].getNumProp(CabbageIDs::value)));
|
|
|
|
#ifndef Cabbage_No_Csound
|
|
|
|
csound->SetChannel( guiCtrls.getReference(i).getStringProp("channel").toUTF8(), guiCtrls[i].getNumProp("value"));
|
|
|
|
//float min = guiCtrls.getReference(i).getNumProp("min");
|
|
|
|
//float range = guiCtrls.getReference(i).getNumProp("range");
|
|
|
|
//setParameter(i, (guiCtrls.getReference(i).getNumProp("value")+min)/range);
|
|
|
|
if(guiCtrls.getReference(i).getStringProp("channeltype")=="string")
|
|
|
|
//deal with combobox strings..
|
|
|
|
csound->SetChannel(guiCtrls.getReference(i).getStringProp(CabbageIDs::channel).toUTF8(), "");
|
|
|
|
// guiCtrls.getReference(i).getStringArrayPropValue("text", guiCtrls[i].getNumProp(CabbageIDs::value)-1).toUTF8().getAddress());
|
|
|
|
else
|
|
|
|
csound->SetChannel( guiCtrls.getReference(i).getStringProp(CabbageIDs::channel).toUTF8(), guiCtrls[i].getNumProp(CabbageIDs::value));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
@@ -771,7 +817,7 @@ void CabbagePluginAudioProcessor::setupNativePluginEditor() |
|
|
|
Logger::writeToLog(parameterInfo);
|
|
|
|
CabbageGUIClass cAttr(parameterInfo, guiID);
|
|
|
|
cAttr.setNumProp("range", dmax-dmin);
|
|
|
|
//cAttr.setStringProp("channel", entry.name);
|
|
|
|
//cAttr.setStringProp(CabbageIDs::channel, entry.name);
|
|
|
|
//cAttr.setNumProp("max", (dmax>0 ? dmax : 1));
|
|
|
|
//cAttr.setNumProp("init", (ddefault<dmin ? dmin : ddefault));
|
|
|
|
|
|
|
@@ -872,8 +918,8 @@ void CabbagePluginAudioProcessor::changeListenerCallback(ChangeBroadcaster *sour |
|
|
|
else
|
|
|
|
yVal = (xyPad->getYValue()/xyPad->getYRange())-(fabs(xyPad->getMinimumYValue())/xyPad->getYRange());
|
|
|
|
|
|
|
|
Logger::writeToLog("Param:"+String(xyPad->paramIndex)+" xyPadXVal:"+String(xVal));
|
|
|
|
Logger::writeToLog("Param:"+String(xyPad->paramIndex+1)+" xyPadYVal:"+String(yVal));
|
|
|
|
//Logger::writeToLog("Param:"+String(xyPad->paramIndex)+" xyPadXVal:"+String(xVal));
|
|
|
|
//Logger::writeToLog("Param:"+String(xyPad->paramIndex+1)+" xyPadYVal:"+String(yVal));
|
|
|
|
|
|
|
|
setParameterNotifyingHost(xyPad->paramIndex, xVal);
|
|
|
|
setParameterNotifyingHost(xyPad->paramIndex+1, yVal);
|
|
|
@@ -905,21 +951,24 @@ const Array<double, CriticalSection> CabbagePluginAudioProcessor::getTable(int t |
|
|
|
//=================================================================================
|
|
|
|
float CabbagePluginAudioProcessor::getParameter (int index)
|
|
|
|
{
|
|
|
|
float range = getGUICtrls(index).getNumProp("range");
|
|
|
|
float min = getGUICtrls(index).getNumProp("min");
|
|
|
|
//Logger::writeToLog("parameterGet-"+String(index)+String("-Min:")+String(min)+" Range:"+String(range)+ " Val:"+String(getGUICtrls(index).getNumProp("value")));
|
|
|
|
//Logger::writeToLog("parameterGet:"+String(index)+String(":")+String(getGUICtrls(index).getNumProp("value")));
|
|
|
|
float range = getGUICtrls(index).getNumProp(CabbageIDs::range);
|
|
|
|
float min = getGUICtrls(index).getNumProp(CabbageIDs::min);
|
|
|
|
//Logger::writeToLog("parameterGet-"+String(index)+String("-Min:")+String(min)+" Range:"+String(range)+ " Val:"+String(getGUICtrls(index).getNumProp(CabbageIDs::value)));
|
|
|
|
//Logger::writeToLog("parameterGet:"+String(index)+String(":")+String(guiCtrls[index].getNumProp(CabbageIDs::value)));
|
|
|
|
|
|
|
|
/* this gets called at any time by our host or out GUI editor */
|
|
|
|
if(index<(int)guiCtrls.size()){//make sure index isn't out of range
|
|
|
|
#ifndef Cabbage_Build_Standalone
|
|
|
|
float val = (getGUICtrls(index).getNumProp("value")/range)-(min/range);
|
|
|
|
if(getGUICtrls(index).getStringProp("type")=="combobox")
|
|
|
|
return (getGUICtrls(index).getNumProp("value")/getGUICtrls(index).getNumProp("comborange"));
|
|
|
|
float val = (getGUICtrls(index).getNumProp(CabbageIDs::value)/range)-(min/range);
|
|
|
|
if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::combobox)
|
|
|
|
return (getGUICtrls(index).getNumProp(CabbageIDs::value)/getGUICtrls(index).getNumProp(CabbageIDs::comborange));
|
|
|
|
else if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::checkbox ||
|
|
|
|
getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::button)
|
|
|
|
return getGUICtrls(index).getNumProp(CabbageIDs::value);
|
|
|
|
else
|
|
|
|
return (getGUICtrls(index).getNumProp("value")/range)-(min/range);
|
|
|
|
return (getGUICtrls(index).getNumProp(CabbageIDs::value)/range)-(min/range);
|
|
|
|
#else
|
|
|
|
return getGUICtrls(index).getNumProp("value");
|
|
|
|
return guiCtrls[index].getNumProp(CabbageIDs::value);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
@@ -929,6 +978,7 @@ else |
|
|
|
|
|
|
|
void CabbagePluginAudioProcessor::setParameter (int index, float newValue)
|
|
|
|
{
|
|
|
|
String stringMessage;
|
|
|
|
#ifndef Cabbage_No_Csound
|
|
|
|
/* this will get called by the plugin GUI sliders or
|
|
|
|
by the host, via automation. The timer thread in the plugin's editor
|
|
|
@@ -941,30 +991,45 @@ if(index<(int)guiCtrls.size())//make sure index isn't out of range |
|
|
|
{
|
|
|
|
#ifndef Cabbage_Build_Standalone
|
|
|
|
//scaling in here because incoming values in plugin mode range from 0-1
|
|
|
|
range = getGUICtrls(index).getNumProp("range");
|
|
|
|
comboRange = getGUICtrls(index).getNumProp("comborange");
|
|
|
|
range = getGUICtrls(index).getNumProp(CabbageIDs::range);
|
|
|
|
comboRange = getGUICtrls(index).getNumProp(CabbageIDs::comborange);
|
|
|
|
//Logger::writeToLog("inValue:"+String(newValue));
|
|
|
|
min = getGUICtrls(index).getNumProp("min");
|
|
|
|
min = getGUICtrls(index).getNumProp(CabbageIDs::min);
|
|
|
|
|
|
|
|
if(getGUICtrls(index).getStringProp("type")=="xypad")
|
|
|
|
if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::xypad)
|
|
|
|
newValue = (jmax(0.f, newValue)*range)+min;
|
|
|
|
else if(getGUICtrls(index).getStringProp("type")=="combobox")//combo box value need to be rounded...
|
|
|
|
else if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::combobox)//combo box value need to be rounded...
|
|
|
|
newValue = (newValue*comboRange);
|
|
|
|
else if(getGUICtrls(index).getStringProp("type")=="checkbox")
|
|
|
|
else if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::checkbox ||
|
|
|
|
getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::button)
|
|
|
|
range=1;
|
|
|
|
else
|
|
|
|
newValue = (newValue*range)+min;
|
|
|
|
|
|
|
|
guiCtrls.getReference(index).setNumProp("value", newValue);
|
|
|
|
messageQueue.addOutgoingChannelMessageToQueue(guiCtrls.getReference(index).getStringProp("channel").toUTF8(), newValue,
|
|
|
|
guiCtrls.getReference(index).getStringProp("type"));
|
|
|
|
Logger::writeToLog(String("parameterSet:"+String(newValue)));
|
|
|
|
#else
|
|
|
|
//no need to scale here when in standalone mode
|
|
|
|
guiCtrls.getReference(index).setNumProp("value", newValue);
|
|
|
|
messageQueue.addOutgoingChannelMessageToQueue(guiCtrls.getReference(index).getStringProp("channel").toUTF8(), newValue,
|
|
|
|
guiCtrls.getReference(index).getStringProp("type"));
|
|
|
|
//guiCtrls.getReference(index).setNumProp(CabbageIDs::value, newValue);
|
|
|
|
//messageQueue.addOutgoingChannelMessageToQueue(guiCtrls.getReference(index).getStringProp(CabbageIDs::channel).toUTF8(), newValue,
|
|
|
|
//guiCtrls.getReference(index).getStringProp("type"));
|
|
|
|
//Logger::writeToLog(String("parameterSet:"+String(newValue)));
|
|
|
|
#endif
|
|
|
|
//Logger::writeToLog(String("parameterSet:"+String(newValue)));
|
|
|
|
//no need to scale here when in standalone mode
|
|
|
|
|
|
|
|
if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::combobox &&
|
|
|
|
getGUICtrls(index).getStringProp(CabbageIDs::channeltype)==CabbageIDs::stringchannel)
|
|
|
|
{
|
|
|
|
stringMessage = getGUICtrls(index).getStringArrayPropValue(CabbageIDs::text, newValue-1);
|
|
|
|
//Logger::writeToLog(stringMessage);
|
|
|
|
messageQueue.addOutgoingChannelMessageToQueue(guiCtrls.getReference(index).getStringProp(CabbageIDs::channel),
|
|
|
|
stringMessage,
|
|
|
|
CabbageIDs::stringchannel);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
messageQueue.addOutgoingChannelMessageToQueue(guiCtrls.getReference(index).getStringProp(CabbageIDs::channel),
|
|
|
|
newValue,
|
|
|
|
guiCtrls.getReference(index).getStringProp(CabbageIDs::type));
|
|
|
|
|
|
|
|
|
|
|
|
guiCtrls.getReference(index).setNumProp(CabbageIDs::value, newValue);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
@@ -979,28 +1044,38 @@ void CabbagePluginAudioProcessor::updateCabbageControls() |
|
|
|
{
|
|
|
|
#ifndef Cabbage_No_Csound
|
|
|
|
String chanName;
|
|
|
|
MYFLT* val=0;
|
|
|
|
//update all control widgets
|
|
|
|
for(int index=0;index<getGUICtrlsSize();index++)
|
|
|
|
if(!CSCompResult)
|
|
|
|
{
|
|
|
|
float value = csound->GetChannel(guiCtrls[index].getStringProp("channel").toUTF8());
|
|
|
|
guiCtrls[index].setNumProp("value", value);
|
|
|
|
}
|
|
|
|
|
|
|
|
MYFLT* val=0;
|
|
|
|
//update all control widgets
|
|
|
|
for(int index=0;index<getGUICtrlsSize();index++)
|
|
|
|
{
|
|
|
|
if(guiCtrls[index].getStringProp(CabbageIDs::channeltype).equalsIgnoreCase(CabbageIDs::stringchannel)){
|
|
|
|
//argghhh!! THIS NEEDS TO ALLOW COMBOBOXEX THAT CONTAIN SNAPSHOTS TO UPDATE!
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
float value = csound->GetChannel(guiCtrls[index].getStringProp(CabbageIDs::channel).getCharPointer());
|
|
|
|
//Logger::writeToLog("Channel:"+guiCtrls[index].getStringProp(CabbageIDs::channel));
|
|
|
|
//Logger::writeToLog("value:"+String(value));
|
|
|
|
guiCtrls.getReference(index).setNumProp(CabbageIDs::value, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//update all layout control widgets
|
|
|
|
//currently this is only needed for table widgets as other layout controls
|
|
|
|
//don't use channel messages...
|
|
|
|
for(int index=0;index<getGUILayoutCtrlsSize();index++)
|
|
|
|
{
|
|
|
|
if(getGUILayoutCtrls(index).getStringProp("type")=="table")
|
|
|
|
for(int index=0;index<getGUILayoutCtrlsSize();index++)
|
|
|
|
{
|
|
|
|
for(int y=0;y<guiLayoutCtrls[index].getStringArrayProp("channel").size();y++){
|
|
|
|
//String test = getGUILayoutCtrls(index).getStringArrayPropValue("channel", y);
|
|
|
|
float value = csound->GetChannel(guiLayoutCtrls[index].getStringArrayPropValue("channel", y).toUTF8());
|
|
|
|
guiLayoutCtrls[index].setTableChannelValues(y, value);
|
|
|
|
if(guiLayoutCtrls[index].getStringProp(CabbageIDs::type)==CabbageIDs::table)
|
|
|
|
{
|
|
|
|
for(int y=0;y<guiLayoutCtrls[index].getStringArrayProp(CabbageIDs::channel).size();y++){
|
|
|
|
//String test = getGUILayoutCtrls(index).getStringArrayPropValue(CabbageIDs::channel, y);
|
|
|
|
float value = csound->GetChannel(guiLayoutCtrls[index].getStringArrayPropValue(CabbageIDs::channel, y).getCharPointer());
|
|
|
|
guiLayoutCtrls[index].setTableChannelValues(y, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sendChangeMessage();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
@@ -1010,8 +1085,27 @@ for(int index=0;index<getGUILayoutCtrlsSize();index++) |
|
|
|
void CabbagePluginAudioProcessor::sendOutgoingMessagesToCsound()
|
|
|
|
{
|
|
|
|
#ifndef Cabbage_No_Csound
|
|
|
|
if(!csCompileResult){
|
|
|
|
#ifndef Cabbage_Build_Standalone
|
|
|
|
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(CabbageIDs::hostbpm.toUTF8(), hostInfo.bpm);
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(CabbageIDs::timeinseconds.toUTF8(), hostInfo.timeInSeconds);
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(CabbageIDs::isplaying.toUTF8(), hostInfo.isPlaying);
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(CabbageIDs::isrecording.toUTF8(), hostInfo.isRecording);
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(CabbageIDs::hostppqpos.toUTF8(), hostInfo.ppqPosition);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(int i=0;i<messageQueue.getNumberOfOutgoingChannelMessagesInQueue();i++)
|
|
|
|
{
|
|
|
|
//Logger::writeToLog("MessageType:"+messageQueue.getOutgoingChannelMessageFromQueue(i).type);
|
|
|
|
if(messageQueue.getOutgoingChannelMessageFromQueue(i).type=="directoryList"){
|
|
|
|
for(int y=0;y<scoreEvents.size();y++)
|
|
|
|
csound->InputMessage(scoreEvents[y].toUTF8());
|
|
|
@@ -1020,21 +1114,27 @@ for(int i=0;i<messageQueue.getNumberOfOutgoingChannelMessagesInQueue();i++) |
|
|
|
//update Csound function tables with values from table widget
|
|
|
|
else if(messageQueue.getOutgoingChannelMessageFromQueue(i).type=="updateTable"){
|
|
|
|
//Logger::writeToLog(messageQueue.getOutgoingChannelMessageFromQueue(i).fStatement.toUTF8());
|
|
|
|
csound->InputMessage(messageQueue.getOutgoingChannelMessageFromQueue(i).fStatement.toUTF8());
|
|
|
|
csound->InputMessage(messageQueue.getOutgoingChannelMessageFromQueue(i).fStatement.getCharPointer());
|
|
|
|
}
|
|
|
|
//catch string messags
|
|
|
|
else if(messageQueue.getOutgoingChannelMessageFromQueue(i).type==CabbageIDs::stringchannel){
|
|
|
|
csound->SetChannel(messageQueue.getOutgoingChannelMessageFromQueue(i).channelName.getCharPointer(),
|
|
|
|
messageQueue.getOutgoingChannelMessageFromQueue(i).stringVal.toUTF8().getAddress());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
csound->SetChannel(messageQueue.getOutgoingChannelMessageFromQueue(i).channelName.toUTF8(),
|
|
|
|
csound->SetChannel(messageQueue.getOutgoingChannelMessageFromQueue(i).channelName.getCharPointer(),
|
|
|
|
messageQueue.getOutgoingChannelMessageFromQueue(i).value);
|
|
|
|
}
|
|
|
|
|
|
|
|
messageQueue.flushOutgoingChannelMessages();
|
|
|
|
|
|
|
|
if(isAutomator){
|
|
|
|
//sendChangeMessage();
|
|
|
|
//sendActionMessage("update automation:"+String(automationParamID)+"|"+String(automationAmp));
|
|
|
|
//Logger::writeToLog("update automation:"+String(automationAmp));
|
|
|
|
if(isAutomator){
|
|
|
|
//sendChangeMessage();
|
|
|
|
//sendActionMessage("update automation:"+String(automationParamID)+"|"+String(automationAmp));
|
|
|
|
//Logger::writeToLog("update automation:"+String(automationAmp));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
@@ -1110,14 +1210,14 @@ int CabbagePluginAudioProcessor::getNumParameters() |
|
|
|
const String CabbagePluginAudioProcessor::getParameterName (int index)
|
|
|
|
{
|
|
|
|
if(index<(int)guiCtrls.size())//make sure index isn't out of range
|
|
|
|
return guiCtrls.getReference(index).getStringProp("channel");
|
|
|
|
return guiCtrls.getReference(index).getStringProp(CabbageIDs::channel);
|
|
|
|
else return String::empty;
|
|
|
|
}
|
|
|
|
|
|
|
|
const String CabbagePluginAudioProcessor::getParameterText (int index)
|
|
|
|
{
|
|
|
|
if(index<(int)guiCtrls.size())//make sure index isn't out of range
|
|
|
|
return String (guiCtrls.getReference(index).getNumProp("value"), 2);
|
|
|
|
return String (guiCtrls.getReference(index).getNumProp(CabbageIDs::value), 2);
|
|
|
|
else return String::empty;
|
|
|
|
}
|
|
|
|
|
|
|
@@ -1164,10 +1264,14 @@ bool CabbagePluginAudioProcessor::producesMidi() const |
|
|
|
}
|
|
|
|
|
|
|
|
void CabbagePluginAudioProcessor::setGuiEnabled(bool val){
|
|
|
|
#ifdef Cabbage_Build_Standalone
|
|
|
|
guiON = val;
|
|
|
|
CabbagePluginAudioProcessorEditor* editor = dynamic_cast< CabbagePluginAudioProcessorEditor*>(this->getActiveEditor());
|
|
|
|
if(editor){
|
|
|
|
if(val==false){
|
|
|
|
int val = getPreference(appProperties, "ExternalEditor");
|
|
|
|
if(val)
|
|
|
|
csdFile.replaceWithText(codeEditor->getAllText());
|
|
|
|
//editor->resizer->setVisible(false);
|
|
|
|
//editor->propsWindow->setVisible(false);
|
|
|
|
}
|
|
|
@@ -1175,6 +1279,7 @@ void CabbagePluginAudioProcessor::setGuiEnabled(bool val){ |
|
|
|
//editor->resizer->setVisible(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int CabbagePluginAudioProcessor::getNumPrograms()
|
|
|
@@ -1222,35 +1327,6 @@ void CabbagePluginAudioProcessor::releaseResources() |
|
|
|
//host widgets are being used
|
|
|
|
void CabbagePluginAudioProcessor::timerCallback(){
|
|
|
|
#ifndef Cabbage_No_Csound
|
|
|
|
|
|
|
|
if(!isGuiEnabled()){
|
|
|
|
//initiliase any channels send host information to Csound
|
|
|
|
AudioPlayHead::CurrentPositionInfo hostInfo;
|
|
|
|
for(int i=0;i<(int)getGUILayoutCtrlsSize();i++){
|
|
|
|
if(getGUILayoutCtrls(i).getStringProp("type")==String("hostbpm")){
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(getGUILayoutCtrls(i).getStringProp("channel").toUTF8(), hostInfo.bpm);
|
|
|
|
}
|
|
|
|
else if(getGUILayoutCtrls(i).getStringProp("type")==String("hosttime")){
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(getGUILayoutCtrls(i).getStringProp("channel").toUTF8(), hostInfo.timeInSeconds);
|
|
|
|
}
|
|
|
|
else if(getGUILayoutCtrls(i).getStringProp("type")==String("hostplaying")){
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(getGUILayoutCtrls(i).getStringProp("channel").toUTF8(), hostInfo.isPlaying);
|
|
|
|
}
|
|
|
|
else if(getGUILayoutCtrls(i).getStringProp("type")==String("hostrecording")){
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(getGUILayoutCtrls(i).getStringProp("channel").toUTF8(), hostInfo.isRecording);
|
|
|
|
}
|
|
|
|
else if(getGUILayoutCtrls(i).getStringProp("type")==String("hostppqpos")){
|
|
|
|
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
|
|
|
|
csound->SetChannel(getGUILayoutCtrls(i).getStringProp("channel").toUTF8(), hostInfo.ppqPosition);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}// end of GUI enabled check
|
|
|
|
|
|
|
|
for(int y=0;y<xyAutomation.size();y++){
|
|
|
|
if(xyAutomation[y])
|
|
|
|
xyAutomation[y]->update();
|
|
|
@@ -1287,7 +1363,7 @@ if(!isSuspended() && !isGuiEnabled()){ |
|
|
|
{
|
|
|
|
getCallbackLock().enter();
|
|
|
|
//slow down calls to these functions, no need for them to be firing at k-rate
|
|
|
|
yieldCounter = (yieldCounter>10) ? 0 : yieldCounter+1;
|
|
|
|
yieldCounter = (yieldCounter>guiRefreshRate) ? 0 : yieldCounter+1;
|
|
|
|
if(yieldCounter==0){
|
|
|
|
sendOutgoingMessagesToCsound();
|
|
|
|
updateCabbageControls();
|
|
|
@@ -1295,13 +1371,14 @@ if(!isSuspended() && !isGuiEnabled()){ |
|
|
|
if(audioSourcesArray.size()>0)
|
|
|
|
sendAudioToCsoundFromSoundFilers(csound->GetKsmps());
|
|
|
|
|
|
|
|
CSCompResult = csound->PerformKsmps();
|
|
|
|
if(CSCompResult!=0)
|
|
|
|
csCompileResult = csound->PerformKsmps();
|
|
|
|
if(csCompileResult!=0)
|
|
|
|
suspendProcessing(true);
|
|
|
|
|
|
|
|
getCallbackLock().exit();
|
|
|
|
csndIndex = 0;
|
|
|
|
}
|
|
|
|
if(!CSCompResult)
|
|
|
|
if(!csCompileResult)
|
|
|
|
{
|
|
|
|
for(int channel = 0; channel < getNumOutputChannels(); channel++ )
|
|
|
|
{
|
|
|
@@ -1449,17 +1526,39 @@ AudioProcessorEditor* CabbagePluginAudioProcessor::createEditor() |
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
void CabbagePluginAudioProcessor::getStateInformation (MemoryBlock& /*destData*/)
|
|
|
|
void CabbagePluginAudioProcessor::getStateInformation (MemoryBlock& destData)
|
|
|
|
{
|
|
|
|
// You should use this method to store your parameters in the memory block.
|
|
|
|
// You could do that either as raw data, or use the XML or ValueTree classes
|
|
|
|
// as intermediaries to make it easy to save and load complex data.
|
|
|
|
// Here's an example of how you can use XML to make it easy and more robust:
|
|
|
|
|
|
|
|
// Create an outer XML element..
|
|
|
|
XmlElement xml ("CABBAGE_PLUGIN_SETTINGS");
|
|
|
|
|
|
|
|
for(int i=0;i<guiCtrls.size();i++)
|
|
|
|
xml.setAttribute (guiCtrls[i].getStringProp(CabbageIDs::channel), guiCtrls[i].getNumProp(CabbageIDs::value));
|
|
|
|
|
|
|
|
|
|
|
|
// then use this helper function to stuff it into the binary blob and return it..
|
|
|
|
copyXmlToBinary (xml, destData);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CabbagePluginAudioProcessor::setStateInformation (const void* /*data*/, int /*sizeInBytes*/)
|
|
|
|
void CabbagePluginAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
|
|
|
|
{
|
|
|
|
// You should use this method to restore your parameters from this memory block,
|
|
|
|
// whose contents will have been created by the getStateInformation() call.
|
|
|
|
// This getXmlFromBinary() helper function retrieves our XML from the binary blob..
|
|
|
|
ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
|
|
|
|
|
|
|
|
if (xmlState != nullptr)
|
|
|
|
{
|
|
|
|
// make sure that it's actually our type of XML object..
|
|
|
|
if (xmlState->hasTagName ("CABBAGE_PLUGIN_SETTINGS"))
|
|
|
|
{
|
|
|
|
for(int i=0;i<this->getNumParameters();i++)
|
|
|
|
this->setParameter(i, (float)xmlState->getDoubleAttribute(guiCtrls[i].getStringProp(CabbageIDs::channel)));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|