AWS DeepComposer 🎹➡️☁️🎶

This year’s Amazon Web Services re:Invent conference in Las Vega, Nevada, was a veritable smorgasbord of announcements, product launches, previews, and a ton of information to try and digest at once.

One very exciting announcement was AWS DeepComposer – which continues to expand on AWS’ mission of “Putting machine learning in the hands of every developer”.
Here’s a slick intro video from the product announcement – come back after!

The service is still in Preview mode, and has an application/review process – so while I wait for the application to clear, I figured I’d poke around a bit and see what I got.

📦 Box Contents

The box. Not super impressive.
The box, open. More impressive.

Opening the box, I’m immediately reminded of a 1980s Casio Keyboard – we had one, and I enjoyed it a lot. This is larger, has no batteries or speakers.

The keyboard itself.

It’s a 32-key keyboard, while the key sizing isn’t 100% the same as that baby grand piano you have tucked somewhere in your vast mansion, it’ll probably be good enough.

The interface is USB Type B. I recently recycled roughly over 20 of these cables in an e-waste purge, thinking “I don’t have anything that uses this connection!” Well, now I do. It’s 2019 – I thought at least Micro USB, if not USB-C would have been the right choice?

Lucky for me, the box also contains a USB-A to USB-B cable, so at least that’s that.
Wait a minute… my 12-inch MacBook from 2016 that I’m using only has a single USB-C port.
Ruh-roh.
Apparently, I packed my USB-A to USB-C plug that I got with my Google Pixel 4 – let’s see if that will work! Even if it does, that means that I can’t use the DeepComposer and charge my laptop at the same time without an external port hub.
Considering that’s the only port (other than a 3.5mm audio jack) on my mac, I’m not too worried about it, especially since the battery is still pretty good.

There’s other packing materials, and a little card with a nice tagline of “Press play on ML” and a URL to visit: https://aws.amazon.com/startcomposing (redirects to the product page link – maybe a future device-specific landing page? Hmmm…)

⚡️ Power it up

I know I don’t have the provisioned account access yet, so I won’t be able to run all the things the presenter did in the video, so I figured I might poke around the connectivity interface and see what I might be able to glean in the absence of a proper setup.

Before I plug in the device, let’s also look at the current state of the Input/Output (I/O) devices, filtered specifically to the Apple USB Host Controller:

$ ioreg -w0 -rc AppleUSBHostController
+-o XHC1@14000000  <class AppleUSBXHCISPTLP, id 0x1000001dd, registered, matched, active, busy 0 (5263 ms), retain 55>
  | {
  |   "IOClass" = "AppleUSBXHCISPTLP"
  |   "kUSBSleepPortCurrentLimit" = 1500
  |   "IOPowerManagement" = {"ChildrenPowerState"=1,"DevicePowerState"=0,"CurrentPowerState"=1,"CapabilityFlags"=4,"MaxPowerState"=3,"DriverPowerState"=0}
  |   "IOProviderClass" = "IOPCIDevice"
  |   "IOProbeScore" = 1000
  |   "UsbRTD3Supported" = Yes
  |   "locationID" = 335544320
  |   "name" = <"XHC1">
  |   "64bit" = Yes
  |   "kUSBWakePortCurrentLimit" = 1500
  |   "IOPCIPauseCompatible" = Yes
  |   "device-properties" = {"acpi-device"="IOACPIPlatformDevice is not serializable","acpi-path"="IOACPIPlane:/_SB/PCI0@0/XHC1@140000"}
  |   "IOPCIPrimaryMatch" = "0x9d2f8086"
  |   "IOMatchCategory" = "IODefaultMatchCategory"
  |   "CFBundleIdentifier" = "com.apple.driver.usb.AppleUSBXHCIPCI"
  |   "Revision" = <0003>
  |   "IOGeneralInterest" = "IOCommand is not serializable"
  |   "IOPCITunnelCompatible" = Yes
  |   "controller-statistics" = {"kControllerStatIOCount"=78,"kControllerStatPowerStateTime"={"kPowerStateOff"="142ms (0%)","kPowerStateSleep"="40191894ms (99%)","kPowerStateOn"="75024ms (0%)","kPowerStateSuspended"="1332ms (0%)"},"kControllerStatSpuriousInterruptCount"=0}
  |   "kUSBSleepSupported" = Yes
  | }
  |
  +-o HS01@14100000  <class AppleUSB20XHCIPort, id 0x100000245, registered, matched, active, busy 0 (4773 ms), retain 13>
  +-o HS03@14200000  <class AppleUSB20XHCIPort, id 0x100000246, registered, matched, active, busy 0 (0 ms), retain 10>
  +-o HS04@14300000  <class AppleUSB20XHCIPort, id 0x100000249, registered, matched, active, busy 0 (0 ms), retain 10>
  +-o HS09@14400000  <class AppleUSB20XHCIPort, id 0x10000024c, registered, matched, active, busy 0 (0 ms), retain 9>
  +-o SSP1@14500000  <class AppleUSB30XHCIPort, id 0x10000024d, registered, matched, active, busy 0 (0 ms), retain 14>
  +-o SSP3@14600000  <class AppleUSB30XHCIPort, id 0x10000024e, registered, matched, active, busy 0 (0 ms), retain 12>
  +-o SSP4@14700000  <class AppleUSB30XHCIPort, id 0x10000024f, registered, matched, active, busy 0 (0 ms), retain 12>

