MacOS – How to always use macbook microphone with Bose QuietComfort 35

audioheadphonesmacosmicrophone

I have noise canceling headphones (Bose QC 35), that also have microphone built-in. If the microphone is active, noise canceling doesn't work, they just pass through ambient sounds (this is by design. I suppose, they did it so you wouldn't feel that you're in "vacuum" when you are talking).

Anyway, the problem is that whenever I connect my headphones to macOS, the system switches from internal microphone to headphones' one. Therefore, noise canceling doesn't work, unless I go to system settings and switch microphone back to the internal one.

This is very annoying, especially considering that I have to do that every time I connect headphones.

Is there any way to force macOS to always use internal microphone, or not to use the specific headphones' one?

Update from 10/2017:

So I found out that "headphones' microphone is being used" only happens when Skype is running. But ever since I stopped using Skype (or having it running all the time), the problem was gone!

This is not the solution for the original question, I'm just leaving it here for the future reference.

Best Answer

I'm not sure how practical this is (I haven't had the chance to measure CPU usage, etc.), but the below AppleScript will do the job—just replace [YOUR HEADPHONES' NAME] with the actual name of your headphones. This is a modified version of a script from an Apple Support Communities thread.

Save the script below as an application, run it, and add it to your startup items—it should run continuously in the background.

repeat
    set statusOld to checkStatus()
    set statusNew to checkStatus()
    repeat while statusOld is equal to statusNew
        delay 5 --for 5 second checks
        set statusNew to checkStatus()
    end repeat
    if statusNew is true then
        tell application "System Preferences" to activate
        tell application "System Preferences"
            reveal anchor "input" of pane id "com.apple.preference.sound"
        end tell
        delay 0.5
        tell application "System Events" to tell process "System Preferences"
            tell table 1 of scroll area 1 of tab group 1 of window 1
                select (row 1 where value of text field 1 is "Internal Microphone")
            end tell
        end tell
        tell application "System Preferences" to quit
    else
        -- Nothing needs to happen, the device was removed
    end if
end repeat

on checkStatus()
    set bluetoothDeviceName to "[YOUR HEADPHONES' NAME]"
    set myString to do shell script "system_profiler SPBluetoothDataType"

    --initial check if it's not even there
    if myString does not contain bluetoothDeviceName then
        return false
    else

        --find out if connected/disconnected
        set AppleScript's text item delimiters to "name:"
        set myList to the text items of myString --each item of mylist is now one of the devices

        set numberOfDevices to count of myList
        set counter to 1
        repeat numberOfDevices times --loop through each devices checking for Connected string
            if item counter of myList contains bluetoothDeviceName then
                if item counter of myList contains "Connected: Yes" then
                    return true
                else if item counter of myList contains "Connected: No" then
                    return false
                else
                    display dialog "Something went wrong with the script" --this shouldn't happen
                end if
            end if
            set counter to counter + 1
        end repeat
    end if
end checkStatus

You could play with the time between checks (the line with the comment for 5 second checks) to reduce resource consumption.

There are a number of new APIs (especially in AVFoundation) coming to macOS High Sierra that would allow for a much cleaner solution to this problem. If you're comfortable with Swift or Objective-C (or the Cocoa scripting bridge in AppleScript and JXA), I would look into using those APIs instead of this script once High Sierra is released. In particular, Apple's Audio Session Programming Guide and this Stack Overflow post show some techniques of detecting Bluetooth connections using AVAudioSession.