@@ -7,7 +7,7 @@ namespace rack { | |||||
namespace audio { | namespace audio { | ||||
struct IO; | |||||
struct Port; | |||||
} | } | ||||
@@ -22,7 +22,7 @@ struct AudioWidget : LedDisplay { | |||||
LedDisplayChoice *sampleRateChoice; | LedDisplayChoice *sampleRateChoice; | ||||
LedDisplaySeparator *sampleRateSeparator; | LedDisplaySeparator *sampleRateSeparator; | ||||
LedDisplayChoice *bufferSizeChoice; | LedDisplayChoice *bufferSizeChoice; | ||||
void setAudioIO(audio::IO *audioIO); | |||||
void setAudioPort(audio::Port *port); | |||||
}; | }; | ||||
@@ -7,7 +7,7 @@ namespace rack { | |||||
namespace midi { | namespace midi { | ||||
struct IO; | |||||
struct Port; | |||||
} | } | ||||
@@ -20,7 +20,7 @@ struct MidiWidget : LedDisplay { | |||||
LedDisplayChoice *deviceChoice; | LedDisplayChoice *deviceChoice; | ||||
LedDisplaySeparator *deviceSeparator; | LedDisplaySeparator *deviceSeparator; | ||||
LedDisplayChoice *channelChoice; | LedDisplayChoice *channelChoice; | ||||
void setMidiIO(midi::IO *midiIO); | |||||
void setMidiPort(midi::Port *port); | |||||
}; | }; | ||||
@@ -14,7 +14,7 @@ namespace rack { | |||||
namespace audio { | namespace audio { | ||||
struct IO { | |||||
struct Port { | |||||
// Stream properties | // Stream properties | ||||
int driver = 0; | int driver = 0; | ||||
int device = -1; | int device = -1; | ||||
@@ -28,8 +28,8 @@ struct IO { | |||||
/** Cached */ | /** Cached */ | ||||
RtAudio::DeviceInfo deviceInfo; | RtAudio::DeviceInfo deviceInfo; | ||||
IO(); | |||||
virtual ~IO(); | |||||
Port(); | |||||
virtual ~Port(); | |||||
std::vector<int> getDrivers(); | std::vector<int> getDrivers(); | ||||
std::string getDriverName(int driver); | std::string getDriverName(int driver); | ||||
@@ -8,8 +8,8 @@ namespace rack { | |||||
void bridgeInit(); | void bridgeInit(); | ||||
void bridgeDestroy(); | void bridgeDestroy(); | ||||
void bridgeAudioSubscribe(int channel, audio::IO *audio); | |||||
void bridgeAudioUnsubscribe(int channel, audio::IO *audio); | |||||
void bridgeAudioSubscribe(int channel, audio::Port *port); | |||||
void bridgeAudioUnsubscribe(int channel, audio::Port *port); | |||||
} // namespace rack | } // namespace rack |
@@ -5,7 +5,7 @@ | |||||
namespace rack { | namespace rack { | ||||
/** Driver ID in AudioIO and MidiIO */ | |||||
/** Driver ID for AudioDriver and MidiDriver */ | |||||
const int BRIDGE_DRIVER = -12512; | const int BRIDGE_DRIVER = -12512; | ||||
const char* const BRIDGE_HOST = "127.0.0.1"; | const char* const BRIDGE_HOST = "127.0.0.1"; | ||||
const int BRIDGE_PORT = 12512; | const int BRIDGE_PORT = 12512; | ||||
@@ -88,10 +88,10 @@ struct OutputDevice : Device { | |||||
}; | }; | ||||
//////////////////// | //////////////////// | ||||
// IO | |||||
// Port | |||||
//////////////////// | //////////////////// | ||||
struct IO { | |||||
struct Port { | |||||
int driverId = -1; | int driverId = -1; | ||||
int deviceId = -1; | int deviceId = -1; | ||||
/* For MIDI output, the channel to output messages. | /* For MIDI output, the channel to output messages. | ||||
@@ -104,7 +104,7 @@ struct IO { | |||||
Driver *driver = NULL; | Driver *driver = NULL; | ||||
/** Remember to call setDriverId(-1) in subclass destructors. */ | /** Remember to call setDriverId(-1) in subclass destructors. */ | ||||
virtual ~IO() {} | |||||
virtual ~Port() {} | |||||
std::vector<int> getDriverIds(); | std::vector<int> getDriverIds(); | ||||
std::string getDriverName(int driverId); | std::string getDriverName(int driverId); | ||||
@@ -123,7 +123,7 @@ struct IO { | |||||
}; | }; | ||||
struct Input : IO { | |||||
struct Input : Port { | |||||
/** Not owned */ | /** Not owned */ | ||||
InputDevice *inputDevice = NULL; | InputDevice *inputDevice = NULL; | ||||
@@ -149,7 +149,7 @@ struct InputQueue : Input { | |||||
}; | }; | ||||
struct Output : IO { | |||||
struct Output : Port { | |||||
/** Not owned */ | /** Not owned */ | ||||
OutputDevice *outputDevice = NULL; | OutputDevice *outputDevice = NULL; | ||||
@@ -15,7 +15,7 @@ static const int AUDIO_INPUTS = 8; | |||||
using namespace rack; | using namespace rack; | ||||
struct AudioInterfaceIO : audio::IO { | |||||
struct AudioInterfacePort : audio::Port { | |||||
std::mutex engineMutex; | std::mutex engineMutex; | ||||
std::condition_variable engineCv; | std::condition_variable engineCv; | ||||
std::mutex audioMutex; | std::mutex audioMutex; | ||||
@@ -26,8 +26,8 @@ struct AudioInterfaceIO : audio::IO { | |||||
dsp::DoubleRingBuffer<dsp::Frame<AUDIO_OUTPUTS>, (1<<15)> outputBuffer; | dsp::DoubleRingBuffer<dsp::Frame<AUDIO_OUTPUTS>, (1<<15)> outputBuffer; | ||||
bool active = false; | bool active = false; | ||||
~AudioInterfaceIO() { | |||||
// Close stream here before destructing AudioInterfaceIO, so the mutexes are still valid when waiting to close. | |||||
~AudioInterfacePort() { | |||||
// Close stream here before destructing AudioInterfacePort, so the mutexes are still valid when waiting to close. | |||||
setDevice(-1, 0); | setDevice(-1, 0); | ||||
} | } | ||||
@@ -69,7 +69,7 @@ struct AudioInterfaceIO : audio::IO { | |||||
else { | else { | ||||
// Timed out, fill output with zeros | // Timed out, fill output with zeros | ||||
std::memset(output, 0, frames * numOutputs * sizeof(float)); | std::memset(output, 0, frames * numOutputs * sizeof(float)); | ||||
// DEBUG("Audio Interface IO underflow"); | |||||
// DEBUG("Audio Interface Port underflow"); | |||||
} | } | ||||
} | } | ||||
@@ -105,7 +105,7 @@ struct AudioInterface : Module { | |||||
NUM_LIGHTS | NUM_LIGHTS | ||||
}; | }; | ||||
AudioInterfaceIO audioIO; | |||||
AudioInterfacePort port; | |||||
int lastSampleRate = 0; | int lastSampleRate = 0; | ||||
int lastNumOutputs = -1; | int lastNumOutputs = -1; | ||||
int lastNumInputs = -1; | int lastNumInputs = -1; | ||||
@@ -125,32 +125,32 @@ struct AudioInterface : Module { | |||||
void step() override { | void step() override { | ||||
// Update SRC states | // Update SRC states | ||||
int sampleRate = (int) APP->engine->getSampleRate(); | int sampleRate = (int) APP->engine->getSampleRate(); | ||||
inputSrc.setRates(audioIO.sampleRate, sampleRate); | |||||
outputSrc.setRates(sampleRate, audioIO.sampleRate); | |||||
inputSrc.setRates(port.sampleRate, sampleRate); | |||||
outputSrc.setRates(sampleRate, port.sampleRate); | |||||
inputSrc.setChannels(audioIO.numInputs); | |||||
outputSrc.setChannels(audioIO.numOutputs); | |||||
inputSrc.setChannels(port.numInputs); | |||||
outputSrc.setChannels(port.numOutputs); | |||||
// Inputs: audio engine -> rack engine | // Inputs: audio engine -> rack engine | ||||
if (audioIO.active && audioIO.numInputs > 0) { | |||||
if (port.active && port.numInputs > 0) { | |||||
// Wait until inputs are present | // Wait until inputs are present | ||||
// Give up after a timeout in case the audio device is being unresponsive. | // Give up after a timeout in case the audio device is being unresponsive. | ||||
std::unique_lock<std::mutex> lock(audioIO.engineMutex); | |||||
std::unique_lock<std::mutex> lock(port.engineMutex); | |||||
auto cond = [&] { | auto cond = [&] { | ||||
return (!audioIO.inputBuffer.empty()); | |||||
return (!port.inputBuffer.empty()); | |||||
}; | }; | ||||
auto timeout = std::chrono::milliseconds(200); | auto timeout = std::chrono::milliseconds(200); | ||||
if (audioIO.engineCv.wait_for(lock, timeout, cond)) { | |||||
if (port.engineCv.wait_for(lock, timeout, cond)) { | |||||
// Convert inputs | // Convert inputs | ||||
int inLen = audioIO.inputBuffer.size(); | |||||
int inLen = port.inputBuffer.size(); | |||||
int outLen = inputBuffer.capacity(); | int outLen = inputBuffer.capacity(); | ||||
inputSrc.process(audioIO.inputBuffer.startData(), &inLen, inputBuffer.endData(), &outLen); | |||||
audioIO.inputBuffer.startIncr(inLen); | |||||
inputSrc.process(port.inputBuffer.startData(), &inLen, inputBuffer.endData(), &outLen); | |||||
port.inputBuffer.startIncr(inLen); | |||||
inputBuffer.endIncr(outLen); | inputBuffer.endIncr(outLen); | ||||
} | } | ||||
else { | else { | ||||
// Give up on pulling input | // Give up on pulling input | ||||
audioIO.active = false; | |||||
port.active = false; | |||||
// DEBUG("Audio Interface underflow"); | // DEBUG("Audio Interface underflow"); | ||||
} | } | ||||
} | } | ||||
@@ -163,15 +163,15 @@ struct AudioInterface : Module { | |||||
else { | else { | ||||
std::memset(&inputFrame, 0, sizeof(inputFrame)); | std::memset(&inputFrame, 0, sizeof(inputFrame)); | ||||
} | } | ||||
for (int i = 0; i < audioIO.numInputs; i++) { | |||||
for (int i = 0; i < port.numInputs; i++) { | |||||
outputs[AUDIO_OUTPUT + i].setVoltage(10.f * inputFrame.samples[i]); | outputs[AUDIO_OUTPUT + i].setVoltage(10.f * inputFrame.samples[i]); | ||||
} | } | ||||
for (int i = audioIO.numInputs; i < AUDIO_INPUTS; i++) { | |||||
for (int i = port.numInputs; i < AUDIO_INPUTS; i++) { | |||||
outputs[AUDIO_OUTPUT + i].setVoltage(0.f); | outputs[AUDIO_OUTPUT + i].setVoltage(0.f); | ||||
} | } | ||||
// Outputs: rack engine -> audio engine | // Outputs: rack engine -> audio engine | ||||
if (audioIO.active && audioIO.numOutputs > 0) { | |||||
if (port.active && port.numOutputs > 0) { | |||||
// Get and push output SRC frame | // Get and push output SRC frame | ||||
if (!outputBuffer.full()) { | if (!outputBuffer.full()) { | ||||
dsp::Frame<AUDIO_OUTPUTS> outputFrame; | dsp::Frame<AUDIO_OUTPUTS> outputFrame; | ||||
@@ -184,51 +184,51 @@ struct AudioInterface : Module { | |||||
if (outputBuffer.full()) { | if (outputBuffer.full()) { | ||||
// Wait until enough outputs are consumed | // Wait until enough outputs are consumed | ||||
// Give up after a timeout in case the audio device is being unresponsive. | // Give up after a timeout in case the audio device is being unresponsive. | ||||
std::unique_lock<std::mutex> lock(audioIO.engineMutex); | |||||
std::unique_lock<std::mutex> lock(port.engineMutex); | |||||
auto cond = [&] { | auto cond = [&] { | ||||
return (audioIO.outputBuffer.size() < (size_t) audioIO.blockSize); | |||||
return (port.outputBuffer.size() < (size_t) port.blockSize); | |||||
}; | }; | ||||
auto timeout = std::chrono::milliseconds(200); | auto timeout = std::chrono::milliseconds(200); | ||||
if (audioIO.engineCv.wait_for(lock, timeout, cond)) { | |||||
if (port.engineCv.wait_for(lock, timeout, cond)) { | |||||
// Push converted output | // Push converted output | ||||
int inLen = outputBuffer.size(); | int inLen = outputBuffer.size(); | ||||
int outLen = audioIO.outputBuffer.capacity(); | |||||
outputSrc.process(outputBuffer.startData(), &inLen, audioIO.outputBuffer.endData(), &outLen); | |||||
int outLen = port.outputBuffer.capacity(); | |||||
outputSrc.process(outputBuffer.startData(), &inLen, port.outputBuffer.endData(), &outLen); | |||||
outputBuffer.startIncr(inLen); | outputBuffer.startIncr(inLen); | ||||
audioIO.outputBuffer.endIncr(outLen); | |||||
port.outputBuffer.endIncr(outLen); | |||||
} | } | ||||
else { | else { | ||||
// Give up on pushing output | // Give up on pushing output | ||||
audioIO.active = false; | |||||
port.active = false; | |||||
outputBuffer.clear(); | outputBuffer.clear(); | ||||
// DEBUG("Audio Interface underflow"); | // DEBUG("Audio Interface underflow"); | ||||
} | } | ||||
} | } | ||||
// Notify audio thread that an output is potentially ready | // Notify audio thread that an output is potentially ready | ||||
audioIO.audioCv.notify_one(); | |||||
port.audioCv.notify_one(); | |||||
} | } | ||||
// Turn on light if at least one port is enabled in the nearby pair | // Turn on light if at least one port is enabled in the nearby pair | ||||
for (int i = 0; i < AUDIO_INPUTS / 2; i++) | for (int i = 0; i < AUDIO_INPUTS / 2; i++) | ||||
lights[INPUT_LIGHT + i].setBrightness(audioIO.active && audioIO.numOutputs >= 2*i+1); | |||||
lights[INPUT_LIGHT + i].setBrightness(port.active && port.numOutputs >= 2*i+1); | |||||
for (int i = 0; i < AUDIO_OUTPUTS / 2; i++) | for (int i = 0; i < AUDIO_OUTPUTS / 2; i++) | ||||
lights[OUTPUT_LIGHT + i].setBrightness(audioIO.active && audioIO.numInputs >= 2*i+1); | |||||
lights[OUTPUT_LIGHT + i].setBrightness(port.active && port.numInputs >= 2*i+1); | |||||
} | } | ||||
json_t *dataToJson() override { | json_t *dataToJson() override { | ||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
json_object_set_new(rootJ, "audio", audioIO.toJson()); | |||||
json_object_set_new(rootJ, "audio", port.toJson()); | |||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void dataFromJson(json_t *rootJ) override { | void dataFromJson(json_t *rootJ) override { | ||||
json_t *audioJ = json_object_get(rootJ, "audio"); | json_t *audioJ = json_object_get(rootJ, "audio"); | ||||
audioIO.fromJson(audioJ); | |||||
port.fromJson(audioJ); | |||||
} | } | ||||
void onReset() override { | void onReset() override { | ||||
audioIO.setDevice(-1, 0); | |||||
port.setDevice(-1, 0); | |||||
} | } | ||||
}; | }; | ||||
@@ -272,7 +272,7 @@ struct AudioInterfaceWidget : ModuleWidget { | |||||
AudioWidget *audioWidget = createWidget<AudioWidget>(mm2px(Vec(3.2122073, 14.837339))); | AudioWidget *audioWidget = createWidget<AudioWidget>(mm2px(Vec(3.2122073, 14.837339))); | ||||
audioWidget->box.size = mm2px(Vec(44, 28)); | audioWidget->box.size = mm2px(Vec(44, 28)); | ||||
audioWidget->setAudioIO(module ? &module->audioIO : NULL); | |||||
audioWidget->setAudioPort(module ? &module->port : NULL); | |||||
addChild(audioWidget); | addChild(audioWidget); | ||||
} | } | ||||
}; | }; | ||||
@@ -139,7 +139,7 @@ struct CV_CCWidget : ModuleWidget { | |||||
typedef Grid16MidiWidget<CcChoice<CV_CC>> TMidiWidget; | typedef Grid16MidiWidget<CcChoice<CV_CC>> TMidiWidget; | ||||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | ||||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | midiWidget->box.size = mm2px(Vec(44, 54.667)); | ||||
midiWidget->setMidiIO(module ? &module->midiOutput : NULL); | |||||
midiWidget->setMidiPort(module ? &module->midiOutput : NULL); | |||||
midiWidget->setModule(module); | midiWidget->setModule(module); | ||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -189,7 +189,7 @@ struct CV_GateWidget : ModuleWidget { | |||||
typedef Grid16MidiWidget<NoteChoice<CV_Gate>> TMidiWidget; | typedef Grid16MidiWidget<NoteChoice<CV_Gate>> TMidiWidget; | ||||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | ||||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | midiWidget->box.size = mm2px(Vec(44, 54.667)); | ||||
midiWidget->setMidiIO(module ? &module->midiOutput : NULL); | |||||
midiWidget->setMidiPort(module ? &module->midiOutput : NULL); | |||||
midiWidget->setModule(module); | midiWidget->setModule(module); | ||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -346,7 +346,7 @@ struct CV_MIDIWidget : ModuleWidget { | |||||
MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.41891, 14.8373))); | MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.41891, 14.8373))); | ||||
midiWidget->box.size = mm2px(Vec(33.840, 28)); | midiWidget->box.size = mm2px(Vec(33.840, 28)); | ||||
midiWidget->setMidiIO(module ? &module->midiOutput : NULL); | |||||
midiWidget->setMidiPort(module ? &module->midiOutput : NULL); | |||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -171,7 +171,7 @@ struct MIDI_CCWidget : ModuleWidget { | |||||
typedef Grid16MidiWidget<CcChoice<MIDI_CC>> TMidiWidget; | typedef Grid16MidiWidget<CcChoice<MIDI_CC>> TMidiWidget; | ||||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | ||||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | midiWidget->box.size = mm2px(Vec(44, 54.667)); | ||||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||||
midiWidget->setMidiPort(module ? &module->midiInput : NULL); | |||||
midiWidget->setModule(module); | midiWidget->setModule(module); | ||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -540,7 +540,7 @@ struct MIDI_CVWidget : ModuleWidget { | |||||
MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.41891, 14.8373))); | MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.41891, 14.8373))); | ||||
midiWidget->box.size = mm2px(Vec(33.840, 28)); | midiWidget->box.size = mm2px(Vec(33.840, 28)); | ||||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||||
midiWidget->setMidiPort(module ? &module->midiInput : NULL); | |||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -196,7 +196,7 @@ struct MIDI_GateWidget : ModuleWidget { | |||||
typedef Grid16MidiWidget<NoteChoice<MIDI_Gate>> TMidiWidget; | typedef Grid16MidiWidget<NoteChoice<MIDI_Gate>> TMidiWidget; | ||||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | ||||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | midiWidget->box.size = mm2px(Vec(44, 54.667)); | ||||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||||
midiWidget->setMidiPort(module ? &module->midiInput : NULL); | |||||
midiWidget->setModule(module); | midiWidget->setModule(module); | ||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -433,7 +433,7 @@ struct MIDI_MapWidget : ModuleWidget { | |||||
MIDI_MapDisplay *midiWidget = createWidget<MIDI_MapDisplay>(mm2px(Vec(3.41891, 14.8373))); | MIDI_MapDisplay *midiWidget = createWidget<MIDI_MapDisplay>(mm2px(Vec(3.41891, 14.8373))); | ||||
midiWidget->box.size = mm2px(Vec(43.999, 102.664)); | midiWidget->box.size = mm2px(Vec(43.999, 102.664)); | ||||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||||
midiWidget->setMidiPort(module ? &module->midiInput : NULL); | |||||
midiWidget->setModule(module); | midiWidget->setModule(module); | ||||
addChild(midiWidget); | addChild(midiWidget); | ||||
} | } | ||||
@@ -8,33 +8,33 @@ namespace app { | |||||
struct AudioDriverItem : ui::MenuItem { | struct AudioDriverItem : ui::MenuItem { | ||||
audio::IO *audioIO; | |||||
audio::Port *port; | |||||
int driver; | int driver; | ||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
audioIO->setDriver(driver); | |||||
port->setDriver(driver); | |||||
} | } | ||||
}; | }; | ||||
struct AudioDriverChoice : LedDisplayChoice { | struct AudioDriverChoice : LedDisplayChoice { | ||||
audio::IO *audioIO; | |||||
audio::Port *port; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!audioIO) | |||||
if (!port) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("Audio driver")); | menu->addChild(createMenuLabel("Audio driver")); | ||||
for (int driver : audioIO->getDrivers()) { | |||||
for (int driver : port->getDrivers()) { | |||||
AudioDriverItem *item = new AudioDriverItem; | AudioDriverItem *item = new AudioDriverItem; | ||||
item->audioIO = audioIO; | |||||
item->port = port; | |||||
item->driver = driver; | item->driver = driver; | ||||
item->text = audioIO->getDriverName(driver); | |||||
item->rightText = CHECKMARK(item->driver == audioIO->driver); | |||||
item->text = port->getDriverName(driver); | |||||
item->rightText = CHECKMARK(item->driver == port->driver); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (audioIO) | |||||
text = audioIO->getDriverName(audioIO->driver); | |||||
if (port) | |||||
text = port->getDriverName(port->driver); | |||||
else | else | ||||
text = ""; | text = ""; | ||||
} | } | ||||
@@ -42,53 +42,53 @@ struct AudioDriverChoice : LedDisplayChoice { | |||||
struct AudioDeviceItem : ui::MenuItem { | struct AudioDeviceItem : ui::MenuItem { | ||||
audio::IO *audioIO; | |||||
audio::Port *port; | |||||
int device; | int device; | ||||
int offset; | int offset; | ||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
audioIO->setDevice(device, offset); | |||||
port->setDevice(device, offset); | |||||
} | } | ||||
}; | }; | ||||
struct AudioDeviceChoice : LedDisplayChoice { | struct AudioDeviceChoice : LedDisplayChoice { | ||||
audio::IO *audioIO; | |||||
audio::Port *port; | |||||
/** Prevents devices with a ridiculous number of channels from being displayed */ | /** Prevents devices with a ridiculous number of channels from being displayed */ | ||||
int maxTotalChannels = 128; | int maxTotalChannels = 128; | ||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!audioIO) | |||||
if (!port) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("Audio device")); | menu->addChild(createMenuLabel("Audio device")); | ||||
int deviceCount = audioIO->getDeviceCount(); | |||||
int deviceCount = port->getDeviceCount(); | |||||
{ | { | ||||
AudioDeviceItem *item = new AudioDeviceItem; | AudioDeviceItem *item = new AudioDeviceItem; | ||||
item->audioIO = audioIO; | |||||
item->port = port; | |||||
item->device = -1; | item->device = -1; | ||||
item->text = "(No device)"; | item->text = "(No device)"; | ||||
item->rightText = CHECKMARK(item->device == audioIO->device); | |||||
item->rightText = CHECKMARK(item->device == port->device); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
for (int device = 0; device < deviceCount; device++) { | for (int device = 0; device < deviceCount; device++) { | ||||
int channels = std::min(maxTotalChannels, audioIO->getDeviceChannels(device)); | |||||
for (int offset = 0; offset < channels; offset += audioIO->maxChannels) { | |||||
int channels = std::min(maxTotalChannels, port->getDeviceChannels(device)); | |||||
for (int offset = 0; offset < channels; offset += port->maxChannels) { | |||||
AudioDeviceItem *item = new AudioDeviceItem; | AudioDeviceItem *item = new AudioDeviceItem; | ||||
item->audioIO = audioIO; | |||||
item->port = port; | |||||
item->device = device; | item->device = device; | ||||
item->offset = offset; | item->offset = offset; | ||||
item->text = audioIO->getDeviceDetail(device, offset); | |||||
item->rightText = CHECKMARK(item->device == audioIO->device && item->offset == audioIO->offset); | |||||
item->text = port->getDeviceDetail(device, offset); | |||||
item->rightText = CHECKMARK(item->device == port->device && item->offset == port->offset); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (!audioIO) { | |||||
if (!port) { | |||||
text = ""; | text = ""; | ||||
return; | return; | ||||
} | } | ||||
text = audioIO->getDeviceDetail(audioIO->device, audioIO->offset); | |||||
text = port->getDeviceDetail(port->device, port->offset); | |||||
if (text.empty()) { | if (text.empty()) { | ||||
text = "(No device)"; | text = "(No device)"; | ||||
color.a = 0.5f; | color.a = 0.5f; | ||||
@@ -101,37 +101,37 @@ struct AudioDeviceChoice : LedDisplayChoice { | |||||
struct AudioSampleRateItem : ui::MenuItem { | struct AudioSampleRateItem : ui::MenuItem { | ||||
audio::IO *audioIO; | |||||
audio::Port *port; | |||||
int sampleRate; | int sampleRate; | ||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
audioIO->setSampleRate(sampleRate); | |||||
port->setSampleRate(sampleRate); | |||||
} | } | ||||
}; | }; | ||||
struct AudioSampleRateChoice : LedDisplayChoice { | struct AudioSampleRateChoice : LedDisplayChoice { | ||||
audio::IO *audioIO; | |||||
audio::Port *port; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!audioIO) | |||||
if (!port) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("Sample rate")); | menu->addChild(createMenuLabel("Sample rate")); | ||||
std::vector<int> sampleRates = audioIO->getSampleRates(); | |||||
std::vector<int> sampleRates = port->getSampleRates(); | |||||
if (sampleRates.empty()) { | if (sampleRates.empty()) { | ||||
menu->addChild(createMenuLabel("(Locked by device)")); | menu->addChild(createMenuLabel("(Locked by device)")); | ||||
} | } | ||||
for (int sampleRate : sampleRates) { | for (int sampleRate : sampleRates) { | ||||
AudioSampleRateItem *item = new AudioSampleRateItem; | AudioSampleRateItem *item = new AudioSampleRateItem; | ||||
item->audioIO = audioIO; | |||||
item->port = port; | |||||
item->sampleRate = sampleRate; | item->sampleRate = sampleRate; | ||||
item->text = string::f("%d Hz", sampleRate); | item->text = string::f("%d Hz", sampleRate); | ||||
item->rightText = CHECKMARK(item->sampleRate == audioIO->sampleRate); | |||||
item->rightText = CHECKMARK(item->sampleRate == port->sampleRate); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (audioIO) | |||||
text = string::f("%g kHz", audioIO->sampleRate / 1000.f); | |||||
if (port) | |||||
text = string::f("%g kHz", port->sampleRate / 1000.f); | |||||
else | else | ||||
text = ""; | text = ""; | ||||
} | } | ||||
@@ -139,52 +139,52 @@ struct AudioSampleRateChoice : LedDisplayChoice { | |||||
struct AudioBlockSizeItem : ui::MenuItem { | struct AudioBlockSizeItem : ui::MenuItem { | ||||
audio::IO *audioIO; | |||||
audio::Port *port; | |||||
int blockSize; | int blockSize; | ||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
audioIO->setBlockSize(blockSize); | |||||
port->setBlockSize(blockSize); | |||||
} | } | ||||
}; | }; | ||||
struct AudioBlockSizeChoice : LedDisplayChoice { | struct AudioBlockSizeChoice : LedDisplayChoice { | ||||
audio::IO *audioIO; | |||||
audio::Port *port; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!audioIO) | |||||
if (!port) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("Block size")); | menu->addChild(createMenuLabel("Block size")); | ||||
std::vector<int> blockSizes = audioIO->getBlockSizes(); | |||||
std::vector<int> blockSizes = port->getBlockSizes(); | |||||
if (blockSizes.empty()) { | if (blockSizes.empty()) { | ||||
menu->addChild(createMenuLabel("(Locked by device)")); | menu->addChild(createMenuLabel("(Locked by device)")); | ||||
} | } | ||||
for (int blockSize : blockSizes) { | for (int blockSize : blockSizes) { | ||||
AudioBlockSizeItem *item = new AudioBlockSizeItem; | AudioBlockSizeItem *item = new AudioBlockSizeItem; | ||||
item->audioIO = audioIO; | |||||
item->port = port; | |||||
item->blockSize = blockSize; | item->blockSize = blockSize; | ||||
float latency = (float) blockSize / audioIO->sampleRate * 1000.0; | |||||
float latency = (float) blockSize / port->sampleRate * 1000.0; | |||||
item->text = string::f("%d (%.1f ms)", blockSize, latency); | item->text = string::f("%d (%.1f ms)", blockSize, latency); | ||||
item->rightText = CHECKMARK(item->blockSize == audioIO->blockSize); | |||||
item->rightText = CHECKMARK(item->blockSize == port->blockSize); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (audioIO) | |||||
text = string::f("%d", audioIO->blockSize); | |||||
if (port) | |||||
text = string::f("%d", port->blockSize); | |||||
else | else | ||||
text = ""; | text = ""; | ||||
} | } | ||||
}; | }; | ||||
void AudioWidget::setAudioIO(audio::IO *audioIO) { | |||||
void AudioWidget::setAudioPort(audio::Port *port) { | |||||
clearChildren(); | clearChildren(); | ||||
math::Vec pos; | math::Vec pos; | ||||
AudioDriverChoice *driverChoice = createWidget<AudioDriverChoice>(pos); | AudioDriverChoice *driverChoice = createWidget<AudioDriverChoice>(pos); | ||||
driverChoice->box.size.x = box.size.x; | driverChoice->box.size.x = box.size.x; | ||||
driverChoice->audioIO = audioIO; | |||||
driverChoice->port = port; | |||||
addChild(driverChoice); | addChild(driverChoice); | ||||
pos = driverChoice->box.getBottomLeft(); | pos = driverChoice->box.getBottomLeft(); | ||||
this->driverChoice = driverChoice; | this->driverChoice = driverChoice; | ||||
@@ -195,7 +195,7 @@ void AudioWidget::setAudioIO(audio::IO *audioIO) { | |||||
AudioDeviceChoice *deviceChoice = createWidget<AudioDeviceChoice>(pos); | AudioDeviceChoice *deviceChoice = createWidget<AudioDeviceChoice>(pos); | ||||
deviceChoice->box.size.x = box.size.x; | deviceChoice->box.size.x = box.size.x; | ||||
deviceChoice->audioIO = audioIO; | |||||
deviceChoice->port = port; | |||||
addChild(deviceChoice); | addChild(deviceChoice); | ||||
pos = deviceChoice->box.getBottomLeft(); | pos = deviceChoice->box.getBottomLeft(); | ||||
this->deviceChoice = deviceChoice; | this->deviceChoice = deviceChoice; | ||||
@@ -206,7 +206,7 @@ void AudioWidget::setAudioIO(audio::IO *audioIO) { | |||||
AudioSampleRateChoice *sampleRateChoice = createWidget<AudioSampleRateChoice>(pos); | AudioSampleRateChoice *sampleRateChoice = createWidget<AudioSampleRateChoice>(pos); | ||||
sampleRateChoice->box.size.x = box.size.x / 2; | sampleRateChoice->box.size.x = box.size.x / 2; | ||||
sampleRateChoice->audioIO = audioIO; | |||||
sampleRateChoice->port = port; | |||||
addChild(sampleRateChoice); | addChild(sampleRateChoice); | ||||
this->sampleRateChoice = sampleRateChoice; | this->sampleRateChoice = sampleRateChoice; | ||||
@@ -218,7 +218,7 @@ void AudioWidget::setAudioIO(audio::IO *audioIO) { | |||||
AudioBlockSizeChoice *bufferSizeChoice = createWidget<AudioBlockSizeChoice>(pos); | AudioBlockSizeChoice *bufferSizeChoice = createWidget<AudioBlockSizeChoice>(pos); | ||||
bufferSizeChoice->box.pos.x = box.size.x / 2; | bufferSizeChoice->box.pos.x = box.size.x / 2; | ||||
bufferSizeChoice->box.size.x = box.size.x / 2; | bufferSizeChoice->box.size.x = box.size.x / 2; | ||||
bufferSizeChoice->audioIO = audioIO; | |||||
bufferSizeChoice->port = port; | |||||
addChild(bufferSizeChoice); | addChild(bufferSizeChoice); | ||||
this->bufferSizeChoice = bufferSizeChoice; | this->bufferSizeChoice = bufferSizeChoice; | ||||
} | } | ||||
@@ -8,36 +8,36 @@ namespace app { | |||||
struct MidiDriverItem : ui::MenuItem { | struct MidiDriverItem : ui::MenuItem { | ||||
midi::IO *midiIO; | |||||
midi::Port *port; | |||||
int driverId; | int driverId; | ||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
midiIO->setDriverId(driverId); | |||||
port->setDriverId(driverId); | |||||
} | } | ||||
}; | }; | ||||
struct MidiDriverChoice : LedDisplayChoice { | struct MidiDriverChoice : LedDisplayChoice { | ||||
midi::IO *midiIO; | |||||
midi::Port *port; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!midiIO) | |||||
if (!port) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("MIDI driver")); | menu->addChild(createMenuLabel("MIDI driver")); | ||||
for (int driverId : midiIO->getDriverIds()) { | |||||
for (int driverId : port->getDriverIds()) { | |||||
MidiDriverItem *item = new MidiDriverItem; | MidiDriverItem *item = new MidiDriverItem; | ||||
item->midiIO = midiIO; | |||||
item->port = port; | |||||
item->driverId = driverId; | item->driverId = driverId; | ||||
item->text = midiIO->getDriverName(driverId); | |||||
item->rightText = CHECKMARK(item->driverId == midiIO->driverId); | |||||
item->text = port->getDriverName(driverId); | |||||
item->rightText = CHECKMARK(item->driverId == port->driverId); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (!midiIO) { | |||||
if (!port) { | |||||
text = ""; | text = ""; | ||||
return; | return; | ||||
} | } | ||||
text = midiIO->getDriverName(midiIO->driverId); | |||||
text = port->getDriverName(port->driverId); | |||||
if (text.empty()) { | if (text.empty()) { | ||||
text = "(No driver)"; | text = "(No driver)"; | ||||
color.a = 0.5f; | color.a = 0.5f; | ||||
@@ -49,44 +49,44 @@ struct MidiDriverChoice : LedDisplayChoice { | |||||
}; | }; | ||||
struct MidiDeviceItem : ui::MenuItem { | struct MidiDeviceItem : ui::MenuItem { | ||||
midi::IO *midiIO; | |||||
midi::Port *port; | |||||
int deviceId; | int deviceId; | ||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
midiIO->setDeviceId(deviceId); | |||||
port->setDeviceId(deviceId); | |||||
} | } | ||||
}; | }; | ||||
struct MidiDeviceChoice : LedDisplayChoice { | struct MidiDeviceChoice : LedDisplayChoice { | ||||
midi::IO *midiIO; | |||||
midi::Port *port; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!midiIO) | |||||
if (!port) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("MIDI device")); | menu->addChild(createMenuLabel("MIDI device")); | ||||
{ | { | ||||
MidiDeviceItem *item = new MidiDeviceItem; | MidiDeviceItem *item = new MidiDeviceItem; | ||||
item->midiIO = midiIO; | |||||
item->port = port; | |||||
item->deviceId = -1; | item->deviceId = -1; | ||||
item->text = "(No device)"; | item->text = "(No device)"; | ||||
item->rightText = CHECKMARK(item->deviceId == midiIO->deviceId); | |||||
item->rightText = CHECKMARK(item->deviceId == port->deviceId); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
for (int deviceId : midiIO->getDeviceIds()) { | |||||
for (int deviceId : port->getDeviceIds()) { | |||||
MidiDeviceItem *item = new MidiDeviceItem; | MidiDeviceItem *item = new MidiDeviceItem; | ||||
item->midiIO = midiIO; | |||||
item->port = port; | |||||
item->deviceId = deviceId; | item->deviceId = deviceId; | ||||
item->text = midiIO->getDeviceName(deviceId); | |||||
item->rightText = CHECKMARK(item->deviceId == midiIO->deviceId); | |||||
item->text = port->getDeviceName(deviceId); | |||||
item->rightText = CHECKMARK(item->deviceId == port->deviceId); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (!midiIO) { | |||||
if (!port) { | |||||
text = ""; | text = ""; | ||||
return; | return; | ||||
} | } | ||||
text = midiIO->getDeviceName(midiIO->deviceId); | |||||
text = port->getDeviceName(port->deviceId); | |||||
if (text.empty()) { | if (text.empty()) { | ||||
text = "(No device)"; | text = "(No device)"; | ||||
color.a = 0.5f; | color.a = 0.5f; | ||||
@@ -98,47 +98,47 @@ struct MidiDeviceChoice : LedDisplayChoice { | |||||
}; | }; | ||||
struct MidiChannelItem : ui::MenuItem { | struct MidiChannelItem : ui::MenuItem { | ||||
midi::IO *midiIO; | |||||
midi::Port *port; | |||||
int channel; | int channel; | ||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
midiIO->channel = channel; | |||||
port->channel = channel; | |||||
} | } | ||||
}; | }; | ||||
struct MidiChannelChoice : LedDisplayChoice { | struct MidiChannelChoice : LedDisplayChoice { | ||||
midi::IO *midiIO; | |||||
midi::Port *port; | |||||
void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
if (!midiIO) | |||||
if (!port) | |||||
return; | return; | ||||
ui::Menu *menu = createMenu(); | ui::Menu *menu = createMenu(); | ||||
menu->addChild(createMenuLabel("MIDI channel")); | menu->addChild(createMenuLabel("MIDI channel")); | ||||
for (int channel : midiIO->getChannels()) { | |||||
for (int channel : port->getChannels()) { | |||||
MidiChannelItem *item = new MidiChannelItem; | MidiChannelItem *item = new MidiChannelItem; | ||||
item->midiIO = midiIO; | |||||
item->port = port; | |||||
item->channel = channel; | item->channel = channel; | ||||
item->text = midiIO->getChannelName(channel); | |||||
item->rightText = CHECKMARK(item->channel == midiIO->channel); | |||||
item->text = port->getChannelName(channel); | |||||
item->rightText = CHECKMARK(item->channel == port->channel); | |||||
menu->addChild(item); | menu->addChild(item); | ||||
} | } | ||||
} | } | ||||
void step() override { | void step() override { | ||||
if (midiIO) | |||||
text = midiIO->getChannelName(midiIO->channel); | |||||
if (port) | |||||
text = port->getChannelName(port->channel); | |||||
else | else | ||||
text = ""; | text = ""; | ||||
} | } | ||||
}; | }; | ||||
void MidiWidget::setMidiIO(midi::IO *midiIO) { | |||||
void MidiWidget::setMidiPort(midi::Port *port) { | |||||
clearChildren(); | clearChildren(); | ||||
math::Vec pos; | math::Vec pos; | ||||
MidiDriverChoice *driverChoice = createWidget<MidiDriverChoice>(pos); | MidiDriverChoice *driverChoice = createWidget<MidiDriverChoice>(pos); | ||||
driverChoice->box.size.x = box.size.x; | driverChoice->box.size.x = box.size.x; | ||||
driverChoice->midiIO = midiIO; | |||||
driverChoice->port = port; | |||||
addChild(driverChoice); | addChild(driverChoice); | ||||
pos = driverChoice->box.getBottomLeft(); | pos = driverChoice->box.getBottomLeft(); | ||||
this->driverChoice = driverChoice; | this->driverChoice = driverChoice; | ||||
@@ -149,7 +149,7 @@ void MidiWidget::setMidiIO(midi::IO *midiIO) { | |||||
MidiDeviceChoice *deviceChoice = createWidget<MidiDeviceChoice>(pos); | MidiDeviceChoice *deviceChoice = createWidget<MidiDeviceChoice>(pos); | ||||
deviceChoice->box.size.x = box.size.x; | deviceChoice->box.size.x = box.size.x; | ||||
deviceChoice->midiIO = midiIO; | |||||
deviceChoice->port = port; | |||||
addChild(deviceChoice); | addChild(deviceChoice); | ||||
pos = deviceChoice->box.getBottomLeft(); | pos = deviceChoice->box.getBottomLeft(); | ||||
this->deviceChoice = deviceChoice; | this->deviceChoice = deviceChoice; | ||||
@@ -160,7 +160,7 @@ void MidiWidget::setMidiIO(midi::IO *midiIO) { | |||||
MidiChannelChoice *channelChoice = createWidget<MidiChannelChoice>(pos); | MidiChannelChoice *channelChoice = createWidget<MidiChannelChoice>(pos); | ||||
channelChoice->box.size.x = box.size.x; | channelChoice->box.size.x = box.size.x; | ||||
channelChoice->midiIO = midiIO; | |||||
channelChoice->port = port; | |||||
addChild(channelChoice); | addChild(channelChoice); | ||||
this->channelChoice = channelChoice; | this->channelChoice = channelChoice; | ||||
} | } | ||||
@@ -9,15 +9,15 @@ namespace rack { | |||||
namespace audio { | namespace audio { | ||||
IO::IO() { | |||||
Port::Port() { | |||||
setDriver(RtAudio::UNSPECIFIED); | setDriver(RtAudio::UNSPECIFIED); | ||||
} | } | ||||
IO::~IO() { | |||||
Port::~Port() { | |||||
closeStream(); | closeStream(); | ||||
} | } | ||||
std::vector<int> IO::getDrivers() { | |||||
std::vector<int> Port::getDrivers() { | |||||
std::vector<RtAudio::Api> apis; | std::vector<RtAudio::Api> apis; | ||||
RtAudio::getCompiledApi(apis); | RtAudio::getCompiledApi(apis); | ||||
std::vector<int> drivers; | std::vector<int> drivers; | ||||
@@ -29,7 +29,7 @@ std::vector<int> IO::getDrivers() { | |||||
return drivers; | return drivers; | ||||
} | } | ||||
std::string IO::getDriverName(int driver) { | |||||
std::string Port::getDriverName(int driver) { | |||||
switch (driver) { | switch (driver) { | ||||
case RtAudio::UNSPECIFIED: return "Unspecified"; | case RtAudio::UNSPECIFIED: return "Unspecified"; | ||||
case RtAudio::LINUX_ALSA: return "ALSA"; | case RtAudio::LINUX_ALSA: return "ALSA"; | ||||
@@ -46,7 +46,7 @@ std::string IO::getDriverName(int driver) { | |||||
} | } | ||||
} | } | ||||
void IO::setDriver(int driver) { | |||||
void Port::setDriver(int driver) { | |||||
// Close device | // Close device | ||||
setDevice(-1, 0); | setDevice(-1, 0); | ||||
@@ -67,7 +67,7 @@ void IO::setDriver(int driver) { | |||||
} | } | ||||
} | } | ||||
int IO::getDeviceCount() { | |||||
int Port::getDeviceCount() { | |||||
if (rtAudio) { | if (rtAudio) { | ||||
return rtAudio->getDeviceCount(); | return rtAudio->getDeviceCount(); | ||||
} | } | ||||
@@ -77,7 +77,7 @@ int IO::getDeviceCount() { | |||||
return 0; | return 0; | ||||
} | } | ||||
bool IO::getDeviceInfo(int device, RtAudio::DeviceInfo *deviceInfo) { | |||||
bool Port::getDeviceInfo(int device, RtAudio::DeviceInfo *deviceInfo) { | |||||
if (!deviceInfo) | if (!deviceInfo) | ||||
return false; | return false; | ||||
@@ -100,7 +100,7 @@ bool IO::getDeviceInfo(int device, RtAudio::DeviceInfo *deviceInfo) { | |||||
return false; | return false; | ||||
} | } | ||||
int IO::getDeviceChannels(int device) { | |||||
int Port::getDeviceChannels(int device) { | |||||
if (device < 0) | if (device < 0) | ||||
return 0; | return 0; | ||||
@@ -115,7 +115,7 @@ int IO::getDeviceChannels(int device) { | |||||
return 0; | return 0; | ||||
} | } | ||||
std::string IO::getDeviceName(int device) { | |||||
std::string Port::getDeviceName(int device) { | |||||
if (device < 0) | if (device < 0) | ||||
return ""; | return ""; | ||||
@@ -130,7 +130,7 @@ std::string IO::getDeviceName(int device) { | |||||
return ""; | return ""; | ||||
} | } | ||||
std::string IO::getDeviceDetail(int device, int offset) { | |||||
std::string Port::getDeviceDetail(int device, int offset) { | |||||
if (device < 0) | if (device < 0) | ||||
return ""; | return ""; | ||||
@@ -154,14 +154,14 @@ std::string IO::getDeviceDetail(int device, int offset) { | |||||
return ""; | return ""; | ||||
} | } | ||||
void IO::setDevice(int device, int offset) { | |||||
void Port::setDevice(int device, int offset) { | |||||
closeStream(); | closeStream(); | ||||
this->device = device; | this->device = device; | ||||
this->offset = offset; | this->offset = offset; | ||||
openStream(); | openStream(); | ||||
} | } | ||||
std::vector<int> IO::getSampleRates() { | |||||
std::vector<int> Port::getSampleRates() { | |||||
if (rtAudio) { | if (rtAudio) { | ||||
try { | try { | ||||
RtAudio::DeviceInfo deviceInfo = rtAudio->getDeviceInfo(device); | RtAudio::DeviceInfo deviceInfo = rtAudio->getDeviceInfo(device); | ||||
@@ -175,7 +175,7 @@ std::vector<int> IO::getSampleRates() { | |||||
return {}; | return {}; | ||||
} | } | ||||
void IO::setSampleRate(int sampleRate) { | |||||
void Port::setSampleRate(int sampleRate) { | |||||
if (sampleRate == this->sampleRate) | if (sampleRate == this->sampleRate) | ||||
return; | return; | ||||
closeStream(); | closeStream(); | ||||
@@ -183,14 +183,14 @@ void IO::setSampleRate(int sampleRate) { | |||||
openStream(); | openStream(); | ||||
} | } | ||||
std::vector<int> IO::getBlockSizes() { | |||||
std::vector<int> Port::getBlockSizes() { | |||||
if (rtAudio) { | if (rtAudio) { | ||||
return {64, 128, 256, 512, 1024, 2048, 4096}; | return {64, 128, 256, 512, 1024, 2048, 4096}; | ||||
} | } | ||||
return {}; | return {}; | ||||
} | } | ||||
void IO::setBlockSize(int blockSize) { | |||||
void Port::setBlockSize(int blockSize) { | |||||
if (blockSize == this->blockSize) | if (blockSize == this->blockSize) | ||||
return; | return; | ||||
closeStream(); | closeStream(); | ||||
@@ -198,7 +198,7 @@ void IO::setBlockSize(int blockSize) { | |||||
openStream(); | openStream(); | ||||
} | } | ||||
void IO::setChannels(int numOutputs, int numInputs) { | |||||
void Port::setChannels(int numOutputs, int numInputs) { | |||||
this->numOutputs = numOutputs; | this->numOutputs = numOutputs; | ||||
this->numInputs = numInputs; | this->numInputs = numInputs; | ||||
onChannelsChange(); | onChannelsChange(); | ||||
@@ -206,18 +206,18 @@ void IO::setChannels(int numOutputs, int numInputs) { | |||||
static int rtCallback(void *outputBuffer, void *inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void *userData) { | static int rtCallback(void *outputBuffer, void *inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void *userData) { | ||||
IO *audioIO = (IO*) userData; | |||||
assert(audioIO); | |||||
Port *port = (Port*) userData; | |||||
assert(port); | |||||
// Exploit the stream time to run code on startup of the audio thread | // Exploit the stream time to run code on startup of the audio thread | ||||
if (streamTime == 0.0) { | if (streamTime == 0.0) { | ||||
system::setThreadName("Audio"); | system::setThreadName("Audio"); | ||||
system::setThreadRealTime(); | system::setThreadRealTime(); | ||||
} | } | ||||
audioIO->processStream((const float *) inputBuffer, (float *) outputBuffer, nFrames); | |||||
port->processStream((const float *) inputBuffer, (float *) outputBuffer, nFrames); | |||||
return 0; | return 0; | ||||
} | } | ||||
void IO::openStream() { | |||||
void Port::openStream() { | |||||
if (device < 0) | if (device < 0) | ||||
return; | return; | ||||
@@ -294,7 +294,7 @@ void IO::openStream() { | |||||
} | } | ||||
} | } | ||||
void IO::closeStream() { | |||||
void Port::closeStream() { | |||||
setChannels(0, 0); | setChannels(0, 0); | ||||
if (rtAudio) { | if (rtAudio) { | ||||
@@ -325,7 +325,7 @@ void IO::closeStream() { | |||||
onCloseStream(); | onCloseStream(); | ||||
} | } | ||||
json_t *IO::toJson() { | |||||
json_t *Port::toJson() { | |||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
json_object_set_new(rootJ, "driver", json_integer(driver)); | json_object_set_new(rootJ, "driver", json_integer(driver)); | ||||
std::string deviceName = getDeviceName(device); | std::string deviceName = getDeviceName(device); | ||||
@@ -338,7 +338,7 @@ json_t *IO::toJson() { | |||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void IO::fromJson(json_t *rootJ) { | |||||
void Port::fromJson(json_t *rootJ) { | |||||
closeStream(); | closeStream(); | ||||
json_t *driverJ = json_object_get(rootJ, "driver"); | json_t *driverJ = json_object_get(rootJ, "driver"); | ||||
@@ -25,7 +25,7 @@ struct BridgeMidiDriver; | |||||
struct BridgeClientConnection; | struct BridgeClientConnection; | ||||
static BridgeClientConnection *connections[BRIDGE_NUM_PORTS] = {}; | static BridgeClientConnection *connections[BRIDGE_NUM_PORTS] = {}; | ||||
static audio::IO *audioListeners[BRIDGE_NUM_PORTS] = {}; | |||||
static audio::Port *audioListeners[BRIDGE_NUM_PORTS] = {}; | |||||
static std::thread serverThread; | static std::thread serverThread; | ||||
static bool serverRunning = false; | static bool serverRunning = false; | ||||
static BridgeMidiDriver *driver = NULL; | static BridgeMidiDriver *driver = NULL; | ||||
@@ -429,7 +429,7 @@ void bridgeDestroy() { | |||||
serverThread.join(); | serverThread.join(); | ||||
} | } | ||||
void bridgeAudioSubscribe(int port, audio::IO *audio) { | |||||
void bridgeAudioSubscribe(int port, audio::Port *audio) { | |||||
if (!(0 <= port && port < BRIDGE_NUM_PORTS)) | if (!(0 <= port && port < BRIDGE_NUM_PORTS)) | ||||
return; | return; | ||||
// Check if an Audio is already subscribed on the port | // Check if an Audio is already subscribed on the port | ||||
@@ -440,7 +440,7 @@ void bridgeAudioSubscribe(int port, audio::IO *audio) { | |||||
connections[port]->refreshAudio(); | connections[port]->refreshAudio(); | ||||
} | } | ||||
void bridgeAudioUnsubscribe(int port, audio::IO *audio) { | |||||
void bridgeAudioUnsubscribe(int port, audio::Port *audio) { | |||||
if (!(0 <= port && port < BRIDGE_NUM_PORTS)) | if (!(0 <= port && port < BRIDGE_NUM_PORTS)) | ||||
return; | return; | ||||
if (audioListeners[port] != audio) | if (audioListeners[port] != audio) | ||||
@@ -48,14 +48,14 @@ void OutputDevice::unsubscribe(Output *output) { | |||||
} | } | ||||
//////////////////// | //////////////////// | ||||
// IO | |||||
// Port | |||||
//////////////////// | //////////////////// | ||||
std::vector<int> IO::getDriverIds() { | |||||
std::vector<int> Port::getDriverIds() { | |||||
return driverIds; | return driverIds; | ||||
} | } | ||||
std::string IO::getDriverName(int driverId) { | |||||
std::string Port::getDriverName(int driverId) { | |||||
auto it = drivers.find(driverId); | auto it = drivers.find(driverId); | ||||
if (it == drivers.end()) | if (it == drivers.end()) | ||||
return ""; | return ""; | ||||
@@ -63,7 +63,7 @@ std::string IO::getDriverName(int driverId) { | |||||
return it->second->getName(); | return it->second->getName(); | ||||
} | } | ||||
void IO::setDriverId(int driverId) { | |||||
void Port::setDriverId(int driverId) { | |||||
// Unset device and driver | // Unset device and driver | ||||
setDeviceId(-1); | setDeviceId(-1); | ||||
if (driver) { | if (driver) { | ||||
@@ -79,18 +79,18 @@ void IO::setDriverId(int driverId) { | |||||
} | } | ||||
} | } | ||||
std::string IO::getChannelName(int channel) { | |||||
std::string Port::getChannelName(int channel) { | |||||
if (channel == -1) | if (channel == -1) | ||||
return "All channels"; | return "All channels"; | ||||
else | else | ||||
return string::f("Channel %d", channel + 1); | return string::f("Channel %d", channel + 1); | ||||
} | } | ||||
void IO::setChannel(int channel) { | |||||
void Port::setChannel(int channel) { | |||||
this->channel = channel; | this->channel = channel; | ||||
} | } | ||||
json_t *IO::toJson() { | |||||
json_t *Port::toJson() { | |||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
json_object_set_new(rootJ, "driver", json_integer(driverId)); | json_object_set_new(rootJ, "driver", json_integer(driverId)); | ||||
std::string deviceName = getDeviceName(deviceId); | std::string deviceName = getDeviceName(deviceId); | ||||
@@ -100,7 +100,7 @@ json_t *IO::toJson() { | |||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void IO::fromJson(json_t *rootJ) { | |||||
void Port::fromJson(json_t *rootJ) { | |||||
json_t *driverJ = json_object_get(rootJ, "driver"); | json_t *driverJ = json_object_get(rootJ, "driver"); | ||||
if (driverJ) | if (driverJ) | ||||
setDriverId(json_integer_value(driverJ)); | setDriverId(json_integer_value(driverJ)); | ||||