void
AudioPluginOSCGUIManager::updateProgram(InstrumentId instrument, int position)
{
    RG_DEBUG << "AudioPluginOSCGUIManager::updateProgram(" << instrument << ","
             << position << ")" << endl;

    if (m_guis.find(instrument) == m_guis.end() ||
            m_guis[instrument].find(position) == m_guis[instrument].end())
        return ;

    PluginContainer *container = 0;
    container = m_studio->getContainerById(instrument);
    if (!container) return;

    AudioPluginInstance *pluginInstance = container->getPlugin(position);
    if (!pluginInstance) return;

    unsigned long rv = StudioControl::getPluginProgram
                       (pluginInstance->getMappedId(),
                        strtoqstr(pluginInstance->getProgram()));

    int bank = rv >> 16;
    int program = rv - (bank << 16);

    RG_DEBUG << "AudioPluginOSCGUIManager::updateProgram(" << instrument << ","
             << position << "): rv " << rv << ", bank " << bank << ", program " << program << endl;

    m_guis[instrument][position]->sendProgram(bank, program);
}
void
AudioPluginOSCGUIManager::updatePort(InstrumentId instrument, int position,
                                     int port)
{
    RG_DEBUG << "AudioPluginOSCGUIManager::updatePort(" << instrument << ","
             << position << "," << port << ")" << endl;

    if (m_guis.find(instrument) == m_guis.end() ||
            m_guis[instrument].find(position) == m_guis[instrument].end())
        return ;

    PluginContainer *container = 0;
    container = m_studio->getContainerById(instrument);
    if (!container) return;

    AudioPluginInstance *pluginInstance = container->getPlugin(position);
    if (!pluginInstance)
        return ;

    PluginPortInstance *porti = pluginInstance->getPort(port);
    if (!porti)
        return ;

    RG_DEBUG << "AudioPluginOSCGUIManager::updatePort(" << instrument << ","
             << position << "," << port << "): value " << porti->value << endl;

    m_guis[instrument][position]->sendPortValue(port, porti->value);
}
Ejemplo n.º 3
0
static void RT_process(SoundPlugin *plugin, int64_t time, int num_frames, float **inputs, float **outputs){
  
  Data *data = (Data*)plugin->data;

#if 0
  for(int ch=0; ch<data->num_output_channels ; ch++)
    memset(outputs[ch], 0, sizeof(float)*num_frames);
  return;
#endif

  // 1. Process audio

  AudioPluginInstance *instance = data->audio_instance;
  AudioSampleBuffer &buffer = data->buffer;

  for(int ch=0; ch<data->num_input_channels ; ch++)
    memcpy(buffer.getWritePointer(ch), inputs[ch], sizeof(float)*num_frames);

  int pos = CRASHREPORTER_set_plugin_name(plugin->type->name);{
    instance->processBlock(buffer, data->midi_buffer);
  }CRASHREPORTER_unset_plugin_name(pos);

  for(int ch=0; ch<data->num_output_channels ; ch++)
    memcpy(outputs[ch], buffer.getReadPointer(ch), sizeof(float)*num_frames);


  // 2. Send out midi (untested, need plugin to test with)

  volatile struct Patch *patch = plugin->patch;
  if (patch!=NULL) {
      
    MidiBuffer::Iterator iterator(data->midi_buffer);
      
    MidiMessage message;
    int samplePosition;
    
    while(iterator.getNextEvent(message, samplePosition)){
#ifndef RELEASE
      if (samplePosition >= num_frames || samplePosition < 0)
        RT_message("The instrument named \"%s\" of type %s/%s\n"
                   "returned illegal sample position: %d",
                   patch==NULL?"<no name>":patch->name,
                   plugin->type->type_name, plugin->type->name,
                   samplePosition
                   );
#endif
      // Make sure samplePosition has a legal value
      if (samplePosition >= num_frames)
        samplePosition = num_frames-1;
      if (samplePosition < 0)
        samplePosition = 0;
      
      int64_t delta_time = PLAYER_get_block_delta_time(pc->start_time+samplePosition);
      int64_t radium_time = pc->start_time + delta_time;
      
      RT_MIDI_send_msg_to_patch_receivers((struct Patch*)patch, message, radium_time);
    }
  }

}
Ejemplo n.º 4
0
static int get_current_preset(struct SoundPlugin *plugin){
#if JUCE_LINUX
  const MessageManagerLock mmLock;
#endif

  Data *data = (Data*)plugin->data;
  AudioPluginInstance *instance = data->audio_instance;

  return instance->getCurrentProgram();
}
Ejemplo n.º 5
0
static void set_current_preset(struct SoundPlugin *plugin, int num){
#if JUCE_LINUX
  const MessageManagerLock mmLock;
#endif

  Data *data = (Data*)plugin->data;
  AudioPluginInstance *instance = data->audio_instance;

  instance->setCurrentProgram(num);
}
Ejemplo n.º 6
0
static const char *get_preset_name(struct SoundPlugin *plugin, int num){
#if JUCE_LINUX
  const MessageManagerLock mmLock;
#endif

  Data *data = (Data*)plugin->data;
  AudioPluginInstance *instance = data->audio_instance;

  return talloc_strdup(instance->getProgramName(num).toRawUTF8());
}
Ejemplo n.º 7
0
static void set_preset_name(struct SoundPlugin *plugin, int num, const char* new_name){
#if JUCE_LINUX
  const MessageManagerLock mmLock;
#endif

  Data *data = (Data*)plugin->data;
  AudioPluginInstance *instance = data->audio_instance;

  instance->changeProgramName(num, new_name);
}
void
AudioPluginOSCGUIManager::startGUI(InstrumentId instrument, int position)
{
    RG_DEBUG << "AudioPluginOSCGUIManager::startGUI: " << instrument << "," << position
             << endl;

    checkOSCThread();

    if (m_guis.find(instrument) != m_guis.end() &&
            m_guis[instrument].find(position) != m_guis[instrument].end()) {
        RG_DEBUG << "stopping GUI first";
        stopGUI(instrument, position);
    }

    // check the label
    PluginContainer *container = 0;
    container = m_studio->getContainerById(instrument);
    if (!container) {
        RG_DEBUG << "AudioPluginOSCGUIManager::startGUI: no such instrument or buss as "
                 << instrument << endl;
        return;
    }

    AudioPluginInstance *pluginInstance = container->getPlugin(position);
    if (!pluginInstance) {
        RG_DEBUG << "AudioPluginOSCGUIManager::startGUI: no plugin at position "
                 << position << " for instrument " << instrument << endl;
        return ;
    }

    try {
        AudioPluginOSCGUI *gui =
            new AudioPluginOSCGUI(pluginInstance,
                                  getOSCUrl(instrument,
                                            position,
                                            strtoqstr(pluginInstance->getIdentifier())),
                                  getFriendlyName(instrument,
                                          position,
                                          strtoqstr(pluginInstance->getIdentifier())));
        m_guis[instrument][position] = gui;

    } catch (Exception e) {

        RG_DEBUG << "AudioPluginOSCGUIManager::startGUI: failed to start GUI: "
                 << e.getMessage() << endl;
    }
}
Ejemplo n.º 9
0
FilterModel FilterGraph::formatFilterModel (AudioProcessorGraph::Node* const node)
{
    //FOR SAVING AND UPDATING
    FilterModel filter;
    
    AudioPluginInstance* plugin = dynamic_cast<AudioPluginInstance*>(node->getProcessor());
    
    if (plugin == nullptr) {
        jassertfalse;
        return filter;
    }
    
    PluginDescription pd;
    plugin->fillInPluginDescription(pd);
    fill_in_filter_pd_info(node, filter, pd);
    return filter;
}
bool
AudioPluginOSCGUIManager::hasGUI(InstrumentId instrument, int position)
{
    PluginContainer *container = 0;
    container = m_studio->getContainerById(instrument);
    if (!container) return false;

    AudioPluginInstance *pluginInstance = container->getPlugin(position);
    if (!pluginInstance) return false;

    try {
        QString filePath = AudioPluginOSCGUI::getGUIFilePath
                           (strtoqstr(pluginInstance->getIdentifier()));
        return ( !filePath.isEmpty() );
    } catch (Exception e) { // that's OK
        return false;
    }
}
Ejemplo n.º 11
0
// The caller is responsible for deleting the object that is returned
AudioPluginInstance *createSynthInstance() {
    AudioPluginFormatManager pluginManager;
    pluginManager.addDefaultFormats();

    PluginDescription desc;
    desc.fileOrIdentifier = resolveRelativePath(PLUGIN_REL_PATH);
    // DBG << desc.fileOrIdentifier << endl;
    desc.uid = 0;

    String errorMessage;
    AudioPluginInstance *instance = pluginManager.createPluginInstance(desc, errorMessage);

    if (!instance) {
        DBG << "Error creating plugin instance: " << errorMessage << endl;
        exit(1);
    }

    // Force initialization on the main thread. This preparation will redone with proper values later.
    instance->prepareToPlay(44100, 512);

    return instance;
}
Ejemplo n.º 12
0
static AudioPluginInstance *get_audio_instance(const TypeData *type_data, float sample_rate, int block_size){
  static bool inited=false;

  static AudioPluginFormatManager formatManager;
    
  if (inited==false){
    formatManager.addDefaultFormats();
    inited=true;
  }

  
  //int uid = VST_get_uid(type_data->library_file_full_path);
  //printf("uid: %d\n",uid);
  //getchar();
  //((PluginDescription*)description)->uid = uid;

  //if (uid==-1)
  //  return NULL;
  
  String errorMessage;

  PluginDescription description;
  
  description.fileOrIdentifier = String(type_data->file_or_identifier);
  description.uid = type_data->uid;
      
  AudioPluginInstance *instance = formatManager.createPluginInstance(description,sample_rate,block_size,errorMessage);

  if (instance==NULL){
    GFX_Message(NULL, "Unable to open VST plugin %s: %s\n",description.fileOrIdentifier.toRawUTF8(), errorMessage.toRawUTF8());
    return NULL;
  }

  instance->setPlayHead(&myAudioPlayHead);

  instance->prepareToPlay(sample_rate, block_size);

  return instance;
}
void
AudioPluginOSCGUIManager::updateConfiguration(InstrumentId instrument, int position,
        QString key)
{
    RG_DEBUG << "AudioPluginOSCGUIManager::updateConfiguration(" << instrument << ","
             << position << "," << key << ")" << endl;

    if (m_guis.find(instrument) == m_guis.end() ||
            m_guis[instrument].find(position) == m_guis[instrument].end())
        return ;

    PluginContainer *container = m_studio->getContainerById(instrument);
    if (!container) return;

    AudioPluginInstance *pluginInstance = container->getPlugin(position);
    if (!pluginInstance) return;

    QString value = strtoqstr(pluginInstance->getConfigurationValue(qstrtostr(key)));

    RG_DEBUG << "AudioPluginOSCGUIManager::updatePort(" << instrument << ","
             << position << "," << key << "): value " << value << endl;

    m_guis[instrument][position]->sendConfiguration(key, value);
}
bool
AudioPluginOSCGUIManager::parseOSCPath(QString path, InstrumentId &instrument,
                                       int &position, QString &method)
{
    RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath(" << path << ")";
    if (!m_studio)
        return false;

    QString pluginStr("/plugin/");

    if (path.startsWith("//")) {
        path = path.right(path.length() - 1);
    }

    if (!path.startsWith(pluginStr)) {
        RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: malformed path "
                 << path << endl;
        return false;
    }

    path = path.right(path.length() - pluginStr.length());

    QString type = path.section('/', 0, 0);
    QString instrumentStr = path.section('/', 1, 1);
    QString positionStr = path.section('/', 2, 2);
    QString label = path.section('/', 3, -2);
    method = path.section('/', -1, -1);

    if (instrumentStr.isEmpty() || positionStr.isEmpty() ) {
        RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: no instrument or position in " << path;
        return false;
    }

    instrument = instrumentStr.toUInt();

    if (positionStr == "synth") {
        position = Instrument::SYNTH_PLUGIN_POSITION;
    } else {
        position = positionStr.toInt();
    }

    // check the label
    PluginContainer *container = m_studio->getContainerById(instrument);
    if (!container) {
        RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: no such instrument or buss as "
                 << instrument << " in path " << path << endl;
        return false;
    }

    AudioPluginInstance *pluginInstance = container->getPlugin(position);
    if (!pluginInstance) {
        RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: no plugin at position "
                 << position << " for instrument " << instrument << " in path "
                 << path << endl;
        return false;
    }

    QString identifier = strtoqstr(pluginInstance->getIdentifier());
    QString iType, iSoName, iLabel;
    PluginIdentifier::parseIdentifier(identifier, iType, iSoName, iLabel);
    if (iLabel != label) {
        RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: wrong label for plugin"
                 << " at position " << position << " for instrument " << instrument
                 << " in path " << path << " (actual label is " << iLabel
                 << ")" << endl;
        return false;
    }

    RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: good path " << path
             << ", got mapped id " << pluginInstance->getMappedId() << endl;

    return true;
}
Ejemplo n.º 15
0
 XmlElement* PMixDocument::createNodeXml (AudioProcessorGraph::Node* const node) noexcept
{
  AudioPluginInstance* plugin = dynamic_cast <AudioPluginInstance*> (node->getProcessor());

  if (plugin == nullptr)
  {
    jassertfalse;
    return nullptr;
  }

  XmlElement* e = new XmlElement ("NODE");
  e->setAttribute ("uid", (int) node->nodeID);
  e->setAttribute ("x", node->properties ["x"].toString());
  e->setAttribute ("y", node->properties ["y"].toString());
  e->setAttribute ("uiLastX", node->properties ["uiLastX"].toString());
  e->setAttribute ("uiLastY", node->properties ["uiLastY"].toString());
  e->setAttribute ("uiStatus", node->properties ["uiStatus"].toString());
  
  PluginDescription pd;
  plugin->fillInPluginDescription (pd);
  
  if(!InternalPluginFormat::isInternalFormat(pd.name))
  {
    e->setAttribute("colour", node->properties ["colour"].toString());
    e->setAttribute ("iposx", node->properties ["iposx"].toString());
    e->setAttribute ("iposy", node->properties ["iposy"].toString());
  }
  
  e->addChildElement (pd.createXml());

  XmlElement* state = new XmlElement ("STATE");

  MemoryBlock m;
  node->getProcessor()->getStateInformation (m);
  state->addTextElement (m.toBase64Encoding());
  e->addChildElement (state);
  
  if(!InternalPluginFormat::isInternalFormat(pd.name))
  {
    XmlElement* params = new XmlElement ("PARAMS");
    Array<var>* paramsArray = node->properties.getVarPointer("params")->getArray();
    
    params->addTextElement("[");
    for(int i=0;i<paramsArray->size();i++)
    {
      var parameterIdx = paramsArray->getReference(i);
      
      params->addTextElement(parameterIdx.toString());
      
      if(i != paramsArray->size()-1)
        params->addTextElement(", ");
    }
    params->addTextElement("]");
    
    e->addChildElement(params);
        
    Array<var>* presetsArr = node->properties.getVarPointer("presets")->getArray();
    
    for(int i=0;i<presetsArr->size();i++)
    {
      XmlElement* presetXML = new XmlElement ("PRESET");
      DynamicObject* thePreset = presetsArr->getReference(i).getDynamicObject();
      presetXML->setAttribute("name", thePreset->getProperty("name").toString());
      presetXML->setAttribute("x", thePreset->getProperty("x").toString());
      presetXML->setAttribute("y", thePreset->getProperty("y").toString());
      presetXML->setAttribute("radius", thePreset->getProperty("radius").toString());
      presetXML->setAttribute("hidden", thePreset->getProperty("hidden").toString());
      //presetXML->setAttribute("distance", thePreset->getProperty("distance").toString());
      presetXML->setAttribute("coeff", thePreset->getProperty("coeff").toString());
      presetXML->setAttribute("uid", thePreset->getProperty("uid").toString());

      Array<var>* paramsArray = thePreset->getProperty("state").getArray();
      
      presetXML->addTextElement("[");
      for(int i=0;i<paramsArray->size();i++)
      {
        var parameterIdx = paramsArray->getReference(i);
        
        presetXML->addTextElement(parameterIdx.toString());
        
        if(i != paramsArray->size()-1)
          presetXML->addTextElement(", ");
      }
      
      presetXML->addTextElement("]");
      
      e->addChildElement(presetXML);
    }
  }
  
  return e;
}
Ejemplo n.º 16
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;
    }
}
Ejemplo n.º 17
0
void
ManageMetronomeDialog::populate(int deviceIndex)
{
    m_metronomeInstrument->clear();

    DeviceList *devices = m_doc->getStudio().getDevices();
    DeviceListConstIterator it;
    int count = 0;
    Device *dev = 0;

    for (it = devices->begin(); it != devices->end(); it++) {

        dev = *it;
        if (!isSuitable(dev)) continue;

        if (count == deviceIndex) break;
        count++;
    }

    // sanity
    if (count < 0 || dev == 0 || !isSuitable(dev)) {
        return ;
    }

    // populate instrument list
    InstrumentList list = dev->getPresentationInstruments();
    InstrumentList::iterator iit;

    const MidiMetronome *metronome = getMetronome(dev);

    // if we've got no metronome against this device then create one
    if (metronome == 0) {
        InstrumentId id = SystemInstrumentBase;

        for (iit = list.begin(); iit != list.end(); ++iit) {
            if ((*iit)->isPercussion()) {
                id = (*iit)->getId();
                break;
            }
        }

        setMetronome(dev, MidiMetronome(id));

        metronome = getMetronome(dev);
    }

    // metronome should now be set but we still check it
    if (metronome) {
        int position = 0;
        int count = 0;

        for (iit = list.begin(); iit != list.end(); ++iit) {

            QString iname(QObject::tr((*iit)->getName().c_str()));
            QString ipname((*iit)->getLocalizedPresentationName());
            QString programName(QObject::tr((*iit)->getProgramName().c_str()));

            QString text;

            if ((*iit)->getType() == Instrument::SoftSynth) {

                iname.replace(QObject::tr("Synth plugin "), "");
                programName = "";

                AudioPluginInstance *plugin = (*iit)->getPlugin
                    (Instrument::SYNTH_PLUGIN_POSITION);
                if (plugin)
                    programName = strtoqstr(plugin->getDisplayName());

            } else {

                iname = ipname;
            }

            if (programName != "") {
                text = tr("%1 (%2)").arg(iname).arg(programName);
            } else {
                text = iname;
            }

            m_metronomeInstrument->addItem(text);

            if ((*iit)->getId() == metronome->getInstrument()) {
                position = count;
            }
            count++;
        }
        m_metronomeInstrument->setCurrentIndex(position);

        m_barPitch = metronome->getBarPitch();
        m_beatPitch = metronome->getBeatPitch();
        m_subBeatPitch = metronome->getSubBeatPitch();
        slotPitchSelectorChanged(0);
        m_metronomeResolution->setCurrentIndex(metronome->getDepth());
        m_metronomeBarVely->setValue(metronome->getBarVelocity());
        m_metronomeBeatVely->setValue(metronome->getBeatVelocity());
        m_metronomeSubBeatVely->setValue(metronome->getSubBeatVelocity());
        m_playEnabled->setChecked(m_doc->getComposition().usePlayMetronome());
        m_recordEnabled->setChecked(m_doc->getComposition().useRecordMetronome());
        slotResolutionChanged(metronome->getDepth());
    }
}
void
AudioPluginOSCGUIManager::dispatch()
{
    if (!m_studio)
        return ;

    while (m_oscBuffer.getReadSpace() > 0) {

        OSCMessage *message = 0;
        m_oscBuffer.read(&message, 1);

        int instrument = message->getTarget();
        int position = message->getTargetData();

        PluginContainer *container = m_studio->getContainerById(instrument);
        if (!container) continue;

        AudioPluginInstance *pluginInstance = container->getPlugin(position);
        if (!pluginInstance) continue;

        AudioPluginOSCGUI *gui = 0;

        if (m_guis.find(instrument) == m_guis.end()) {
            RG_DEBUG << "AudioPluginOSCGUIManager: no GUI for instrument "
                     << instrument << endl;
        } else if (m_guis[instrument].find(position) == m_guis[instrument].end()) {
            RG_DEBUG << "AudioPluginOSCGUIManager: no GUI for instrument "
                     << instrument << ", position " << position << endl;
        } else {
            gui = m_guis[instrument][position];
        }

        std::string method = message->getMethod();

        char type;
        const lo_arg *arg;

        // These generally call back on the RosegardenMainWindow.  We'd
        // like to emit signals, but making AudioPluginOSCGUIManager a
        // QObject is problematic if it's only conditionally compiled.

        if (method == "control") {

            if (message->getArgCount() != 2) {
                RG_DEBUG << "AudioPluginOSCGUIManager: wrong number of args ("
                         << message->getArgCount() << ") for control method"
                         << endl;
                goto done;
            }
            if (!(arg = message->getArg(0, type)) || type != 'i') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get port number"
                         << endl;
                goto done;
            }
            int port = arg->i;
            if (!(arg = message->getArg(1, type)) || type != 'f') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get port value"
                         << endl;
                goto done;
            }
            float value = arg->f;

            RG_DEBUG << "AudioPluginOSCGUIManager: setting port " << port
                     << " to value " << value << endl;

            m_mainWindow->slotChangePluginPort(instrument, position, port, value);

        } else if (method == "program") {

            if (message->getArgCount() != 2) {
                RG_DEBUG << "AudioPluginOSCGUIManager: wrong number of args ("
                         << message->getArgCount() << ") for program method"
                         << endl;
                goto done;
            }
            if (!(arg = message->getArg(0, type)) || type != 'i') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get bank number"
                         << endl;
                goto done;
            }
            int bank = arg->i;
            if (!(arg = message->getArg(1, type)) || type != 'i') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get program number"
                         << endl;
                goto done;
            }
            int program = arg->i;

            QString programName = StudioControl::getPluginProgram
                                  (pluginInstance->getMappedId(), bank, program);

            m_mainWindow->slotChangePluginProgram(instrument, position, programName);

        } else if (method == "update") {

            if (message->getArgCount() != 1) {
                RG_DEBUG << "AudioPluginOSCGUIManager: wrong number of args ("
                         << message->getArgCount() << ") for update method"
                         << endl;
                goto done;
            }
            if (!(arg = message->getArg(0, type)) || type != 's') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get GUI URL"
                         << endl;
                goto done;
            }
            QString url = &arg->s;

            if (!gui) {
                RG_DEBUG << "AudioPluginOSCGUIManager: no GUI for update method"
                         << endl;
                goto done;
            }

            gui->setGUIUrl(url);

            for (AudioPluginInstance::ConfigMap::const_iterator i =
                        pluginInstance->getConfiguration().begin();
                    i != pluginInstance->getConfiguration().end(); ++i) {

                QString key = strtoqstr(i->first);
                QString value = strtoqstr(i->second);

#ifdef DSSI_PROJECT_DIRECTORY_KEY

                if (key == PluginIdentifier::RESERVED_PROJECT_DIRECTORY_KEY) {
                    key = DSSI_PROJECT_DIRECTORY_KEY;
                }
#endif

                RG_DEBUG << "update: configuration: " << key << " -> "
                         << value << endl;

                gui->sendConfiguration(key, value);
            }

            unsigned long rv = StudioControl::getPluginProgram
                               (pluginInstance->getMappedId(), strtoqstr(pluginInstance->getProgram()));

            int bank = rv >> 16;
            int program = rv - (bank << 16);
            gui->sendProgram(bank, program);

            int controlCount = 0;
            for (PortInstanceIterator i = pluginInstance->begin();
                    i != pluginInstance->end(); ++i) {
                gui->sendPortValue((*i)->number, (*i)->value);
                /* Avoid overloading the GUI if there are lots and lots of ports */
                if (++controlCount % 50 == 0)
                    usleep(300000);
            }

            gui->show();

        } else if (method == "configure") {

            if (message->getArgCount() != 2) {
                RG_DEBUG << "AudioPluginOSCGUIManager: wrong number of args ("
                         << message->getArgCount() << ") for configure method"
                         << endl;
                goto done;
            }

            if (!(arg = message->getArg(0, type)) || type != 's') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get configure key"
                         << endl;
                goto done;
            }
            QString key = &arg->s;

            if (!(arg = message->getArg(1, type)) || type != 's') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get configure value"
                         << endl;
                goto done;
            }
            QString value = &arg->s;

