Categories
Uncategorized

Enabling AAC and AptX over Bluetooth on MacOS

I recently purchased a pair of Sony MDR-1000X Bluetooth noise-cancelling headphones. Although I usually prefer Sennheiser headphones (my previous pair of NC headphones was the Sennheiser Momentum Wireless 2 (aka HD-1)), I went with the Sony due to their support of the AAC codec, as my primary devices are all Apple.

By default on OS X and MacOS, the headphones will connect with the SBC codec when playing audio. (And occasionally a fallback to the low-quality SCO streaming codec for some voice-chat apps like Cisco Jabber) The OS does support aptX and AAC over bluetooth, but you have to jump through some hoops to enable them. Why? who knows. My best guess is that it is becuase SBC is the universally supported (and required) codec for the A2DP Bluetooth audio profile, and using that maximizes compatibility and minimizes customer complaints. If you can’t reliably detect what a headset supports, then the lowest common denominator is the safe choice.

AirPods however do automatically use the AAC codec without the user having to set any options.


Update 4 Dec 2017:

Thanks to Anders Carling in the comments, looks like there is a much easier way to check and update these settings.

Open Terminal and enter “sudo defaults read bluetoothaudiod” and type in your password when prompted. You should then see the current settings:

"AAC Bitrate" = 128;
"AAC CBR" = 0;
"Apple Bitpool Max" = 64;
"Apple Bitpool Min" = 2;
"Apple Initial Bitpool" = 40;
"Disable HFP" = 0;
"Enable AAC codec" = 1;
"Enable AptX codec" = 0;

If you get an error “Domain bluetoothaudiod does not exist”, that means none of these settings have been set before, update the setting as shown below and you’ll be able to read the setting as outlined above.

To update these settings in the Terminal:

to enable AptX:

sudo defaults write bluetoothaudiod "Enable AptX codec" -bool true

to enable AAC:

sudo defaults write bluetoothaudiod "Enable AAC codec" -bool true

To disable either one, just change “-bool true” to “-bool false” at the end of the command.


Here’s the original method, still handy in case you want a GUI to toggle the settings:

To enable aptX or AAC support, you need to get a copy of Apple’s Bluetooth Explorer development utility.

Go to the Apple developer downloads page – you will need to register a developer account if you don’t already have one.

Search for “Additional Tools for Xcode” – at the time of this writing, the latest released version is for Xcode 9.0. This will download a .dmg file that contains “Bluetooth Explorer.app” – this is the only file you need, move it anywhere, and you can delete the rest.

If you’re already logged in to the developer site, you can also use this direct link for the 9.0 version:

https://download.developer.apple.com/Developer_Tools/Additional_Tools_for_Xcode_9/Additional_Tools_for_Xcode_9.dmg

For older versions you’ll get “Hardware IO Tools for Xcode 7.3”

Run Bluetooth Explorer, then go to Tools>Audio Options. Select “Enable AAC”. If you have an aptX-only device you can enable that here as well. If your headset is already connected, disconnect and reconnect. You don’t need to re-pair the device.

Once you’re reconnected, you can verify which codec you’re connecting with by enabling the Bluetooth menu bar icon (System Preferences >Bluetooth>Show Bluetooth in menu bar), then holding down option and clicking the Bluetooth menu bar icon and navigating to the headphones entry.

That’s it. You’ll be running the improved wireless codec, and should notice a definite improvement.

 

Categories
Sci-Fi

Star Wars Headspace and ATTLAS’ “Sunset Over Manaan”

Although it had been released a while earlier, I didn’t notice the Star Wars Headspace album until seeing the vinyl at Star Wars Celebration. It’s an interesting electronic album – it is not remixes of Star Wars music, but new music in a Star Wars theme, with quotes and sound clips from the movies throughout. It bounces around several styles, like downtempo, trap, house, and ambient. Overall worth a listen.

This track in particular, which is on the downtempo/ambient side has been stuck in my head for a week. It’s a gorgeous song – starts out dark and melancholy, building to a slight tense middle that reminds me a little of BT’s “The Antikythera Mechanism” with its quick instrumental chops, then becoming positive and wistful towards the end. You might think I’m imagining a bit much with this tune, but close your eyes and give this a quiet listen and you just might hear it as well.

ATTLAS – Sunset Over Manaan

Categories
Software Development

Command line argument parsing in .NET Core with Microsoft.Extensions.CommandLineUtils

In a recent .NET Standard/Core based library, I found myself needing to include some command line tooling. I never found a command line argument parsing library I really liked for full .NET Framework apps, so I decided to hunt for any new possibilities for a netcoreapp. Happily I found a very nice little utility that’s used natively by the dotnet CLI – The Microsoft.Extensions.CommandLineUtils package. Unfortunately there doesn’t seem to be any official documentation or much in the way of complete examples, so I thought I’d share what I’ve set up as a template for my own projects.

To just jump right in, I’ve created a example project you can try out:
https://github.com/anthonyreilly/ConsoleArgs

If you want to take a deep dive, Microsoft’s has a sources package on GitHub:  Microsoft.Extensions.CommandLineUtils.Sources

This walkthrough is using a simplified version of the example application – see the version in Github for additional comments and and options.

static void Main(string[] args)
{
    var app = new CommandLineApplication();
    app.Name = "ConsoleArgs";
    app.Description = ".NET Core console app with argument parsing.";

    app.HelpOption("-?|-h|--help");

    var basicOption = app.Option("-o|--option<optionvalue>",
            "Some option value",
            CommandOptionType.SingleValue);

    app.OnExecute(() => {
        if (basicOption.HasValue()) {
            Console.WriteLine("Option was selected, value: {0}", basicOption.Value());
        }
        else {
            app.ShowHint();
        }

        return 0;
    });

    app.Command("simple-command", (command) => {
            command.Description = "This is the description for simple-command.";
            command.HelpOption("-?|-h|--help");

            command.OnExecute(() => {
                Console.WriteLine("simple-command has finished.");
                return 0;
            });
    });

    app.Execute(args);
}

