implementation of CoreAudioInternal::getBitDepth()


#1

The returned bit depth for CoreAudio devices is currently hardcoded to 32 bit. Here is a small patch that returns the actual bit depth of the device (as set in "Audio MIDI Setup.app" ).

 

-- a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp
+++ b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp
@@ -154,6 +154,7 @@ public:
          bufferSize (512),
          numInputChans (0),
          numOutputChans (0),
+         bitDepth(0),
          callbacksAllowed (true)
     {
         jassert (deviceID != 0);
@@ -392,6 +393,24 @@ public:
         StringArray newInNames  (getChannelInfo (true,  newInChans));
         StringArray newOutNames (getChannelInfo (false, newOutChans));

+        AudioStreamBasicDescription asbd;
+        pa.mSelector = kAudioStreamPropertyPhysicalFormat;
+        bitDepth = 0;
+
+        size = sizeof(asbd);
+        pa.mScope = kAudioDevicePropertyScopeOutput;
+        if (OK(AudioObjectGetPropertyData(deviceID, &pa, 0, NULL, &size, &asbd)))
+        {
+            bitDepth = asbd.mBitsPerChannel;
+        }
+
+        size = sizeof(asbd);
+        pa.mScope = kAudioDevicePropertyScopeInput;
+        if (OK(AudioObjectGetPropertyData(deviceID, &pa, 0, NULL, &size, &asbd)))
+        {
+            bitDepth = asbd.mBitsPerChannel;
+        }
+
         // after getting the new values, lock + apply them
         const ScopedLock sl (callbackLock);

@@ -647,6 +666,7 @@ public:

     double getSampleRate() const  { return sampleRate; }
     int getBufferSize() const     { return bufferSize; }
+    int getBitDepth() const       { return bitDepth; }

     void audioCallback (const AudioBufferList* inInputData,
                         AudioBufferList* outOutputData)
@@ -745,6 +765,7 @@ private:
     int bufferSize;
     HeapBlock<float> audioBuffer;
     int numInputChans, numOutputChans;
+    int bitDepth;
     bool callbacksAllowed;

     Array<CallbackDetailsForChannel> inputChannelInfo, outputChannelInfo;
@@ -886,7 +907,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->getBitDepth(); }
     int getCurrentBufferSizeSamples() override          { return internal->getBufferSize(); }

     int getDefaultBufferSize() override
@@ -1120,8 +1141,10 @@ public:
         int depth = 32;

         for (int i = 0; i < devices.size(); ++i)
+        {
+            if (devices.getUnchecked(i)->device->getCurrentBitDepth())
                 depth = jmin (depth, devices.getUnchecked(i)->device->getCurrentBitDepth());

-
+        }
         return depth;
     }

(and it turns out a lot of mac have their default output set to 16-bit by default instead of using a higher bit depth... not good)

 

 

Although I understand almost nothing to the coreaudio api, it seems to work fine . Except that  when the device bit depth is changed "Audio MIDI Setup.app" , the juce listener is not notified of this changes, although it does listen to kAudioStreamPropertyPhysicalFormat in deviceListenerProc . Maybe it is because this is a kAudioStreamProperty and not a kAudioDeviceProperty , if that means anything..


#2

Thanks, I didn't realise that info was available, I'll add it.. TBH I've never really found a situation where it's useful to know this, but it's good to have it in there for completeness!


#3

I also thought it was not useful to know this, but recently had a few customers complaining about ugly hissing noise at the tail of some sounds on their macbooks. I first blamed the hardware, but it turned out the builtin output of their macs was set to 16bit depth, and it is relatively easy to trigger audible ("audible" depending also a lot on the headphones used) quantization noise with this bit depth as the system applies not dithering when converting to 16bits. So now I'm considering displaying a warning for those having their macs configured as 16-bits output.