Enabling/Disabling USB Audio at runtime

Davidelvig

Well-known member
I have a USB audio output at the end of my audio chain (as well as I2S to the SGTL5000)

once define in the design tool, and instantiated at the top of my code file, is there any way to disable that USB Audio at runtime, so that it would cease to be seen by a connected USB host as an Audio input?

Alternatively, could it be enabled at runtime?
 
Without modifying the library source code, you could insert a queue object, which has a begin() and end() method. It may do what you wanted.
 
I've done more testing.

iPad (9th generation) with iOS 18.1.1
GarageBand

USB Camera Adaptor
My Teensy 4.1-based MIDI controller

With USB_MIDI_SERIAL defined
I can send USB MIDI and the GarageBand receives and plays it.

With USB_MIDI_AUDIO_SERIAL defined
No luck.

I've tried these things:
  • with USB_MIDI_AUDIO_SERIAL still defined, removing the AudioOutputUSB object and any references
  • in USB_AUDIO.H, commenting out the begin() statement in
    AudioOutputUSB(void) : AudioStream(2, inputQueueArray) { begin(); }
One app on the iPad (ThumbJam) still seem so t"see" the controller as a MIDI input and output, but does not respond to play i.e. when messages are being sent).

So, at the moment, I can:
  1. Use USB Audio; or
  2. Allow USB MIDI to iPads
with different firmware builds.

I expect the hook to USB Audio comes in instantiation of classes, before loop() is called.

Any ideas for how to get the best of both worlds?

(BTW, the Apple USB Camera adaptor appears key to USB MIDI to the iPad. A standard USB C to Lightning does not result in a detected MIDI controller.)
 
I think I'm seeing the light.
If anyone is groking this and can confirm or deny assumptions, I'd welcome it:

  1. Teensy's USB Audio, when enabled through a define, becomes the equivalent of a stereo USB Microphone and USB headphones
  2. When plugged in to a Mac, the Teensy's USB audio IO becomes available to any app on the Mac
  3. Applications (zoom, GarageBand) may decide to attach themselves automatically to that new device upon its plugin
Is that all correct?
 
I've done some work with trying to do the equivalent of a virtual disconnect and reconnect of the USB devices (including audio) and never been able to quite get it working cleanly across multiple operating systems. I wonder if to truly simulate it perfectly you need to pull the VBUS line low with an open-drain driver or something on the PCB.

On to your other questions, yes the teensy will appear as a USB audio device (just like an USB audio interface with audio input and output. I'm not sure I'd go as far as to say it declares it'self as a microphone and headphones specifically, but don't quote me on that.)

As a result, yes it can interfere with other applications, but that's they're programming. Some applications assume when a new audio device is suddenly connected, you intended to use it so it switches. This happens all the time for me on Aviate Audio Multiverse (Teensy based) engineering calls where I plug in the pedal and I lose my mic. Again, this isn't a Teensy issue, it's how the Zoom developers chose to behave with USB aidop connects.
 
I have a USB audio output at the end of my audio chain (as well as I2S to the SGTL5000)

once define in the design tool, and instantiated at the top of my code file, is there any way to disable that USB Audio at runtime, so that it would cease to be seen by a connected USB host as an Audio input?

Alternatively, could it be enabled at runtime?
You can simply disconnect or reconnect the patch cords to the USB output object, as is done in the following code fragments for an I2S input object:

// I2S Signal In AudioInputI2S audioLineIn; . . . // setEnabled // // Enable/disable module's LR input signals // void AudioInput::setEnabled(bool state) { if (state) { enabled = true; audioInToGainLeft.connect(audioLineIn, 0, gainLeft, 0); audioInToGainRight.connect(audioLineIn, 1, gainRight, 0); } else { enabled = false; audioInToGainLeft.disconnect(); audioInToGainRight.disconnect(); } }
 
You can simply disconnect or reconnect the patch cords to the USB output object, as is done in the following code fragments for an I2S input object:

// I2S Signal In AudioInputI2S audioLineIn; // Gain amplifiers set output gain AudioAmplifier gainLeft; AudioAmplifier gainRight; // Line In gain [0.0,1.0] float inputGain; const float inputGainDefault = 1.0; // Unity gain (0 dB) // Inter-module patch cords AudioConnection audioInToGainLeft; AudioConnection audioInToGainRight; . . . // setEnabled // // Enable/disable module's LR input signals // void AudioInput::setEnabled(bool state) { if (state) { enabled = true; audioInToGainLeft.connect(audioLineIn, 0, gainLeft, 0); audioInToGainRight.connect(audioLineIn, 1, gainRight, 0); } else { enabled = false; audioInToGainLeft.disconnect(); audioInToGainRight.disconnect(); } }
 
Back
Top