A shorter version of this can be seen in the built-in System Information app, under the USB section.

Now I’m ready – let’s see what happens!

Plugging in, the first positive indication is that I see a series of red and blue LEDs briefly light up behind the top row of buttons, a quick cycle. So we know that at the very least, the little adapter is providing some power to the USB device.

Let’s look at the output of the I/O device state now:

$ ioreg -w0 -rc AppleUSBHostController
+-o XHC1@14000000  <class AppleUSBXHCISPTLP, id 0x1000001dd, registered, matched, active, busy 0 (7030 ms), retain 60>
  | {
  |   "IOClass" = "AppleUSBXHCISPTLP"
  |   "kUSBSleepPortCurrentLimit" = 1500
  |   "IOPowerManagement" = {"ChildrenPowerState"=3,"DevicePowerState"=2,"CurrentPowerState"=3,"CapabilityFlags"=32768,"MaxPowerState"=3,"DriverPowerState"=0}
  |   "IOProviderClass" = "IOPCIDevice"
  |   "IOProbeScore" = 1000
  |   "UsbRTD3Supported" = Yes
  |   "locationID" = 335544320
  |   "name" = <"XHC1">
  |   "64bit" = Yes
  |   "kUSBWakePortCurrentLimit" = 1500
  |   "IOPCIPauseCompatible" = Yes
  |   "device-properties" = {"acpi-device"="IOACPIPlatformDevice is not serializable","acpi-path"="IOACPIPlane:/_SB/PCI0@0/XHC1@140000"}
  |   "IOPCIPrimaryMatch" = "0x9d2f8086"
  |   "IOMatchCategory" = "IODefaultMatchCategory"
  |   "CFBundleIdentifier" = "com.apple.driver.usb.AppleUSBXHCIPCI"
  |   "Revision" = <0003>
  |   "IOGeneralInterest" = "IOCommand is not serializable"
  |   "IOPCITunnelCompatible" = Yes
  |   "controller-statistics" = {"kControllerStatIOCount"=104,"kControllerStatPowerStateTime"={"kPowerStateOff"="142ms (0%)","kPowerStateSleep"="40554314ms (99%)","kPowerStateOn"="245721ms (0%)","kPowerStateSuspended"="1333ms (0%)"},"kControllerStatSpuriousInterruptCount"=0}
  |   "kUSBSleepSupported" = Yes
  | }
  |
  +-o HS01@14100000  <class AppleUSB20XHCIPort, id 0x100000245, registered, matched, active, busy 0 (6540 ms), retain 18>
  | +-o AKM322@14100000  <class IOUSBHostDevice, id 0x100004670, registered, matched, active, busy 0 (1766 ms), retain 23>
  |   +-o AppleUSBHostLegacyClient  <class AppleUSBHostLegacyClient, id 0x100004673, !registered, !matched, active, busy 0, retain 9>
  |   +-o AppleUSBHostCompositeDevice  <class AppleUSBHostCompositeDevice, id 0x10000467b, !registered, !matched, active, busy 0, retain 4>
  |   +-o IOUSBHostInterface@0  <class IOUSBHostInterface, id 0x10000467d, registered, matched, active, busy 0 (3 ms), retain 6>
  |   +-o IOUSBHostInterface@1  <class IOUSBHostInterface, id 0x10000467e, registered, matched, active, busy 0 (3 ms), retain 6>
  +-o HS03@14200000  <class AppleUSB20XHCIPort, id 0x100000246, registered, matched, active, busy 0 (0 ms), retain 10>
  +-o HS04@14300000  <class AppleUSB20XHCIPort, id 0x100000249, registered, matched, active, busy 0 (0 ms), retain 10>
  +-o HS09@14400000  <class AppleUSB20XHCIPort, id 0x10000024c, registered, matched, active, busy 0 (0 ms), retain 9>
  +-o SSP1@14500000  <class AppleUSB30XHCIPort, id 0x10000024d, registered, matched, active, busy 0 (0 ms), retain 14>
  +-o SSP3@14600000  <class AppleUSB30XHCIPort, id 0x10000024e, registered, matched, active, busy 0 (0 ms), retain 12>
  +-o SSP4@14700000  <class AppleUSB30XHCIPort, id 0x10000024f, registered, matched, active, busy 0 (0 ms), retain 12>

