var BitcrushAudioProcessor::getState()
{
	DynamicObject* properties = new DynamicObject;
	properties->setProperty("bitcrush", bitcrush->getValue());
	properties->setProperty("downsample", downsample->getValue());
	properties->setProperty("wet", wet->getValue());
	return var(properties);
}
var FilterAudioProcessor::getState()
{
	DynamicObject* properties = new DynamicObject;
	properties->setProperty("frequency", frequency->getValue());
	properties->setProperty("resonance", resonance->getValue());
	properties->setProperty("filterType", filterType);
	return var(&properties);
}
var VolumeAudioProcessor::getState()
{
	DynamicObject* properties = new DynamicObject;
	properties->setProperty("volumeL", volumeL->getValue());
	properties->setProperty("volumeR", volumeR->getValue());
	properties->setProperty("stereoCoupling", stereoCoupling->getBoolValue());
	return var(&properties);
}
void IniFile::load()
{
    const GenericScopedLock<CriticalSection> scopedlock(lock);
    StringArray lines;
    file.readLines(lines);
    lines.removeEmptyStrings();
    lines.trim();

    clear();

    String section("__empty");
    for (int i = 0; i < lines.size(); i++) {
        if (lines[i].startsWithChar(';')) {
            continue;
        }
        if (lines[i].startsWithChar('[') && lines[i].endsWithChar(']')) {
            section = lines[i].substring(1, lines[i].length() - 1);
            continue;
        }
        if (!lines[i].containsChar('=')) {
            continue;
        }
        String key = lines[i].upToFirstOccurrenceOf("=", false, false).trim();
        String value = lines[i].fromFirstOccurrenceOf("=", false, false).trim();

        DynamicObject *sectionObject;
        if (data.contains(section)) {
            sectionObject = data[section].getDynamicObject();
        } else {
            sectionObject = new DynamicObject();
            data.set(section, var(sectionObject));
        }
        sectionObject->setProperty(key, var(value));
    }    
}
Beispiel #5
0
const var EnviJSONRPC::toArray (const StringPairArray &stringPairArray)
{
	var ret = empty(false);
	DynamicObject *dso = ret.getDynamicObject();

	for (int i=0; i<stringPairArray.size(); i++)
	{
		dso->setProperty (stringPairArray.getAllKeys() [i], stringPairArray.getAllValues() [i]);
	}

	return (ret);
}
//==============================================================================
void MidiSelectProcessor::getStateInformation (MemoryBlock &destData)
{
    // Use json for better forward-compatibility (not just splat)
    
    DynamicObject *data = new DynamicObject;
    data->setProperty("lowerNote", lowerNote);
    data->setProperty("upperNote", upperNote);
    
    String json = JSON::toString(var(data), true);
    
    MemoryOutputStream stream(destData, false);
    stream.write(json.toUTF8(), json.length());
}
void IniFile::set(const String& section, const String& key, const String& value)
{
    const GenericScopedLock<CriticalSection> scopedlock(lock);
    String realSection(section);
    if (realSection.isEmpty()) {
        realSection = "__empty";
    }

    DynamicObject *sectionObject;
    if (data.contains(realSection)) {
        sectionObject = data[realSection].getDynamicObject();
    } else {
        sectionObject = new DynamicObject();
        data.set(section, var(sectionObject));
    }

    sectionObject->setProperty(key, var(value));
}
Beispiel #8
0
static var parseModuleDesc (const StringArray& lines)
{
    DynamicObject* o = new DynamicObject();
    var result (o);

    for (int i = 0; i < lines.size(); ++i)
    {
        String line = trimCommentCharsFromStartOfLine (lines[i]);

        int colon = line.indexOfChar (':');

        if (colon >= 0)
        {
            String key = line.substring (0, colon).trim();
            String value = line.substring (colon + 1).trim();

            o->setProperty (key, value);
        }
    }

    return result;
}
Beispiel #9
0
const var EnviData::toVAR(const EnviData &enviData)
{
	String ret;
	DynamicObject *ds = new DynamicObject();
	ds->setProperty ("name", enviData.name);
	ds->setProperty ("type", enviData.type);
	ds->setProperty ("instance", enviData.instance);
	var values;

	for (int i=0; i<enviData.getNumValues(); i++)
	{
		DynamicObject *value = new DynamicObject();
		value->setProperty ("name", enviData[i].name);
		value->setProperty ("value", enviData[i].value.toString());
		value->setProperty ("unit", enviData[i].unit);
		value->setProperty ("error", enviData[i].error);
		value->setProperty ("timestamp", enviData[i].timestamp.toMilliseconds());

		values.append (value);
	}
	ds->setProperty ("values", values);

	return (var(ds));
}
var ApplicationSettingsFile::toJSON()
{
	DynamicObject *root = new DynamicObject();
	root->setProperty("PlayType", (int)playType);
	root->setProperty("UseGlobalHooks", useGlobalHooks);

	Array<var> keyPressObjects;
	for (int i = 0; i < stopAllSoundsKeys.size(); ++i)
	{
		const KeyPress &keyPress = stopAllSoundsKeys.getUnchecked(i);
		DynamicObject *keyPressObject = new DynamicObject();
		keyPressObject->setProperty("KeyCode", keyPress.getKeyCode());
		keyPressObject->setProperty("ModifierFlags", keyPress.getModifiers().getRawFlags());
		keyPressObject->setProperty("TextCharacter", (int)keyPress.getTextCharacter());
		keyPressObjects.add(var(keyPressObject));
	}

	root->setProperty("StopAllSoundKeyPresses", keyPressObjects);

	return var(root);
}
Beispiel #11
0
void PMixDocument::createNodeFromXml (XmlElement& xml, const String& newSourceCode)
{
  PluginDescription pd;
  
  forEachXmlChildElement (xml, e)
  {
    if (pd.loadFromXml (*e))
      break;
  }
  
  String errorMessage;
  
  AudioPluginInstance* instance = audioEngine.createPluginInstance(pd, errorMessage);
  
  jassert(instance != nullptr);
  
  if (pd.pluginFormatName == "FAUST")
  {
    FaustAudioPluginInstance* faustProc = dynamic_cast<FaustAudioPluginInstance*>(instance);
    faustProc->initialize(getLibraryPath(), drawPath);
    
    if (newSourceCode.length())
      faustProc->setSourceCode(newSourceCode, true);
    
    // TODO: this is a bit wrong!
    faustProc->prepareToPlay(44100., 8192);
    
//    xml.setAttribute("numInputs", faustProc->getNumInputChannels());
//    xml.setAttribute("numOutputs", faustProc->getNumOutputChannels()); ???
  }
  
  AudioProcessorGraph::Node::Ptr node (audioEngine.getGraph().addNode (instance, xml.getIntAttribute ("uid")));
  
  if (!newSourceCode.length())
  {
    if (const XmlElement* const state = xml.getChildByName ("STATE"))
    {
      MemoryBlock m;
      m.fromBase64Encoding (state->getAllSubText());
      
      node->getProcessor()->setStateInformation (m.getData(), (int) m.getSize());
    }
  }
  
  node->properties.set ("x", xml.getDoubleAttribute ("x"));
  node->properties.set ("y", xml.getDoubleAttribute ("y"));
  node->properties.set ("uiLastX", xml.getIntAttribute ("uiLastX"));
  node->properties.set ("uiLastY", xml.getIntAttribute ("uiLastY"));
  node->properties.set ("uiStatus", xml.getIntAttribute ("uiStatus"));

  // presets etc for faust & plugin nodes
  if(!InternalPluginFormat::isInternalFormat(pd.name))
  {
    node->properties.set ("colour", xml.getStringAttribute ("colour"));
    node->properties.set ("iposx", xml.getDoubleAttribute ("iposx"));
    node->properties.set ("iposy", xml.getDoubleAttribute ("iposy"));
    if (const XmlElement* const params = xml.getChildByName ("PARAMS"))
    {
      var vparams = JSON::parse(params->getAllSubText());
      node->properties.set ("params", vparams);
    }
    
    Array<var> presetsArr;
    
    forEachXmlChildElement (xml, e)
    {
      if (e->hasTagName ("PRESET"))
      {
        DynamicObject* obj = new DynamicObject();
        obj->setProperty("name", e->getStringAttribute("name"));
        obj->setProperty("x", e->getDoubleAttribute("x"));
        obj->setProperty("y", e->getDoubleAttribute("y"));
        obj->setProperty("radius", e->getDoubleAttribute("radius"));
        obj->setProperty("hidden", e->getBoolAttribute("hidden"));
        //  obj->setProperty("distance", e->getDoubleAttribute("distance"));
        obj->setProperty("coeff", e->getDoubleAttribute("coeff"));
        
        var vparams = JSON::parse(e->getAllSubText());
        obj->setProperty("state", vparams);
        obj->setProperty("uid", e->getIntAttribute("uid"));
        
        var preset = var(obj);
        presetsArr.add(preset);
      }
    }
    
    node->properties.set("presets", presetsArr);
  }
var PanAudioProcessor::getState()
{
	DynamicObject* properties = new DynamicObject;
	properties->setProperty("panning", panning->getValue());
	return var(&properties);
}
Beispiel #13
0
bool handlePluginRequest(const PluginRequestParameters &params, OutputStream &ostream,
                         ThreadSafePlugin *plugin = nullptr) {
    if (!plugin) {
        // It's very possible that all of this was a premature optimization.
        // For VSTs at least, code loading and caching is handled by ModuleHandle::findOrCreateModule,
        // and each instantiation only requires a couple of disc hits for working directory setting.
        // On the other hand, we want to make sure that each audio request has a "fresh" instance.
        // The easiest way to do this is by bypassing the instance pool and instantiating on demand.

#if PLUGIN_POOL_SIZE

        // Recurse with a plugin from the pool, locking on it.
        // Keep trying with a delay until a timeout occurs.
        const int TIMEOUT = 5000, WAIT = 200;
        int64 startTime = Time::currentTimeMillis();

        while (Time::currentTimeMillis() < startTime + TIMEOUT) {
            int i = 0;
            while ((plugin = pluginPool[i++])) {
                const ScopedTryLock pluginTryLock(plugin->crit);
                if (pluginTryLock.isLocked()) {
                    DBG << "Handling with plugin " << i << endl;
                    return handlePluginRequest(params, ostream, plugin);
                }
            }
            DBG << "Trying again in " << WAIT << endl;
            Thread::sleep(WAIT);
        }

        // If we were unable to obtain a lock, return failure.
        DBG << "Timeout" << endl;
        return false;

#else

        ThreadSafePlugin temporaryPlugin(createSynthInstance());
        return handlePluginRequest(params, ostream, &temporaryPlugin);

#endif
    }
    else {
        // Re-acquire or acquire the lock.
        const ScopedLock pluginLock(plugin->crit);
        AudioPluginInstance *instance = plugin->instance; // unmanaged, for simplicity

        // Attempt to reset the plugin in all ways possible.
        instance->reset();
        // Setting default parameters here causes miniTERA to become unresponsive to parameter settings.
        // It's possible that it's effectively pressing some interface buttons that change the editor mode entirely.
        // It's not necessary anyways if the plugin instance has been freshly created (see above).
        // pluginParametersOldNewFallback(instance, nullptr, &pluginDefaults); // note that the defaults may be empty
        instance->setCurrentProgram(0);

        // Load preset if specified, before listing or modifying parameters!
        if (params.presetNumber >= 0 && params.presetNumber < instance->getNumPrograms()) {
            DBG << "Setting program/preset: " << params.presetNumber << endl;
            instance->setCurrentProgram(params.presetNumber);
        }
        int currentProgram = instance->getCurrentProgram();
        DBG << "Current program/preset: " << currentProgram << " - " << instance->getProgramName(currentProgram) << endl;

        // Set parameters, starting with named, then indexed
        pluginParametersSet(instance, params.parameters);
        pluginParametersSetIndexed(instance, params.indexedParameters);

        // If parameters requested, output them and return
        if (params.listParameters) {
            DBG << "Rendering parameter list: # parameters " << instance->getNumPrograms() << endl;

            // Output each parameter setting in two places:
            // an indexed array and a dictionary by name
            // All DynamicObjects created will be freed when their var's leave scope.
            DynamicObject *outer = new DynamicObject();
            DynamicObject *innerParams = new DynamicObject();
            var indexedParamVar;
            {
                for (int i = 0, n = instance->getNumParameters(); i < n; ++i) {
                    String name = instance->getParameterName(i);
                    float val = instance->getParameter(i);
                    innerParams->setProperty(name, val);

                    DynamicObject *indexedInnerObj = new DynamicObject();
                    indexedInnerObj->setProperty("index", i);
                    indexedInnerObj->setProperty("name", name);
                    indexedInnerObj->setProperty("value", val);
                    indexedParamVar.append(var(indexedInnerObj)); // frees indexedInnerObj when this scope ends
                }
            }
            outer->setProperty(Identifier("parameters"), var(innerParams));
            outer->setProperty(Identifier("indexedParameters"), indexedParamVar);

            // List presets/programs.
            var progVar;
            {
                for (int i = 0, n = instance->getNumPrograms(); i < n; ++i) {
                    progVar.append(var(instance->getProgramName(i)));
                }
            }
            outer->setProperty(Identifier("presets"), progVar);

            var outerVar(outer);
            JSON::writeToStream(ostream, outerVar);
            // DBG << JSON::toString(outerVar, true /* allOnOneLine */) << endl;

            return true;
        }

        // Now attempt to render audio.
        AudioFormatManager formatManager;
        formatManager.registerBasicFormats();
        OptionalScopedPointer<AudioFormat> outputFormat(formatManager.findFormatForFileExtension(params.getFormatName()), false);
        if (!outputFormat) return false;

        instance->setNonRealtime(true);
        instance->prepareToPlay(params.sampleRate, params.blockSize);
        instance->setNonRealtime(true);

        // The writer takes ownership of the output stream; the  writer will delete it when the writer leaves scope.
        // Therefore, we pass a special pointer class that does not allow the writer to delete it.
        OutputStream *ostreamNonDeleting = new NonDeletingOutputStream(&ostream);
        ScopedPointer<AudioFormatWriter> writer(outputFormat->createWriterFor(ostreamNonDeleting,
                                                params.sampleRate, params.nChannels, params.bitDepth,
                                                StringPairArray(), 0));

        // Create a MIDI buffer
        MidiBuffer midiBuffer;
        midiBuffer.addEvent(MidiMessage::noteOn(params.midiChannel, (uint8)params.midiPitch, (uint8)params.midiVelocity),
                            0 /* time */);
        midiBuffer.addEvent(MidiMessage::allNotesOff(params.midiChannel),
                            params.noteSeconds * params.sampleRate);

        AudioSampleBuffer buffer(params.nChannels, params.blockSize);
        int numBuffers = (int)(params.renderSeconds * params.sampleRate / params.blockSize);
        for (int i = 0; i < numBuffers; ++i) {
            // DBG << "Processing block " << i << "..." << flush;
            instance->processBlock(buffer, midiBuffer);
            // DBG << " left RMS level " << buffer.getRMSLevel(0, 0, params.blockSize) << endl;
            writer->writeFromAudioSampleBuffer(buffer, 0 /* offset into buffer */, params.blockSize);
        }

        instance->reset();

        return true;
    }
}