You start off by initializing the application:

var app = new CommandLineApplication();
app.Name = "ConsoleArgs";
app.Description = ".NET Core console app with argument parsing.";
app.HelpOption("-?|-h|--help");

Name should be the name of the executable itself, Description is used in the help text, and then HelpOption enables the help option and help text output.

You can then set the available arguments and options.

var basicOption = app.Option("-o|--option<optionvalue>",
   "Some option value",
   CommandOptionType.SingleValue);

The example project has some examples of Arguments, but Options is the way to go. You pass in the template, which specifies the name of the option and it’s help text at the same time.

Breaking down the template, you start with a pipe-delimited list of option flags, here we’re using -o and —option, which is a common convention: a dash and single letter, or a double-dash and a name. You can list just one, or many flags to use as needed.

After the list is a space, and then a text description of what to pass in. Here we’re using “<optionvalue>” but this is optional. The dotnet CLI seems to skip this, and just rely on the help text in the description to explain to the user what to enter after the option.

Second is a description for the help text. Finally, you set the option’s type, as a choice of NoValue (a boolean type flag), SingleValue, or MultipleValue. There are examples of each in the project.

Options can be passed with or without an equals sign (=) or enclosing quotes, although quotes are needed when passing values with spaces or delimiters.

-o value
-o=value
-o=”value”
-o “value”
-o=”value one two three”

You then create a function and pass it into OnExecute() that will parse the options and execute the work.

app.OnExecute(() =&amp;gt; {
   if (basicOption.HasValue()) {
      Console.WriteLine("Option was selected, value: {0}", basicOption.Value());
   }
   else {
      app.ShowHint();
   }

   return 0;
});

This is basically the default “command”. For a single-task kind of application you may not need more than this, but if you’re familiar with the dotnet CLI, you can do the same command/option pattern and add additional commands that in turn can have their own options and arguments.

Here we add an additional simple command, that does not have any options:

app.Command("simple-command", (command) =&amp;gt; {
   command.Description = "This is the description for simple-command.";
   command.HelpOption("-?|-h|--help");

   command.OnExecute(() =&amp;gt; {
   Console.WriteLine("simple-command has finished.");
   return 0;
  });
});

Within this new command, you can add additional options and commands as needed.

Finally, you need to actually start the application, and pass in the raw, standard command line arguments array for the utility to parse and execute the commands:

app.Execute(args);

One of my favorite things about this utility, and a great help to UX, the help text is automatically formatted for you using the Name, Description, and ExtendedHelpText properties specified in the code. If you run the full example, you’ll get something like this:

Usage: ConsoleArgs [arguments] [options] [command]

Arguments:
  argOne  App argument one
  argTwo  App argument two

Options:
  -?|-h|--help               Show help information
  -o|--option  Some option value

Commands:
  complex-command  This is the description for complex-command.
  simple-command   This is the description for simple-command.

Use "ConsoleArgs [command] --help" for more information about a command.
This is a sample console app to demostrate the usage of Microsoft.Extensions.CommandLineUtils.
Depending on your OS, you may need to execute the application as ConsoleArgs.exe or 'dotnet ConsoleArgs.dll'

With relatively little effort, you can whip up a console application with some nice user-friendly polish.

Check out the complete example here for a more complex setup and additional explanations.

Update 2017-07-31: Looks like the ASP.NET Core team has decided against publishing this package on NuGet with 2.0.0 – but it will still be available as source for you to integrate and compile yourself (See this GitHub commit message )

Stop producing Microsoft.Extensions.CommandLineUtils
This library was only intended for usage with ASP.NET Core’s tools, and not a general purpose library. After receiving bugs and questions about this, we realized that we didn’t really intend to produce and support a command-line parsing library.
We will still leave the 1.0.0 and 1.1.0 versions of this library on NuGet.org, but the current plan is to stop producing new versions of this package.
The source code is still available for internal use via Microsoft.Extensions.CommandLineUtils.Sources, however we will not be publishing this library again as a general purpose library.

Update 2017-11-01:  Good news – this has been forked as a community project, per Ben Brandt at knightlycode.com:

Nate McMaster, a software engineer on the ASP.NET Core project, has since forked the project as a community project in his free time: “This is a fork of Microsoft.Extensions.CommandLineUtils, which is no longer under active development. This fork, on the other hand, will continue release updates and take contributions.”

https://github.com/natemcmaster/CommandLineUtils

One of the interesting new features Nate has added is the parsing of response files for the command line parameters. Things are looking up.

Categories
Sci-Fi

Star Wars Celebration Orlando 2017

This past weekend, I went to Star Wars Celebration Orlando. The first day saw some terribly mismanaged queue organization resulting in multi-hour waits. The organizers, ReedPOP, did respond and improved the line organization on Friday, leading to much smoother queues as the weekend went on. It seemed that the main reason was the last-minute addition of bag checks and a small number of metal detectors, creating a bottleneck of a single small entrance in a facility that usually offers dozens of entrances for attendees.

This was a record-setting event in terms of attendance, which is saying something considering the the Orange County Convention Center is the 2nd largest facility of it’s kind in the US. Massive crowds, but an amazing experience throughout. My only regret is not ordering tickets earlier and planning a full 4-day stay.

The list of guests was impressive, and a long list of high-demand panels made it a difficult event to take in all at once.

The next Celebration is tentatively scheduled for 2019, and hopefully for that one I’ll go all-in.