| @@ -185,15 +185,12 @@ public: | |||
| const int tempBufSize = bufferSize + 4; | |||
| audioBuffer.calloc ((size_t) ((numInputChans + numOutputChans) * tempBufSize)); | |||
| tempInputBuffers.calloc ((size_t) numInputChans + 2); | |||
| tempInputBuffers.calloc ((size_t) numInputChans + 2); | |||
| tempOutputBuffers.calloc ((size_t) numOutputChans + 2); | |||
| int count = 0; | |||
| for (int i = 0; i < numInputChans; ++i) | |||
| tempInputBuffers[i] = audioBuffer + count++ * tempBufSize; | |||
| for (int i = 0; i < numOutputChans; ++i) | |||
| tempOutputBuffers[i] = audioBuffer + count++ * tempBufSize; | |||
| for (int i = 0; i < numInputChans; ++i) tempInputBuffers[i] = audioBuffer + count++ * tempBufSize; | |||
| for (int i = 0; i < numOutputChans; ++i) tempOutputBuffers[i] = audioBuffer + count++ * tempBufSize; | |||
| } | |||
| struct CallbackDetailsForChannel | |||
| @@ -283,7 +280,7 @@ public: | |||
| if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, nullptr, &size))) | |||
| { | |||
| HeapBlock <AudioValueRange> ranges; | |||
| HeapBlock<AudioValueRange> ranges; | |||
| ranges.calloc (size, 1); | |||
| if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, ranges))) | |||
| @@ -322,7 +319,7 @@ public: | |||
| if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, nullptr, &size))) | |||
| { | |||
| HeapBlock <AudioValueRange> ranges; | |||
| HeapBlock<AudioValueRange> ranges; | |||
| ranges.calloc (size, 1); | |||
| if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, ranges))) | |||
| @@ -424,7 +421,7 @@ public: | |||
| StringArray getSources (bool input) | |||
| { | |||
| StringArray s; | |||
| HeapBlock <OSType> types; | |||
| HeapBlock<OSType> types; | |||
| const int num = getAllDataSourcesForDevice (deviceID, types); | |||
| for (int i = 0; i < num; ++i) | |||
| @@ -466,7 +463,7 @@ public: | |||
| { | |||
| if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, ¤tSourceID))) | |||
| { | |||
| HeapBlock <OSType> types; | |||
| HeapBlock<OSType> types; | |||
| const int num = getAllDataSourcesForDevice (deviceID, types); | |||
| for (int i = 0; i < num; ++i) | |||
| @@ -487,7 +484,7 @@ public: | |||
| { | |||
| if (deviceID != 0) | |||
| { | |||
| HeapBlock <OSType> types; | |||
| HeapBlock<OSType> types; | |||
| const int num = getAllDataSourcesForDevice (deviceID, types); | |||
| if (isPositiveAndBelow (index, num)) | |||
| @@ -1049,12 +1046,12 @@ public: | |||
| devices.clear(); | |||
| } | |||
| void addDevice (AudioIODevice* device) | |||
| void addDevice (AudioIODevice* device, bool useInputs, bool useOutputs) | |||
| { | |||
| jassert (device != nullptr); | |||
| jassert (! isOpen()); | |||
| jassert (! device->isOpen()); | |||
| devices.add (new DeviceWrapper (*this, device)); | |||
| devices.add (new DeviceWrapper (*this, device, useInputs, useOutputs)); | |||
| } | |||
| Array<AudioIODevice*> getDevices() const | |||
| @@ -1072,8 +1069,7 @@ public: | |||
| StringArray names; | |||
| for (int i = 0; i < devices.size(); ++i) | |||
| names.addArray (devices.getUnchecked(i)->device->getOutputChannelNames()); | |||
| names.addArray (devices.getUnchecked(i)->getOutputChannelNames()); | |||
| names.appendNumbersToDuplicates (false, true); | |||
| return names; | |||
| @@ -1084,7 +1080,7 @@ public: | |||
| StringArray names; | |||
| for (int i = 0; i < devices.size(); ++i) | |||
| names.addArray (devices.getUnchecked(i)->device->getInputChannelNames()); | |||
| names.addArray (devices.getUnchecked(i)->getInputChannelNames()); | |||
| names.appendNumbersToDuplicates (false, true); | |||
| return names; | |||
| @@ -1181,8 +1177,8 @@ public: | |||
| BigInteger ins (inputChannels >> totalInputChanIndex); | |||
| BigInteger outs (outputChannels >> totalOutputChanIndex); | |||
| int numIns = d.device->getInputChannelNames().size(); | |||
| int numOuts = d.device->getOutputChannelNames().size(); | |||
| int numIns = d.getInputChannelNames().size(); | |||
| int numOuts = d.getOutputChannelNames().size(); | |||
| totalInputChanIndex += numIns; | |||
| totalOutputChanIndex += numOuts; | |||
| @@ -1225,9 +1221,13 @@ public: | |||
| for (int i = 0; i < devices.size(); ++i) | |||
| { | |||
| const int numChans = devices.getUnchecked(i)->device->getOutputChannelNames().size(); | |||
| chans |= (devices.getUnchecked(i)->device->getActiveOutputChannels() << start); | |||
| start += numChans; | |||
| const int numChans = devices.getUnchecked(i)->getOutputChannelNames().size(); | |||
| if (numChans > 0) | |||
| { | |||
| chans |= (devices.getUnchecked(i)->device->getActiveOutputChannels() << start); | |||
| start += numChans; | |||
| } | |||
| } | |||
| return chans; | |||
| @@ -1240,9 +1240,13 @@ public: | |||
| for (int i = 0; i < devices.size(); ++i) | |||
| { | |||
| const int numChans = devices.getUnchecked(i)->device->getInputChannelNames().size(); | |||
| chans |= (devices.getUnchecked(i)->device->getActiveInputChannels() << start); | |||
| start += numChans; | |||
| const int numChans = devices.getUnchecked(i)->getInputChannelNames().size(); | |||
| if (numChans > 0) | |||
| { | |||
| chans |= (devices.getUnchecked(i)->device->getActiveInputChannels() << start); | |||
| start += numChans; | |||
| } | |||
| } | |||
| return chans; | |||
| @@ -1469,8 +1473,9 @@ private: | |||
| //============================================================================== | |||
| struct DeviceWrapper : private AudioIODeviceCallback | |||
| { | |||
| DeviceWrapper (AudioIODeviceCombiner& cd, AudioIODevice* d) | |||
| DeviceWrapper (AudioIODeviceCombiner& cd, AudioIODevice* d, bool useIns, bool useOuts) | |||
| : owner (cd), device (d), inputIndex (0), outputIndex (0), | |||
| useInputs (useIns), useOutputs (useOuts), | |||
| inputFifo (32), outputFifo (32), done (false) | |||
| { | |||
| } | |||
| @@ -1490,10 +1495,12 @@ private: | |||
| inputFifo.reset(); | |||
| outputFifo.reset(); | |||
| String err (device->open (inputChannels, outputChannels, sampleRate, bufferSize)); | |||
| String err (device->open (useInputs ? inputChannels : BigInteger(), | |||
| useOutputs ? outputChannels : BigInteger(), | |||
| sampleRate, bufferSize)); | |||
| numInputChans = device->getActiveInputChannels().countNumberOfSetBits(); | |||
| numOutputChans = device->getActiveOutputChannels().countNumberOfSetBits(); | |||
| numInputChans = useInputs ? device->getActiveInputChannels().countNumberOfSetBits() : 0; | |||
| numOutputChans = useOutputs ? device->getActiveOutputChannels().countNumberOfSetBits() : 0; | |||
| inputIndex = channelIndex; | |||
| outputIndex = channelIndex + numInputChans; | |||
| @@ -1518,6 +1525,9 @@ private: | |||
| outputFifo.reset(); | |||
| } | |||
| StringArray getOutputChannelNames() const { return useOutputs ? device->getOutputChannelNames() : StringArray(); } | |||
| StringArray getInputChannelNames() const { return useInputs ? device->getInputChannelNames() : StringArray(); } | |||
| bool isInputReady (int numSamples) const noexcept | |||
| { | |||
| return numInputChans == 0 || inputFifo.getNumReady() >= numSamples; | |||
| @@ -1655,6 +1665,7 @@ private: | |||
| AudioIODeviceCombiner& owner; | |||
| ScopedPointer<AudioIODevice> device; | |||
| int inputIndex, numInputChans, outputIndex, numOutputChans; | |||
| bool useInputs, useOutputs; | |||
| AbstractFifo inputFifo, outputFifo; | |||
| bool done; | |||
| @@ -1850,8 +1861,8 @@ public: | |||
| if (out == nullptr) return in.release(); | |||
| ScopedPointer<AudioIODeviceCombiner> combo (new AudioIODeviceCombiner (combinedName)); | |||
| combo->addDevice (in.release()); | |||
| combo->addDevice (out.release()); | |||
| combo->addDevice (in.release(), true, false); | |||
| combo->addDevice (out.release(), false, true); | |||
| return combo.release(); | |||
| } | |||
| @@ -1874,7 +1885,7 @@ private: | |||
| if (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, nullptr, &size) == noErr) | |||
| { | |||
| HeapBlock <AudioBufferList> bufList; | |||
| HeapBlock<AudioBufferList> bufList; | |||
| bufList.calloc (size, 1); | |||
| if (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, bufList) == noErr) | |||