- Library code update
- project update (added Eigen) git-svn-id: http://moon:8086/svn/software/trunk/projects/mpsk_rx_gui@94 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
@@ -859,8 +859,11 @@ void AudioDeviceManager::addMidiInputCallback (const String& name, MidiInputCall
|
||||
if (name.isEmpty() || isMidiInputEnabled (name))
|
||||
{
|
||||
const ScopedLock sl (midiCallbackLock);
|
||||
midiCallbacks.add (callbackToAdd);
|
||||
midiCallbackDevices.add (name);
|
||||
|
||||
MidiCallbackInfo mc;
|
||||
mc.deviceName = name;
|
||||
mc.callback = callbackToAdd;
|
||||
midiCallbacks.add (mc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -868,11 +871,12 @@ void AudioDeviceManager::removeMidiInputCallback (const String& name, MidiInputC
|
||||
{
|
||||
for (int i = midiCallbacks.size(); --i >= 0;)
|
||||
{
|
||||
if (midiCallbackDevices[i] == name && midiCallbacks.getUnchecked(i) == callbackToRemove)
|
||||
const MidiCallbackInfo& mc = midiCallbacks.getReference(i);
|
||||
|
||||
if (mc.callback == callbackToRemove && mc.deviceName == name)
|
||||
{
|
||||
const ScopedLock sl (midiCallbackLock);
|
||||
midiCallbacks.remove (i);
|
||||
midiCallbackDevices.remove (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -881,16 +885,14 @@ void AudioDeviceManager::handleIncomingMidiMessageInt (MidiInput* source, const
|
||||
{
|
||||
if (! message.isActiveSense())
|
||||
{
|
||||
const bool isDefaultSource = (source == nullptr || source == enabledMidiInputs.getFirst());
|
||||
|
||||
const ScopedLock sl (midiCallbackLock);
|
||||
|
||||
for (int i = midiCallbackDevices.size(); --i >= 0;)
|
||||
for (int i = 0; i < midiCallbacks.size(); ++i)
|
||||
{
|
||||
const String name (midiCallbackDevices[i]);
|
||||
const MidiCallbackInfo& mc = midiCallbacks.getReference(i);
|
||||
|
||||
if ((isDefaultSource && name.isEmpty()) || (name.isNotEmpty() && name == source->getName()))
|
||||
midiCallbacks.getUnchecked(i)->handleIncomingMidiMessage (source, message);
|
||||
if (mc.deviceName.isEmpty() || mc.deviceName == source->getName())
|
||||
mc.callback->handleIncomingMidiMessage (source, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,10 +209,9 @@ public:
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the current device properties that are in use.
|
||||
|
||||
@see setAudioDeviceSetup
|
||||
*/
|
||||
void getAudioDeviceSetup (AudioDeviceSetup& setup);
|
||||
void getAudioDeviceSetup (AudioDeviceSetup& result);
|
||||
|
||||
/** Changes the current device or its settings.
|
||||
|
||||
@@ -261,9 +260,7 @@ public:
|
||||
void setCurrentAudioDeviceType (const String& type,
|
||||
bool treatAsChosenDevice);
|
||||
|
||||
|
||||
/** Closes the currently-open device.
|
||||
|
||||
You can call restartLastAudioDevice() later to reopen it in the same state
|
||||
that it was just in.
|
||||
*/
|
||||
@@ -305,8 +302,8 @@ public:
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the average proportion of available CPU being spent inside the audio callbacks.
|
||||
|
||||
Returns a value between 0 and 1.0
|
||||
@returns A value between 0 and 1.0 to indicate the approximate proportion of CPU
|
||||
time spent in the callbacks.
|
||||
*/
|
||||
double getCpuUsage() const;
|
||||
|
||||
@@ -333,16 +330,16 @@ public:
|
||||
void setMidiInputEnabled (const String& midiInputDeviceName, bool enabled);
|
||||
|
||||
/** Returns true if a given midi input device is being used.
|
||||
|
||||
@see setMidiInputEnabled
|
||||
*/
|
||||
bool isMidiInputEnabled (const String& midiInputDeviceName) const;
|
||||
|
||||
/** Registers a listener for callbacks when midi events arrive from a midi input.
|
||||
|
||||
The device name can be empty to indicate that it wants events from whatever the
|
||||
current "default" device is. Or it can be the name of one of the midi input devices
|
||||
(see MidiInput::getDevices() for the names).
|
||||
The device name can be empty to indicate that it wants to receive all incoming
|
||||
events from all the enabled MIDI inputs. Or it can be the name of one of the
|
||||
MIDI input devices if it just wants the events from that device. (see
|
||||
MidiInput::getDevices() for the list of device names).
|
||||
|
||||
Only devices which are enabled (see the setMidiInputEnabled() method) will have their
|
||||
events forwarded on to listeners.
|
||||
@@ -350,8 +347,7 @@ public:
|
||||
void addMidiInputCallback (const String& midiInputDeviceName,
|
||||
MidiInputCallback* callback);
|
||||
|
||||
/** Removes a listener that was previously registered with addMidiInputCallback().
|
||||
*/
|
||||
/** Removes a listener that was previously registered with addMidiInputCallback(). */
|
||||
void removeMidiInputCallback (const String& midiInputDeviceName,
|
||||
MidiInputCallback* callback);
|
||||
|
||||
@@ -371,22 +367,17 @@ public:
|
||||
void setDefaultMidiOutput (const String& deviceName);
|
||||
|
||||
/** Returns the name of the default midi output.
|
||||
|
||||
@see setDefaultMidiOutput, getDefaultMidiOutput
|
||||
*/
|
||||
String getDefaultMidiOutputName() const { return defaultMidiOutputName; }
|
||||
const String& getDefaultMidiOutputName() const noexcept { return defaultMidiOutputName; }
|
||||
|
||||
/** Returns the current default midi output device.
|
||||
|
||||
If no device has been selected, or the device can't be opened, this will
|
||||
return 0.
|
||||
|
||||
If no device has been selected, or the device can't be opened, this will return nullptr.
|
||||
@see getDefaultMidiOutputName
|
||||
*/
|
||||
MidiOutput* getDefaultMidiOutput() const noexcept { return defaultMidiOutput; }
|
||||
|
||||
/** Returns a list of the types of device supported.
|
||||
*/
|
||||
/** Returns a list of the types of device supported. */
|
||||
const OwnedArray<AudioIODeviceType>& getAvailableDeviceTypes();
|
||||
|
||||
//==============================================================================
|
||||
@@ -429,9 +420,7 @@ public:
|
||||
void enableInputLevelMeasurement (bool enableMeasurement);
|
||||
|
||||
/** Returns the current input level.
|
||||
|
||||
To use this, you must first enable it by calling enableInputLevelMeasurement().
|
||||
|
||||
See enableInputLevelMeasurement() for more info.
|
||||
*/
|
||||
double getCurrentInputLevel() const;
|
||||
@@ -468,10 +457,16 @@ private:
|
||||
int testSoundPosition;
|
||||
AudioSampleBuffer tempBuffer;
|
||||
|
||||
struct MidiCallbackInfo
|
||||
{
|
||||
String deviceName;
|
||||
MidiInputCallback* callback;
|
||||
};
|
||||
|
||||
StringArray midiInsFromXml;
|
||||
OwnedArray<MidiInput> enabledMidiInputs;
|
||||
Array<MidiInputCallback*> midiCallbacks;
|
||||
StringArray midiCallbackDevices;
|
||||
Array<MidiCallbackInfo> midiCallbacks;
|
||||
|
||||
String defaultMidiOutputName;
|
||||
ScopedPointer<MidiOutput> defaultMidiOutput;
|
||||
CriticalSection audioCallbackLock, midiCallbackLock;
|
||||
|
||||
@@ -22,20 +22,16 @@
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
AudioIODevice::AudioIODevice (const String& deviceName, const String& typeName_)
|
||||
: name (deviceName),
|
||||
typeName (typeName_)
|
||||
AudioIODevice::AudioIODevice (const String& deviceName, const String& deviceTypeName)
|
||||
: name (deviceName), typeName (deviceTypeName)
|
||||
{
|
||||
}
|
||||
|
||||
AudioIODevice::~AudioIODevice()
|
||||
{
|
||||
}
|
||||
AudioIODevice::~AudioIODevice() {}
|
||||
|
||||
bool AudioIODevice::hasControlPanel() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void AudioIODeviceCallback::audioDeviceError (const String&) {}
|
||||
bool AudioIODevice::setAudioPreprocessingEnabled (bool) { return false; }
|
||||
bool AudioIODevice::hasControlPanel() const { return false; }
|
||||
|
||||
bool AudioIODevice::showControlPanel()
|
||||
{
|
||||
@@ -43,6 +39,3 @@ bool AudioIODevice::showControlPanel()
|
||||
// their hasControlPanel() method.
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void AudioIODeviceCallback::audioDeviceError (const String&) {}
|
||||
|
||||
@@ -289,6 +289,11 @@ public:
|
||||
*/
|
||||
virtual bool showControlPanel();
|
||||
|
||||
/** On devices which support it, this allows automatic gain control or other
|
||||
mic processing to be disabled.
|
||||
If the device doesn't support this operation, it'll return false.
|
||||
*/
|
||||
virtual bool setAudioPreprocessingEnabled (bool shouldBeEnabled);
|
||||
|
||||
//==============================================================================
|
||||
protected:
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
method. Each of the objects returned can then be used to list the available
|
||||
devices of that type. E.g.
|
||||
@code
|
||||
OwnedArray <AudioIODeviceType> types;
|
||||
OwnedArray<AudioIODeviceType> types;
|
||||
myAudioDeviceManager.createAudioDeviceTypes (types);
|
||||
|
||||
for (int i = 0; i < types.size(); ++i)
|
||||
|
||||
@@ -125,6 +125,7 @@
|
||||
#if JUCE_USE_ANDROID_OPENSLES
|
||||
#include <SLES/OpenSLES.h>
|
||||
#include <SLES/OpenSLES_Android.h>
|
||||
#include <SLES/OpenSLES_AndroidConfiguration.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "juce_audio_devices",
|
||||
"name": "JUCE audio and midi I/O device classes",
|
||||
"version": "3.0.5",
|
||||
"version": "3.0.8",
|
||||
"description": "Classes to play and record from audio and midi i/o devices.",
|
||||
"website": "http://www.juce.com/juce",
|
||||
"license": "GPL/Commercial",
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
|
||||
Array<double> getAvailableSampleRates() override
|
||||
{
|
||||
static const double rates[] = { 8000.0, 16000.0, 32000.0, 44100.0, 48000.0 };
|
||||
static const double rates[] = { 8000.0, 16000.0, 32000.0, 44100.0, 48000.0 };
|
||||
return Array<double> (rates, numElementsInArray (rates));
|
||||
}
|
||||
|
||||
@@ -165,6 +165,33 @@ public:
|
||||
oldCallback->audioDeviceStopped();
|
||||
}
|
||||
|
||||
bool setAudioPreprocessingEnabled (bool enable) override
|
||||
{
|
||||
return recorder != nullptr && recorder->setAudioPreprocessingEnabled (enable);
|
||||
}
|
||||
|
||||
private:
|
||||
//==================================================================================================
|
||||
CriticalSection callbackLock;
|
||||
AudioIODeviceCallback* callback;
|
||||
int actualBufferSize, sampleRate;
|
||||
int inputLatency, outputLatency;
|
||||
bool deviceOpen;
|
||||
String lastError;
|
||||
BigInteger activeOutputChans, activeInputChans;
|
||||
int numInputChannels, numOutputChannels;
|
||||
AudioSampleBuffer inputBuffer, outputBuffer;
|
||||
struct Player;
|
||||
struct Recorder;
|
||||
|
||||
AudioIODeviceCallback* setCallback (AudioIODeviceCallback* const newCallback)
|
||||
{
|
||||
const ScopedLock sl (callbackLock);
|
||||
AudioIODeviceCallback* const oldCallback = callback;
|
||||
callback = newCallback;
|
||||
return oldCallback;
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
if (recorder != nullptr) recorder->start();
|
||||
@@ -190,28 +217,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//==================================================================================================
|
||||
CriticalSection callbackLock;
|
||||
AudioIODeviceCallback* callback;
|
||||
int actualBufferSize, sampleRate;
|
||||
int inputLatency, outputLatency;
|
||||
bool deviceOpen;
|
||||
String lastError;
|
||||
BigInteger activeOutputChans, activeInputChans;
|
||||
int numInputChannels, numOutputChannels;
|
||||
AudioSampleBuffer inputBuffer, outputBuffer;
|
||||
struct Player;
|
||||
struct Recorder;
|
||||
|
||||
AudioIODeviceCallback* setCallback (AudioIODeviceCallback* const newCallback)
|
||||
{
|
||||
const ScopedLock sl (callbackLock);
|
||||
AudioIODeviceCallback* const oldCallback = callback;
|
||||
callback = newCallback;
|
||||
return oldCallback;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
struct Engine
|
||||
{
|
||||
@@ -230,6 +235,7 @@ private:
|
||||
SL_IID_ANDROIDSIMPLEBUFFERQUEUE = (SLInterfaceID*) library.getFunction ("SL_IID_ANDROIDSIMPLEBUFFERQUEUE");
|
||||
SL_IID_PLAY = (SLInterfaceID*) library.getFunction ("SL_IID_PLAY");
|
||||
SL_IID_RECORD = (SLInterfaceID*) library.getFunction ("SL_IID_RECORD");
|
||||
SL_IID_ANDROIDCONFIGURATION = (SLInterfaceID*) library.getFunction ("SL_IID_ANDROIDCONFIGURATION");
|
||||
|
||||
check ((*engineObject)->Realize (engineObject, SL_BOOLEAN_FALSE));
|
||||
check ((*engineObject)->GetInterface (engineObject, *SL_IID_ENGINE, &engineInterface));
|
||||
@@ -271,6 +277,7 @@ private:
|
||||
SLInterfaceID* SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
|
||||
SLInterfaceID* SL_IID_PLAY;
|
||||
SLInterfaceID* SL_IID_RECORD;
|
||||
SLInterfaceID* SL_IID_ANDROIDCONFIGURATION;
|
||||
|
||||
private:
|
||||
DynamicLibrary library;
|
||||
@@ -334,8 +341,8 @@ private:
|
||||
SLDataFormat_PCM pcmFormat =
|
||||
{
|
||||
SL_DATAFORMAT_PCM,
|
||||
numChannels,
|
||||
sampleRate * 1000, // (sample rate units are millihertz)
|
||||
(SLuint32) numChannels,
|
||||
(SLuint32) (sampleRate * 1000), // (sample rate units are millihertz)
|
||||
SL_PCMSAMPLEFORMAT_FIXED_16,
|
||||
SL_PCMSAMPLEFORMAT_FIXED_16,
|
||||
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
|
||||
@@ -434,7 +441,8 @@ private:
|
||||
struct Recorder
|
||||
{
|
||||
Recorder (int numChannels, int sampleRate, Engine& engine)
|
||||
: recorderObject (nullptr), recorderRecord (nullptr), recorderBufferQueue (nullptr),
|
||||
: recorderObject (nullptr), recorderRecord (nullptr),
|
||||
recorderBufferQueue (nullptr), configObject (nullptr),
|
||||
bufferList (numChannels)
|
||||
{
|
||||
jassert (numChannels == 1); // STEREO doesn't always work!!
|
||||
@@ -442,8 +450,8 @@ private:
|
||||
SLDataFormat_PCM pcmFormat =
|
||||
{
|
||||
SL_DATAFORMAT_PCM,
|
||||
numChannels,
|
||||
sampleRate * 1000, // (sample rate units are millihertz)
|
||||
(SLuint32) numChannels,
|
||||
(SLuint32) (sampleRate * 1000), // (sample rate units are millihertz)
|
||||
SL_PCMSAMPLEFORMAT_FIXED_16,
|
||||
SL_PCMSAMPLEFORMAT_FIXED_16,
|
||||
(numChannels == 1) ? SL_SPEAKER_FRONT_CENTER : (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT),
|
||||
@@ -466,6 +474,7 @@ private:
|
||||
{
|
||||
check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_RECORD, &recorderRecord));
|
||||
check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue));
|
||||
check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_ANDROIDCONFIGURATION, &configObject));
|
||||
check ((*recorderBufferQueue)->RegisterCallback (recorderBufferQueue, staticCallback, this));
|
||||
check ((*recorderRecord)->SetRecordState (recorderRecord, SL_RECORDSTATE_STOPPED));
|
||||
|
||||
@@ -532,10 +541,20 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
bool setAudioPreprocessingEnabled (bool enable)
|
||||
{
|
||||
SLuint32 mode = enable ? SL_ANDROID_RECORDING_PRESET_GENERIC
|
||||
: SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
|
||||
|
||||
return configObject != nullptr
|
||||
&& check ((*configObject)->SetConfiguration (configObject, SL_ANDROID_KEY_RECORDING_PRESET, &mode, sizeof (mode)));
|
||||
}
|
||||
|
||||
private:
|
||||
SLObjectItf recorderObject;
|
||||
SLRecordItf recorderRecord;
|
||||
SLAndroidSimpleBufferQueueItf recorderBufferQueue;
|
||||
SLAndroidConfigurationItf configObject;
|
||||
|
||||
BufferList bufferList;
|
||||
|
||||
|
||||
@@ -67,7 +67,12 @@ public:
|
||||
return s;
|
||||
}
|
||||
|
||||
Array<double> getAvailableSampleRates() override { return sampleRates; }
|
||||
Array<double> getAvailableSampleRates() override
|
||||
{
|
||||
// can't find a good way to actually ask the device for which of these it supports..
|
||||
static const double rates[] = { 8000.0, 16000.0, 22050.0, 32000.0, 44100.0, 48000.0 };
|
||||
return Array<double> (rates, numElementsInArray (rates));
|
||||
}
|
||||
|
||||
Array<int> getAvailableBufferSizes() override
|
||||
{
|
||||
@@ -79,7 +84,7 @@ public:
|
||||
return r;
|
||||
}
|
||||
|
||||
int getDefaultBufferSize() override { return 1024; }
|
||||
int getDefaultBufferSize() override { return 1024; }
|
||||
|
||||
String open (const BigInteger& inputChannelsWanted,
|
||||
const BigInteger& outputChannelsWanted,
|
||||
@@ -117,10 +122,9 @@ public:
|
||||
AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, routingChangedStatic, this);
|
||||
|
||||
fixAudioRouteIfSetToReceiver();
|
||||
updateDeviceInfo();
|
||||
|
||||
setSessionFloat64Property (kAudioSessionProperty_PreferredHardwareSampleRate, targetSampleRate);
|
||||
updateSampleRates();
|
||||
updateDeviceInfo();
|
||||
|
||||
setSessionFloat32Property (kAudioSessionProperty_PreferredHardwareIOBufferDuration, preferredBufferSize / sampleRate);
|
||||
updateCurrentBufferSize();
|
||||
@@ -162,8 +166,15 @@ public:
|
||||
BigInteger getActiveOutputChannels() const override { return activeOutputChans; }
|
||||
BigInteger getActiveInputChannels() const override { return activeInputChans; }
|
||||
|
||||
int getOutputLatencyInSamples() override { return 0; } //xxx
|
||||
int getInputLatencyInSamples() override { return 0; } //xxx
|
||||
int getOutputLatencyInSamples() override { return getLatency (kAudioSessionProperty_CurrentHardwareOutputLatency); }
|
||||
int getInputLatencyInSamples() override { return getLatency (kAudioSessionProperty_CurrentHardwareInputLatency); }
|
||||
|
||||
int getLatency (AudioSessionPropertyID propID)
|
||||
{
|
||||
Float32 latency = 0;
|
||||
getSessionProperty (propID, latency);
|
||||
return roundToInt (latency * getCurrentSampleRate());
|
||||
}
|
||||
|
||||
void start (AudioIODeviceCallback* newCallback) override
|
||||
{
|
||||
@@ -197,11 +208,16 @@ public:
|
||||
bool isPlaying() override { return isRunning && callback != nullptr; }
|
||||
String getLastError() override { return lastError; }
|
||||
|
||||
bool setAudioPreprocessingEnabled (bool enable) override
|
||||
{
|
||||
return setSessionUInt32Property (kAudioSessionProperty_Mode, enable ? kAudioSessionMode_Default
|
||||
: kAudioSessionMode_Measurement);
|
||||
}
|
||||
|
||||
private:
|
||||
//==================================================================================================
|
||||
CriticalSection callbackLock;
|
||||
Float64 sampleRate;
|
||||
Array<Float64> sampleRates;
|
||||
int numInputChannels, numOutputChannels;
|
||||
int preferredBufferSize, actualBufferSize;
|
||||
bool isRunning;
|
||||
@@ -322,38 +338,6 @@ private:
|
||||
getSessionProperty (kAudioSessionProperty_AudioInputAvailable, audioInputIsAvailable);
|
||||
}
|
||||
|
||||
void updateSampleRates()
|
||||
{
|
||||
getSessionProperty (kAudioSessionProperty_CurrentHardwareSampleRate, sampleRate);
|
||||
|
||||
sampleRates.clear();
|
||||
sampleRates.add (sampleRate);
|
||||
|
||||
const int commonSampleRates[] = { 8000, 16000, 22050, 32000, 44100, 48000 };
|
||||
|
||||
for (int i = 0; i < numElementsInArray (commonSampleRates); ++i)
|
||||
{
|
||||
Float64 rate = (Float64) commonSampleRates[i];
|
||||
|
||||
if (rate != sampleRate)
|
||||
{
|
||||
setSessionFloat64Property (kAudioSessionProperty_PreferredHardwareSampleRate, rate);
|
||||
|
||||
Float64 actualSampleRate = 0.0;
|
||||
getSessionProperty (kAudioSessionProperty_CurrentHardwareSampleRate, actualSampleRate);
|
||||
|
||||
if (actualSampleRate == rate)
|
||||
sampleRates.add (actualSampleRate);
|
||||
}
|
||||
}
|
||||
|
||||
DefaultElementComparator<Float64> comparator;
|
||||
sampleRates.sort (comparator);
|
||||
|
||||
setSessionFloat64Property (kAudioSessionProperty_PreferredHardwareSampleRate, sampleRate);
|
||||
getSessionProperty (kAudioSessionProperty_CurrentHardwareSampleRate, sampleRate);
|
||||
}
|
||||
|
||||
void updateCurrentBufferSize()
|
||||
{
|
||||
Float32 bufferDuration = sampleRate > 0 ? (Float32) (preferredBufferSize / sampleRate) : 0.0f;
|
||||
@@ -455,12 +439,12 @@ private:
|
||||
static OSStatus processStatic (void* client, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time,
|
||||
UInt32 /*busNumber*/, UInt32 numFrames, AudioBufferList* data)
|
||||
{
|
||||
return static_cast <iOSAudioIODevice*> (client)->process (flags, time, numFrames, data);
|
||||
return static_cast<iOSAudioIODevice*> (client)->process (flags, time, numFrames, data);
|
||||
}
|
||||
|
||||
static void routingChangedStatic (void* client, AudioSessionPropertyID, UInt32 /*inDataSize*/, const void* propertyValue)
|
||||
{
|
||||
static_cast <iOSAudioIODevice*> (client)->routingChanged (propertyValue);
|
||||
static_cast<iOSAudioIODevice*> (client)->routingChanged (propertyValue);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
@@ -552,9 +536,9 @@ private:
|
||||
return AudioSessionGetProperty (propID, &valueSize, &result);
|
||||
}
|
||||
|
||||
static void setSessionUInt32Property (AudioSessionPropertyID propID, UInt32 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v); }
|
||||
static void setSessionFloat32Property (AudioSessionPropertyID propID, Float32 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v); }
|
||||
static void setSessionFloat64Property (AudioSessionPropertyID propID, Float64 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v); }
|
||||
static bool setSessionUInt32Property (AudioSessionPropertyID propID, UInt32 v) noexcept { return AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; }
|
||||
static bool setSessionFloat32Property (AudioSessionPropertyID propID, Float32 v) noexcept { return AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; }
|
||||
static bool setSessionFloat64Property (AudioSessionPropertyID propID, Float64 v) noexcept { return AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; }
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice)
|
||||
};
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
#define JUCE_ALSA_LOG(x)
|
||||
#define JUCE_ALSA_LOG(x) {}
|
||||
#define JUCE_CHECKED_RESULT(x) (x)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -144,6 +144,7 @@ public:
|
||||
: owner (d),
|
||||
inputLatency (0),
|
||||
outputLatency (0),
|
||||
bitDepth (32),
|
||||
callback (nullptr),
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
|
||||
audioProcID (0),
|
||||
@@ -232,7 +233,7 @@ public:
|
||||
size = sizeof (nameNSString);
|
||||
|
||||
pa.mSelector = kAudioObjectPropertyElementName;
|
||||
pa.mElement = chanNum + 1;
|
||||
pa.mElement = (AudioObjectPropertyElement) chanNum + 1;
|
||||
|
||||
if (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &nameNSString) == noErr)
|
||||
{
|
||||
@@ -352,6 +353,22 @@ public:
|
||||
return (int) lat;
|
||||
}
|
||||
|
||||
int getBitDepthFromDevice (AudioObjectPropertyScope scope) const
|
||||
{
|
||||
AudioObjectPropertyAddress pa;
|
||||
pa.mElement = kAudioObjectPropertyElementMaster;
|
||||
pa.mSelector = kAudioStreamPropertyPhysicalFormat;
|
||||
pa.mScope = scope;
|
||||
|
||||
AudioStreamBasicDescription asbd;
|
||||
UInt32 size = sizeof (asbd);
|
||||
|
||||
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &asbd)))
|
||||
return (int) asbd.mBitsPerChannel;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void updateDetailsFromDevice()
|
||||
{
|
||||
stopTimer();
|
||||
@@ -377,7 +394,7 @@ public:
|
||||
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &sr)))
|
||||
sampleRate = sr;
|
||||
|
||||
UInt32 framesPerBuf = bufferSize;
|
||||
UInt32 framesPerBuf = (UInt32) bufferSize;
|
||||
size = sizeof (framesPerBuf);
|
||||
pa.mSelector = kAudioDevicePropertyBufferFrameSize;
|
||||
AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &framesPerBuf);
|
||||
@@ -392,6 +409,13 @@ public:
|
||||
StringArray newInNames (getChannelInfo (true, newInChans));
|
||||
StringArray newOutNames (getChannelInfo (false, newOutChans));
|
||||
|
||||
const int inputBitDepth = getBitDepthFromDevice (kAudioDevicePropertyScopeInput);
|
||||
const int outputBitDepth = getBitDepthFromDevice (kAudioDevicePropertyScopeOutput);
|
||||
|
||||
bitDepth = jmax (inputBitDepth, outputBitDepth);
|
||||
if (bitDepth <= 0)
|
||||
bitDepth = 32;
|
||||
|
||||
// after getting the new values, lock + apply them
|
||||
const ScopedLock sl (callbackLock);
|
||||
|
||||
@@ -728,6 +752,7 @@ public:
|
||||
//==============================================================================
|
||||
CoreAudioIODevice& owner;
|
||||
int inputLatency, outputLatency;
|
||||
int bitDepth;
|
||||
BigInteger activeInputChans, activeOutputChans;
|
||||
StringArray inChanNames, outChanNames;
|
||||
Array<double> sampleRates;
|
||||
@@ -886,7 +911,7 @@ public:
|
||||
Array<int> getAvailableBufferSizes() override { return internal->bufferSizes; }
|
||||
|
||||
double getCurrentSampleRate() override { return internal->getSampleRate(); }
|
||||
int getCurrentBitDepth() override { return 32; } // no way to find out, so just assume it's high..
|
||||
int getCurrentBitDepth() override { return internal->bitDepth; }
|
||||
int getCurrentBufferSizeSamples() override { return internal->getBufferSize(); }
|
||||
|
||||
int getDefaultBufferSize() override
|
||||
@@ -1387,7 +1412,7 @@ private:
|
||||
d.done = (d.numInputChans == 0);
|
||||
}
|
||||
|
||||
for (int tries = 3;;)
|
||||
for (int tries = 5;;)
|
||||
{
|
||||
bool anyRemaining = false;
|
||||
|
||||
@@ -1434,7 +1459,7 @@ private:
|
||||
d.done = (d.numOutputChans == 0);
|
||||
}
|
||||
|
||||
for (int tries = 3;;)
|
||||
for (int tries = 5;;)
|
||||
{
|
||||
bool anyRemaining = false;
|
||||
|
||||
|
||||
@@ -365,7 +365,7 @@ public:
|
||||
void updateSampleRates()
|
||||
{
|
||||
// find a list of sample rates..
|
||||
const int possibleSampleRates[] = { 44100, 48000, 88200, 96000, 176400, 192000 };
|
||||
const int possibleSampleRates[] = { 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000 };
|
||||
Array<double> newRates;
|
||||
|
||||
if (asioObject != nullptr)
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace WasapiClasses
|
||||
void logFailure (HRESULT hr)
|
||||
{
|
||||
(void) hr;
|
||||
jassert (hr != 0x800401f0); // If you hit this, it means you're trying to call from
|
||||
// a thread which hasn't been initialised with CoInitialize().
|
||||
jassert (hr != (HRESULT) 0x800401f0); // If you hit this, it means you're trying to call from
|
||||
// a thread which hasn't been initialised with CoInitialize().
|
||||
|
||||
#if JUCE_WASAPI_LOGGING
|
||||
if (FAILED (hr))
|
||||
|
||||
@@ -182,6 +182,10 @@ void AudioTransportSource::setNextReadPosition (int64 newPosition)
|
||||
newPosition = (int64) (newPosition * sourceSampleRate / sampleRate);
|
||||
|
||||
positionableSource->setNextReadPosition (newPosition);
|
||||
|
||||
if (resamplerSource != nullptr)
|
||||
resamplerSource->flushBuffers();
|
||||
|
||||
inputStreamEOF = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user