// Unfortunately the deprecated getInputSpeakerArrangement/getOutputSpeakerArrangement return // references to strings. Therefore we need to keep a copy. Once getInputSpeakerArrangement is // removed, we can also remove this function void AudioProcessor::updateSpeakerFormatStrings() { cachedInputSpeakerArrString.clear(); cachedOutputSpeakerArrString.clear(); if (getBusCount (true) > 0) cachedInputSpeakerArrString = getBus (true, 0)->getCurrentLayout().getSpeakerArrangementAsString(); if (getBusCount (false) > 0) cachedOutputSpeakerArrString = getBus (false, 0)->getCurrentLayout().getSpeakerArrangementAsString(); }
bool AudioProcessor::enableAllBuses() { BusesLayout layouts; const int numInputs = getBusCount (true); const int numOutputs = getBusCount (false); for (int i = 0; i < numInputs; ++i) layouts.inputBuses. add (getBus (true, i)->lastLayout); for (int i = 0; i < numOutputs; ++i) layouts.outputBuses.add (getBus (false, i)->lastLayout); return setBusesLayout (layouts); }
AudioProcessor::BusesLayout AudioProcessor::getBusesLayout() const { BusesLayout layouts; const int numInputs = getBusCount (true); const int numOutputs = getBusCount (false); for (int i = 0; i < numInputs; ++i) layouts.inputBuses. add (getBus (true, i)->getCurrentLayout()); for (int i = 0; i < numOutputs; ++i) layouts.outputBuses.add (getBus (false, i)->getCurrentLayout()); return layouts; }
void AudioProcessor::audioIOChanged (bool busNumberChanged, bool channelNumChanged) { const int numInputBuses = getBusCount (true); const int numOutputBuses = getBusCount (false); for (int dir = 0; dir < 2; ++dir) { const bool isInput = (dir == 0); const int n = (isInput ? numInputBuses : numOutputBuses); for (int i = 0; i < n; ++i) { if (Bus* bus = getBus (isInput, i)) bus->updateChannelCount(); } } cachedTotalIns = countTotalChannels (inputBuses); cachedTotalOuts = countTotalChannels (outputBuses); updateSpeakerFormatStrings(); if (busNumberChanged) numBusesChanged(); if (channelNumChanged) numChannelsChanged(); processorLayoutsChanged(); }
bool AudioProcessor::applyBusLayouts (const BusesLayout& layouts) { if (layouts == getBusesLayout()) return true; const int numInputBuses = getBusCount (true); const int numOutputBuses = getBusCount (false); const int oldNumberOfIns = getTotalNumInputChannels(); const int oldNumberOfOuts = getTotalNumOutputChannels(); if (layouts.inputBuses. size() != numInputBuses || layouts.outputBuses.size() != numOutputBuses) return false; for (int busIdx = 0; busIdx < numInputBuses; ++busIdx) { Bus& bus = *getBus (true, busIdx); const AudioChannelSet& set = layouts.getChannelSet (true, busIdx); bus.layout = set; if (! set.isDisabled()) bus.lastLayout = set; } for (int busIdx = 0; busIdx < numOutputBuses; ++busIdx) { Bus& bus = *getBus (false, busIdx); const AudioChannelSet& set = layouts.getChannelSet (false, busIdx); bus.layout = set; if (! set.isDisabled()) bus.lastLayout = set; } const bool channelNumChanged = (oldNumberOfIns != getTotalNumInputChannels() || oldNumberOfOuts != getTotalNumOutputChannels()); audioIOChanged (false, channelNumChanged); return true; }
bool AudioProcessor::setChannelLayoutOfBus (bool isInputBus, int busIdx, const AudioChannelSet& layout) { if (Bus* bus = getBus (isInputBus, busIdx)) { BusesLayout layouts = bus->getBusesLayoutForLayoutChangeOfBus (layout); if (layouts.getChannelSet (isInputBus, busIdx) == layout) return applyBusLayouts (layouts); return false; } // busIdx parameter is invalid jassertfalse; return false; }
bool AudioProcessor::setBusesLayoutWithoutEnabling (const BusesLayout& arr) { const int numIns = getBusCount (true); const int numOuts = getBusCount (false); jassert (arr.inputBuses. size() == numIns && arr.outputBuses.size() == numOuts); BusesLayout request = arr; const BusesLayout current = getBusesLayout(); for (int i = 0; i < numIns; ++i) if (request.getNumChannels (true, i) == 0) request.getChannelSet (true, i) = current.getChannelSet (true, i); for (int i = 0; i < numOuts; ++i) if (request.getNumChannels (false, i) == 0) request.getChannelSet (false, i) = current.getChannelSet (false, i); if (! checkBusesLayoutSupported(request)) return false; for (int dir = 0; dir < 2; ++dir) { const bool isInput = (dir != 0); for (int i = 0; i < (isInput ? numIns : numOuts); ++i) { Bus& bus = *getBus (isInput, i); AudioChannelSet& set = request.getChannelSet (isInput, i); if (! bus.isEnabled()) { if (! set.isDisabled()) bus.lastLayout = set; set = AudioChannelSet::disabled(); } } } return setBusesLayout (request); }
bool AudioProcessor::canApplyBusCountChange (bool isInput, bool isAdding, AudioProcessor::BusProperties& outProperties) { if ( isAdding && ! canAddBus (isInput)) return false; if (! isAdding && ! canRemoveBus (isInput)) return false; const int num = getBusCount (isInput); // No way for me to find out the default layout if there are no other busses!! if (num == 0) return false; if (isAdding) { outProperties.busName = String (isInput ? "Input #" : "Output #") + String (getBusCount (isInput)); outProperties.defaultLayout = (num > 0 ? getBus (isInput, num - 1)->getDefaultLayout() : AudioChannelSet()); outProperties.isActivatedByDefault = true; } return true; }
/** * @brief Executes one CPU cycle * @return true if success, otherwise false */ virtual bool execute() { bool retval = true; TestInstruction data; U32 oldPC = mContext.reg[REG_PC]; if (getBus()->request(soc::Bus::BUSOP_READ, mContext.reg[REG_PC], data.value32)) { // Increment Program Counter mContext.reg[REG_PC] += INSTRUCTION_SIZE; switch (data.format1.opcode) { case 0x01: // LOAD LOW Immediate data into register printf("0x%08x: OpCode: %8s(0x%02x) RegIndex: 0x%02x Data: 0x%04x\n", oldPC, "LOADLI", data.format1.opcode, data.format1.regIndex, data.format1.data); if (data.format1.regIndex >= MAX_CPUREGISTERS) { retval = false; } else { U32 value = mContext.reg[data.format1.regIndex]; value = (value&0xFFFF0000) | data.format1.data; mContext.reg[data.format1.regIndex] = value; } break; case 0x02: // LOAD HIGH Immediate data into register printf("0x%08x: OpCode: %8s(0x%02x) RegIndex: 0x%02x Data: 0x%04x\n", oldPC, "LOADHI", data.format1.opcode, data.format1.regIndex, data.format1.data); if (data.format1.regIndex >= MAX_CPUREGISTERS) { retval = false; } else { U32 value = mContext.reg[data.format1.regIndex]; value = (value&0x00000FFFF) | (data.format1.data << 16); mContext.reg[data.format1.regIndex] = value; } break; default: retval = false; } if (retval == false) { // Invalid operation printf("0x%08x: OpCode: %8s(0x%02x) Byte1: 0x%02x Byte2: 0x%02x Byte3: 0x%02x\n", oldPC, "INVALID", data.format1.opcode, data.value8[1], data.value8[2], data.value8[3]); } } else { // failure to read next command // from location pc printf("Bus failure for address: 0x%08x\n", mContext.reg[REG_PC]); retval = false; } return retval; }
AudioProcessor::BusesLayout AudioProcessor::getNextBestLayout (const BusesLayout& layouts) const { // if you are hitting this assertion then you are requesting a next // best layout which does not have the same number of buses as the // audio processor. jassert (layouts.inputBuses. size() == getBusCount (true) && layouts.outputBuses.size() == getBusCount (false)); if (checkBusesLayoutSupported (layouts)) return layouts; BusesLayout originalState = getBusesLayout(); BusesLayout currentState = originalState; BusesLayout bestSupported = currentState; for (int dir = 0; dir < 2; ++dir) { const bool isInput = (dir > 0); Array<AudioChannelSet>& currentLayouts = (isInput ? currentState.inputBuses : currentState.outputBuses); const Array<AudioChannelSet>& bestLayouts = (isInput ? bestSupported.inputBuses : bestSupported.outputBuses); const Array<AudioChannelSet>& requestedLayouts = (isInput ? layouts.inputBuses : layouts.outputBuses); const Array<AudioChannelSet>& originalLayouts = (isInput ? originalState.inputBuses : originalState.outputBuses); for (int busIdx = 0; busIdx < requestedLayouts.size(); ++busIdx) { AudioChannelSet& best = bestLayouts .getReference (busIdx); const AudioChannelSet& requested = requestedLayouts.getReference (busIdx); const AudioChannelSet& original = originalLayouts .getReference (busIdx); // do we need to do anything if (original == requested) continue; currentState = bestSupported; AudioChannelSet& current = currentLayouts .getReference (busIdx); // already supported? current = requested; if (checkBusesLayoutSupported (currentState)) { bestSupported = currentState; continue; } // try setting the opposite bus to the identical layout const bool oppositeDirection = ! isInput; if (getBusCount (oppositeDirection) > busIdx) { AudioChannelSet& oppositeLayout = (oppositeDirection ? currentState.inputBuses : currentState.outputBuses).getReference (busIdx); oppositeLayout = requested; if (checkBusesLayoutSupported (currentState)) { bestSupported = currentState; continue; } // try setting the default layout oppositeLayout = getBus (oppositeDirection, busIdx)->getDefaultLayout(); if (checkBusesLayoutSupported (currentState)) { bestSupported = currentState; continue; } } // try setting all other buses to the identical layout BusesLayout allTheSame; for (int oDir = 0; oDir < 2; ++oDir) { const bool oIsInput = (oDir == 0); const int oBusNum = getBusCount (oIsInput); for (int oBusIdx = 0; oBusIdx < oBusNum; ++oBusIdx) (oIsInput ? allTheSame.inputBuses : allTheSame.outputBuses).add (requested); } if (checkBusesLayoutSupported (allTheSame)) { bestSupported = allTheSame; continue; } // what is closer the default or the current layout? int distance = abs (best.size() - requested.size()); const AudioChannelSet& defaultLayout = getBus (isInput, busIdx)->getDefaultLayout(); if (abs (defaultLayout.size() - requested.size()) < distance) { current = defaultLayout; if (checkBusesLayoutSupported (currentState)) bestSupported = currentState; } } } return bestSupported; }