@@ -15,8 +15,6 @@ namespace app { | |||
struct AudioWidget : LedDisplay { | |||
/** Not owned */ | |||
audio::IO *audioIO = NULL; | |||
LedDisplayChoice *driverChoice; | |||
LedDisplaySeparator *driverSeparator; | |||
LedDisplayChoice *deviceChoice; | |||
@@ -24,8 +22,7 @@ struct AudioWidget : LedDisplay { | |||
LedDisplayChoice *sampleRateChoice; | |||
LedDisplaySeparator *sampleRateSeparator; | |||
LedDisplayChoice *bufferSizeChoice; | |||
AudioWidget(); | |||
void step() override; | |||
void setAudioIO(audio::IO *audioIO); | |||
}; | |||
@@ -15,15 +15,12 @@ namespace app { | |||
struct MidiWidget : LedDisplay { | |||
/** Not owned */ | |||
midi::IO *midiIO = NULL; | |||
LedDisplayChoice *driverChoice; | |||
LedDisplaySeparator *driverSeparator; | |||
LedDisplayChoice *deviceChoice; | |||
LedDisplaySeparator *deviceSeparator; | |||
LedDisplayChoice *channelChoice; | |||
MidiWidget(); | |||
void step() override; | |||
void setMidiIO(midi::IO *midiIO); | |||
}; | |||
@@ -272,8 +272,7 @@ struct AudioInterfaceWidget : ModuleWidget { | |||
AudioWidget *audioWidget = createWidget<AudioWidget>(mm2px(Vec(3.2122073, 14.837339))); | |||
audioWidget->box.size = mm2px(Vec(44, 28)); | |||
if (module) | |||
audioWidget->audioIO = &module->audioIO; | |||
audioWidget->setAudioIO(module ? &module->audioIO : NULL); | |||
addChild(audioWidget); | |||
} | |||
}; | |||
@@ -139,8 +139,7 @@ struct CV_CCWidget : ModuleWidget { | |||
typedef Grid16MidiWidget<CcChoice<CV_CC>> TMidiWidget; | |||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | |||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | |||
if (module) | |||
midiWidget->midiIO = &module->midiOutput; | |||
midiWidget->setMidiIO(module ? &module->midiOutput : NULL); | |||
midiWidget->setModule(module); | |||
addChild(midiWidget); | |||
} | |||
@@ -189,8 +189,7 @@ struct CV_GateWidget : ModuleWidget { | |||
typedef Grid16MidiWidget<NoteChoice<CV_Gate>> TMidiWidget; | |||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | |||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | |||
if (module) | |||
midiWidget->midiIO = &module->midiOutput; | |||
midiWidget->setMidiIO(module ? &module->midiOutput : NULL); | |||
midiWidget->setModule(module); | |||
addChild(midiWidget); | |||
} | |||
@@ -346,8 +346,7 @@ struct CV_MIDIWidget : ModuleWidget { | |||
MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.41891, 14.8373))); | |||
midiWidget->box.size = mm2px(Vec(33.840, 28)); | |||
if (module) | |||
midiWidget->midiIO = &module->midiOutput; | |||
midiWidget->setMidiIO(module ? &module->midiOutput : NULL); | |||
addChild(midiWidget); | |||
} | |||
@@ -167,8 +167,7 @@ struct MIDI_CCWidget : ModuleWidget { | |||
typedef Grid16MidiWidget<CcChoice<MIDI_CC>> TMidiWidget; | |||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | |||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | |||
if (module) | |||
midiWidget->midiIO = &module->midiInput; | |||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||
midiWidget->setModule(module); | |||
addChild(midiWidget); | |||
} | |||
@@ -540,8 +540,7 @@ struct MIDI_CVWidget : ModuleWidget { | |||
MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.41891, 14.8373))); | |||
midiWidget->box.size = mm2px(Vec(33.840, 28)); | |||
if (module) | |||
midiWidget->midiIO = &module->midiInput; | |||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||
addChild(midiWidget); | |||
} | |||
@@ -196,8 +196,7 @@ struct MIDI_GateWidget : ModuleWidget { | |||
typedef Grid16MidiWidget<NoteChoice<MIDI_Gate>> TMidiWidget; | |||
TMidiWidget *midiWidget = createWidget<TMidiWidget>(mm2px(Vec(3.399621, 14.837339))); | |||
midiWidget->box.size = mm2px(Vec(44, 54.667)); | |||
if (module) | |||
midiWidget->midiIO = &module->midiInput; | |||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||
midiWidget->setModule(module); | |||
addChild(midiWidget); | |||
} | |||
@@ -72,8 +72,7 @@ struct MIDI_MapWidget : ModuleWidget { | |||
MIDI_MapDisplay *midiWidget = createWidget<MIDI_MapDisplay>(mm2px(Vec(3.4, 14.839))); | |||
midiWidget->box.size = mm2px(Vec(43.999, 102.664)); | |||
if (module) | |||
midiWidget->midiIO = &module->midiInput; | |||
midiWidget->setMidiIO(module ? &module->midiInput : NULL); | |||
midiWidget->setModule(module); | |||
addChild(midiWidget); | |||
} | |||
@@ -16,25 +16,25 @@ struct AudioDriverItem : ui::MenuItem { | |||
}; | |||
struct AudioDriverChoice : LedDisplayChoice { | |||
AudioWidget *audioWidget; | |||
audio::IO *audioIO; | |||
void onAction(const event::Action &e) override { | |||
if (!audioWidget->audioIO) | |||
if (!audioIO) | |||
return; | |||
ui::Menu *menu = createMenu(); | |||
menu->addChild(createMenuLabel("Audio driver")); | |||
for (int driver : audioWidget->audioIO->getDrivers()) { | |||
for (int driver : audioIO->getDrivers()) { | |||
AudioDriverItem *item = new AudioDriverItem; | |||
item->audioIO = audioWidget->audioIO; | |||
item->audioIO = audioIO; | |||
item->driver = driver; | |||
item->text = audioWidget->audioIO->getDriverName(driver); | |||
item->rightText = CHECKMARK(item->driver == audioWidget->audioIO->driver); | |||
item->text = audioIO->getDriverName(driver); | |||
item->rightText = CHECKMARK(item->driver == audioIO->driver); | |||
menu->addChild(item); | |||
} | |||
} | |||
void step() override { | |||
if (audioWidget->audioIO) | |||
text = audioWidget->audioIO->getDriverName(audioWidget->audioIO->driver); | |||
if (audioIO) | |||
text = audioIO->getDriverName(audioIO->driver); | |||
else | |||
text = ""; | |||
} | |||
@@ -51,44 +51,44 @@ struct AudioDeviceItem : ui::MenuItem { | |||
}; | |||
struct AudioDeviceChoice : LedDisplayChoice { | |||
AudioWidget *audioWidget; | |||
audio::IO *audioIO; | |||
/** Prevents devices with a ridiculous number of channels from being displayed */ | |||
int maxTotalChannels = 128; | |||
void onAction(const event::Action &e) override { | |||
if (!audioWidget->audioIO) | |||
if (!audioIO) | |||
return; | |||
ui::Menu *menu = createMenu(); | |||
menu->addChild(createMenuLabel("Audio device")); | |||
int deviceCount = audioWidget->audioIO->getDeviceCount(); | |||
int deviceCount = audioIO->getDeviceCount(); | |||
{ | |||
AudioDeviceItem *item = new AudioDeviceItem; | |||
item->audioIO = audioWidget->audioIO; | |||
item->audioIO = audioIO; | |||
item->device = -1; | |||
item->text = "(No device)"; | |||
item->rightText = CHECKMARK(item->device == audioWidget->audioIO->device); | |||
item->rightText = CHECKMARK(item->device == audioIO->device); | |||
menu->addChild(item); | |||
} | |||
for (int device = 0; device < deviceCount; device++) { | |||
int channels = std::min(maxTotalChannels, audioWidget->audioIO->getDeviceChannels(device)); | |||
for (int offset = 0; offset < channels; offset += audioWidget->audioIO->maxChannels) { | |||
int channels = std::min(maxTotalChannels, audioIO->getDeviceChannels(device)); | |||
for (int offset = 0; offset < channels; offset += audioIO->maxChannels) { | |||
AudioDeviceItem *item = new AudioDeviceItem; | |||
item->audioIO = audioWidget->audioIO; | |||
item->audioIO = audioIO; | |||
item->device = device; | |||
item->offset = offset; | |||
item->text = audioWidget->audioIO->getDeviceDetail(device, offset); | |||
item->rightText = CHECKMARK(item->device == audioWidget->audioIO->device && item->offset == audioWidget->audioIO->offset); | |||
item->text = audioIO->getDeviceDetail(device, offset); | |||
item->rightText = CHECKMARK(item->device == audioIO->device && item->offset == audioIO->offset); | |||
menu->addChild(item); | |||
} | |||
} | |||
} | |||
void step() override { | |||
if (!audioWidget->audioIO) { | |||
if (!audioIO) { | |||
text = ""; | |||
return; | |||
} | |||
text = audioWidget->audioIO->getDeviceDetail(audioWidget->audioIO->device, audioWidget->audioIO->offset); | |||
text = audioIO->getDeviceDetail(audioIO->device, audioIO->offset); | |||
if (text.empty()) { | |||
text = "(No device)"; | |||
color.a = 0.5f; | |||
@@ -109,29 +109,29 @@ struct AudioSampleRateItem : ui::MenuItem { | |||
}; | |||
struct AudioSampleRateChoice : LedDisplayChoice { | |||
AudioWidget *audioWidget; | |||
audio::IO *audioIO; | |||
void onAction(const event::Action &e) override { | |||
if (!audioWidget->audioIO) | |||
if (!audioIO) | |||
return; | |||
ui::Menu *menu = createMenu(); | |||
menu->addChild(createMenuLabel("Sample rate")); | |||
std::vector<int> sampleRates = audioWidget->audioIO->getSampleRates(); | |||
std::vector<int> sampleRates = audioIO->getSampleRates(); | |||
if (sampleRates.empty()) { | |||
menu->addChild(createMenuLabel("(Locked by device)")); | |||
} | |||
for (int sampleRate : sampleRates) { | |||
AudioSampleRateItem *item = new AudioSampleRateItem; | |||
item->audioIO = audioWidget->audioIO; | |||
item->audioIO = audioIO; | |||
item->sampleRate = sampleRate; | |||
item->text = string::f("%d Hz", sampleRate); | |||
item->rightText = CHECKMARK(item->sampleRate == audioWidget->audioIO->sampleRate); | |||
item->rightText = CHECKMARK(item->sampleRate == audioIO->sampleRate); | |||
menu->addChild(item); | |||
} | |||
} | |||
void step() override { | |||
if (audioWidget->audioIO) | |||
text = string::f("%g kHz", audioWidget->audioIO->sampleRate / 1000.f); | |||
if (audioIO) | |||
text = string::f("%g kHz", audioIO->sampleRate / 1000.f); | |||
else | |||
text = ""; | |||
} | |||
@@ -147,86 +147,82 @@ struct AudioBlockSizeItem : ui::MenuItem { | |||
}; | |||
struct AudioBlockSizeChoice : LedDisplayChoice { | |||
AudioWidget *audioWidget; | |||
audio::IO *audioIO; | |||
void onAction(const event::Action &e) override { | |||
if (!audioWidget->audioIO) | |||
if (!audioIO) | |||
return; | |||
ui::Menu *menu = createMenu(); | |||
menu->addChild(createMenuLabel("Block size")); | |||
std::vector<int> blockSizes = audioWidget->audioIO->getBlockSizes(); | |||
std::vector<int> blockSizes = audioIO->getBlockSizes(); | |||
if (blockSizes.empty()) { | |||
menu->addChild(createMenuLabel("(Locked by device)")); | |||
} | |||
for (int blockSize : blockSizes) { | |||
AudioBlockSizeItem *item = new AudioBlockSizeItem; | |||
item->audioIO = audioWidget->audioIO; | |||
item->audioIO = audioIO; | |||
item->blockSize = blockSize; | |||
float latency = (float) blockSize / audioWidget->audioIO->sampleRate * 1000.0; | |||
float latency = (float) blockSize / audioIO->sampleRate * 1000.0; | |||
item->text = string::f("%d (%.1f ms)", blockSize, latency); | |||
item->rightText = CHECKMARK(item->blockSize == audioWidget->audioIO->blockSize); | |||
item->rightText = CHECKMARK(item->blockSize == audioIO->blockSize); | |||
menu->addChild(item); | |||
} | |||
} | |||
void step() override { | |||
if (audioWidget->audioIO) | |||
text = string::f("%d", audioWidget->audioIO->blockSize); | |||
if (audioIO) | |||
text = string::f("%d", audioIO->blockSize); | |||
else | |||
text = ""; | |||
} | |||
}; | |||
AudioWidget::AudioWidget() { | |||
box.size = mm2px(math::Vec(44, 28)); | |||
void AudioWidget::setAudioIO(audio::IO *audioIO) { | |||
clearChildren(); | |||
math::Vec pos = math::Vec(); | |||
math::Vec pos; | |||
AudioDriverChoice *driverChoice = createWidget<AudioDriverChoice>(pos); | |||
driverChoice->audioWidget = this; | |||
driverChoice->box.size.x = box.size.x; | |||
driverChoice->audioIO = audioIO; | |||
addChild(driverChoice); | |||
pos = driverChoice->box.getBottomLeft(); | |||
this->driverChoice = driverChoice; | |||
this->driverSeparator = createWidget<LedDisplaySeparator>(pos); | |||
this->driverSeparator->box.size.x = box.size.x; | |||
addChild(this->driverSeparator); | |||
AudioDeviceChoice *deviceChoice = createWidget<AudioDeviceChoice>(pos); | |||
deviceChoice->audioWidget = this; | |||
deviceChoice->box.size.x = box.size.x; | |||
deviceChoice->audioIO = audioIO; | |||
addChild(deviceChoice); | |||
pos = deviceChoice->box.getBottomLeft(); | |||
this->deviceChoice = deviceChoice; | |||
this->deviceSeparator = createWidget<LedDisplaySeparator>(pos); | |||
this->deviceSeparator->box.size.x = box.size.x; | |||
addChild(this->deviceSeparator); | |||
AudioSampleRateChoice *sampleRateChoice = createWidget<AudioSampleRateChoice>(pos); | |||
sampleRateChoice->audioWidget = this; | |||
sampleRateChoice->box.size.x = box.size.x / 2; | |||
sampleRateChoice->audioIO = audioIO; | |||
addChild(sampleRateChoice); | |||
this->sampleRateChoice = sampleRateChoice; | |||
this->sampleRateSeparator = createWidget<LedDisplaySeparator>(pos); | |||
this->sampleRateSeparator->box.pos.x = box.size.x / 2; | |||
this->sampleRateSeparator->box.size.y = this->sampleRateChoice->box.size.y; | |||
addChild(this->sampleRateSeparator); | |||
AudioBlockSizeChoice *bufferSizeChoice = createWidget<AudioBlockSizeChoice>(pos); | |||
bufferSizeChoice->audioWidget = this; | |||
bufferSizeChoice->box.pos.x = box.size.x / 2; | |||
bufferSizeChoice->box.size.x = box.size.x / 2; | |||
bufferSizeChoice->audioIO = audioIO; | |||
addChild(bufferSizeChoice); | |||
this->bufferSizeChoice = bufferSizeChoice; | |||
} | |||
void AudioWidget::step() { | |||
this->driverChoice->box.size.x = box.size.x; | |||
this->driverSeparator->box.size.x = box.size.x; | |||
this->deviceChoice->box.size.x = box.size.x; | |||
this->deviceSeparator->box.size.x = box.size.x; | |||
this->sampleRateChoice->box.size.x = box.size.x / 2; | |||
this->sampleRateSeparator->box.pos.x = box.size.x / 2; | |||
this->bufferSizeChoice->box.pos.x = box.size.x / 2; | |||
this->bufferSizeChoice->box.size.x = box.size.x / 2; | |||
LedDisplay::step(); | |||
} | |||
} // namespace app | |||
} // namespace rack |
@@ -16,28 +16,28 @@ struct MidiDriverItem : ui::MenuItem { | |||
}; | |||
struct MidiDriverChoice : LedDisplayChoice { | |||
MidiWidget *midiWidget; | |||
midi::IO *midiIO; | |||
void onAction(const event::Action &e) override { | |||
if (!midiWidget->midiIO) | |||
if (!midiIO) | |||
return; | |||
ui::Menu *menu = createMenu(); | |||
menu->addChild(createMenuLabel("MIDI driver")); | |||
for (int driverId : midiWidget->midiIO->getDriverIds()) { | |||
for (int driverId : midiIO->getDriverIds()) { | |||
MidiDriverItem *item = new MidiDriverItem; | |||
item->midiIO = midiWidget->midiIO; | |||
item->midiIO = midiIO; | |||
item->driverId = driverId; | |||
item->text = midiWidget->midiIO->getDriverName(driverId); | |||
item->rightText = CHECKMARK(item->driverId == midiWidget->midiIO->driverId); | |||
item->text = midiIO->getDriverName(driverId); | |||
item->rightText = CHECKMARK(item->driverId == midiIO->driverId); | |||
menu->addChild(item); | |||
} | |||
} | |||
void step() override { | |||
if (!midiWidget->midiIO) { | |||
if (!midiIO) { | |||
text = ""; | |||
return; | |||
} | |||
text = midiWidget->midiIO->getDriverName(midiWidget->midiIO->driverId); | |||
text = midiIO->getDriverName(midiIO->driverId); | |||
if (text.empty()) { | |||
text = "(No driver)"; | |||
color.a = 0.5f; | |||
@@ -57,36 +57,36 @@ struct MidiDeviceItem : ui::MenuItem { | |||
}; | |||
struct MidiDeviceChoice : LedDisplayChoice { | |||
MidiWidget *midiWidget; | |||
midi::IO *midiIO; | |||
void onAction(const event::Action &e) override { | |||
if (!midiWidget->midiIO) | |||
if (!midiIO) | |||
return; | |||
ui::Menu *menu = createMenu(); | |||
menu->addChild(createMenuLabel("MIDI device")); | |||
{ | |||
MidiDeviceItem *item = new MidiDeviceItem; | |||
item->midiIO = midiWidget->midiIO; | |||
item->midiIO = midiIO; | |||
item->deviceId = -1; | |||
item->text = "(No device)"; | |||
item->rightText = CHECKMARK(item->deviceId == midiWidget->midiIO->deviceId); | |||
item->rightText = CHECKMARK(item->deviceId == midiIO->deviceId); | |||
menu->addChild(item); | |||
} | |||
for (int deviceId : midiWidget->midiIO->getDeviceIds()) { | |||
for (int deviceId : midiIO->getDeviceIds()) { | |||
MidiDeviceItem *item = new MidiDeviceItem; | |||
item->midiIO = midiWidget->midiIO; | |||
item->midiIO = midiIO; | |||
item->deviceId = deviceId; | |||
item->text = midiWidget->midiIO->getDeviceName(deviceId); | |||
item->rightText = CHECKMARK(item->deviceId == midiWidget->midiIO->deviceId); | |||
item->text = midiIO->getDeviceName(deviceId); | |||
item->rightText = CHECKMARK(item->deviceId == midiIO->deviceId); | |||
menu->addChild(item); | |||
} | |||
} | |||
void step() override { | |||
if (!midiWidget->midiIO) { | |||
if (!midiIO) { | |||
text = ""; | |||
return; | |||
} | |||
text = midiWidget->midiIO->getDeviceName(midiWidget->midiIO->deviceId); | |||
text = midiIO->getDeviceName(midiIO->deviceId); | |||
if (text.empty()) { | |||
text = "(No device)"; | |||
color.a = 0.5f; | |||
@@ -106,69 +106,65 @@ struct MidiChannelItem : ui::MenuItem { | |||
}; | |||
struct MidiChannelChoice : LedDisplayChoice { | |||
MidiWidget *midiWidget; | |||
midi::IO *midiIO; | |||
void onAction(const event::Action &e) override { | |||
if (!midiWidget->midiIO) | |||
if (!midiIO) | |||
return; | |||
ui::Menu *menu = createMenu(); | |||
menu->addChild(createMenuLabel("MIDI channel")); | |||
for (int channel : midiWidget->midiIO->getChannels()) { | |||
for (int channel : midiIO->getChannels()) { | |||
MidiChannelItem *item = new MidiChannelItem; | |||
item->midiIO = midiWidget->midiIO; | |||
item->midiIO = midiIO; | |||
item->channel = channel; | |||
item->text = midiWidget->midiIO->getChannelName(channel); | |||
item->rightText = CHECKMARK(item->channel == midiWidget->midiIO->channel); | |||
item->text = midiIO->getChannelName(channel); | |||
item->rightText = CHECKMARK(item->channel == midiIO->channel); | |||
menu->addChild(item); | |||
} | |||
} | |||
void step() override { | |||
if (midiWidget->midiIO) | |||
text = midiWidget->midiIO->getChannelName(midiWidget->midiIO->channel); | |||
if (midiIO) | |||
text = midiIO->getChannelName(midiIO->channel); | |||
else | |||
text = ""; | |||
} | |||
}; | |||
MidiWidget::MidiWidget() { | |||
box.size = mm2px(math::Vec(44, 28)); | |||
void MidiWidget::setMidiIO(midi::IO *midiIO) { | |||
clearChildren(); | |||
math::Vec pos = math::Vec(); | |||
math::Vec pos; | |||
MidiDriverChoice *driverChoice = createWidget<MidiDriverChoice>(pos); | |||
driverChoice->midiWidget = this; | |||
driverChoice->box.size.x = box.size.x; | |||
driverChoice->midiIO = midiIO; | |||
addChild(driverChoice); | |||
pos = driverChoice->box.getBottomLeft(); | |||
this->driverChoice = driverChoice; | |||
this->driverSeparator = createWidget<LedDisplaySeparator>(pos); | |||
this->driverSeparator->box.size.x = box.size.x; | |||
addChild(this->driverSeparator); | |||
MidiDeviceChoice *deviceChoice = createWidget<MidiDeviceChoice>(pos); | |||
deviceChoice->midiWidget = this; | |||
deviceChoice->box.size.x = box.size.x; | |||
deviceChoice->midiIO = midiIO; | |||
addChild(deviceChoice); | |||
pos = deviceChoice->box.getBottomLeft(); | |||
this->deviceChoice = deviceChoice; | |||
this->deviceSeparator = createWidget<LedDisplaySeparator>(pos); | |||
this->deviceSeparator->box.size.x = box.size.x; | |||
addChild(this->deviceSeparator); | |||
MidiChannelChoice *channelChoice = createWidget<MidiChannelChoice>(pos); | |||
channelChoice->midiWidget = this; | |||
channelChoice->box.size.x = box.size.x; | |||
channelChoice->midiIO = midiIO; | |||
addChild(channelChoice); | |||
this->channelChoice = channelChoice; | |||
} | |||
void MidiWidget::step() { | |||
this->driverChoice->box.size.x = box.size.x; | |||
this->driverSeparator->box.size.x = box.size.x; | |||
this->deviceChoice->box.size.x = box.size.x; | |||
this->deviceSeparator->box.size.x = box.size.x; | |||
this->channelChoice->box.size.x = box.size.x; | |||
LedDisplay::step(); | |||
} | |||
} // namespace app | |||
} // namespace rack |