void GenericProcessor::disableEditor() { GenericEditor* ed = getEditor(); if (ed != 0) ed->stopAcquisition(); }
void ProcessorGraph::refreshColors() { for (int i = 0; i < getNumNodes(); i++) { Node* node = getNode(i); int nodeId = node->nodeId; if (nodeId != OUTPUT_NODE_ID && nodeId != AUDIO_NODE_ID && nodeId != RECORD_NODE_ID && nodeId != MESSAGE_CENTER_ID) { GenericProcessor* p =(GenericProcessor*) node->getProcessor(); GenericEditor* e = (GenericEditor*) p->getEditor(); e->refreshColors(); } } }
void ProcessorGraph::changeListenerCallback(ChangeBroadcaster* source) { for (int i = 0; i < getNumNodes(); i++) { Node* node = getNode(i); int nodeId = node->nodeId; if (nodeId != OUTPUT_NODE_ID && nodeId != AUDIO_NODE_ID && nodeId != RECORD_NODE_ID && nodeId != RESAMPLING_NODE_ID) { GenericProcessor* p =(GenericProcessor*) node->getProcessor(); GenericEditor* e = (GenericEditor*) p->getEditor(); e->refreshColors(); } } }
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); // 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 ChannelSelector::buttonClicked(Button* button) { //checkChannelSelectors(); if (button == paramsButton) { // make sure param buttons are visible allButton->setState(true); desiredOffset = parameterOffset; startTimer(20); return; } else if (button == audioButton) { // make sure audio buttons are visible if (audioButton->getState()) { allButton->setState(false); desiredOffset = audioOffset; startTimer(20); } else { paramsButton->setToggleState(true, false); } return; } else if (button == recordButton) { // make sure record buttons are visible; if (recordButton->getState()) { allButton->setState(true); desiredOffset = recordOffset; startTimer(20); } else { paramsButton->setToggleState(true, false); } return; } else if (button == allButton) { // select all active buttons if (offsetLR == recordOffset) { for (int i = 0; i < recordButtons.size(); i++) { recordButtons[i]->setToggleState(true, true); } } else if (offsetLR == parameterOffset) { for (int i = 0; i < parameterButtons.size(); i++) { parameterButtons[i]->setToggleState(true, true); } } else if (offsetLR == audioOffset) { // do nothing--> button is disabled } } else if (button == noneButton) { // deselect all active buttons if (offsetLR == recordOffset) { for (int i = 0; i < recordButtons.size(); i++) { recordButtons[i]->setToggleState(false, true); } } else if (offsetLR == parameterOffset) { for (int i = 0; i < parameterButtons.size(); i++) { parameterButtons[i]->setToggleState(false, true); } } else if (offsetLR == audioOffset) { for (int i = 0; i < audioButtons.size(); i++) { audioButtons[i]->setToggleState(false, true); } } } else { ChannelSelectorButton* b = (ChannelSelectorButton*) button; if (b->getType() == AUDIO) { // get audio node, and inform it of the change GenericEditor* editor = (GenericEditor*) getParentComponent(); Channel* ch = editor->getChannel(b->getChannel()-1); //int channelNum = editor->getStartChannel() + b->getChannel() - 1; bool status = b->getToggleState(); if (acquisitionIsActive) // use setParameter to change parameter safely { editor->getProcessorGraph()-> getAudioNode()-> setChannelStatus(ch, status); } else // change parameter directly { ch->isMonitored = status; } } else if (b->getType() == RECORD) { // get record node, and inform it of the change GenericEditor* editor = (GenericEditor*) getParentComponent(); Channel* ch = editor->getChannel(b->getChannel()-1); //int channelNum = editor->getStartChannel() + b->getChannel() - 1; bool status = b->getToggleState(); if (acquisitionIsActive) // use setParameter to change parameter safely { editor->getProcessorGraph()-> getRecordNode()-> setChannelStatus(ch, status); } else // change parameter directly { ch->isRecording = status; } } else { // do nothing if (radioStatus) // if radio buttons are active { // send a message to parent GenericEditor* editor = (GenericEditor*) getParentComponent(); editor->channelChanged(b->getChannel()); } } } }
void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor, int index, int insertionPoint, int action) { enum actions {ADD, MOVE, REMOVE, ACTIVATE, UPDATE}; // Step 1: update the editor array if (action == ADD) { std::cout << " Adding editor." << std::endl; editorArray.insert(insertionPoint, activeEditor); } else if (action == MOVE) { std::cout << " Moving editors." << std::endl; if (insertionPoint < index) editorArray.move(index, insertionPoint); else if (insertionPoint > index) editorArray.move(index, insertionPoint-1); } else if (action == REMOVE) { std::cout << " Removing editor." << std::endl; GenericProcessor* p = (GenericProcessor*) editorArray[index]->getProcessor(); // if the processor to be removed is a merger, // we need to inform the other source that its merger has disappeared if (p->isMerger()) { p->switchIO(); if (p->getSourceNode() != 0) p->getSourceNode()->setDestNode(0); } // if the processor to be removed is a splitter, we need to make sure // there aren't any orphaned processors if (p->isSplitter()) { p->switchIO(); if (p->getDestNode() != 0) { std::cout << "Found an orphaned signal chain" << std::endl; p->getDestNode()->setSourceNode(0); createNewTab(p->getDestNode()->getEditor()); } } editorArray.remove(index); int t = activeEditor->tabNumber(); // std::cout << editorArray.size() << " " << t << std::endl; bool merger; if (editorArray.size() > 0) { GenericProcessor* p = (GenericProcessor*) editorArray[0]->getProcessor(); merger = (p->isMerger() && p->stillHasSource()); if (merger) { std::cout << "We've got a merger!" << std::endl; //p->switchSource(); } } if (editorArray.size() > 0 && !merger) // if there are still editors in this chain { if (t > -1) // pass on tab { // std::cout << "passing on the tab." << std::endl; int nextEditor = jmax(0,0);//index-1); editorArray[nextEditor]->tabNumber(t); signalChainArray[t]->setEditor(editorArray[nextEditor]); } int nextEditor = jmin(index,editorArray.size()-1); activeEditor = editorArray[nextEditor]; activeEditor->select(); //activeEditor->grabKeyboardFocus(); } else { std::cout << "Tab number " << t << std::endl; removeTab(t); if (signalChainArray.size() > 0) // if there are other chains { int nextTab = jmin(t,signalChainArray.size()-1); activeEditor = signalChainArray[nextTab]->getEditor(); activeEditor->select(); signalChainArray[nextTab]->setToggleState(true,false); // send it back to update connections } else { activeEditor = 0; // nothing is active // signalChainNeedsSource = true; } } } else //no change { std::cout << "Activating editor" << std::endl; } // Step 2: update connections if (action != ACTIVATE && action != UPDATE && editorArray.size() > 0) { std::cout << "Updating connections." << std::endl; GenericProcessor* source = 0; GenericProcessor* dest = (GenericProcessor*) editorArray[0]->getProcessor(); dest->setSourceNode(source); for (int n = 1; n < editorArray.size(); n++) { dest = (GenericProcessor*) editorArray[n]->getProcessor(); source = (GenericProcessor*) editorArray[n-1]->getProcessor(); dest->setSourceNode(source); } dest->setDestNode(0); } // Step 3: check for new tabs if (action != ACTIVATE && action != UPDATE) { std::cout << "Checking for new tabs." << std::endl; for (int n = 0; n < editorArray.size(); n++) { GenericProcessor* p = (GenericProcessor*) editorArray[n]->getProcessor(); if (p->getSourceNode() == 0)// && editorArray[n]->tabNumber() == -1) { if (editorArray[n]->tabNumber() == -1) { if (!p->isMerger()) { std::cout << p->getName() << " has no source node. Creating a new tab." << std::endl; createNewTab(editorArray[n]); } } } else { if (editorArray[n]->tabNumber() > -1) { removeTab(editorArray[n]->tabNumber()); } editorArray[n]->tabNumber(-1); // reset tab status } if (p->isMerger()) { std::cout << "It's a merger!" << std::endl; //createNewTab(editorArray[n]); } } } // Step 4: Refresh editors in editor array, based on active editor for (int n = 0; n < editorArray.size(); n++) { editorArray[n]->setVisible(false); } editorArray.clear(); std::cout << "Cleared editor array." << std::endl; GenericEditor* editorToAdd = activeEditor; while (editorToAdd != 0) { std::cout << "Inserting " << editorToAdd->getName() << " at point 0." << std::endl; editorArray.insert(0,editorToAdd); GenericProcessor* currentProcessor = (GenericProcessor*) editorToAdd->getProcessor(); GenericProcessor* source = currentProcessor->getSourceNode(); if (source != 0) { std::cout << "Source: " << source->getName() << std::endl; // need to switch the splitter somehow // if (action == ACTIVATE || action == UPDATE) // { // if (source->isSplitter()) // { // source->setPathToProcessor(currentProcessor); // } // } editorToAdd = (GenericEditor*) source->getEditor(); } else { if (editorToAdd->tabNumber() >= 0) signalChainArray[editorToAdd->tabNumber()]->setToggleState(true, false); std::cout << "No source found." << std::endl; editorToAdd = 0; } } editorToAdd = activeEditor; while (editorToAdd != 0) { GenericProcessor* currentProcessor = (GenericProcessor*) editorToAdd->getProcessor(); GenericProcessor* dest = currentProcessor->getDestNode(); if (dest != 0) { std::cout << "Destination: " << dest->getName() << std::endl; editorToAdd = (GenericEditor*) dest->getEditor(); editorArray.add(editorToAdd); std::cout << "Inserting " << editorToAdd->getName() << " at the end." << std::endl; if (dest->isMerger()) { std::cout << "It's a merger!" << std::endl; if (dest->getSourceNode() != currentProcessor) editorToAdd->switchSource(); } } else { std::cout << "No dest found." << std::endl; editorToAdd = 0; } } // Step 5: check the validity of the signal chain if (true) { //action != ACTIVATE) { bool enable = true; if (editorArray.size() == 1) { GenericProcessor* source = (GenericProcessor*) editorArray[0]->getProcessor(); if (source->isSource()) editorArray[0]->setEnabledState(true); else editorArray[0]->setEnabledState(false); } else { for (int n = 0; n < editorArray.size()-1; n++) { GenericProcessor* source = (GenericProcessor*) editorArray[n]->getProcessor(); GenericProcessor* dest = (GenericProcessor*) editorArray[n+1]->getProcessor(); if (n == 0 && !source->isSource()) enable = false; editorArray[n]->setEnabledState(enable); if (source->canSendSignalTo(dest) && source->enabledState()) enable = true; else enable = false; if (source->isSplitter()) { if (source->getDestNode() != dest) { //source->switchIO(); editorArray[n]->switchDest(); } } if (enable) std::cout << "Enabling node." << std::endl; else std::cout << "Not enabling node." << std::endl; editorArray[n+1]->setEnabledState(enable); } } } // Step 6: inform the tabs that something has changed for (int n = 0; n < signalChainArray.size(); n++) { if (signalChainArray[n]->getToggleState()) { signalChainArray[n]->hasNewConnections(true); } } // Step 7: update all settings if (action != ACTIVATE) { std::cout << "Updating settings." << std::endl; Array<GenericProcessor*> splitters; for (int n = 0; n < signalChainArray.size(); n++) { // iterate through signal chains GenericEditor* source = signalChainArray[n]->getEditor(); GenericProcessor* p = source->getProcessor(); p->update(); if (p->isSplitter()) { splitters.add(p); } GenericProcessor* dest = p->getDestNode(); while (dest != 0) { // iterate through processors dest->update(); dest = dest->getDestNode(); if (dest == 0 && splitters.size() > 0) { splitters.getFirst()->switchIO(); dest = splitters[0]->getDestNode(); splitters.remove(0); } } } } std::cout << "Finished adding new editor." << std::endl << std::endl << std::endl; }
void ChannelSelector::buttonClicked(Button* button) { //checkChannelSelectors(); if (button == paramsButton) { // make sure param buttons are visible allButton->setState(true); desiredOffset = parameterOffset; startTimer(20); return; } else if (button == audioButton) { // make sure audio buttons are visible if (audioButton->getState()) { allButton->setState(false); desiredOffset = audioOffset; startTimer(20); } else { paramsButton->setToggleState(true, dontSendNotification); } return; } else if (button == recordButton) { // make sure record buttons are visible; if (recordButton->getState()) { allButton->setState(true); desiredOffset = recordOffset; startTimer(20); } else { paramsButton->setToggleState(true, dontSendNotification); } return; } else if (button == allButton) { // select all active buttons if (offsetLR == recordOffset) { for (int i = 0; i < recordButtonsManager.getNumButtons(); ++i) { recordButtonsManager.getButtonAt (i)->setToggleState (true, sendNotification); } } else if (offsetLR == parameterOffset) { for (int i = 0; i < parameterButtonsManager.getNumButtons(); ++i) { parameterButtonsManager.getButtonAt (i)->setToggleState (true, sendNotification); } } else if (offsetLR == audioOffset) { // do nothing--> button is disabled } } else if (button == noneButton) { // deselect all active buttons if (offsetLR == recordOffset) { for (int i = 0; i < recordButtonsManager.getNumButtons(); ++i) { recordButtonsManager.getButtonAt (i)->setToggleState (false, sendNotification); } } else if (offsetLR == parameterOffset) { for (int i = 0; i < parameterButtonsManager.getNumButtons(); ++i) { parameterButtonsManager.getButtonAt (i)->setToggleState (false, sendNotification); } } else if (offsetLR == audioOffset) { for (int i = 0; i < audioButtonsManager.getNumButtons(); ++i) { audioButtonsManager.getButtonAt (i)->setToggleState (false, sendNotification); } } if (radioStatus) // if radio buttons are active { // send a message to parent GenericEditor* editor = (GenericEditor*) getParentComponent(); editor->channelChanged (-1, false); } } else { ChannelSelectorButton* b = (ChannelSelectorButton*)button; if (b->getType() == AUDIO) { // get audio node, and inform it of the change GenericEditor* editor = (GenericEditor*)getParentComponent(); Channel* ch = editor->getChannel(b->getChannel() - 1); //int channelNum = editor->getStartChannel() + b->getChannel() - 1; bool status = b->getToggleState(); std::cout << "Requesting audio monitor for channel " << ch->nodeIndex + 1 << std::endl; if (acquisitionIsActive) // use setParameter to change parameter safely { AccessClass::getProcessorGraph()-> getAudioNode()->setChannelStatus(ch, status); } else // change parameter directly { ch->isMonitored = status; } } else if (b->getType() == RECORD) { // get record node, and inform it of the change GenericEditor* editor = (GenericEditor*)getParentComponent(); Channel* ch = editor->getChannel(b->getChannel() - 1); //int channelNum = editor->getStartChannel() + b->getChannel() - 1; bool status = b->getToggleState(); if (acquisitionIsActive) // use setParameter to change parameter safely { AccessClass::getProcessorGraph()-> getRecordNode()-> setChannelStatus(ch, status); } else // change parameter directly { //std::cout << "Setting record status for channel " << b->getChannel() << std::endl; ch->setRecordState(status); } AccessClass::getGraphViewer()->repaint(); } else // parameter type { GenericEditor* editor = (GenericEditor*) getParentComponent(); editor->channelChanged (b->getChannel() - 1, b->getToggleState()); // do nothing if (radioStatus) // if radio buttons are active { // send a message to parent GenericEditor* editor = (GenericEditor*) getParentComponent(); editor->channelChanged (b->getChannel(), b->getToggleState()); } } } refreshParameterColors(); }
void ChannelSelector::refreshParameterColors() { GenericEditor* p = dynamic_cast<GenericEditor*>(getParentComponent()); p->updateParameterButtons(-1); }
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