From 54fbe407afde659a926e6ea155280a42bd028777 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sat, 16 Jan 2021 17:02:59 -0500 Subject: [PATCH] Split `audio::Port::offset` to inputOffset and outputOffset, and `audio::Port::maxChannels` to maxInputs and maxOutputs. --- include/audio.hpp | 19 +++------- src/app/AudioWidget.cpp | 48 +++++++++++++++++++------ src/audio.cpp | 71 ++++++++----------------------------- src/core/AudioInterface.cpp | 3 +- 4 files changed, 58 insertions(+), 83 deletions(-) diff --git a/include/audio.hpp b/include/audio.hpp index c4876e34..d51d3729 100644 --- a/include/audio.hpp +++ b/include/audio.hpp @@ -46,11 +46,6 @@ struct Driver { virtual int getDeviceNumOutputs(int deviceId) { return 0; } - /** Returns a detailed description of the device without obtaining it. - `offset` specifies the first channel (zero-indexed). - E.g. "MySoundcard (1-2 in, 1-2 out)" - */ - std::string getDeviceDetail(int deviceId, int offset, int maxChannels); /** Adds the given port as a reference holder of a device and returns the it. Creates the Device if no ports are subscribed before calling. @@ -90,11 +85,6 @@ struct Device { virtual int getNumOutputs() { return 0; } - /** Returns a detailed description of the device. - `offset` specifies the first channel (zero-indexed). - E.g. "MySoundcard (1-2 in, 1-2 out)" - */ - std::string getDetail(int offset, int maxChannels); /** Returns a list of all valid (user-selectable) sample rates. The device may accept sample rates not in this list, but it *must* accept sample rates in the list. @@ -139,9 +129,11 @@ That is, if the active Device throws a `rack::Exception`, it is caught and logge */ struct Port { /** The first channel index of the device to process. */ - int offset = 0; + int inputOffset = 0; + int outputOffset = 0; /** Maximum number of channels to process. */ - int maxChannels = 8; + int maxInputs = 8; + int maxOutputs = 8; // private int driverId = -1; @@ -177,9 +169,6 @@ struct Port { int getBlockSize(); void setBlockSize(int blockSize); - int getOffset(); - void setOffset(int offset); - int getNumInputs(); int getNumOutputs(); diff --git a/src/app/AudioWidget.cpp b/src/app/AudioWidget.cpp index 4e0f7017..96ded6b3 100644 --- a/src/app/AudioWidget.cpp +++ b/src/app/AudioWidget.cpp @@ -8,6 +8,23 @@ namespace rack { namespace app { +static std::string getDetailTemplate(std::string name, int numInputs, int inputOffset, int maxInputs, int numOutputs, int outputOffset, int maxOutputs) { + std::string text = name; + text += " ("; + if (inputOffset < numInputs) { + text += string::f("%d-%d in", inputOffset + 1, std::min(inputOffset + maxInputs, numInputs)); + } + if (inputOffset < numInputs && outputOffset < numOutputs) { + text += ", "; + } + if (outputOffset < numOutputs) { + text += string::f("%d-%d out", outputOffset + 1, std::min(outputOffset + maxOutputs, numOutputs)); + } + text += ")"; + return text; +} + + struct AudioDriverValueItem : ui::MenuItem { audio::Port* port; int driverId; @@ -67,10 +84,12 @@ struct AudioDriverItem : ui::MenuItem { struct AudioDeviceValueItem : ui::MenuItem { audio::Port* port; int deviceId; - int offset; + int inputOffset; + int outputOffset; void onAction(const event::Action& e) override { port->setDeviceId(deviceId); - port->setOffset(offset); + port->inputOffset = inputOffset; + port->outputOffset = outputOffset; } }; @@ -88,18 +107,24 @@ static void appendAudioDeviceMenu(ui::Menu* menu, audio::Port* port) { } for (int deviceId : port->getDeviceIds()) { - int channels = std::max(port->getDeviceNumInputs(deviceId), port->getDeviceNumOutputs(deviceId)); + int numInputs = port->getDeviceNumInputs(deviceId); + int numOutputs = port->getDeviceNumOutputs(deviceId); + std::string name = port->getDeviceName(deviceId); + // Prevents devices with a ridiculous number of channels from being displayed - const int maxTotalChannels = port->maxChannels * 16; - channels = std::min(maxTotalChannels, channels); + for (int i = 0; i < 8; i++) { + int inputOffset = i * port->maxInputs; + int outputOffset = i * port->maxOutputs; + if (inputOffset >= numInputs && outputOffset >= numOutputs) + break; - for (int offset = 0; offset < channels; offset += port->maxChannels) { AudioDeviceValueItem* item = new AudioDeviceValueItem; item->port = port; item->deviceId = deviceId; - item->offset = offset; - item->text = port->getDeviceDetail(deviceId, offset); - item->rightText = CHECKMARK(item->deviceId == port->getDeviceId() && item->offset == port->getOffset()); + item->inputOffset = inputOffset; + item->outputOffset = outputOffset; + item->text = getDetailTemplate(name, numInputs, inputOffset, port->maxInputs, numOutputs, outputOffset, port->maxOutputs); + item->rightText = CHECKMARK(item->deviceId == port->getDeviceId() && inputOffset == port->inputOffset && outputOffset == port->outputOffset); menu->addChild(item); } } @@ -117,7 +142,10 @@ struct AudioDeviceChoice : LedDisplayChoice { text = ""; if (box.size.x >= 200.0) text += "Device: "; - std::string detail = (port && port->device) ? port->device->getDetail(port->getOffset(), port->maxChannels) : ""; + std::string detail = ""; + if (port && port->device) + detail = getDetailTemplate(port->device->getName(), port->getNumInputs(), port->inputOffset, port->maxInputs, port->getNumOutputs(), port->outputOffset, port->maxOutputs); + if (detail != "") { text += detail; color.a = 1.0; diff --git a/src/audio.cpp b/src/audio.cpp index 1ffa0236..67af2363 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -8,31 +8,10 @@ namespace audio { static std::vector> drivers; -static std::string getDetailTemplate(std::string name, int numInputs, int numOutputs, int offset, int maxChannels) { - std::string text = name; - text += " ("; - if (offset < numInputs) { - text += string::f("%d-%d in", offset + 1, std::min(offset + maxChannels, numInputs)); - } - if (offset < numInputs && offset < numOutputs) { - text += ", "; - } - if (offset < numOutputs) { - text += string::f("%d-%d out", offset + 1, std::min(offset + maxChannels, numOutputs)); - } - text += ")"; - return text; -} - //////////////////// // Driver //////////////////// -std::string Driver::getDeviceDetail(int deviceId, int offset, int maxChannels) { - if (deviceId < 0) - return ""; - return getDetailTemplate(getDeviceName(deviceId), getDeviceNumInputs(deviceId), getDeviceNumOutputs(deviceId), offset, maxChannels); -} //////////////////// // Device @@ -48,10 +27,6 @@ void Device::unsubscribe(Port* port) { subscribed.erase(it); } -std::string Device::getDetail(int offset, int maxChannels) { - return getDetailTemplate(getName(), getNumInputs(), getNumOutputs(), offset, maxChannels); -} - void Device::processBuffer(const float* input, int inputStride, float* output, int outputStride, int frames) { // Zero output in case no Port writes values to it. std::memset(output, 0, frames * outputStride * sizeof(float)); @@ -59,15 +34,15 @@ void Device::processBuffer(const float* input, int inputStride, float* output, i for (Port* port : subscribed) { // Setting the thread context should probably be the responsibility of Port, but because processInput() etc are overridden, this is the only good place for it. contextSet(port->context); - port->processInput(input + port->getOffset(), inputStride, frames); + port->processInput(input + port->inputOffset, inputStride, frames); } for (Port* port : subscribed) { contextSet(port->context); - port->processBuffer(input + port->getOffset(), inputStride, output + port->getOffset(), outputStride, frames); + port->processBuffer(input + port->inputOffset, inputStride, output + port->outputOffset, outputStride, frames); } for (Port* port : subscribed) { contextSet(port->context); - port->processOutput(output + port->getOffset(), outputStride, frames); + port->processOutput(output + port->outputOffset, outputStride, frames); } } @@ -106,7 +81,6 @@ void Port::reset() { firstDriverId = driverIds[0]; setDriverId(firstDriverId); - setOffset(0); } Driver* Port::getDriver() { @@ -236,19 +210,6 @@ std::string Port::getDeviceName(int deviceId) { } } -std::string Port::getDeviceDetail(int deviceId, int offset) { - if (!driver) - return ""; - try { - // Use maxChannels from Port. - return driver->getDeviceDetail(deviceId, offset, maxChannels); - } - catch (Exception& e) { - WARN("Audio port could not get device detail: %s", e.what()); - return 0; - } -} - std::set Port::getSampleRates() { if (!device) return {}; @@ -319,20 +280,11 @@ void Port::setBlockSize(int blockSize) { } } -int Port::getOffset() { - return offset; -} - -void Port::setOffset(int offset) { - this->offset = offset; -} - - int Port::getNumInputs() { if (!device) return 0; try { - return std::min(device->getNumInputs() - getOffset(), maxChannels); + return std::min(device->getNumInputs() - inputOffset, maxInputs); } catch (Exception& e) { WARN("Audio port could not get device number of inputs: %s", e.what()); @@ -344,7 +296,7 @@ int Port::getNumOutputs() { if (!device) return 0; try { - return std::min(device->getNumOutputs() - getOffset(), maxChannels); + return std::min(device->getNumOutputs() - outputOffset, maxOutputs); } catch (Exception& e) { WARN("Audio port could not get device number of outputs: %s", e.what()); @@ -363,7 +315,8 @@ json_t* Port::toJson() { json_object_set_new(rootJ, "sampleRate", json_real(getSampleRate())); json_object_set_new(rootJ, "blockSize", json_integer(getBlockSize())); - json_object_set_new(rootJ, "offset", json_integer(getOffset())); + json_object_set_new(rootJ, "inputOffset", json_integer(inputOffset)); + json_object_set_new(rootJ, "outputOffset", json_integer(outputOffset)); return rootJ; } @@ -397,9 +350,13 @@ void Port::fromJson(json_t* rootJ) { if (blockSizeJ) setBlockSize(json_integer_value(blockSizeJ)); - json_t* offsetJ = json_object_get(rootJ, "offset"); - if (offsetJ) - setOffset(json_integer_value(offsetJ)); + json_t* inputOffsetJ = json_object_get(rootJ, "inputOffset"); + if (inputOffsetJ) + inputOffset = json_integer_value(inputOffsetJ); + + json_t* outputOffsetJ = json_object_get(rootJ, "outputOffset"); + if (outputOffsetJ) + outputOffset = json_integer_value(outputOffsetJ); } //////////////////// diff --git a/src/core/AudioInterface.cpp b/src/core/AudioInterface.cpp index a19b9685..2f32e8cd 100644 --- a/src/core/AudioInterface.cpp +++ b/src/core/AudioInterface.cpp @@ -71,7 +71,8 @@ struct AudioInterface : Module, audio::Port { configLight(OUTPUT_LIGHTS + 2 * i, string::f("Device input %d/%d status", 2 * i + 1, 2 * i + 2)); lightDivider.setDivision(512); - maxChannels = std::max(NUM_AUDIO_INPUTS, NUM_AUDIO_OUTPUTS); + maxOutputs = NUM_AUDIO_INPUTS; + maxInputs = NUM_AUDIO_OUTPUTS; inputSrc.setQuality(6); outputSrc.setQuality(6);