Is there a way to automatically adjust EQ settings when the audio output changes?

Solution 1:

Reading the current audio output gives "Built-in Output" for both headphones and internal speakers, however we need to be able to tell between headphones and speakers. In order to do this, you can use code from this answer to create a program that checks whether headphones are plugged in or another audio output is in use:

#include <CoreAudio/CoreAudio.h>
#include <iostream>

void updateEQ() {
    AudioDeviceID defaultDevice = 0;
    UInt32 defaultSize = sizeof(AudioDeviceID);

    const AudioObjectPropertyAddress defaultAddr = {
        kAudioHardwarePropertyDefaultOutputDevice,
        kAudioObjectPropertyScopeGlobal,
        kAudioObjectPropertyElementMaster
    };

    AudioObjectGetPropertyData(kAudioObjectSystemObject, &defaultAddr, 0, NULL, &defaultSize, &defaultDevice);

    AudioObjectPropertyAddress property;
    property.mSelector = kAudioDevicePropertyDataSource;
    property.mScope = kAudioDevicePropertyScopeOutput;
    property.mElement = kAudioObjectPropertyElementMaster;

    UInt32 dataSourceId = 0;
    UInt32 dataSourceIdSize = sizeof(UInt32);

    AudioObjectGetPropertyData(defaultDevice, &property, 0, NULL, &dataSourceIdSize, &dataSourceId);

    if (dataSourceId == 'hdpn') {
        std::cout << "Changed to headphones" << std::endl;
        system("osascript <<path to speaker EQ script>>");
    } else {
        std::cout << "Changed to not headphones" << std::endl;
        system("osascript <<path to other EQ script>>");
    }
}


int main(int argc, const char * argv[])
{
    updateEQ();
    return 0;
}

Each EQ script is then a simple AppleScript script that updates iTunes's EQ, for example the speaker EQ script is:

tell application "iTunes"
    set current EQ preset to (get first EQ preset whose name is "Speakers")
    set EQ enabled to true
end tell