Again, this is pretty verbose, but if you look closely, you’ll see that the device at address HS01@14100000 now has a sub-device associated with it – AKM322@14100000.

Yay! We can see that the device is powered, and the system registers it.

What is this thing??

A quick search for the device prefix string “AKM322” brought be to a device similar in nature:
https://www.amazon.com/midiplus-32-Key-Keyboard-Controller-AKM322/dp/B016O5F2GQ
Here’s the listing for the DeepComposer device: https://www.amazon.com/AWS-DeepComposer-learning-enabled-keyboard-developers/dp/B07YGZ4V5B/

If you’re asking – “why the price difference?”, well the DeepComposer device comes with some cloud features too!

We want you to know:
To train your models and create new musical compositions, AWS DeepComposer is priced at $99, this includes the keyboard, plus a 3-month free trial of AWS DeepComposer services to train your models and create original musical compositions. Each month of the free trail includes enough to cover up to 4 training jobs and 40 inference jobs per month, during the free trial period.

So for the dollar value, you’re getting not only the device, but also some AWS Cloud Goodness!

Visiting what appears to be the manufacturer’s page, we can see more details about the hardware, so that’s cool. It’s a MIDI device, translating analog signals (like pressing keys for with different pressures and durations) into digital signals.
Cool stuff! There might be some secret AWS goodness in the DeepComposer model – we’ll have to wait and see.

Make some noise!!

Again, I don’t yet have access to the DeepComposer interface, so I found a macOS MIDI testing guide that I followed: https://support.apple.com/en-gb/HT201840

The test was successful, but I only got a single note “ding” response, confirming that the device works, can communicate back to my computer. But I want to hear something!

Apple produces Logic Pro – but at a $199 price tag, I don’t really want to spend that just to mess around until I can really try out the DeepComposer service.
Apple also produces GarageBand – for free! Fire it up, and wait for the 2GB download to complete over hotel wifi. This is also where I unplug the keyboard, and plug in the power – since we’re going to be here for a while…

I’ll check back once I’ve got some more details to report. Hope you enjoyed this set of musings, and hopefully I’ll have more to show you soon!

Other Reading

There’s not too much out there just yet – as this is a preview service, just announced.
I posted a link to a video of the original announcement, and you can also read some of the announcement blog post details here:

https://aws.amazon.com/blogs/aws/aws-deepcomposer-compose-music-with-generative-machine-learning-models/