#ifdef DSSI_RESERVED_CONFIGURE_PREFIX

            if (key.startsWith(DSSI_RESERVED_CONFIGURE_PREFIX) ||
                    key == PluginIdentifier::RESERVED_PROJECT_DIRECTORY_KEY) {
                RG_DEBUG << "AudioPluginOSCGUIManager: illegal reserved configure call from gui: " << key << " -> " << value;
                goto done;
            }
#endif

            RG_DEBUG << "AudioPluginOSCGUIManager: configure(" << key << "," << value
                     << ")" << endl;

            m_mainWindow->slotChangePluginConfiguration(instrument, position,
#ifdef DSSI_GLOBAL_CONFIGURE_PREFIX
                    key.startsWith(DSSI_GLOBAL_CONFIGURE_PREFIX),
#else
                    false,
#endif
                    key, value);

        } else if (method == "midi") {

            if (message->getArgCount() != 1) {
                RG_DEBUG << "AudioPluginOSCGUIManager: wrong number of args ("
                         << message->getArgCount() << ") for midi method"
                         << endl;
                goto done;
            }
            if (!(arg = message->getArg(0, type)) || type != 'm') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get MIDI event"
                         << endl;
                goto done;
            }

            RG_DEBUG << "AudioPluginOSCGUIManager: handling MIDI message";

            // let's only handle note on and note off

            int eventCode = arg->m[1];
            int eventType = eventCode & MIDI_MESSAGE_TYPE_MASK;
            if (eventType == MIDI_NOTE_ON ||
                    eventType == MIDI_NOTE_OFF) {
                MappedEvent ev(instrument,
                               MappedEvent::MidiNote,
                               MidiByte(arg->m[2]),
                               MidiByte(arg->m[3]),
                               RealTime::zeroTime,
                               RealTime::zeroTime,
                               RealTime::zeroTime);
                if (eventType == MIDI_NOTE_OFF)
                    ev.setVelocity(0);
                StudioControl::sendMappedEvent(ev);
            }

        } else if (method == "exiting") {

            RG_DEBUG << "AudioPluginOSCGUIManager: GUI exiting";
            stopGUI(instrument, position);
            m_mainWindow->slotPluginGUIExited(instrument, position);

        } else {

            RG_DEBUG << "AudioPluginOSCGUIManager: unknown method " << method;
        }

