1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00
This commit is contained in:
jules 2008-07-04 09:51:27 +00:00
parent 64ae185d39
commit 9a2abee330
6 changed files with 84 additions and 524 deletions

View file

@ -953,37 +953,6 @@ public:
};
//==============================================================================
/*static int findBestMatchForName (const String& name, const StringArray& names)
{
int i = names.indexOf (name);
if (i >= 0)
return i;
StringArray tokens1;
tokens1.addTokens (name, T(" :-"), 0);
int bestResult = -1;
int bestNumMatches = 1;
for (i = 0; i < names.size(); ++i)
{
StringArray tokens2;
tokens2.addTokens (names[i], T(" :-"), 0);
int matches = 0;
for (int j = tokens1.size(); --j >= 0;)
if (tokens2.contains (tokens1 [j]))
++matches;
if (matches > bestNumMatches)
bestResult = i;
}
return bestResult;
}*/
class DSoundAudioIODevice : public AudioIODevice,
public Thread
{

View file

@ -479,7 +479,7 @@ public:
~AudioDemo()
{
audioDeviceManager.removeMidiInputCallback (&synthSource.midiCollector);
audioDeviceManager.removeMidiInputCallback (String::empty, &synthSource.midiCollector);
audioDeviceManager.setAudioCallback (0);
transportSource.removeChangeListener (this);

View file

@ -106,6 +106,12 @@ void AudioDeviceManager::createDeviceTypesIfNeeded()
}
}
const OwnedArray <AudioIODeviceType>& AudioDeviceManager::getAvailableDeviceTypes()
{
createDeviceTypesIfNeeded();
return availableDeviceTypes;
}
//==============================================================================
extern AudioIODeviceType* juce_createDefaultAudioIODeviceType();
@ -394,20 +400,25 @@ const String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& ne
return error;
}
inputChannels.clear();
inputChannels.setRange (0, numInputChansNeeded, true);
outputChannels.clear();
outputChannels.setRange (0, numOutputChansNeeded, true);
}
else
{
if (! newSetup.useDefaultInputChannels)
inputChannels = newSetup.inputChannels;
if (newSetup.useDefaultInputChannels)
{
inputChannels.clear();
inputChannels.setRange (0, numInputChansNeeded, true);
}
if (! newSetup.useDefaultOutputChannels)
outputChannels = newSetup.outputChannels;
if (newSetup.useDefaultOutputChannels)
{
outputChannels.clear();
outputChannels.setRange (0, numOutputChansNeeded, true);
}
}
if (! newSetup.useDefaultInputChannels)
inputChannels = newSetup.inputChannels;
if (! newSetup.useDefaultOutputChannels)
outputChannels = newSetup.outputChannels;
currentSetup = newSetup;
currentSetup.sampleRate = chooseBestSampleRate (newSetup.sampleRate);
@ -484,212 +495,6 @@ double AudioDeviceManager::chooseBestSampleRate (double rate) const
return rate;
}
/*const String AudioDeviceManager::setAudioDevices (const String& outputDeviceName,
const String& inputDeviceName,
int blockSizeToUse,
double sampleRateToUse,
const BitArray* inChans,
const BitArray* outChans,
const bool treatAsChosenDevice)
{
stopDevice();
String error;
if (outputDeviceName.isNotEmpty() || inputDeviceName.isNotEmpty())
{
const StringArray outputNames (getAvailableAudioOutputDeviceNames());
int outputIndex = outputNames.indexOf (outputDeviceName);
if (outputIndex < 0 && outputDeviceName.isNotEmpty())
{
deleteDevices();
error << "No such device: " << outputDeviceName;
return error;
}
const StringArray inputNames (getAvailableAudioInputDeviceNames());
int inputIndex = inputNames.indexOf (inputDeviceName);
if (inputIndex < 0 && inputDeviceName.isNotEmpty())
{
deleteDevices();
error << "No such device: " << inputDeviceName;
return error;
}
if (currentAudioInputDevice == 0
|| currentAudioInputDevice->getLastError().isNotEmpty()
|| ! inputDeviceName.equalsIgnoreCase (currentAudioInputDevice->getName())
|| currentAudioOutputDevice == 0
|| currentAudioOutputDevice->getLastError().isNotEmpty()
|| ! outputDeviceName.equalsIgnoreCase (currentAudioOutputDevice->getName()))
{
// change of device..
deleteDevices();
int n = 0;
for (int i = 0; i < availableDeviceTypes.size(); ++i)
{
AudioIODeviceType* const type = availableDeviceTypes[i];
const StringArray names (type->getDeviceNames (true));
if (inputIndex >= n && inputIndex < n + names.size())
{
currentAudioInputDevice = type->createDevice (inputDeviceName);
if (currentAudioInputDevice == 0)
error = "Can't open device: " + inputDeviceName;
else
error = currentAudioInputDevice->getLastError();
if (error.isNotEmpty())
{
deleteDevices();
return error;
}
break;
}
n += names.size();
}
//xxx
if (true)//inputDeviceName != outputDeviceName)
{
// Using different input and output devices..
n = 0;
for (int i = 0; i < availableDeviceTypes.size(); ++i)
{
AudioIODeviceType* const type = availableDeviceTypes[i];
const StringArray names (type->getDeviceNames (false));
if (outputIndex >= n && outputIndex < n + names.size())
{
currentAudioOutputDevice = type->createDevice (outputDeviceName);
if (currentAudioOutputDevice == 0)
error = "Can't open device: " + outputDeviceName;
else
error = currentAudioOutputDevice->getLastError();
if (error.isNotEmpty())
{
deleteDevices();
return error;
}
break;
}
n += names.size();
}
if (currentAudioInputDevice != 0 && currentAudioOutputDevice != 0)
{
//xxx enable this optim
}
ConglomeratingAudioIODevice* const combiner = new ConglomeratingAudioIODevice();
combiner->addDevice (currentAudioInputDevice, false, true);
combiner->addDevice (currentAudioOutputDevice, true, false);
currentAudioDevice = combiner;
}
else
{
// Using a single device for in + out..
currentAudioOutputDevice = currentAudioInputDevice;
currentAudioDevice = currentAudioInputDevice;
}
inputChannels.clear();
inputChannels.setRange (0, numInputChansNeeded, true);
outputChannels.clear();
outputChannels.setRange (0, numOutputChansNeeded, true);
}
if (inChans != 0)
inputChannels = *inChans;
if (outChans != 0)
outputChannels = *outChans;
error = restartDevice (blockSizeToUse,
sampleRateToUse,
inputChannels,
outputChannels);
if (error.isNotEmpty())
deleteDevices();
}
else
{
deleteDevices();
}
if (treatAsChosenDevice && error.isEmpty())
updateXml();
return error;
}
const String AudioDeviceManager::restartDevice (int blockSizeToUse,
double sampleRateToUse,
const BitArray& inChans,
const BitArray& outChans)
{
stopDevice();
inputChannels = inChans;
outputChannels = outChans;
if (sampleRateToUse > 0)
{
bool ok = false;
for (int i = currentAudioDevice->getNumSampleRates(); --i >= 0;)
{
const double sr = currentAudioDevice->getSampleRate (i);
if (sr == sampleRateToUse)
ok = true;
}
if (! ok)
sampleRateToUse = 0;
}
if (sampleRateToUse == 0)
{
double lowestAbove44 = 0.0;
for (int i = currentAudioDevice->getNumSampleRates(); --i >= 0;)
{
const double sr = currentAudioDevice->getSampleRate (i);
if (sr >= 44100.0 && (lowestAbove44 == 0 || sr < lowestAbove44))
lowestAbove44 = sr;
}
if (lowestAbove44 == 0.0)
sampleRateToUse = currentAudioDevice->getSampleRate (0);
else
sampleRateToUse = lowestAbove44;
}
const String error (currentAudioDevice->open (inChans, outChans,
sampleRateToUse, blockSizeToUse));
if (error.isEmpty())
currentAudioDevice->start (&callbackHandler);
sendChangeMessage (this);
return error;
}
*/
void AudioDeviceManager::stopDevice()
{
if (currentAudioDevice != 0)

View file

@ -299,7 +299,7 @@ public:
/**
*/
const OwnedArray <AudioIODeviceType>& getAvailableDeviceTypes() const throw() { return availableDeviceTypes; }
const OwnedArray <AudioIODeviceType>& getAvailableDeviceTypes();
//==============================================================================
/** Creates a list of available types.

View file

@ -41,6 +41,63 @@ BEGIN_JUCE_NAMESPACE
#include "../../../../juce_core/text/juce_LocalisedStrings.h"
//==============================================================================
class SimpleDeviceManagerInputLevelMeter : public Component,
public Timer
{
public:
SimpleDeviceManagerInputLevelMeter (AudioDeviceManager* const manager_)
: manager (manager_),
totalBlocks (7)
{
numBlocks = 0;
startTimer (50);
manager->enableInputLevelMeasurement (true);
}
~SimpleDeviceManagerInputLevelMeter()
{
manager->enableInputLevelMeasurement (false);
}
void timerCallback()
{
const int newNumBlocks = roundDoubleToInt (manager->getCurrentInputLevel() * totalBlocks);
if (newNumBlocks != numBlocks)
{
numBlocks = newNumBlocks;
repaint();
}
}
void paint (Graphics& g)
{
g.setColour (Colours::white.withAlpha (0.8f));
g.fillRoundedRectangle (0.0f, 0.0f, (float) getWidth(), (float) getHeight(), 3.0f);
g.setColour (Colours::black.withAlpha (0.2f));
g.drawRoundedRectangle (1.0f, 1.0f, getWidth() - 2.0f, getHeight() - 2.0f, 3.0f, 1.0f);
const float w = (getWidth() - 6.0f) / (float) totalBlocks;
for (int i = 0; i < totalBlocks; ++i)
{
if (i >= numBlocks)
g.setColour (Colours::lightblue.withAlpha (0.6f));
else
g.setColour (i < totalBlocks - 1 ? Colours::blue.withAlpha (0.5f)
: Colours::red);
g.fillRoundedRectangle (3.0f + i * w + w * 0.1f, 3.0f, w * 0.8f, getHeight() - 6.0f, w * 0.4f);
}
}
private:
AudioDeviceManager* const manager;
const int totalBlocks;
int numBlocks;
};
//==============================================================================
class MidiInputSelectorComponentListBox : public ListBox,
public ListBoxModel
@ -414,7 +471,8 @@ public:
inputDeviceLabel = new Label (String::empty, TRANS ("input:"));
inputDeviceLabel->attachToComponent (inputDeviceDropDown, true);
addAndMakeVisible (inputLevelMeter = AudioDeviceSelectorComponent::createSimpleLevelMeterComponent (setup.manager));
addAndMakeVisible (inputLevelMeter
= new SimpleDeviceManagerInputLevelMeter (setup.manager));
}
addNamesToDeviceBox (*inputDeviceDropDown, true);
@ -588,7 +646,7 @@ private:
{
const StringArray devs (type->getDeviceNames (isInputs));
combo.clear();
combo.clear (true);
for (int i = 0; i < devs.size(); ++i)
combo.addItem (devs[i], i + 1);
@ -1007,8 +1065,6 @@ void AudioDeviceSelectorComponent::buttonClicked (Button*)
void AudioDeviceSelectorComponent::comboBoxChanged (ComboBox* comboBoxThatHasChanged)
{
// AudioIODevice* const audioDevice = deviceManager.getCurrentAudioDevice();
if (comboBoxThatHasChanged == deviceTypeDropDown)
{
AudioIODeviceType* const type = deviceManager.getAvailableDeviceTypes() [deviceTypeDropDown->getSelectedId() - 1];
@ -1021,124 +1077,15 @@ void AudioDeviceSelectorComponent::comboBoxChanged (ComboBox* comboBoxThatHasCha
changeListenerCallback (0); // needed in case the type hasn't actally changed
}
/* if (outputDeviceDropDown->getSelectedId() < 0)
{
deviceManager.setAudioDevices (String::empty, deviceManager.getCurrentAudioInputDeviceName(), 0, 0, 0, 0, true);
}
else
{
String error (deviceManager.setAudioDevices (deviceName, deviceManager.getCurrentAudioInputDeviceName(), 0, 0, 0, 0, true));
if (error.isNotEmpty())
{
#if JUCE_WIN32
if (deviceManager.getInputChannels().countNumberOfSetBits() > 0
&& deviceManager.getOutputChannels().countNumberOfSetBits() > 0)
{
// in DSound, some machines lose their primary input device when a mic
// is removed, and this also buggers up our attempt at opening an output
// device, so this is a workaround that doesn't fail in that case.
BitArray noInputs;
error = deviceManager.setAudioDevices (deviceName, deviceManager.getCurrentAudioInputDeviceName(), 0, 0, &noInputs, 0, false);
}
#endif
if (error.isNotEmpty())
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
T("Error while opening \"")
+ deviceName
+ T("\""),
error);
}
}
deviceName = deviceManager.getCurrentAudioOutputDeviceName();
if (deviceName.isNotEmpty())
outputDeviceDropDown->setText (deviceName, true);
else
outputDeviceDropDown->setSelectedId (-1, true);
}
else if (comboBoxThatHasChanged == inputDeviceDropDown)
{
String deviceName (inputDeviceDropDown->getText());
if (inputDeviceDropDown->getSelectedId() < 0)
{
deviceManager.setAudioDevices (deviceManager.getCurrentAudioOutputDeviceName(), String::empty, 0, 0, 0, 0, true);
}
else
{
String error (deviceManager.setAudioDevices (deviceManager.getCurrentAudioOutputDeviceName(), deviceName, 0, 0, 0, 0, true));
if (error.isNotEmpty())
{
#if JUCE_WIN32
if (deviceManager.getInputChannels().countNumberOfSetBits() > 0
&& deviceManager.getOutputChannels().countNumberOfSetBits() > 0)
{
// in DSound, some machines lose their primary input device when a mic
// is removed, and this also buggers up our attempt at opening an output
// device, so this is a workaround that doesn't fail in that case.
BitArray noInputs;
error = deviceManager.setAudioDevices (deviceManager.getCurrentAudioOutputDeviceName(), deviceName, 0, 0, &noInputs, 0, false);
}
#endif
if (error.isNotEmpty())
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
T("Error while opening \"")
+ deviceName
+ T("\""),
error);
}
}
deviceName = deviceManager.getCurrentAudioOutputDeviceName();
if (deviceName.isNotEmpty())
inputDeviceDropDown->setText (deviceName, true);
else
inputDeviceDropDown->setSelectedId (-1, true);*/
}
else if (comboBoxThatHasChanged == midiOutputSelector)
{
deviceManager.setDefaultMidiOutput (midiOutputSelector->getText());
}
/*else if (audioDevice != 0)
{
if (bufferSizeDropDown != 0 && comboBoxThatHasChanged == bufferSizeDropDown)
{
if (bufferSizeDropDown->getSelectedId() > 0)
deviceManager.setAudioDevices (deviceManager.getCurrentAudioOutputDeviceName(),
deviceManager.getCurrentAudioInputDeviceName(),
bufferSizeDropDown->getSelectedId(),
audioDevice->getCurrentSampleRate(),
0, 0, true);
}
else if (sampleRateDropDown != 0 && comboBoxThatHasChanged == sampleRateDropDown)
{
if (sampleRateDropDown->getSelectedId() > 0)
deviceManager.setAudioDevices (deviceManager.getCurrentAudioOutputDeviceName(),
deviceManager.getCurrentAudioInputDeviceName(),
audioDevice->getCurrentBufferSizeSamples(),
sampleRateDropDown->getSelectedId(),
0, 0, true);
}
}*/
}
void AudioDeviceSelectorComponent::changeListenerCallback (void*)
{
/*deleteAndZero (sampleRateDropDown);
deleteAndZero (inputChansBox);
deleteAndZero (inputsLabel);
deleteAndZero (outputChansBox);
deleteAndZero (outputsLabel);
deleteAndZero (sampleRateLabel);
deleteAndZero (bufferSizeDropDown);
deleteAndZero (bufferSizeLabel);
deleteAndZero (launchUIButton);*/
if (deviceTypeDropDown != 0)
{
deviceTypeDropDown->setText (deviceManager.getCurrentAudioDeviceType(), false);
@ -1175,98 +1122,6 @@ void AudioDeviceSelectorComponent::changeListenerCallback (void*)
}
}
/* AudioIODevice* const currentDevice = deviceManager.getCurrentAudioDevice();
if (currentDevice != 0)
{
if (deviceManager.getCurrentAudioOutputDevice() == 0)
outputDeviceDropDown->setSelectedId (-1, true);
else
outputDeviceDropDown->setText (deviceManager.getCurrentAudioOutputDeviceName(), true);
if (deviceManager.getCurrentAudioInputDevice() == 0)
inputDeviceDropDown->setSelectedId (-1, true);
else
inputDeviceDropDown->setText (deviceManager.getCurrentAudioInputDeviceName(), true);
// sample rate
addAndMakeVisible (sampleRateDropDown = new ComboBox ("samplerate"));
sampleRateLabel = new Label ("l2", TRANS ("sample rate:"));
sampleRateLabel->attachToComponent (sampleRateDropDown, true);
const int numRates = currentDevice->getNumSampleRates();
int i;
for (i = 0; i < numRates; ++i)
{
const int rate = roundDoubleToInt (currentDevice->getSampleRate (i));
sampleRateDropDown->addItem (String (rate) + T(" Hz"), rate);
}
const double currentRate = currentDevice->getCurrentSampleRate();
sampleRateDropDown->setSelectedId (roundDoubleToInt (currentRate), true);
sampleRateDropDown->addListener (this);
// buffer size
addAndMakeVisible (bufferSizeDropDown = new ComboBox ("buffersize"));
bufferSizeLabel = new Label ("l2", TRANS ("audio buffer size:"));
bufferSizeLabel->attachToComponent (bufferSizeDropDown, true);
const int numBufferSizes = currentDevice->getNumBufferSizesAvailable();
for (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);
bufferSizeDropDown->addListener (this);
if (currentDevice->hasControlPanel())
{
addAndMakeVisible (launchUIButton = new TextButton (TRANS ("show this device's control panel"),
TRANS ("opens the device's own control panel")));
launchUIButton->addButtonListener (this);
}
// output chans
if (maxOutputChannels > 0 && minOutputChannels < currentDevice->getOutputChannelNames().size())
{
addAndMakeVisible (outputChansBox
= new AudioDeviceSelectorComponentListBox (deviceManager,
AudioDeviceSelectorComponentListBox::audioOutputType,
TRANS ("(no audio output channels found)"),
minOutputChannels, maxOutputChannels));
outputsLabel = new Label ("l3", TRANS ("active output channels:"));
outputsLabel->attachToComponent (outputChansBox, true);
}
// input chans
if (maxInputChannels > 0 && minInputChannels < currentDevice->getInputChannelNames().size())
{
addAndMakeVisible (inputChansBox
= new AudioDeviceSelectorComponentListBox (deviceManager,
AudioDeviceSelectorComponentListBox::audioInputType,
TRANS ("(no audio input channels found)"),
minInputChannels, maxInputChannels));
inputsLabel = new Label ("l4", TRANS ("active input channels:"));
inputsLabel->attachToComponent (inputChansBox, true);
}
}
else
{
outputDeviceDropDown->setSelectedId (-1, true);
inputDeviceDropDown->setSelectedId (-1, true);
}*/
if (midiInputsList != 0)
{
midiInputsList->updateContent();
@ -1297,67 +1152,4 @@ void AudioDeviceSelectorComponent::changeListenerCallback (void*)
}
//==============================================================================
class SimpleDeviceManagerInputLevelMeter : public Component,
public Timer
{
public:
SimpleDeviceManagerInputLevelMeter (AudioDeviceManager* const manager_)
: manager (manager_),
totalBlocks (7)
{
numBlocks = 0;
startTimer (50);
manager->enableInputLevelMeasurement (true);
}
~SimpleDeviceManagerInputLevelMeter()
{
manager->enableInputLevelMeasurement (false);
}
void timerCallback()
{
const int newNumBlocks = roundDoubleToInt (manager->getCurrentInputLevel() * totalBlocks);
if (newNumBlocks != numBlocks)
{
numBlocks = newNumBlocks;
repaint();
}
}
void paint (Graphics& g)
{
g.setColour (Colours::white.withAlpha (0.8f));
g.fillRoundedRectangle (0.0f, 0.0f, (float) getWidth(), (float) getHeight(), 3.0f);
g.setColour (Colours::black.withAlpha (0.2f));
g.drawRoundedRectangle (1.0f, 1.0f, getWidth() - 2.0f, getHeight() - 2.0f, 3.0f, 1.0f);
const float w = (getWidth() - 6.0f) / (float) totalBlocks;
for (int i = 0; i < totalBlocks; ++i)
{
if (i >= numBlocks)
g.setColour (Colours::lightblue.withAlpha (0.6f));
else
g.setColour (i < totalBlocks - 1 ? Colours::blue.withAlpha (0.5f)
: Colours::red);
g.fillRoundedRectangle (3.0f + i * w + w * 0.1f, 3.0f, w * 0.8f, getHeight() - 6.0f, w * 0.4f);
}
}
private:
AudioDeviceManager* const manager;
const int totalBlocks;
int numBlocks;
};
Component* AudioDeviceSelectorComponent::createSimpleLevelMeterComponent (AudioDeviceManager* managerToDisplay)
{
return new SimpleDeviceManagerInputLevelMeter (managerToDisplay);
}
END_JUCE_NAMESPACE

View file

@ -89,12 +89,6 @@ public:
/** @internal */
void changeListenerCallback (void*);
//==============================================================================
/** Called by the device-specific displays to create a little level meter that
just displays the current total input levels from the given device manager.
*/
static Component* createSimpleLevelMeterComponent (AudioDeviceManager* managerToDisplay);
//==============================================================================
juce_UseDebuggingNewOperator