void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSection> tabs) { clearConnections(); // clear processor graph std::cout << "Updating connections:" << std::endl; std::cout << std::endl; std::cout << std::endl; Array<GenericProcessor*> splitters; // GenericProcessor* activeSplitter = nullptr; for (int n = 0; n < tabs.size(); n++) // cycle through the tabs { std::cout << "Signal chain: " << n << std::endl; std::cout << std::endl; GenericEditor* sourceEditor = (GenericEditor*) tabs[n]->getEditor(); GenericProcessor* source = (GenericProcessor*) sourceEditor->getProcessor(); while (source != nullptr)// && destEditor->isEnabled()) { std::cout << "Source node: " << source->getName() << "." << std::endl; GenericProcessor* dest = (GenericProcessor*) source->getDestNode(); if (source->enabledState()) { // add the connections to audio and record nodes if necessary if (!(source->isSink() || source->isSplitter() || source->isMerger() || source->isUtility()) && !(source->wasConnected)) { std::cout << " Connecting to audio and record nodes." << std::endl; connectProcessorToAudioAndRecordNodes(source); } else { std::cout << " NOT connecting to audio and record nodes." << std::endl; } if (dest != nullptr) { while (dest->isMerger()) // find the next dest that's not a merger { dest = dest->getDestNode(); if (dest == nullptr) break; } if (dest != nullptr) { while (dest->isSplitter()) { if (!dest->wasConnected) { if (!splitters.contains(dest)) { splitters.add(dest); dest->switchIO(0); // go down first path } else { int splitterIndex = splitters.indexOf(dest); splitters.remove(splitterIndex); dest->switchIO(1); // go down second path dest->wasConnected = true; // make sure we don't re-use this splitter } } dest = dest->getDestNode(); if (dest == nullptr) break; } if (dest != nullptr) { if (dest->enabledState()) { connectProcessors(source, dest); } } } else { std::cout << " No dest node." << std::endl; } } else { std::cout << " No dest node." << std::endl; } } std::cout << std::endl; source->wasConnected = true; source = dest; // switch source and dest if (source == nullptr && splitters.size() > 0) { source = splitters.getLast(); GenericProcessor* newSource;// = source->getSourceNode(); while (source->isSplitter() || source->isMerger()) { newSource = source->getSourceNode(); newSource->setPathToProcessor(source); source = newSource; } } } // end while source != 0 } // end "tabs" for loop } // end method
void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSection> tabs) { clearConnections(); // clear processor graph std::cout << "Updating connections:" << std::endl; Array<GenericProcessor*> splitters; for (int n = 0; n < tabs.size(); n++) { std::cout << "Signal chain " << n << std::endl; GenericEditor* sourceEditor = (GenericEditor*) tabs[n]->getEditor(); GenericProcessor* source = (GenericProcessor*) sourceEditor->getProcessor(); while (source != 0)// && destEditor->isEnabled()) { std::cout << "Source node: " << source->getName() << ", "; GenericProcessor* dest = (GenericProcessor*) source->getDestNode(); if (dest != 0) { std::cout << "Dest node: " << dest->getName() << std::endl; if (dest->isMerger()) // move it forward by one { dest = dest->getDestNode(); } else if (dest->isSplitter()) { if (!dest->wasConnected) splitters.add(dest); dest = dest->getDestNode(); } } else { std::cout << "no dest node." << std::endl; } if (source->enabledState()) { // add the connections to audio and record nodes if necessary if (!(source->isSink() || source->isSplitter() || source->isMerger() || source->isUtility()) && !(source->wasConnected)) { std::cout << " Connecting to audio and record nodes." << std::endl; //source->setStartChannel(getAudioNode()->getNextChannel(false)); for (int chan = 0; chan < source->getNumOutputs(); chan++) { getAudioNode()->addInputChannel(source, chan); getAudioNode()->settings.sampleRate = source->getSampleRate(); // THIS IS A HACK TO MAKE SURE AUDIO NODE KNOWS WHAT THE SAMPLE RATE SHOULD BE // std::cout << "Connecting to audio channel: " << // getAudioNode()->getNextChannel(false) << std::endl; //getAudioNode()->enableCurrentChannel(source->audioStatus(chan)); addConnection(source->getNodeId(), // sourceNodeID chan, // sourceNodeChannelIndex AUDIO_NODE_ID, // destNodeID getAudioNode()->getNextChannel(true)); // destNodeChannelIndex // add 2 to account for 2 output channels //std::cout << getAudioNode()->getNextChannel(false) << " "; getRecordNode()->addInputChannel(source, chan); // std::cout << "Connecting to record channel: " << // getRecordNode()->getNextChannel(false) << std::endl; addConnection(source->getNodeId(), // sourceNodeID chan, // sourceNodeChannelIndex RECORD_NODE_ID, // destNodeID getRecordNode()->getNextChannel(true)); // destNodeChannelIndex } // connect event channel addConnection(source->getNodeId(), // sourceNodeID midiChannelIndex, // sourceNodeChannelIndex RECORD_NODE_ID, // destNodeID midiChannelIndex); // destNodeChannelIndex // connect event channel addConnection(source->getNodeId(), // sourceNodeID midiChannelIndex, // sourceNodeChannelIndex AUDIO_NODE_ID, // destNodeID midiChannelIndex); // destNodeChannelIndex getRecordNode()->addInputChannel(source, midiChannelIndex); } std::cout << std::endl; if (dest != 0) { if (dest->enabledState()) std::cout << " OK." << std::endl; else std::cout << " Not OK." << std::endl; if (dest->enabledState()) { std::cout << " Connecting " << source->getName() << " channel "; for (int chan = 0; chan < source->getNumOutputs(); chan++) { std::cout << chan << " "; addConnection(source->getNodeId(), // sourceNodeID chan, // sourceNodeChannelIndex dest->getNodeId(), // destNodeID dest->getNextChannel(true)); // destNodeChannelIndex } std::cout << " to " << dest->getName() << std::endl; std::cout << " Connecting " << source->getName() << " event channel to " << dest->getName() << std::endl; // connect event channel addConnection(source->getNodeId(), // sourceNodeID midiChannelIndex, // sourceNodeChannelIndex dest->getNodeId(), // destNodeID midiChannelIndex); // destNodeChannelIndex } } } source->wasConnected = true; source = dest; // switch source and dest if (source == 0 && splitters.size() > 0) { dest = splitters.getFirst(); // dest is now the splitter splitters.remove(0); // take it out of the dest->switchIO(); // switch to the other destination dest->wasConnected = true; // don't want to re-add splitter source = dest->getSourceNode(); // splitter is now source } } // end while source != 0 } // end "tabs" for loop } // end method
void JUCEApplication::getAllCommands (Array <CommandID>& commands) { commands.add (StandardApplicationCommandIDs::quit); }
void SpikeDetectorEditor::buttonEvent(Button* button) { if (electrodeEditorButtons[0]->getToggleState()) // EDIT is active { std::cout << "Editing active." << std::endl; if (electrodeButtons.contains((ElectrodeButton*) button)) { ElectrodeButton* eb = (ElectrodeButton*) button; int electrodeNum = eb->getChannelNum()-1; std::cout << "Channel number: " << electrodeNum << std::endl; Array<int> a; a.add(electrodeNum); channelSelector->setActiveChannels(a); SpikeDetector* processor = (SpikeDetector*) getProcessor(); thresholdSlider->setActive(true); thresholdSlider->setValue(processor->getChannelThreshold(electrodeList->getSelectedItemIndex(), electrodeButtons.indexOf((ElectrodeButton*) button))); } } int num = numElectrodes->getText().getIntValue(); if (button == upButton) { numElectrodes->setText(String(++num), true); return; } else if (button == downButton) { if (num > 1) numElectrodes->setText(String(--num), true); return; } else if (button == plusButton) { // std::cout << "Plus button pressed!" << std::endl; int type = electrodeTypes->getSelectedId(); std::cout << type << std::endl; int nChans; switch (type) { case 1: nChans = 1; break; case 2: nChans = 2; break; case 3: nChans = 4; break; default: nChans = 1; } for (int n = 0; n < num; n++) { if (!addElectrode(nChans)) { sendActionMessage("Not enough channels to add electrode."); } } refreshElectrodeList(); if (electrodeList->getNumItems() > 0) { electrodeList->setSelectedId(electrodeList->getNumItems(), true); electrodeList->setText(electrodeList->getItemText(electrodeList->getNumItems()-1)); lastId = electrodeList->getNumItems(); electrodeList->setEditableText(true); drawElectrodeButtons(electrodeList->getNumItems()-1); } getEditorViewport()->makeEditorVisible(this, true, true); return; } else if (button == electrodeEditorButtons[0]) // EDIT { Array<int> activeChannels; for (int i = 0; i < electrodeButtons.size(); i++) { if (button->getToggleState()) { electrodeButtons[i]->setToggleState(false, false); electrodeButtons[i]->setRadioGroupId(299); channelSelector->activateButtons(); channelSelector->setRadioStatus(true); } else { electrodeButtons[i]->setToggleState(true, false); electrodeButtons[i]->setRadioGroupId(0); channelSelector->inactivateButtons(); channelSelector->setRadioStatus(false); activeChannels.add(electrodeButtons[i]->getChannelNum()-1); } } if (!button->getToggleState()) { thresholdSlider->setActive(false); // This will be -1 with nothing selected int selectedItemIndex = electrodeList->getSelectedItemIndex(); if (selectedItemIndex != -1) { drawElectrodeButtons(selectedItemIndex); } else { electrodeButtons.clear(); } } // channelSelector->setActiveChannels(activeChannels); return; } else if (button == electrodeEditorButtons[1]) // MONITOR { return; } else if (button == electrodeEditorButtons[2]) // DELETE { removeElectrode(electrodeList->getSelectedItemIndex()); getEditorViewport()->makeEditorVisible(this, true, true); return; } }
//------------------------------------------------------------------------------ //values: mass-type, parameters, identifier ValueTree MDLParser::getMassTree(const String& line, RegularExpression& re) { StringArray values; re.fullMatchValues(line, values, 3); ValueTree newTree = ObjectFactory::getMassTreeFromStringId(values[0]); if (!newTree.isValid()) { throw std::runtime_error("Cannot parse mass-like object"); } const Point<int> pos = getPos(line); newTree.setProperty(Ids::posX, pos.getX(), nullptr); newTree.setProperty(Ids::posY, pos.getY(), nullptr); if (newTree.getType() != Ids::port && newTree.getType() != Ids::ground) { StringArray paramsArray = MDLHelper::getParamsFromString(values[1]); if (newTree.getType() == Ids::resonators) { static const int NUM_RES_PARAMS = 3; if(paramsArray.size() % NUM_RES_PARAMS == 0) { ValueTree paramsTree(Ids::parameters); Array<ValueTree> valuesArr; for (int np = 0; np < NUM_RES_PARAMS; ++np) { valuesArr.add(ValueTree(Ids::parameter)); } for (int n = 0; n < paramsArray.size(); ++n) { const int paramIdx = n % NUM_RES_PARAMS; ValueTree subVal(ObjectsHelper::getResonatorParamsIds()[paramIdx]); subVal.setProperty(Ids::value, paramsArray[n].trim(), nullptr); valuesArr[paramIdx].addChild(subVal, -1, nullptr); } for (int np = 0; np < NUM_RES_PARAMS; ++np) { paramsTree.addChild(valuesArr[np], -1, nullptr); } newTree.addChild(paramsTree, -1, nullptr); } } else { newTree.addChild(ObjectFactory::createParamsTree(paramsArray), -1, nullptr); } } else if (newTree.getType() == Ids::ground) { ValueTree paramsTree(Ids::parameters); ValueTree param(Ids::parameter); param.setProperty(Ids::value, values[1].trim(), nullptr); paramsTree.addChild(param, -1, nullptr); newTree.addChild(paramsTree, -1, nullptr); } newTree.setProperty(Ids::identifier, values[2].trim(), nullptr); return newTree; }
void ColouredElement::getColourSpecificProperties (Array <PropertyComponent*>& props) { props.add (new ElementFillModeProperty (this, false)); switch (getFillType().mode) { case JucerFillType::solidColour: props.add (new ElementFillColourProperty ("colour", this, ElementFillColourProperty::solidColour, false)); break; case JucerFillType::linearGradient: case JucerFillType::radialGradient: props.add (new ElementFillColourProperty ("colour 1", this, ElementFillColourProperty::gradientColour1, false)); props.add (new ElementFillPositionProperty (this, "x1", PositionPropertyBase::componentX, true, false)); props.add (new ElementFillPositionProperty (this, "y1", PositionPropertyBase::componentY, true, false)); props.add (new ElementFillColourProperty ("colour 2", this, ElementFillColourProperty::gradientColour2, false)); props.add (new ElementFillPositionProperty (this, "x2", PositionPropertyBase::componentX, false, false)); props.add (new ElementFillPositionProperty (this, "y2", PositionPropertyBase::componentY, false, false)); break; case JucerFillType::imageBrush: props.add (new ImageBrushResourceProperty (this, false)); props.add (new ImageBrushPositionProperty (this, "anchor x", PositionPropertyBase::componentX, false)); props.add (new ImageBrushPositionProperty (this, "anchor y", PositionPropertyBase::componentY, false)); props.add (new ImageBrushOpacityProperty (this, false)); break; default: jassertfalse; break; } if (showOutline) { props.add (new EnableStrokeProperty (this)); if (isStrokePresent) { props.add (new StrokeThicknessProperty (this)); if (showJointAndEnd) { props.add (new StrokeJointProperty (this)); props.add (new StrokeEndCapProperty (this)); } props.add (new ElementFillModeProperty (this, true)); switch (getStrokeType().fill.mode) { case JucerFillType::solidColour: props.add (new ElementFillColourProperty ("colour", this, ElementFillColourProperty::solidColour, true)); break; case JucerFillType::linearGradient: case JucerFillType::radialGradient: props.add (new ElementFillColourProperty ("colour 1", this, ElementFillColourProperty::gradientColour1, true)); props.add (new ElementFillPositionProperty (this, "x1", PositionPropertyBase::componentX, true, true)); props.add (new ElementFillPositionProperty (this, "y1", PositionPropertyBase::componentY, true, true)); props.add (new ElementFillColourProperty ("colour 2", this, ElementFillColourProperty::gradientColour2, true)); props.add (new ElementFillPositionProperty (this, "x2", PositionPropertyBase::componentX, false, true)); props.add (new ElementFillPositionProperty (this, "y2", PositionPropertyBase::componentY, false, true)); break; case JucerFillType::imageBrush: props.add (new ImageBrushResourceProperty (this, true)); props.add (new ImageBrushPositionProperty (this, "stroke anchor x", PositionPropertyBase::componentX, true)); props.add (new ImageBrushPositionProperty (this, "stroke anchor y", PositionPropertyBase::componentY, true)); props.add (new ImageBrushOpacityProperty (this, true)); break; default: jassertfalse; break; } } } }
//============================================================================== void PaintElementPath::getEditableProperties (Array <PropertyComponent*>& properties) { properties.add (new PathWindingModeProperty (this)); getColourSpecificProperties (properties); }
void AssetTree::addGroups (const StringArray& groups, Array<Item>& result) { for (const String& g : groups) result.add (addGroup (g)); }
void FileChooser::showPlatformDialog (Array<File>& results, const String& title_, const File& currentFileOrDirectory, const String& filter, bool selectsDirectory, bool /*selectsFiles*/, bool isSaveDialogue, bool warnAboutOverwritingExistingFiles, bool selectMultipleFiles, FilePreviewComponent* extraInfoComponent) { using namespace FileChooserHelpers; const String title (title_); HeapBlock<WCHAR> files; const int charsAvailableForResult = 32768; files.calloc (charsAvailableForResult + 1); int filenameOffset = 0; FileChooserCallbackInfo info; // use a modal window as the parent for this dialog box // to block input from other app windows Component parentWindow (String::empty); const Rectangle<int> mainMon (Desktop::getInstance().getMainMonitorArea()); parentWindow.setBounds (mainMon.getX() + mainMon.getWidth() / 4, mainMon.getY() + mainMon.getHeight() / 4, 0, 0); parentWindow.setOpaque (true); parentWindow.setAlwaysOnTop (areThereAnyAlwaysOnTopWindows()); parentWindow.addToDesktop (0); if (extraInfoComponent == nullptr) parentWindow.enterModalState(); if (currentFileOrDirectory.isDirectory()) { info.initialPath = currentFileOrDirectory.getFullPathName(); } else { currentFileOrDirectory.getFileName().copyToUTF16 (files, charsAvailableForResult * sizeof (WCHAR)); info.initialPath = currentFileOrDirectory.getParentDirectory().getFullPathName(); } if (selectsDirectory) { BROWSEINFO bi = { 0 }; bi.hwndOwner = (HWND) parentWindow.getWindowHandle(); bi.pszDisplayName = files; bi.lpszTitle = title.toWideCharPointer(); bi.lParam = (LPARAM) &info; bi.lpfn = browseCallbackProc; #ifdef BIF_USENEWUI bi.ulFlags = BIF_USENEWUI | BIF_VALIDATE; #else bi.ulFlags = 0x50; #endif LPITEMIDLIST list = SHBrowseForFolder (&bi); if (! SHGetPathFromIDListW (list, files)) { files[0] = 0; info.returnedString = String::empty; } LPMALLOC al; if (list != 0 && SUCCEEDED (SHGetMalloc (&al))) al->Free (list); if (info.returnedString.isNotEmpty()) { results.add (File (String (files)).getSiblingFile (info.returnedString)); return; } } else { DWORD flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY; if (warnAboutOverwritingExistingFiles) flags |= OFN_OVERWRITEPROMPT; if (selectMultipleFiles) flags |= OFN_ALLOWMULTISELECT; if (extraInfoComponent != nullptr) { flags |= OFN_ENABLEHOOK; info.customComponent = new CustomComponentHolder (extraInfoComponent); info.customComponent->enterModalState(); } const int filterSpaceNumChars = 2048; HeapBlock<WCHAR> filters; filters.calloc (filterSpaceNumChars); const int bytesWritten = filter.copyToUTF16 (filters.getData(), filterSpaceNumChars * sizeof (WCHAR)); filter.copyToUTF16 (filters + (bytesWritten / sizeof (WCHAR)), (int) ((filterSpaceNumChars - 1) * sizeof (WCHAR) - bytesWritten)); OPENFILENAMEW of = { 0 }; String localPath (info.initialPath); #ifdef OPENFILENAME_SIZE_VERSION_400W of.lStructSize = OPENFILENAME_SIZE_VERSION_400W; #else of.lStructSize = sizeof (of); #endif of.hwndOwner = (HWND) parentWindow.getWindowHandle(); of.lpstrFilter = filters.getData(); of.nFilterIndex = 1; of.lpstrFile = files; of.nMaxFile = charsAvailableForResult; of.lpstrInitialDir = localPath.toWideCharPointer(); of.lpstrTitle = title.toWideCharPointer(); of.Flags = flags; of.lCustData = (LPARAM) &info; if (extraInfoComponent != nullptr) of.lpfnHook = &openCallback; if (! (isSaveDialogue ? GetSaveFileName (&of) : GetOpenFileName (&of))) return; filenameOffset = of.nFileOffset; } if (selectMultipleFiles && filenameOffset > 0 && files [filenameOffset - 1] == 0) { const WCHAR* filename = files + filenameOffset; while (*filename != 0) { results.add (File (String (files) + "\\" + String (filename))); filename += wcslen (filename) + 1; } } else if (files[0] != 0) { results.add (File (String (files))); } }
bool MDLParser::parseMDL(const File& f) { RegularExpression re; RegularExpression reComment("\\A\\s*#[^#].*$"); const File& in = f;//mdlFile.getFile(); String mdlContent = in.loadFileAsString(); ValueTree mdlTree(Objects::synthamodeler);// = mdlFile.mdlRoot; mdlTree.setProperty(Ids::mdlName, in.getFileName(), nullptr); mdlTree.setProperty(Ids::mdlPath, in.getFullPathName(), nullptr); StringArray lines; lines.addTokens(mdlContent, "\n", "\""); for (int i = 0; i < lines.size(); ++i) { String line = lines[i]; if(reComment.fullMatch(line) || line.isEmpty()) { continue; } if(re.fullMatch(SAMRegex::getVertexLine(), line)) { StringArray values; re.fullMatchValues(line, values, 4); ValueTree newTree; if (values[0].compare("mass") == 0) { newTree = ValueTree(Ids::mass); } else if (values[0].compare("port") == 0) { newTree = ValueTree(Ids::port); } else if (values[0].compare("ground") == 0) { newTree = ValueTree(Ids::ground); } else if (values[0].compare("resonators") == 0) { newTree = ValueTree(Ids::resonators); } else { DBG("Something went really wrong!"); return false; } Point<int> pos = getPos(line); newTree.setProperty(Ids::posX, pos.getX(), nullptr); newTree.setProperty(Ids::posY, pos.getY(), nullptr); if(newTree.getType() != Ids::port && newTree.getType() != Ids::ground) { StringArray paramsArray = MDLHelper::getParamsFromString(values[1]); if(newTree.getType() == Ids::resonators) { static const int NUM_RES_PARAMS = 3; if(paramsArray.size() % NUM_RES_PARAMS == 0) { ValueTree paramsTree(Ids::parameters); Array<ValueTree> valuesArr; for (int np = 0; np < NUM_RES_PARAMS; ++np) { valuesArr.add(ValueTree(Ids::parameter)); } for (int n = 0; n < paramsArray.size(); ++n) { const int paramIdx = n % NUM_RES_PARAMS; ValueTree subVal(ObjectsHelper::getResonatorParamsIds()[paramIdx]); subVal.setProperty(Ids::value, paramsArray[n].trim(), nullptr); valuesArr[paramIdx].addChild(subVal, -1, nullptr); } for (int np = 0; np < NUM_RES_PARAMS; ++np) { paramsTree.addChild(valuesArr[np], -1, nullptr); } newTree.addChild(paramsTree, -1, nullptr); } } else { newTree.addChild(ObjectFactory::createParamsTree(paramsArray), -1, nullptr); } } if(newTree.getType() == Ids::ground) { ValueTree paramsTree(Ids::parameters); ValueTree param(Ids::parameter); param.setProperty(Ids::value, values[1].trim(), nullptr); paramsTree.addChild(param, -1, nullptr); newTree.addChild(paramsTree, -1, nullptr); } newTree.setProperty(Ids::identifier, values[2].trim(), nullptr); ValueTree masses = mdlTree.getOrCreateChildWithName(Objects::masses, nullptr); masses.addChild(newTree, -1, nullptr); } else if(re.fullMatch(SAMRegex::getLinkLine(), line)) { StringArray values; re.fullMatchValues(line, values, 5); ValueTree linkTree; if (values[0].compare("link") == 0) { linkTree = ValueTree(Ids::link); } else if (values[0].compare("touch") == 0) { linkTree = ValueTree(Ids::touch); } else if (values[0].compare("pulsetouch") == 0) { linkTree = ValueTree(Ids::pulsetouch); } else if (values[0].compare("pluck") == 0) { linkTree = ValueTree(Ids::pluck); } else if (values[0].compare("detent") == 0) { linkTree = ValueTree(Ids::detent); } else if (values[0].compare("softeninglink") == 0) { linkTree = ValueTree(Ids::softeninglink); } else if (values[0].compare("stiffeninglink") == 0) { linkTree = ValueTree(Ids::stiffeninglink); } else { DBG("Something went really wrong!"); return false; } StringArray paramsArray = MDLHelper::getParamsFromString(values[1]); linkTree.addChild(ObjectFactory::createParamsTree(paramsArray), -1, nullptr); linkTree.setProperty(Ids::identifier, values[2].trim(), nullptr); linkTree.setProperty(Ids::startVertex, values[3].trim(), nullptr); linkTree.setProperty(Ids::endVertex, values[4].trim(), nullptr); ValueTree linksTree = mdlTree.getOrCreateChildWithName(Objects::links, nullptr); linksTree.addChild(linkTree, -1, nullptr); } else if(re.fullMatch(SAMRegex::getFaustCodeLine(), line)) { StringArray values; re.fullMatchValues(line, values, 1); ValueTree faustcodeTree(Ids::faustcode); faustcodeTree.setProperty(Ids::value, values[0].trim(), nullptr); ValueTree fcbTree = mdlTree.getOrCreateChildWithName(Objects::faustcodeblock, nullptr); fcbTree.addChild(faustcodeTree, -1, nullptr); } else if(re.fullMatch(SAMRegex::getAudioOutLine(), line)) { StringArray values; re.fullMatchValues(line, values, 3); Point<int> pos = getPos(line); ValueTree audioTree(Ids::audioout); audioTree.setProperty(Ids::posX, pos.x, nullptr); audioTree.setProperty(Ids::posY, pos.y, nullptr); audioTree.setProperty(Ids::identifier, values[0].trim(), nullptr); // split everything from line starting with first colon int posColon = values[1].indexOf(":"); String audioLine; if(posColon > 0) { audioLine = values[1].substring(0, posColon); audioLine = MDLHelper::removeUnbalancedParentheses(audioLine); audioTree.setProperty(Ids::optional,values[1].substring(posColon+1), nullptr); } else { audioTree.setProperty(Ids::optional, "", nullptr); audioLine = values[1]; } // add outputDSP to optional values if not present if(! audioTree[Ids::optional].toString().contains("outputDSP")) { String aoOpt = audioTree[Ids::optional].toString(); if(aoOpt.isNotEmpty()) { aoOpt = ":" + aoOpt; } String aoOpt2 = "outputDSP" + aoOpt; audioTree.setProperty(Ids::optional, aoOpt2, nullptr); } // remove unbalanced parentheses audioLine = MDLHelper::removeUnbalancedParentheses(audioLine); // remove surrounding paranthese if there are some. String audioLineClean = MDLHelper::removeSurroundingParentheses(audioLine); StringArray audioOutSourcesList; audioOutSourcesList.addTokens(audioLineClean, "+", "\""); ValueTree audioSources(Ids::sources); for (int l = 0; l < audioOutSourcesList.size(); ++l) { if(audioOutSourcesList[l].trim().compare("0.0") != 0) { ValueTree aoSource(Ids::audiosource); aoSource.setProperty(Ids::value, audioOutSourcesList[l].trim(), nullptr); audioSources.addChild(aoSource, -1, nullptr); } } audioTree.addChild(audioSources, -1, nullptr); ValueTree audioObjectsTree = mdlTree.getOrCreateChildWithName(Objects::audioobjects, nullptr); audioObjectsTree.addChild(audioTree, -1, nullptr); } else if(re.fullMatch(SAMRegex::getWaveguideLine(), line)) { StringArray values; re.fullMatchValues(line, values, 5); ValueTree waveguideTree(Ids::waveguide); StringArray paramsArray(values.begin(), 2); waveguideTree.addChild(ObjectFactory::createParamsTree(paramsArray), -1, nullptr); waveguideTree.setProperty(Ids::identifier, values[2].trim(), nullptr); waveguideTree.setProperty(Ids::startVertex, values[3].trim(), nullptr); waveguideTree.setProperty(Ids::endVertex, values[4].trim(), nullptr); ValueTree wavesTree = mdlTree.getOrCreateChildWithName(Objects::waveguides, nullptr); wavesTree.addChild(waveguideTree, -1, nullptr); } else if(re.fullMatch(SAMRegex::getTerminationLine(), line)) { StringArray values; re.fullMatchValues(line, values, 4); Point<int> pos = getPos(line); ValueTree terminationTree(Ids::termination); terminationTree.setProperty(Ids::posX, pos.x, nullptr); terminationTree.setProperty(Ids::posY, pos.y, nullptr); StringArray paramsArray = MDLHelper::getParamsFromString(values[1]); terminationTree.addChild(ObjectFactory::createParamsTree(paramsArray), -1, nullptr); terminationTree.setProperty(Ids::identifier, values[2].trim(), nullptr); ValueTree terminations = mdlTree.getOrCreateChildWithName(Objects::terminations, nullptr); terminations.addChild(terminationTree, -1, nullptr); } else if(re.fullMatch(SAMRegex::getJunctionLine(), line)) { StringArray values; re.fullMatchValues(line, values, 4); Point<int> pos = getPos(line); ValueTree junctTree(Ids::junction); junctTree.setProperty(Ids::posX, pos.x, nullptr); junctTree.setProperty(Ids::posY, pos.y, nullptr); ValueTree junctParams(Ids::parameters); ValueTree junctParam(Ids::parameter); junctParam.setProperty(Ids::value, values[1].trim(), nullptr); junctParams.addChild(junctParam, -1, nullptr); junctTree.addChild(junctParams, -1, nullptr); junctTree.setProperty(Ids::identifier, values[2].trim(), nullptr); ValueTree junctsTree = mdlTree.getOrCreateChildWithName(Objects::junctions, nullptr); junctsTree.addChild(junctTree, -1, nullptr); } else if(re.fullMatch(SAMRegex::getCommentObjectLine(), line)) { StringArray values; if(! re.fullMatchValues(line, values, 3)) { DBG("Error reading comment object!"); } ValueTree newTree(Ids::comment); Point<int> pos = getPos(line); newTree.setProperty(Ids::posX, pos.getX(), nullptr); newTree.setProperty(Ids::posY, pos.getY(), nullptr); newTree.setProperty(Ids::identifier, values[2], nullptr); StringArray paramsArray = MDLHelper::getParamsFromString(values[1]); StringArray commVal; commVal.addTokens(paramsArray[0].unquoted(), "|" , "\""); newTree.setProperty(Ids::value, commVal.joinIntoString("\n"), nullptr); newTree.setProperty(Ids::fontSize, paramsArray[1], nullptr); newTree.setProperty(Ids::commentColour, paramsArray[2], nullptr); ValueTree comments = mdlTree.getOrCreateChildWithName(Objects::comments, nullptr); comments.addChild(newTree, -1, nullptr); } } // DBG(mdlTree.toXmlString()); mdlFile.mdlRoot = mdlTree; return true; }
void CudaRenderer::constructBlurLUT(void) { // start by constructing low-discrepancy unit square int N = 100; // number of samples int S = 24; // max radius // init to random Array<Vec2f> pos; for (int i=0; i < N; i++) { Vec2f p; p.x = (float)hashBits(i) / (float)(((U64)1)<<32); p.y = (float)hashBits(i+N) / (float)(((U64)1)<<32); pos.add(p); } // relax by repulsion force Array<Vec2f> force; force.resize(N); for (int i=0; i < 20; i++) { for (int j=0; j < N; j++) { Vec2f f(0.f, 0.f); Vec2f p = pos[j]; for (int k=0; k < N; k++) { if (k==j) continue; Vec2f q = pos[k]; Vec2f d = p-q; if (d.x > .5f) d.x -= 1.f; if (d.y > .5f) d.y -= 1.f; if (d.x < -.5f) d.x += 1.f; if (d.y < -.5f) d.y += 1.f; float d2 = (d.x*d.x + d.y*d.y); float m = 1.f/d2; m *= .0001f; f += d.normalized() * m; } float flen = f.length(); flen = min(flen, .2f); f = f.normalized() * flen; force[j] = f; } for (int j=0; j < N; j++) { Vec2f p = pos[j]; p += force[j]; while (p.x > 1.f) p.x -= 1.f; while (p.y > 1.f) p.y -= 1.f; while (p.x < 0.f) p.x += 1.f; while (p.y < 0.f) p.y += 1.f; pos[j] = p; } } // form into a disc for (int i=0; i < N; i++) { Vec2f p = pos[i]; float an = p.x * 2.f * 3.14159f; float d = p.y; // inverse square weighting p.x = d * sinf(an); p.y = d * cosf(an); p = (p + 1.f) * .5f; pos[i] = p; } // work with pixels from now on Array<Vec2i> ipos; for (int i=0; i < N; i++) { Vec2f p = pos[i]; p.x = min(max(p.x, 0.f), 1.f); p.y = min(max(p.y, 0.f), 1.f); p = (pos[i] - .5f) * 2.f * (float)S; int x = (int)(p.x+.5f); int y = (int)(p.y+.5f); ipos.add(Vec2i(x, y)); } // trim set to unique pixels Set<Vec2i> used; Array<Vec2i> iposTemp = ipos; ipos.clear(); for (int i=0; i < N; i++) { Vec2i p = iposTemp[i]; if (used.contains(p)) continue; used.add(p); ipos.add(p); } N = ipos.getSize(); printf("CudaRenderer: blur LUT has %d samples\n", ipos.getSize()); // sort according to distance for (int i=0; i < N; i++) { int dmin = -1; int imin = 0; for (int j=i; j < N; j++) { Vec2i p = ipos[j]; int d = p.x*p.x + p.y*p.y; if (d < dmin || dmin < 0) { dmin = d; imin = j; } } swap(ipos[i], ipos[imin]); } // construct bitmap for support find Array<int> bmap; bmap.resize(4*S*S); for (int i=0; i < bmap.getSize(); i++) bmap[i] = -1; // blit seeds for (int i=0; i < N; i++) { Vec2i p = ipos[i]; p.x += S; p.y += S; p.x = min(max(p.x, 0), 2*S-1); p.y = min(max(p.y, 0), 2*S-1); bmap[p.x + 2*S*p.y] = i; } // fill until full for(;;) { Array<int> bmapTemp = bmap; bool changed = false; for (int y=0; y < 2*S; y++) for (int x=0; x < 2*S; x++) { int d2 = sqr(x-S) + sqr(y-S); if (d2 > S*S) continue; int b = bmap[x+2*S*y]; if (b >= 0) continue; int x0 = max(x-1, 0); int x1 = min(x+1, 2*S-1); int y0 = max(y-1, 0); int y1 = min(y+1, 2*S-1); for (int py=y0; py<=y1; py++) for (int px=x0; px<=x1; px++) { int c = bmap[px+2*S*py]; if (c >= 0) b = c; } if (b >= 0) { changed = true; bmapTemp[x+2*S*y] = b; } } if (!changed) break; bmap = bmapTemp; } // count weights Array<int> weight; weight.resize(N); for (int i=0; i < N; i++) weight[i] = 0; for (int i=0; i < 4*S*S; i++) { int b = bmap[i]; if (b >= 0) weight[b]++; } // construct lut for (int i=0; i < N; i++) m_blurLUT.add(Vec3i(ipos[i].x, ipos[i].y, weight[i])); // convert bitmap into lut #if 0 m_blurLUT.clear(); for (int y=0; y < 2*S; y++) for (int x=0; x < 2*S; x++) { int b = bmap[x+2*S*y]; if (b < 0) continue; m_blurLUT.add(Vec3i(x-S, y-S, hashBits(b))); } #endif }
void CudaCompiler::staticInit(void) { if (s_inited || hasError()) return; s_inited = true; // List potential CUDA and Visual Studio paths. Array<String> potentialCudaPaths; #ifdef _WIN32 F32 driverVersion = CudaModule::getDriverVersion() / 10.0f; Array<String> potentialVSPaths; for (char drive = 'C'; drive <= 'E'; drive++) { for (int progX86 = 0; progX86 <= 1; progX86++) { String prog = sprintf("%c:\\%s", drive, (progX86 == 0) ? "Program Files" : "Program Files (x86)"); potentialCudaPaths.add(prog + sprintf("\\NVIDIA GPU Computing Toolkit\\CUDA\\v%.1f", driverVersion)); potentialVSPaths.add(prog + "\\Microsoft Visual Studio 10.0"); potentialVSPaths.add(prog + "\\Microsoft Visual Studio 9.0"); potentialVSPaths.add(prog + "\\Microsoft Visual Studio 8"); } potentialCudaPaths.add(sprintf("%c:\\CUDA", drive)); } #else potentialCudaPaths.add("/usr"); #endif // Query environment variables. String pathEnv = queryEnv("PATH"); String includeEnv = queryEnv("INCLUDE"); String cudaBinEnv = queryEnv("CUDA_BIN_PATH"); String cudaIncEnv = queryEnv("CUDA_INC_PATH"); // Find CUDA binary path. Array<String> cudaBinList; if (s_staticCudaBinPath.getLength()) cudaBinList.add(s_staticCudaBinPath); else { cudaBinList.add(cudaBinEnv); splitPathList(cudaBinList, pathEnv); for (int i = 0; i < potentialCudaPaths.getSize(); i++) { cudaBinList.add(potentialCudaPaths[i] + SEPARATOR"bin"); cudaBinList.add(potentialCudaPaths[i] + SEPARATOR"bin64"); } } String cudaBinPath; for (int i = 0; i < cudaBinList.getSize(); i++) { if (!cudaBinList[i].getLength() || !fileExists(cudaBinList[i] + SEPARATOR NVCC)) continue; // Execute "nvcc --version". #ifdef _MSC_VER FILE* pipe = _popen(sprintf("\"%s"SEPARATOR NVCC"\" --version 2>nul", cudaBinList[i].getPtr()).getPtr(), "rt"); #else FILE* pipe = popen((String("\"") + cudaBinList[i] + SEPARATOR NVCC"\" --version 2>/dev/null").getPtr(), "r"); #endif if (!pipe) continue; Array<char> output; while (!feof(pipe)) output.add((char)fgetc(pipe)); #ifdef _MSC_VER fclose(pipe); #else pclose(pipe); #endif // Invalid response => ignore. output.add(0); String response(output.getPtr()); if (!response.startsWith("nvcc: NVIDIA")) continue; // Hash response. cudaBinPath = cudaBinList[i]; s_nvccVersionHash = hash<String>(response); break; } if (!cudaBinPath.getLength()) fail("Unable to detect CUDA Toolkit binary path!\nPlease set CUDA_BIN_PATH environment variable."); // Find Visual Studio binary path. #ifdef _MSC_VER Array<String> vsBinList; splitPathList(vsBinList, pathEnv); for (int i = 0; i < potentialVSPaths.getSize(); i++) vsBinList.add(potentialVSPaths[i] + "\\VC\\bin"); String vsBinPath; for (int i = 0; i < vsBinList.getSize(); i++) { if (vsBinList[i].getLength() && fileExists(vsBinList[i] + "\\vcvars32.bat")) { vsBinPath = vsBinList[i]; break; } } if (!vsBinPath.getLength()) fail("Unable to detect Visual Studio binary path!\nPlease run VCVARS32.BAT."); #endif // Find CUDA include path. Array<String> cudaIncList; cudaIncList.add(cudaBinPath + SEPARATOR".."SEPARATOR"include"); cudaIncList.add(cudaIncEnv); splitPathList(cudaIncList, includeEnv); #ifdef _WIN32 cudaIncList.add("C:\\CUDA\\include"); cudaIncList.add("D:\\CUDA\\include"); #else cudaIncList.add("/usr/include"); cudaIncList.add("/usr/lib/nvidia-cuda-toolkit/include"); #endif String cudaIncPath; for (int i = 0; i < cudaIncList.getSize(); i++) { if (cudaIncList[i].getLength() && fileExists(cudaIncList[i] + SEPARATOR"cuda.h")) { cudaIncPath = cudaIncList[i]; break; } } if (!cudaIncPath.getLength()) fail("Unable to detect CUDA Toolkit include path!\nPlease set CUDA_INC_PATH environment variable."); // Find Visual Studio include path. #ifdef _MSC_VER Array<String> vsIncList; vsIncList.add(vsBinPath + "\\..\\INCLUDE"); splitPathList(vsIncList, includeEnv); for (int i = 0; i < potentialVSPaths.getSize(); i++) vsIncList.add(potentialVSPaths[i] + "\\VC\\INCLUDE"); String vsIncPath; for (int i = 0; i < vsIncList.getSize(); i++) { if (vsIncList[i].getLength() && fileExists(vsIncList[i] + "\\crtdefs.h")) { vsIncPath = vsIncList[i]; break; } } if (!vsIncPath.getLength()) fail("Unable to detect Visual Studio include path!\nPlease run VCVARS32.BAT."); #endif // Form NVCC command line. #ifdef _MSV_VER s_nvccCommand = sprintf("set PATH=%s;%s & "NVCC" -ccbin \"%s\" -I\"%s\" -I\"%s\" -I. -D_CRT_SECURE_NO_DEPRECATE", cudaBinPath.getPtr(), pathEnv.getPtr(), vsBinPath.getPtr(), cudaIncPath.getPtr(), vsIncPath.getPtr()); #else s_nvccCommand = sprintf("PATH=%s:%s "NVCC" -I\"%s\" -I.", cudaBinPath.getPtr(), pathEnv.getPtr(), cudaIncPath.getPtr()); #endif }
void DiskInfoRequestHandler::handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) { Application& app = Application::instance(); app.logger().information("Start processing request from: "+request.clientAddress().toString()); Timestamp start; SharedPtr<HDDExplorer> explorer = hddExplorerCache.get(0); if(explorer.isNull()){ explorer = new HDDExplorer; hddExplorerCache.add(0, explorer); } Object responseObject; if((*explorer).isSuccessfullyDiscovered() && (*explorer).getAvailableHDDs().size()>0){ responseObject.set("found", true); vector<string> hdds = (*explorer).getAvailableHDDs(); Array disks; for(vector<string>::iterator iter = hdds.begin(); iter!=hdds.end(); iter++){ string hddPath = *iter; SharedPtr<DiskInfo> info = smartInfoCache.get(hddPath); if(info.isNull()){ info = new DiskInfo(hddPath); smartInfoCache.add(hddPath, info); } Object jsonObject = (*info).toJSONObject(); disks.add(jsonObject); } responseObject.set("disks", disks); } else { responseObject.set("found", false); } response.setContentType("application/javascript; charset=utf-8"); HTMLForm form(request); string callbackFunc = "callback"; if(form.has("callback") && !form.get("callback").empty()){ callbackFunc = form.get("callback"); } std::stringstream ostr; ostr<<callbackFunc<<"("; //send callback for JSONP responseObject.stringify(ostr); ostr<<")"; string serialized = ostr.str(); response.sendBuffer(serialized.c_str(), serialized.size());//connection keep-alive. We need to //know content-length Timestamp end; string secs = NumberFormatter::format((end-start)/1000)+" msecs"; app.logger().information("Request from: "+request.clientAddress().toString()+ " succesfully processed in "+secs); }
JackAudioIODeviceType() : AudioIODeviceType ("JACK"), hasScanned (false) { activeDeviceTypes.add (this); }
static void createStroke (const float thickness, const PathStrokeType::JointStyle jointStyle, const PathStrokeType::EndCapStyle endStyle, Path& destPath, const Path& source, const AffineTransform& transform, const float extraAccuracy, const Arrowhead* const arrowhead) { jassert (extraAccuracy > 0); if (thickness <= 0) { destPath.clear(); return; } const Path* sourcePath = &source; Path temp; if (sourcePath == &destPath) { destPath.swapWithPath (temp); sourcePath = &temp; } else { destPath.clear(); } destPath.setUsingNonZeroWinding (true); const float maxMiterExtensionSquared = 9.0f * thickness * thickness; const float width = 0.5f * thickness; // Iterate the path, creating a list of the // left/right-hand lines along either side of it... PathFlatteningIterator it (*sourcePath, transform, PathFlatteningIterator::defaultTolerance / extraAccuracy); Array <LineSection> subPath; subPath.ensureStorageAllocated (512); LineSection l; l.x1 = 0; l.y1 = 0; const float minSegmentLength = 0.0001f; while (it.next()) { if (it.subPathIndex == 0) { if (subPath.size() > 0) { addSubPath (destPath, subPath, false, width, maxMiterExtensionSquared, jointStyle, endStyle, arrowhead); subPath.clearQuick(); } l.x1 = it.x1; l.y1 = it.y1; } l.x2 = it.x2; l.y2 = it.y2; float dx = l.x2 - l.x1; float dy = l.y2 - l.y1; const float hypotSquared = dx*dx + dy*dy; if (it.closesSubPath || hypotSquared > minSegmentLength || it.isLastInSubpath()) { const float len = std::sqrt (hypotSquared); if (len == 0) { l.rx1 = l.rx2 = l.lx1 = l.lx2 = l.x1; l.ry1 = l.ry2 = l.ly1 = l.ly2 = l.y1; } else { const float offset = width / len; dx *= offset; dy *= offset; l.rx2 = l.x1 - dy; l.ry2 = l.y1 + dx; l.lx1 = l.x1 + dy; l.ly1 = l.y1 - dx; l.lx2 = l.x2 + dy; l.ly2 = l.y2 - dx; l.rx1 = l.x2 - dy; l.ry1 = l.y2 + dx; } subPath.add (l); if (it.closesSubPath) { addSubPath (destPath, subPath, true, width, maxMiterExtensionSquared, jointStyle, endStyle, arrowhead); subPath.clearQuick(); } else { l.x1 = it.x2; l.y1 = it.y2; } } } if (subPath.size() > 0) addSubPath (destPath, subPath, false, width, maxMiterExtensionSquared, jointStyle, endStyle, arrowhead); }
/// Initializes constraints and prepares data to be processed Sivia::Sivia(Data &data, bool calcInner) { //constraints to check to see if a trajectory belongs to a tube //c1= gdot= d/dx(gi)(x,t)*f(x,t)+d/dt(gi)(x,t)>=0 //c2= gi(x,t)=0j //c3= g(x,t)<=0 Function g("g.txt"); Function dg(g, Function::DIFF); // d/dx(gi)(x,t) Variable x(data.numVarF),t; //we have x[] and t as variables for our fns // initialize auxMat and auxVector to the correct sizes and fill with zeros IntervalMatrix auxMat(data.numVarF+1, data.numVarF,Interval::ZERO); IntervalVector auxVector(data.numVarF+1,Interval::ZERO); //put 1 in the diagonal of auxMat for (int i=0; i<data.numVarF; i++){ auxMat[i][i]=1;} auxVector[data.numVarF]=1; if (calcInner){ //for the inner approximation of the tube, we set a new function f and its correspondent constraints cout<<endl<<"Start inner approx calculation"<<endl; Function f=("f.txt"); Function gdot(x,t,dg(x,t)*(auxMat*transpose(f(x,t))+auxVector)); NumConstraint c3(g, EQ); //LEQ means less or equal 0 Array<Ctc> individualTubeConstraints; //put together the constraints in an array individualTubeConstraints.add(*new CtcHC4(Array<NumConstraint>(c3))); CtcUnion unionTubeConstraints(individualTubeConstraints); //calculate the union Ctc3BCid tubeConstraints(unionTubeConstraints); //this contracts the whole union to its final form data.boxes.push_back(data.initialBox); //initialize the boxes do_Sivia(tubeConstraints, data, gdot, calcInner); print_results(data); } else{ //for the outer approximation Function f("f.txt"); Function gdot(x,t,dg(x,t)*(auxMat*transpose(f(x,t))+auxVector)); //c1 & c2 Array<NumConstraint> c1, c2; int numConstraints = data.g->expr().dim.max_index()+1; //find how many gi we have for (int i = 0; i < numConstraints; ++i) { //create constraints based on the dimensions of g c1.add(*new NumConstraint(x,t,gdot(x,t)[i] >= 0)); c2.add(*new NumConstraint(x,t,g(x,t)[i] = 0)); } NumConstraint c3(g, LEQ); //LEQ means less or equal 0 Array<Ctc> individualTubeConstraints; //put together the constraints in an array for (int i=0;i<numConstraints ;i++) { individualTubeConstraints.add(*new CtcHC4(Array<NumConstraint>(c1[i],c2[i],c3)));} CtcUnion unionTubeConstraints(individualTubeConstraints); //calculate the union Ctc3BCid tubeConstraints(unionTubeConstraints); //this contracts the whole union to its final form data.boxes.push_back(data.initialBox); //initialize the boxes do_Sivia(tubeConstraints, data, gdot, calcInner); if (!data.calcInner){ print_results(data); } } }
// Searches a buffer for a set of spikes that matches those in the test sound int findOffsetOfSpikes (const AudioSampleBuffer& buffer) const { const float minSpikeLevel = 5.0f; const double smooth = 0.975; const float* s = buffer.getReadPointer (0); const int spikeDriftAllowed = 5; Array<int> spikesFound; spikesFound.ensureStorageAllocated (100); double runningAverage = 0; int lastSpike = 0; for (int i = 0; i < buffer.getNumSamples() - 10; ++i) { const float samp = std::abs (s[i]); if (samp > runningAverage * minSpikeLevel && i > lastSpike + 20) { lastSpike = i; spikesFound.add (i); } runningAverage = runningAverage * smooth + (1.0 - smooth) * samp; } int bestMatch = -1; int bestNumMatches = spikePositions.size() / 3; // the minimum number of matches required if (spikesFound.size() < bestNumMatches) return -1; for (int offsetToTest = 0; offsetToTest < buffer.getNumSamples() - 2048; ++offsetToTest) { int numMatchesHere = 0; int foundIndex = 0; for (int refIndex = 0; refIndex < spikePositions.size(); ++refIndex) { const int referenceSpike = spikePositions.getUnchecked (refIndex) + offsetToTest; int spike = 0; while ((spike = spikesFound.getUnchecked (foundIndex)) < referenceSpike - spikeDriftAllowed && foundIndex < spikesFound.size() - 1) ++foundIndex; if (spike >= referenceSpike - spikeDriftAllowed && spike <= referenceSpike + spikeDriftAllowed) ++numMatchesHere; } if (numMatchesHere > bestNumMatches) { bestNumMatches = numMatchesHere; bestMatch = offsetToTest; if (numMatchesHere == spikePositions.size()) break; } } return bestMatch; }
void addArray (Array<String>& dest, const CharType* const* strings) { if (strings != nullptr) while (*strings != nullptr) dest.add (*strings++); }
void PathPoint::getEditableProperties (Array<PropertyComponent*>& props) { const int index = owner->points.indexOf (this); jassert (index >= 0); switch (type) { case Path::Iterator::startNewSubPath: props.add (new PathPointPositionProperty (owner, index, 0, "x", PositionPropertyBase::componentX)); props.add (new PathPointPositionProperty (owner, index, 0, "y", PositionPropertyBase::componentY)); props.add (new PathPointClosedProperty (owner, index)); props.add (new AddNewPointProperty (owner, index)); break; case Path::Iterator::lineTo: props.add (new PathPointTypeProperty (owner, index)); props.add (new PathPointPositionProperty (owner, index, 0, "x", PositionPropertyBase::componentX)); props.add (new PathPointPositionProperty (owner, index, 0, "y", PositionPropertyBase::componentY)); props.add (new AddNewPointProperty (owner, index)); break; case Path::Iterator::quadraticTo: props.add (new PathPointTypeProperty (owner, index)); props.add (new PathPointPositionProperty (owner, index, 0, "control pt x", PositionPropertyBase::componentX)); props.add (new PathPointPositionProperty (owner, index, 0, "control pt y", PositionPropertyBase::componentY)); props.add (new PathPointPositionProperty (owner, index, 1, "x", PositionPropertyBase::componentX)); props.add (new PathPointPositionProperty (owner, index, 1, "y", PositionPropertyBase::componentY)); props.add (new AddNewPointProperty (owner, index)); break; case Path::Iterator::cubicTo: props.add (new PathPointTypeProperty (owner, index)); props.add (new PathPointPositionProperty (owner, index, 0, "control pt1 x", PositionPropertyBase::componentX)); props.add (new PathPointPositionProperty (owner, index, 0, "control pt1 y", PositionPropertyBase::componentY)); props.add (new PathPointPositionProperty (owner, index, 1, "control pt2 x", PositionPropertyBase::componentX)); props.add (new PathPointPositionProperty (owner, index, 1, "control pt2 y", PositionPropertyBase::componentY)); props.add (new PathPointPositionProperty (owner, index, 2, "x", PositionPropertyBase::componentX)); props.add (new PathPointPositionProperty (owner, index, 2, "y", PositionPropertyBase::componentY)); props.add (new AddNewPointProperty (owner, index)); break; case Path::Iterator::closePath: break; default: jassertfalse; break; } }
void addArray (Array<String>& dest, const CharType* const* const strings, const int numberOfStrings) { for (int i = 0; i < numberOfStrings; ++i) dest.add (strings [i]); }
bool TestExtMemcached::test_Memcached_types() { Array list; list.add("boolean_true", true); list.add("boolean_false", false); list.add("string", "just a string"); list.add("string_empty", ""); list.add("integer_positive_integer", 10); list.add("integer_negative_integer", -10); list.add("integer_zero_integer", 0); list.add("float_positive1", 3.912131); list.add("float_positive2", 1.2131E+52); list.add("float_negative", -42.123312); list.add("float_zero", 0.0); list.add("null", null); list.add("array_empty", Array()); list.add("array", CREATE_VECTOR4(1, 2, 3, "foo")); CREATE_MEMCACHED(); for (ArrayIter iter(list); iter; ++iter) { VERIFY(memc->t_set(iter.first(), iter.second(), EXPIRATION)); VS(memc->t_get(iter.first()), iter.second()); } for (ArrayIter iter(list); iter; ++iter) { VERIFY(memc->t_delete(iter.first())); } VERIFY(memc->t_setmulti(list, EXPIRATION)); Variant res = memc->t_getmulti(list.keys()); VERIFY(res.isArray()); Array resArray = res.toArray(); VERIFY(resArray->size() == list.size()); for (ArrayIter iter(resArray); iter; ++iter) { VS(iter.second(), list[iter.first()]); } return Count(true); }
void FileChooser::showPlatformDialog (Array<File>& results, const String& title, const File& file, const String& filters, bool isDirectory, bool /* selectsFiles */, bool isSave, bool /* warnAboutOverwritingExistingFiles */, bool selectMultipleFiles, FilePreviewComponent* /* previewComponent */) { String separator; StringArray args; const File previousWorkingDirectory (File::getCurrentWorkingDirectory()); const bool isKdeFullSession = SystemStats::getEnvironmentVariable ("KDE_FULL_SESSION", String::empty) .equalsIgnoreCase ("true"); if (exeIsAvailable ("kdialog") && (isKdeFullSession || ! exeIsAvailable ("zenity"))) { // use kdialog for KDE sessions or if zenity is missing args.add ("kdialog"); if (title.isNotEmpty()) args.add ("--title=" + title); if (selectMultipleFiles) { separator = "\n"; args.add ("--multiple"); args.add ("--separate-output"); args.add ("--getopenfilename"); } else { if (isSave) args.add ("--getsavefilename"); else if (isDirectory) args.add ("--getexistingdirectory"); else args.add ("--getopenfilename"); } String startPath; if (file.exists()) { startPath = file.getFullPathName(); } else if (file.getParentDirectory().exists()) { startPath = file.getParentDirectory().getFullPathName(); } else { startPath = File::getSpecialLocation (File::userHomeDirectory).getFullPathName(); if (isSave) startPath += "/" + file.getFileName(); } args.add (startPath); args.add (filters.replaceCharacter (';', ' ')); args.add ("2>/dev/null"); } else { // zenity args.add ("zenity"); args.add ("--file-selection"); if (title.isNotEmpty()) args.add ("--title=" + title); if (selectMultipleFiles) { separator = ":"; args.add ("--multiple"); args.add ("--separator=" + separator); } else { if (isDirectory) args.add ("--directory"); if (isSave) args.add ("--save"); } if (file.isDirectory()) file.setAsCurrentWorkingDirectory(); else if (file.getParentDirectory().exists()) file.getParentDirectory().setAsCurrentWorkingDirectory(); else File::getSpecialLocation (File::userHomeDirectory).setAsCurrentWorkingDirectory(); if (! file.getFileName().isEmpty()) args.add ("--filename=" + file.getFileName()); } ChildProcess child; if (child.start (args, ChildProcess::wantStdOut)) { const String result (child.readAllProcessOutput().trim()); if (result.isNotEmpty()) { StringArray tokens; if (selectMultipleFiles) tokens.addTokens (result, separator, "\""); else tokens.add (result); for (int i = 0; i < tokens.size(); ++i) results.add (File::getCurrentWorkingDirectory().getChildFile (tokens[i])); } child.waitForProcessToFinish (60 * 1000); } previousWorkingDirectory.setAsCurrentWorkingDirectory(); }
void File::findFileSystemRoots (Array<File>& destArray) { destArray.add (File ("/")); }
static Image getIconFromIcnsFile (const File& icnsFile, const int size) { FileInputStream stream (icnsFile); if (! stream.openedOk()) return {}; const int numHeaderSectionBytes = 4; char headerSection [numHeaderSectionBytes]; if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes || headerSection[0] != 'i' || headerSection[1] != 'c' || headerSection[2] != 'n' || headerSection[3] != 's') return {}; if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes) return {}; const auto dataSize = juce::ByteOrder::bigEndianInt (headerSection); if (dataSize <= 0) return {}; OwnedArray<juce::ImageFileFormat> internalFormats; internalFormats.add (new PNGImageFormat()); internalFormats.add (new JPEGImageFormat()); Array<Image> images; auto maxWidth = 0; auto maxWidthIndex = -1; while (stream.getPosition() < dataSize) { const auto sectionStart = stream.getPosition(); if (! stream.setPosition (sectionStart + 4)) break; if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes) break; const auto sectionSize = ByteOrder::bigEndianInt (headerSection); if (sectionSize <= 0) break; const auto sectionDataStart = stream.getPosition(); for (auto* fmt : internalFormats) { if (fmt->canUnderstand (stream)) { stream.setPosition (sectionDataStart); images.add (fmt->decodeImage (stream)); const auto lastImageIndex = images.size() - 1; const auto lastWidth = images.getReference (lastImageIndex).getWidth(); if (lastWidth > maxWidth) { maxWidthIndex = lastImageIndex; maxWidth = lastWidth; } } stream.setPosition (sectionDataStart); } stream.setPosition (sectionStart + sectionSize); } return maxWidthIndex == -1 ? juce::Image() : images.getReference (maxWidthIndex).rescaled (size, size, Graphics::ResamplingQuality::highResamplingQuality); }
bool TestExtMemcached::test_Memcached_types() { Array list; list.add(s_boolean_true, true); list.add(s_boolean_false, false); list.add(s_string, "just a string"); list.add(s_string_empty, empty_string); list.add(s_integer_positive_integer, 10); list.add(s_integer_negative_integer, -10); list.add(s_integer_zero_integer, 0); list.add(s_float_positive1, 3.912131); list.add(s_float_positive2, 1.2131E+52); list.add(s_float_negative, -42.123312); list.add(s_float_zero, 0.0); list.add(s_null, uninit_null()); list.add(s_array_empty, Array()); list.add(s_array, make_packed_array(1, 2, 3, "foo")); CREATE_MEMCACHED(); for (ArrayIter iter(list); iter; ++iter) { VERIFY(memc->t_set(iter.first(), iter.second(), EXPIRATION)); VS(memc->t_get(iter.first()), iter.second()); } for (ArrayIter iter(list); iter; ++iter) { VERIFY(memc->t_delete(iter.first())); } VERIFY(memc->t_setmulti(list, EXPIRATION)); Variant res = memc->t_getmulti(f_array_keys(list).toArray()); VERIFY(res.isArray()); Array resArray = res.toArray(); VERIFY(resArray->size() == list.size()); for (ArrayIter iter(resArray); iter; ++iter) { VS(iter.second(), list[iter.first()]); } return Count(true); }
Fracture* VertPositionMutation::mutate(Fracture* fracture) { // get all verts that are not corners Array<Vertex*>* nonCorner = new Array<Vertex*>(); for(int i=0;i<fracture->getVerts()->getSize();i++) if(!fracture->getVerts()->get(i)->getIsCorner()) nonCorner->add(fracture->getVerts()->get(i)); int numVerts = nonCorner->getSize(); if(!numVerts) // if only corners return the original fracture return fracture; // get a random non-boundary vert int randVert = RNG::RandomInt(numVerts); Vertex* ranVert = nonCorner->get(randVert); // get the move amount and distance before making a jump real moveLimit = EvolutionSettings::getInstance()->getMaxMovePercent(); real distBeforeJump = EvolutionSettings::getInstance()->getDistBeforeJump(); if(ranVert->getBoundary()) { // move along boundary line Array<Edge*>* boundaryEdges = new Array<Edge*>(); for(int i=0;i<ranVert->getEdges()->getSize();i++) if(ranVert->getEdges()->get(i)->getIsBoundary()) boundaryEdges->add(ranVert->getEdges()->get(i)); // choose a random edge to move by int randDir = RNG::RandomInt(boundaryEdges->getSize()); Edge* edgeToMoveBy = boundaryEdges->get(randDir); // get the edge length real length = edgeToMoveBy->length(); // if the length is too small move the other direction // in the future this is going to check if it can jump i.e // it will jump around a corner. if(length < distBeforeJump) { for(int i=0;i<boundaryEdges->getSize();i++) { // this should always work since there should be at least // two boundary edges attached if(boundaryEdges->get(i)!=edgeToMoveBy) { edgeToMoveBy = boundaryEdges->get(i); i = boundaryEdges->getSize(); } } // recheck length and abort if the check fails real length = edgeToMoveBy->length(); if(length < distBeforeJump) return fracture; } // get a random mutation value real mutateScale = RNG::RandomFloat(moveLimit); // Get the two points on the edge to move on Point2 firstPoint = ranVert->getLocation(); Point2 secondPoint = edgeToMoveBy->getOtherPoint(ranVert->getID()); // calculate the vert's new location Point2 slope = secondPoint.minus(firstPoint); slope.scale(mutateScale); Point2 newLoc = firstPoint.add(slope); // set the new location ranVert->setLocation(newLoc); // tell the verts edges about its new location ranVert->updateEdges(); // clean up while(boundaryEdges->getSize()) boundaryEdges->removeLast(); delete boundaryEdges; } else { // maybe implement move along edges ??? // move about faces using barycentric coordinates // get the faces containing the point Array<Face*>* facesWithVert = fracture->getFacesWithVertex(ranVert); // create a face containing all points around the vert Face* faceToMutateAround = new Face(); for(int i=0;i<facesWithVert->getSize();i++) { Face* tmp = facesWithVert->get(i); for(int j=0;j<tmp->getEdges()->getSize();j++) if(!tmp->getEdges()->get(j)->eitherMatch(ranVert->getID())) faceToMutateAround->getEdges()->add(tmp->getEdges()->get(j)->copy()); for(int j=0;j<tmp->getVerts()->getSize();j++) if(tmp->getVerts()->get(j)->getID() != ranVert->getID()) faceToMutateAround->getVerts()->add(tmp->getVerts()->get(j)->copy(faceToMutateAround->getEdges())); } // create the container for the generated Tris Array<Tri*>* generatedTris = new Array<Tri*>(); // detect if the face is convex or not faceToMutateAround->detectIfConvex(); if(faceToMutateAround->getIsConvex()) { // TODO :: Do this the more efficient way // convex case mutation (easy) // generate tris for(int i=0;i<faceToMutateAround->getEdges()->getSize();i++) generatedTris->add(new Tri(faceToMutateAround->getEdges()->get(i),ranVert->getLocation(),ranVert->getID())); // create barycentric coordinates for mutation (2 * #tris) // TODO :: Combine this with the case below int numBarys = generatedTris->getSize()*2; real barys[numBarys]; for(int i=0;i<numBarys;i++) barys[i] = RNG::RandomFloat(moveLimit); // apply mutations Point2 newPos; newPos.xpos = 0.0; newPos.ypos = 0.0; int pointID = ranVert->getID(); for(int i=0;i<generatedTris->getSize();i++) { // get new position real baryOne = barys[i*2]; real baryTwo = barys[i*2-1]; real baryThree = 1.0 - baryOne - baryTwo; newPos = generatedTris->get(i)->interpolatePosition(baryOne,baryTwo,baryThree); // update the position in all the remaining tris for(int j=i;j<generatedTris->getSize();j++) generatedTris->get(j)->updatePosition(pointID,newPos); } // set new position of vert ranVert->setLocation(newPos); // update edges ranVert->updateEdges(); // clean up } else { // concave case mutation (harder) // create collection for trimesh shell Array<Vertex*>* vertsInView = new Array<Vertex*>(); Array<Vertex*>* sortedVertsInView = new Array<Vertex*>(); Array<Edge*>* trimeshShell = new Array<Edge*>(); // get all verts in view for(int i=0;i<faceToMutateAround->getVerts()->getSize();i++) { Vertex* vert = faceToMutateAround->getVerts()->get(i); // create a temp edge to check for intersections Edge* tmpEdge = new Edge(ranVert->getLocation(),vert->getLocation()); bool noIntersection = true; // check if intersections for(int i=0;i<faceToMutateAround->getEdges()->getSize();i++) if(faceToMutateAround->getEdges()->get(i)->intersects(tmpEdge)) noIntersection = false; // if no intersections add it to the list of verts in view if(noIntersection) vertsInView->add(vert); // Note :: vert is still a copy // clean up delete tmpEdge; } // sort verts Array<Integer>* sortedIDs = faceToMutateAround->sortVertIDsByPath(); for(int i=0;i<sortedIDs->getSize();i++) for(int j=0;j<vertsInView->getSize();i++) if(vertsInView->get(j)->getID() == sortedIDs->get(i).val) { sortedVertsInView->add(vertsInView->get(j)); j = vertsInView->getSize(); } // create shell from verts for(int i=0;i<sortedVertsInView->getSize();i++) { Vertex* one = sortedVertsInView->get(i); Vertex* two = i==sortedVertsInView->getSize()-1 ? sortedVertsInView->get(0) : sortedVertsInView->get(i+1); Edge* newEdge = new Edge(one->getLocation(),two->getLocation(),one->getID(),two->getID()); trimeshShell->add(newEdge); } // generate tris for(int i=0;i<trimeshShell->getSize();i++) generatedTris->add(new Tri(trimeshShell->get(i),ranVert->getLocation(),ranVert->getID())); // create barycentric coordinates for mutation (Only 2 for this case) // TODO :: Combine this with the case above //int numBarys = generatedTris->getSize()*2; int numBarys = 2; real barys[numBarys]; for(int i=0;i<numBarys;i++) barys[i] = RNG::RandomFloat(moveLimit); // apply mutations Point2 newPos; newPos.xpos = 0.0; newPos.ypos = 0.0; int pointID = ranVert->getID(); int ranTri = RNG::RandomInt(generatedTris->getSize()); //for(int i=0;i<generatedTris->getSize();i++) { // get new position //real baryOne = barys[i*2]; //real baryTwo = barys[i*2-1]; real baryOne = barys[0]; real baryTwo = barys[1]; real baryThree = 1.0 - baryOne - baryTwo; newPos = generatedTris->get(ranTri)->interpolatePosition(baryOne,baryTwo,baryThree); // update the position in all the remaining tris (skip for this step) // for(int j=i;j<generatedTris->getSize();j++) // generatedTris->get(j)->updatePosition(pointID,newPos); //} // set new position of vert ranVert->setLocation(newPos); // update edges ranVert->updateEdges(); // clean up while(vertsInView->getSize()) vertsInView->removeLast(); while(sortedIDs->getSize()) sortedIDs->removeLast(); while(sortedVertsInView->getSize()) sortedVertsInView->removeLast(); while(trimeshShell->getSize()) delete trimeshShell->removeLast(); delete vertsInView; delete trimeshShell; delete sortedVertsInView; delete sortedIDs; } // clean up while(nonCorner->getSize()) nonCorner->removeLast(); while(facesWithVert->getSize()) facesWithVert->removeLast(); while(generatedTris->getSize()) delete generatedTris->removeLast(); while(faceToMutateAround->getVerts()->getSize()) delete faceToMutateAround->getVerts()->removeLast(); while(faceToMutateAround->getEdges()->getSize()) delete faceToMutateAround->getEdges()->removeLast(); delete faceToMutateAround; delete generatedTris; delete facesWithVert; delete nonCorner; } return fracture; }
Array<AudioChannelSet> AudioChannelSet::channelSetsWithNumberOfChannels (int numChannels) { Array<AudioChannelSet> retval; if (numChannels != 0) { retval.add (AudioChannelSet::discreteChannels (numChannels)); if (numChannels == 1) { retval.add (AudioChannelSet::mono()); } else if (numChannels == 2) { retval.add (AudioChannelSet::stereo()); } else if (numChannels == 3) { retval.add (AudioChannelSet::createLCR()); retval.add (AudioChannelSet::createLRS()); } else if (numChannels == 4) { retval.add (AudioChannelSet::quadraphonic()); retval.add (AudioChannelSet::createLCRS()); retval.add (AudioChannelSet::ambisonic()); } else if (numChannels == 5) { retval.add (AudioChannelSet::create5point0()); retval.add (AudioChannelSet::pentagonal()); } else if (numChannels == 6) { retval.add (AudioChannelSet::create5point1()); retval.add (AudioChannelSet::create6point0()); retval.add (AudioChannelSet::create6point0Music()); retval.add (AudioChannelSet::hexagonal()); } else if (numChannels == 7) { retval.add (AudioChannelSet::create7point0()); retval.add (AudioChannelSet::create7point0SDDS()); retval.add (AudioChannelSet::create6point1()); retval.add (AudioChannelSet::create6point1Music()); } else if (numChannels == 8) { retval.add (AudioChannelSet::create7point1()); retval.add (AudioChannelSet::create7point1SDDS()); retval.add (AudioChannelSet::octagonal()); } } return retval; }
bool update (CodeDocument& document, int lineNum, CodeDocument::Iterator& source, CodeTokeniser* analyser, const int spacesPerTab, const CodeDocument::Position& selectionStart, const CodeDocument::Position& selectionEnd) { Array <SyntaxToken> newTokens; newTokens.ensureStorageAllocated (8); if (analyser == nullptr) { newTokens.add (SyntaxToken (document.getLine (lineNum), -1)); } else if (lineNum < document.getNumLines()) { const CodeDocument::Position pos (&document, lineNum, 0); createTokens (pos.getPosition(), pos.getLineText(), source, analyser, newTokens); } replaceTabsWithSpaces (newTokens, spacesPerTab); int newHighlightStart = 0; int newHighlightEnd = 0; if (selectionStart.getLineNumber() <= lineNum && selectionEnd.getLineNumber() >= lineNum) { const String line (document.getLine (lineNum)); CodeDocument::Position lineStart (&document, lineNum, 0), lineEnd (&document, lineNum + 1, 0); newHighlightStart = indexToColumn (jmax (0, selectionStart.getPosition() - lineStart.getPosition()), line, spacesPerTab); newHighlightEnd = indexToColumn (jmin (lineEnd.getPosition() - lineStart.getPosition(), selectionEnd.getPosition() - lineStart.getPosition()), line, spacesPerTab); } if (newHighlightStart != highlightColumnStart || newHighlightEnd != highlightColumnEnd) { highlightColumnStart = newHighlightStart; highlightColumnEnd = newHighlightEnd; } else { if (tokens.size() == newTokens.size()) { bool allTheSame = true; for (int i = newTokens.size(); --i >= 0;) { if (tokens.getReference(i) != newTokens.getReference(i)) { allTheSame = false; break; } } if (allTheSame) return false; } } tokens.swapWithArray (newTokens); return true; }
//============================================================================== void Project::createPropertyEditors (PropertyListBuilder& props) { props.add (new TextPropertyComponent (getProjectNameValue(), "Project Name", 256, false), "The name of the project."); props.add (new TextPropertyComponent (getVersionValue(), "Project Version", 16, false), "The project's version number, This should be in the format major.minor.point[.point]"); props.add (new TextPropertyComponent (getCompanyName(), "Company Name", 256, false), "Your company name, which will be added to the properties of the binary where possible"); props.add (new TextPropertyComponent (getCompanyWebsite(), "Company Website", 256, false), "Your company website, which will be added to the properties of the binary where possible"); props.add (new TextPropertyComponent (getCompanyEmail(), "Company E-mail", 256, false), "Your company e-mail, which will be added to the properties of the binary where possible"); { StringArray projectTypeNames; Array<var> projectTypeCodes; const Array<ProjectType*>& types = ProjectType::getAllTypes(); for (int i = 0; i < types.size(); ++i) { projectTypeNames.add (types.getUnchecked(i)->getDescription()); projectTypeCodes.add (types.getUnchecked(i)->getType()); } props.add (new ChoicePropertyComponent (getProjectTypeValue(), "Project Type", projectTypeNames, projectTypeCodes)); } props.add (new TextPropertyComponent (getBundleIdentifier(), "Bundle Identifier", 256, false), "A unique identifier for this product, mainly for use in OSX/iOS builds. It should be something like 'com.yourcompanyname.yourproductname'"); getProjectType().createPropertyEditors (*this, props); { const int maxSizes[] = { 20480, 10240, 6144, 2048, 1024, 512, 256, 128, 64 }; StringArray maxSizeNames; Array<var> maxSizeCodes; maxSizeNames.add (TRANS("Default")); maxSizeCodes.add (var::null); maxSizeNames.add (String::empty); maxSizeCodes.add (var::null); for (int i = 0; i < numElementsInArray (maxSizes); ++i) { const int sizeInBytes = maxSizes[i] * 1024; maxSizeNames.add (File::descriptionOfSizeInBytes (sizeInBytes)); maxSizeCodes.add (sizeInBytes); } props.add (new ChoicePropertyComponent (getMaxBinaryFileSize(), "BinaryData.cpp size limit", maxSizeNames, maxSizeCodes), "When splitting binary data into multiple cpp files, the Introjucer attempts to keep the file sizes below this threshold. " "(Note that individual resource files which are larger than this size cannot be split across multiple cpp files)."); } props.add (new BooleanPropertyComponent (shouldIncludeBinaryInAppConfig(), "Include Binary", "Include BinaryData.h in the AppConfig.h file")); props.add (new TextPropertyComponent (getProjectPreprocessorDefs(), "Preprocessor definitions", 32768, true), "Global preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace, commas, or " "new-lines to separate the items - to include a space or comma in a definition, precede it with a backslash."); props.add (new TextPropertyComponent (getProjectUserNotes(), "Notes", 32768, true), "Extra comments: This field is not used for code or project generation, it's just a space where you can express your thoughts."); }
/** This function processes all the change requests to remove all the the redundant ones, and to tell what kind of initialization must be done. Depending on the results, the convolution engines might be reset, or simply updated, or they might not need any change at all. */ void processFifo() { if (getNumRemainingEntries() == 0 || isThreadRunning() || mustInterpolate) return; // retrieve the information from the FIFO for processing Array<ChangeRequest> requests; Array<juce::var> requestParameters; while (getNumRemainingEntries() > 0) { ChangeRequest type = ChangeRequest::changeEngine; juce::var parameter; readFromFifo (type, parameter); requests.add (type); requestParameters.add (parameter); } // remove any useless messages for (int i = 0; i < (int) ChangeRequest::numChangeRequestTypes; ++i) { bool exists = false; for (int n = requests.size(); --n >= 0;) { if (requests[n] == (ChangeRequest) i) { if (! exists) { exists = true; } else { requests.remove (n); requestParameters.remove (n); } } } } changeLevel = 0; for (int n = 0; n < requests.size(); ++n) { switch (requests[n]) { case ChangeRequest::changeEngine: changeLevel = 3; break; case ChangeRequest::changeSampleRate: { double newSampleRate = requestParameters[n]; if (currentInfo.sampleRate != newSampleRate) changeLevel = 3; currentInfo.sampleRate = newSampleRate; } break; case ChangeRequest::changeMaximumBufferSize: { int newMaximumBufferSize = requestParameters[n]; if (currentInfo.maximumBufferSize != (size_t) newMaximumBufferSize) changeLevel = 3; currentInfo.maximumBufferSize = (size_t) newMaximumBufferSize; } break; case ChangeRequest::changeSource: { auto* arrayParameters = requestParameters[n].getArray(); auto newSourceType = static_cast<SourceType> (static_cast<int> (arrayParameters->getUnchecked (0))); if (currentInfo.sourceType != newSourceType) changeLevel = jmax (2, changeLevel); if (newSourceType == SourceType::sourceBinaryData) { auto& prm = arrayParameters->getRawDataPointer()[1]; auto* newMemoryBlock = prm.getBinaryData(); auto* newPtr = newMemoryBlock->getData(); auto newSize = newMemoryBlock->getSize(); if (currentInfo.sourceData != newPtr || currentInfo.sourceDataSize != newSize) changeLevel = jmax (2, changeLevel); currentInfo.sourceType = SourceType::sourceBinaryData; currentInfo.sourceData = newPtr; currentInfo.sourceDataSize = newSize; currentInfo.fileImpulseResponse = File(); } else if (newSourceType == SourceType::sourceAudioFile) { File newFile (arrayParameters->getUnchecked (1).toString()); if (currentInfo.fileImpulseResponse != newFile) changeLevel = jmax (2, changeLevel); currentInfo.sourceType = SourceType::sourceAudioFile; currentInfo.fileImpulseResponse = newFile; currentInfo.sourceData = nullptr; currentInfo.sourceDataSize = 0; } else if (newSourceType == SourceType::sourceAudioBuffer) { double bufferSampleRate (arrayParameters->getUnchecked (1)); changeLevel = jmax (2, changeLevel); currentInfo.sourceType = SourceType::sourceAudioBuffer; currentInfo.bufferSampleRate = bufferSampleRate; currentInfo.fileImpulseResponse = File(); currentInfo.sourceData = nullptr; currentInfo.sourceDataSize = 0; } } break; case ChangeRequest::changeImpulseResponseSize: { int64 newSize = requestParameters[n]; if (currentInfo.impulseResponseSize != (size_t) newSize) changeLevel = jmax (1, changeLevel); currentInfo.impulseResponseSize = (size_t) newSize; } break; case ChangeRequest::changeStereo: { bool newWantsStereo = requestParameters[n]; if (currentInfo.wantsStereo != newWantsStereo) changeLevel = jmax (1, changeLevel); currentInfo.wantsStereo = newWantsStereo; } break; case ChangeRequest::changeTrimming: { bool newWantsTrimming = requestParameters[n]; if (currentInfo.wantsTrimming != newWantsTrimming) changeLevel = jmax(1, changeLevel); currentInfo.wantsTrimming = newWantsTrimming; } break; default: jassertfalse; break; } } if (currentInfo.sourceType == SourceType::sourceNone) { currentInfo.sourceType = SourceType::sourceAudioBuffer; if (currentInfo.sampleRate == 0) currentInfo.sampleRate = 44100; if (currentInfo.maximumBufferSize == 0) currentInfo.maximumBufferSize = 128; currentInfo.bufferSampleRate = currentInfo.sampleRate; currentInfo.impulseResponseSize = 1; currentInfo.fileImpulseResponse = File(); currentInfo.sourceData = nullptr; currentInfo.sourceDataSize = 0; AudioBuffer<float> newBuffer; newBuffer.setSize (1, 1); newBuffer.setSample (0, 0, 1.f); copyBufferToTemporaryLocation (newBuffer); } // action depending on the change level if (changeLevel == 3) { interpolationBuffer.setSize (2, static_cast<int> (currentInfo.maximumBufferSize)); processImpulseResponse(); initializeConvolutionEngines(); } else if (changeLevel == 2) { startThread(); } else if (changeLevel == 1) { startThread(); } }