done:
        delete message;
    }
Ejemplo n.º 19
0
void
TrackParameterBox::updateInstrument(const Instrument *instrument)
{
    // As with the Device field above, this will rarely change and it is
    // expensive to clear and reload.  So, we should cache enough info to
    // detect a real change.  This would be Instrument names and IDs.

    const DeviceId deviceId = instrument->getDevice()->getId();
    const Device &device = *(m_doc->getStudio().getDevice(deviceId));

    const InstrumentList instrumentList = device.getPresentationInstruments();

    // Generate local instrument name and ID lists to compare against the
    // members.

    std::vector<InstrumentId> instrumentIds;
    std::vector<QString> instrumentNames;

    // For each instrument
    for (size_t instrumentIndex = 0;
         instrumentIndex < instrumentList.size();
         ++instrumentIndex) {
        const Instrument &loopInstrument = *(instrumentList[instrumentIndex]);

        instrumentIds.push_back(loopInstrument.getId());

        QString instrumentName(QObject::tr(loopInstrument.getName().c_str()));
        QString programName(
                QObject::tr(loopInstrument.getProgramName().c_str()));

        if (loopInstrument.getType() == Instrument::SoftSynth) {

            instrumentName.replace(QObject::tr("Synth plugin"), "");

            programName = "";

            AudioPluginInstance *plugin =
                    instrument->getPlugin(Instrument::SYNTH_PLUGIN_POSITION);
            if (plugin)
                programName = strtoqstr(plugin->getDisplayName());
        }

        if (programName != "")
            instrumentName += " (" + programName + ")";

        // cut off the redundant eg. "General MIDI Device" that appears in the
        // combo right above here anyway
        instrumentName = instrumentName.mid(
                instrumentName.indexOf("#"), instrumentName.length());

        instrumentNames.push_back(instrumentName);
    }

    // If there has been an actual change
    if (instrumentIds != m_instrumentIds2  ||
        instrumentNames != m_instrumentNames2) {

        // Update the cache.
        m_instrumentIds2 = instrumentIds;
        m_instrumentNames2 = instrumentNames;

        // Reload the combobox

        m_instrument->clear();

        // For each instrument, add the name to the combobox.
        // ??? If we used a QStringList, we could just call addItems().
        for (size_t instrumentIndex = 0;
             instrumentIndex < m_instrumentNames2.size();
             ++instrumentIndex) {
            m_instrument->addItem(m_instrumentNames2[instrumentIndex]);
        }
    }

    // Find the current instrument in the instrument ID list.

    const InstrumentId instrumentId = instrument->getId();

    // Assume not found.
    int currentIndex = -1;

    // For each Instrument
    for (size_t instrumentIndex = 0;
         instrumentIndex < m_instrumentIds2.size();
         ++instrumentIndex) {
        // If this is the selected Instrument
        if (m_instrumentIds2[instrumentIndex] == instrumentId) {
            currentIndex = instrumentIndex;
            break;
        }
    }

    // Set the index.
    m_instrument->setCurrentIndex(currentIndex);
}
Ejemplo n.º 20
0
		virtual void menuItemSelected(int menuItemID, int)
		{
			if (menuItemID == 200)
			{
				WildcardFileFilter wildcardFilter("*.mid", String::empty, "Midi files");
				FileBrowserComponent browser(FileBrowserComponent::canSelectFiles | FileBrowserComponent::openMode, 
					lastOpenedFile.exists() ? lastOpenedFile : File(String("C:\\Users\\GeorgeKrueger\\Documents")), &wildcardFilter, nullptr);
				FileChooserDialogBox dialogBox("Open a midi file",
					"Please choose a midi file to open...",
					browser,
					false,
					Colours::lightgrey);

				if (dialogBox.show())
				{
					File selectedFile = browser.getSelectedFile(0);
					lastOpenedFile = selectedFile;
					FileInputStream fileStream(selectedFile);
					juce::MidiFile midiFile;
					midiFile.readFrom(fileStream);
					int numTracks = midiFile.getNumTracks();
					midiFile.convertTimestampTicksToSeconds();
					String msg;
					msg << "Opened midi file: " << selectedFile.getFileName() << " Tracks: " << numTracks << "\n";
					log(msg);

					for (int i = 0; i < numTracks; ++i)
					{
						const MidiMessageSequence* msgSeq = midiFile.getTrack(i);
						
						OwnedArray<PluginDescription> results;
						String plugFile = "C:\\VST\\FMMF.dll";
						VSTPluginFormat vstFormat;
						vstFormat.findAllTypesForFile(results, plugFile);
						if (results.size() > 0) {
							msg.clear();
							msg << "Found " << results.size() << " plugin(s) matching file " << plugFile << "\n";
							log(msg);

							int secsToRender = 10;
							double sampleRate = 44100;
							int totalSizeInSamples = static_cast<int>(44100 * secsToRender);
							AudioPluginInstance* plugInst = vstFormat.createInstanceFromDescription(*results[0], sampleRate, totalSizeInSamples);
							if (!plugInst) {
								msg.clear();
								msg << "Failed to load plugin " << plugFile << "\n";
								log(msg);
								continue;
							}

							int numInputChannels = plugInst->getTotalNumInputChannels();
							int numOutputChannels = plugInst->getTotalNumOutputChannels();
							msg.clear();
							msg << "Plugin input channels: " << numInputChannels << " output channels: " << numOutputChannels 
								<< " Current program: " << plugInst->getCurrentProgram() << "\n";
							log(msg);

							int maxChannels = std::max(numInputChannels, numOutputChannels);
							AudioBuffer<float> buffer(maxChannels, totalSizeInSamples);
							
							MidiBuffer midiMessages;
							for (int j = 0; j < msgSeq->getNumEvents(); ++j)
							{
								MidiMessageSequence::MidiEventHolder* midiEventHolder = msgSeq->getEventPointer(j);
								MidiMessage midiMsg = midiEventHolder->message;
								int samplePos = static_cast<int>(midiMsg.getTimeStamp() * sampleRate);
								midiMessages.addEvent(midiMsg, samplePos);
							}

							plugInst->prepareToPlay(sampleRate, totalSizeInSamples);
							plugInst->processBlock(buffer, midiMessages);

							/*File txtOutFile("C:\\Users\\GeorgeKrueger\\Documents\\GitHub\\soundserver2\\out.txt");
							FileOutputStream* txtOutStream = txtOutFile.createOutputStream();
							for (int j = 0; j < 44100; ++j)
							{
								float sample = buffer.getSample(0, j);
								txtOutStream->writeFloat(sample);
								txtOutStream->writeText(" ", true, false);
							}*/

							File outputFile("C:\\Users\\GeorgeKrueger\\Documents\\GitHub\\soundserver2\\out.wav");
							if (outputFile.exists()) {
								outputFile.deleteFile();
							}
							FileOutputStream* fileOutputStream = outputFile.createOutputStream();
							WavAudioFormat wavFormat;
							StringPairArray metadataValues;
							juce::AudioFormatWriter* wavFormatWriter = wavFormat.createWriterFor(
								fileOutputStream, sampleRate, 2, 16, metadataValues, 0);
							bool writeAudioDataRet = wavFormatWriter->writeFromAudioSampleBuffer(buffer, 0, buffer.getNumSamples());
							wavFormatWriter->flush();

							msg.clear();
							msg << "Done writing to output file " << outputFile.getFileName() << " . Write return value: " 
								<< (int)writeAudioDataRet << "\n";
							log(msg);

							delete wavFormatWriter;
							delete plugInst;
						}
						else {
							msg.clear();
							msg << "Could not find plugin from file " << plugFile << "\n";
							log(msg);
						}
					}
				}
			}
		}
