| @@ -1093,327 +1093,6 @@ private: | |||||
| const CoreAudioIODevice& operator= (const CoreAudioIODevice&); | const CoreAudioIODevice& operator= (const CoreAudioIODevice&); | ||||
| }; | }; | ||||
| //============================================================================== | |||||
| class CoreAudioDevicePanel : public Component, | |||||
| public ComboBoxListener, | |||||
| public ChangeListener, | |||||
| public ButtonListener | |||||
| { | |||||
| public: | |||||
| CoreAudioDevicePanel (AudioIODeviceType* type_, | |||||
| AudioIODeviceType::DeviceSetupDetails& setup_) | |||||
| : type (type_), | |||||
| setup (setup_) | |||||
| { | |||||
| sampleRateDropDown = 0; | |||||
| sampleRateLabel = 0; | |||||
| bufferSizeDropDown = 0; | |||||
| bufferSizeLabel = 0; | |||||
| outputDeviceDropDown = 0; | |||||
| outputDeviceLabel = 0; | |||||
| inputDeviceDropDown = 0; | |||||
| inputDeviceLabel = 0; | |||||
| testButton = 0; | |||||
| inputLevelMeter = 0; | |||||
| type->scanForDevices(); | |||||
| if (setup.maxNumOutputChannels > 0) | |||||
| { | |||||
| outputDeviceDropDown = new ComboBox (String::empty); | |||||
| addNamesToDeviceBox (*outputDeviceDropDown, false); | |||||
| outputDeviceDropDown->addListener (this); | |||||
| addAndMakeVisible (outputDeviceDropDown); | |||||
| outputDeviceLabel = new Label (String::empty, TRANS ("output:")); | |||||
| outputDeviceLabel->attachToComponent (outputDeviceDropDown, true); | |||||
| addAndMakeVisible (testButton = new TextButton (TRANS ("Test"))); | |||||
| testButton->addButtonListener (this); | |||||
| } | |||||
| if (setup.maxNumInputChannels > 0) | |||||
| { | |||||
| inputDeviceDropDown = new ComboBox (String::empty); | |||||
| addNamesToDeviceBox (*inputDeviceDropDown, true); | |||||
| inputDeviceDropDown->addListener (this); | |||||
| addAndMakeVisible (inputDeviceDropDown); | |||||
| inputDeviceLabel = new Label (String::empty, TRANS ("input:")); | |||||
| inputDeviceLabel->attachToComponent (inputDeviceDropDown, true); | |||||
| addAndMakeVisible (inputLevelMeter = AudioDeviceSelectorComponent::createSimpleLevelMeterComponent (setup_.manager)); | |||||
| } | |||||
| setup.manager->addChangeListener (this); | |||||
| changeListenerCallback (0); | |||||
| } | |||||
| ~CoreAudioDevicePanel() | |||||
| { | |||||
| setup.manager->removeChangeListener (this); | |||||
| deleteAndZero (outputDeviceLabel); | |||||
| deleteAndZero (inputDeviceLabel); | |||||
| deleteAndZero (sampleRateLabel); | |||||
| deleteAndZero (bufferSizeLabel); | |||||
| deleteAllChildren(); | |||||
| } | |||||
| void resized() | |||||
| { | |||||
| const int lx = proportionOfWidth (0.35f); | |||||
| const int w = proportionOfWidth (0.5f); | |||||
| const int h = 24; | |||||
| const int space = 6; | |||||
| const int dh = h + space; | |||||
| int y = 0; | |||||
| if (outputDeviceDropDown != 0) | |||||
| { | |||||
| outputDeviceDropDown->setBounds (lx, y, w, h); | |||||
| testButton->setBounds (outputDeviceDropDown->getRight() + 8, | |||||
| outputDeviceDropDown->getY(), | |||||
| getWidth() - outputDeviceDropDown->getRight() - 10, | |||||
| h); | |||||
| y += dh; | |||||
| } | |||||
| if (inputDeviceDropDown != 0) | |||||
| { | |||||
| inputDeviceDropDown->setBounds (lx, y, w, h); | |||||
| inputLevelMeter->setBounds (inputDeviceDropDown->getRight() + 8, | |||||
| inputDeviceDropDown->getY(), | |||||
| getWidth() - inputDeviceDropDown->getRight() - 10, | |||||
| h); | |||||
| y += dh; | |||||
| } | |||||
| y += space * 2; | |||||
| if (sampleRateDropDown != 0) | |||||
| { | |||||
| sampleRateDropDown->setBounds (lx, y, w, h); | |||||
| y += dh; | |||||
| } | |||||
| if (bufferSizeDropDown != 0) | |||||
| { | |||||
| bufferSizeDropDown->setBounds (lx, y, w, h); | |||||
| y += dh; | |||||
| } | |||||
| } | |||||
| void comboBoxChanged (ComboBox* comboBoxThatHasChanged) | |||||
| { | |||||
| if (comboBoxThatHasChanged == 0) | |||||
| return; | |||||
| AudioDeviceManager::AudioDeviceSetup config; | |||||
| setup.manager->getAudioDeviceSetup (config); | |||||
| String error; | |||||
| if (comboBoxThatHasChanged == outputDeviceDropDown | |||||
| || comboBoxThatHasChanged == inputDeviceDropDown) | |||||
| { | |||||
| config.outputDeviceName = outputDeviceDropDown->getSelectedId() < 0 ? String::empty | |||||
| : outputDeviceDropDown->getText(); | |||||
| config.inputDeviceName = inputDeviceDropDown->getSelectedId() < 0 ? String::empty | |||||
| : inputDeviceDropDown->getText(); | |||||
| if (comboBoxThatHasChanged == inputDeviceDropDown) | |||||
| config.useDefaultInputChannels = true; | |||||
| else | |||||
| config.useDefaultOutputChannels = true; | |||||
| error = setup.manager->setAudioDeviceSetup (config, true); | |||||
| showCorrectDeviceName (inputDeviceDropDown, true); | |||||
| showCorrectDeviceName (outputDeviceDropDown, false); | |||||
| } | |||||
| else if (comboBoxThatHasChanged == sampleRateDropDown) | |||||
| { | |||||
| if (sampleRateDropDown->getSelectedId() > 0) | |||||
| { | |||||
| config.sampleRate = sampleRateDropDown->getSelectedId(); | |||||
| error = setup.manager->setAudioDeviceSetup (config, true); | |||||
| } | |||||
| } | |||||
| else if (comboBoxThatHasChanged == bufferSizeDropDown) | |||||
| { | |||||
| if (bufferSizeDropDown->getSelectedId() > 0) | |||||
| { | |||||
| config.bufferSize = bufferSizeDropDown->getSelectedId(); | |||||
| error = setup.manager->setAudioDeviceSetup (config, true); | |||||
| } | |||||
| } | |||||
| if (error.isNotEmpty()) | |||||
| { | |||||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, | |||||
| T("Error when trying to open audio device!"), | |||||
| error); | |||||
| } | |||||
| } | |||||
| void buttonClicked (Button*) | |||||
| { | |||||
| setup.manager->playTestSound(); | |||||
| } | |||||
| void changeListenerCallback (void*) | |||||
| { | |||||
| AudioIODevice* const currentDevice = setup.manager->getCurrentAudioDevice(); | |||||
| if (currentDevice != 0) | |||||
| { | |||||
| showCorrectDeviceName (inputDeviceDropDown, true); | |||||
| showCorrectDeviceName (outputDeviceDropDown, false); | |||||
| // sample rate.. | |||||
| { | |||||
| if (sampleRateDropDown == 0) | |||||
| { | |||||
| addAndMakeVisible (sampleRateDropDown = new ComboBox (String::empty)); | |||||
| sampleRateDropDown->addListener (this); | |||||
| delete sampleRateLabel; | |||||
| sampleRateLabel = new Label (String::empty, TRANS ("sample rate:")); | |||||
| sampleRateLabel->attachToComponent (sampleRateDropDown, true); | |||||
| } | |||||
| else | |||||
| { | |||||
| sampleRateDropDown->clear(); | |||||
| sampleRateDropDown->removeListener (this); | |||||
| } | |||||
| const int numRates = currentDevice->getNumSampleRates(); | |||||
| for (int i = 0; i < numRates; ++i) | |||||
| { | |||||
| const int rate = roundDoubleToInt (currentDevice->getSampleRate (i)); | |||||
| sampleRateDropDown->addItem (String (rate) + T(" Hz"), rate); | |||||
| } | |||||
| sampleRateDropDown->setSelectedId (roundDoubleToInt (currentDevice->getCurrentSampleRate()), true); | |||||
| sampleRateDropDown->addListener (this); | |||||
| } | |||||
| // buffer size | |||||
| { | |||||
| if (bufferSizeDropDown == 0) | |||||
| { | |||||
| addAndMakeVisible (bufferSizeDropDown = new ComboBox (String::empty)); | |||||
| bufferSizeDropDown->addListener (this); | |||||
| delete bufferSizeLabel; | |||||
| bufferSizeLabel = new Label (String::empty, TRANS ("audio buffer size:")); | |||||
| bufferSizeLabel->attachToComponent (bufferSizeDropDown, true); | |||||
| } | |||||
| else | |||||
| { | |||||
| bufferSizeDropDown->clear(); | |||||
| } | |||||
| const int numBufferSizes = currentDevice->getNumBufferSizesAvailable(); | |||||
| double currentRate = currentDevice->getCurrentSampleRate(); | |||||
| if (currentRate == 0) | |||||
| currentRate = 44100.0; | |||||
| for (int i = 0; i < numBufferSizes; ++i) | |||||
| { | |||||
| const int bs = currentDevice->getBufferSizeSamples (i); | |||||
| bufferSizeDropDown->addItem (String (bs) | |||||
| + T(" samples (") | |||||
| + String (bs * 1000.0 / currentRate, 1) | |||||
| + T(" ms)"), | |||||
| bs); | |||||
| } | |||||
| bufferSizeDropDown->setSelectedId (currentDevice->getCurrentBufferSizeSamples(), true); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| jassert (setup.manager->getCurrentAudioDevice() == 0); // not the correct device type! | |||||
| deleteAndZero (sampleRateLabel); | |||||
| deleteAndZero (bufferSizeLabel); | |||||
| deleteAndZero (sampleRateDropDown); | |||||
| deleteAndZero (bufferSizeDropDown); | |||||
| if (outputDeviceDropDown != 0) | |||||
| outputDeviceDropDown->setSelectedId (-1, true); | |||||
| if (inputDeviceDropDown != 0) | |||||
| inputDeviceDropDown->setSelectedId (-1, true); | |||||
| } | |||||
| resized(); | |||||
| setSize (getWidth(), getLowestY() + 4); | |||||
| } | |||||
| private: | |||||
| AudioIODeviceType* const type; | |||||
| const AudioIODeviceType::DeviceSetupDetails setup; | |||||
| ComboBox* outputDeviceDropDown; | |||||
| ComboBox* inputDeviceDropDown; | |||||
| ComboBox* sampleRateDropDown; | |||||
| ComboBox* bufferSizeDropDown; | |||||
| Label* outputDeviceLabel; | |||||
| Label* inputDeviceLabel; | |||||
| Label* sampleRateLabel; | |||||
| Label* bufferSizeLabel; | |||||
| TextButton* testButton; | |||||
| Component* inputLevelMeter; | |||||
| void showCorrectDeviceName (ComboBox* const box, const bool isInput) | |||||
| { | |||||
| if (box != 0) | |||||
| { | |||||
| CoreAudioIODevice* const currentDevice = dynamic_cast <CoreAudioIODevice*> (setup.manager->getCurrentAudioDevice()); | |||||
| const int index = (currentDevice == 0) ? -1 | |||||
| : (isInput ? currentDevice->inputIndex | |||||
| : currentDevice->outputIndex); | |||||
| if (index >= 0) | |||||
| box->setText (type->getDeviceNames (isInput) [index], true); | |||||
| else | |||||
| box->setSelectedId (-1, true); | |||||
| if (! isInput) | |||||
| testButton->setEnabled (index >= 0); | |||||
| } | |||||
| } | |||||
| void addNamesToDeviceBox (ComboBox& combo, bool isInputs) | |||||
| { | |||||
| const StringArray devs (type->getDeviceNames (isInputs)); | |||||
| for (int i = 0; i < devs.size(); ++i) | |||||
| combo.addItem (devs[i], i + 1); | |||||
| combo.addItem (TRANS("<< none >>"), -1); | |||||
| combo.setSelectedId (-1, true); | |||||
| } | |||||
| int getLowestY() const | |||||
| { | |||||
| int y = 0; | |||||
| for (int i = getNumChildComponents(); --i >= 0;) | |||||
| y = jmax (y, getChildComponent (i)->getBottom()); | |||||
| return y; | |||||
| } | |||||
| CoreAudioDevicePanel (const CoreAudioDevicePanel&); | |||||
| const CoreAudioDevicePanel& operator= (const CoreAudioDevicePanel&); | |||||
| }; | |||||
| //============================================================================== | //============================================================================== | ||||
| class CoreAudioIODeviceType : public AudioIODeviceType | class CoreAudioIODeviceType : public AudioIODeviceType | ||||
| { | { | ||||