Ejemplo n.º 21
0
// ??? Break this stuff off into an InstrumentPopup class.  This class is too
//     big.
void
TrackButtons::populateInstrumentPopup(Instrument *thisTrackInstr, QMenu* instrumentPopup)
{
    // pixmaps for icons to show connection states as variously colored boxes
    // ??? Factor out the icon-related stuff to make this routine clearer.
    //     getIcon(Instrument *) would be ideal, but might not be easy.
    //     getIcon(Device *) would also be needed.
    static QPixmap connectedPixmap, unconnectedPixmap,
                   connectedUsedPixmap, unconnectedUsedPixmap,
                   connectedSelectedPixmap, unconnectedSelectedPixmap;

    static bool havePixmaps = false;
        
    if (!havePixmaps) {

        IconLoader il;
        
        connectedPixmap = il.loadPixmap("connected");
        connectedUsedPixmap = il.loadPixmap("connected-used");
        connectedSelectedPixmap = il.loadPixmap("connected-selected");
        unconnectedPixmap = il.loadPixmap("unconnected");
        unconnectedUsedPixmap = il.loadPixmap("unconnected-used");
        unconnectedSelectedPixmap = il.loadPixmap("unconnected-selected");

        havePixmaps = true;
    }

    Composition &comp = m_doc->getComposition();

    // clear the popup
    instrumentPopup->clear();

    QMenu *currentSubMenu = 0;

    // position index
    int count = 0;

    int currentDevId = -1;

    // Get the list
    Studio &studio = m_doc->getStudio();
    InstrumentList list = studio.getPresentationInstruments();

    // For each instrument
    for (InstrumentList::iterator it = list.begin(); it != list.end(); ++it) {

        if (!(*it)) continue; // sanity check

        // get the Localized instrument name, with the string hackery performed
        // in Instrument
        QString iname((*it)->getLocalizedPresentationName());

        // translate the program name
        //
        // Note we are converting the string from std to Q back to std then to
        // C.  This is obviously ridiculous, but the fact that we have programName
        // here at all makes me think it exists as some kind of necessary hack
        // to coax tr() into behaving nicely.  I decided to change it as little
        // as possible to get it to compile, and not refactor this down to the
        // simplest way to call tr() on a C string.
        QString programName(strtoqstr((*it)->getProgramName()));
        programName = QObject::tr(programName.toStdString().c_str());

        Device *device = (*it)->getDevice();
        DeviceId devId = device->getId();
        bool connectedIcon = false;

        // Determine the proper program name and whether it is connected

        if ((*it)->getType() == Instrument::SoftSynth) {
            programName = "";
            AudioPluginInstance *plugin =
                    (*it)->getPlugin(Instrument::SYNTH_PLUGIN_POSITION);
            if (plugin) {
                // we don't translate any plugin program names or other texts
                programName = strtoqstr(plugin->getDisplayName());
                connectedIcon = (plugin->getIdentifier() != "");
            }
        } else if ((*it)->getType() == Instrument::Audio) {
            connectedIcon = true;
        } else {
            QString conn = RosegardenSequencer::getInstance()->
                    getConnection(devId);
            connectedIcon = (conn != "");
        }

        // These two are for selecting the correct icon to display.
        bool instrUsedByMe = false;
        bool instrUsedByAnyone = false;

        if (thisTrackInstr && thisTrackInstr->getId() == (*it)->getId()) {
            instrUsedByMe = true;
            instrUsedByAnyone = true;
        }

        // If we have switched to a new device, we'll create a new submenu
        if (devId != (DeviceId)(currentDevId)) {

            currentDevId = int(devId);

            // For selecting the correct icon to display.
            bool deviceUsedByAnyone = false;

            if (instrUsedByMe)
                deviceUsedByAnyone = true;
            else {
                for (Composition::trackcontainer::iterator tit =
                         comp.getTracks().begin();
                     tit != comp.getTracks().end(); ++tit) {

                    if (tit->second->getInstrument() == (*it)->getId()) {
                        instrUsedByAnyone = true;
                        deviceUsedByAnyone = true;
                        break;
                    }

                    Instrument *instr =
                        studio.getInstrumentById(tit->second->getInstrument());
                    if (instr && (instr->getDevice()->getId() == devId)) {
                        deviceUsedByAnyone = true;
                    }
                }
            }

            QIcon icon
                (connectedIcon ?
                 (deviceUsedByAnyone ?
                  connectedUsedPixmap : connectedPixmap) :
                 (deviceUsedByAnyone ?
                  unconnectedUsedPixmap : unconnectedPixmap));

            // Create a submenu for this device
            QMenu *subMenu = new QMenu(instrumentPopup);
            subMenu->setMouseTracking(true);
            subMenu->setIcon(icon);
            // Not needed so long as AA_DontShowIconsInMenus is false.
            //subMenu->menuAction()->setIconVisibleInMenu(true);

            // Menu title
            QString deviceName = QObject::tr(device->getName().c_str());
            subMenu->setTitle(deviceName);

            // QObject name
            subMenu->setObjectName(deviceName);

            // Add the submenu to the popup menu
            instrumentPopup->addMenu(subMenu);

            // Connect the submenu to slotInstrumentSelected()
            connect(subMenu, SIGNAL(triggered(QAction*)),
                    this, SLOT(slotInstrumentSelected(QAction*)));

            currentSubMenu = subMenu;

        } else if (!instrUsedByMe) {