Additional audio output for Teensy 4.1

Sandro

Well-known member
Dear Audio Library developers, actually AudioOutputPWM does not support Teensy 4.1: is there any chance for this feature? I'm using a T41 @600MHz + Audio Board for the main audio in/out, but I also need an additional audio output (even mono, even 8-10 bit
should be fine) compatible with the presence of the Audio Board.
Thanks in advance!
 
This is a simple modification that allows the teensy to act as a speaker. This can be used to play music from your phone through the speakers on the teensy.
 
Have you tried MQS? It's pretty much PWM with some extra features to improve quality.

Thank you Paul for replying; I read about MQS, my dubt is about the possible "overload" of the SPI0 bus (used by MSQ, if I don't mistake) that will be shared with a Flash memory chip (intensively used both for write and read)... ok, it's only a dubt .. I have no idea of the amount of time the SPI bus is busy.. ok, I will check MSQ! :)
 
More dubts: SPI0 is used as kind of PWM by MQS, so should be incompatible with any other device on it..
 
Indeed MSQ consumes the SPI pins which connect to the SD socket on the audio shield.

The SD socket on Teensy 4.1 will still work. And it's much faster, because it uses dedicated SDIO rather than SPI.

If you *really* need SPI for SD card and MQS, with 3 wires you could connect the SD card to SPI1 (pins 1, 26, 27). See this example for the way to make the SD library access a different SPI port.

https://github.com/PaulStoffregen/S...6d71/examples/SdFat_Usage/SdFat_Usage.ino#L54
 
Indeed MSQ consumes the SPI pins which connect to the SD socket on the audio shield.

The SD socket on Teensy 4.1 will still work. And it's much faster, because it uses dedicated SDIO rather than SPI.

If you *really* need SPI for SD card and MQS, with 3 wires you could connect the SD card to SPI1 (pins 1, 26, 27). See this example for the way to make the SD library access a different SPI port.

https://github.com/PaulStoffregen/S...6d71/examples/SdFat_Usage/SdFat_Usage.ino#L54

I'm using SPI0 for Flash chip (not the SD card) but I assume the issue is the same... So, actually I have:
- Flash chip on SPI0
- SPI Display on SPI1

(both cannot share the same SPI bus, because flash memory reading performance degrades too much).. Maybe I could move the Flash chip to SPI2..
 
I'm using SPI0 for Flash chip (not the SD card) but I assume the issue is the same... So, actually I have:
- Flash chip on SPI0
- SPI Display on SPI1

(both cannot share the same SPI bus, because flash memory reading performance degrades too much).. Maybe I could move the Flash chip to SPI2..

Noway... I'm using SPI2 for n.2 PSRAM chips... Uff!! :/
 
The PSRAM chips use FlexSPI2, not SPI2, so you should still have SPI2 available.

FlexSPI is completely different and separate from normal SPI.
 
What is the status of the AudioOutputPWM for T4? I noted a commented out section in output_pwm.cpp and uncommented it,
getting some output, but mainly noise apparently. Basically is this a reasonable small bit of work that I could attempt?
 
What is the status of the AudioOutputPWM for T4?

On a long list of very low priority features.


I noted a commented out section in output_pwm.cpp and uncommented it,
getting some output, but mainly noise apparently. Basically is this a reasonable small bit of work that I could attempt?

Frank contributed that code, then decided it wasn't ready. I haven't used it, so I really don't know.

Sure, if you can get it working reasonably well, please send a pull request. Also please know I'm months behind on Audio. Planning to merge lots of contributions next week, then (hopefully) get back to MTP the following week. If you can keep all your changes within output_pwm.cpp and output_pwm.h and contained within #ifdef for Teensy 4, then I'll consider it low risk and merge for 1.57. If more changes are needed elsewhere in the library, it might wait for 1.58.
 
I think I've found the issues - cache flushed on wrong addresses, and no guard to prevent double calling of update_all().

Will try to put a pull-request together.

Yup, done that: https://github.com/PaulStoffregen/Audio/pull/432

Some 'scope output with rough low-pass filtering on the pins:
audio_pwm_output_T4.png
 
Last edited:
I've manged to test it on pins 0 to 9 relatively successfully so far, but some combinations reverse the relative polarity of the PWM on
the two output pins (which are coarse and fine outputs - I'll still need to look into this.

I didn't seem to be able to fire it up on pin 10, though I don't think I was using SPI (just AudioOutputPWM and AudioSynthWaveform
objects, Serial and pin 13 to blink an LED).
 
OK a little more investigation - I'd forgotten to check which pins use FlexPWM - on the T4 its 0--9, 22 and 23 only (not counting the SMT pads on the underside).

Of these pins 0, 1 have their register polarity reversed compared to the others and the AudioOutputPWM code doesn't account for this yet. So long as you don't mix {0,1}
with {2,3,4,5,6,7,8,9,22,23} you shouldn't see reversed relative polarity.

Adding support for QuadTimer based PWM pins is another matter though...
 
I've found another issue - when the two pins are on the same FlexPWM unit and submodule they clash and it won't work,
specifically these 3 pairs of pins will not work:

2,3
6,9
7,8

So don't use these in the begin(pina, pinb) call.

The issue will be that the code is trying to setup two DMA actions on the one submodule I suspect - I'll have a look at this, no idea
if this is a simple fix or not.

The inversion issue I mentioned before can be fixed BTW, once I've done some more investigation I'll create another pull req.
 
Looking at how DMA multiplexing works it appears you can't trigger multiple DMA channels from the same source, meaning
that two pins on the same FlexPWM submodule cannot both be driven by DMA - I tried using the triggerAtTransfersOf() method
to trigger one DMA from the other but that didn't seem to work.

So I can do a workaround that simply doesn't drive the LSB pin at all in this circumstance, reducing the precision to 8 bit.

Another thought is that it ought to be easy to do a noise-shaped PWM output class running at higher frequency which can
get good precision on a single pin. Many class D amps work around 300kHz or so so 8 PWM cycles per 44.1k sample might
be plausible for this (352.8kHz).
 
Hi MarkT I tried the new object downloaded from https://github.com/PaulStoffregen/Audio/pull/432; I didn't modify the begin call:
void AudioOutputPWM::begin(void) { begin(3, 4); }
and connected pins 3, 4 from T41 to the raccomanded filter:

PWM.jpg

than I uploaded a test sketch (Guitar.ino) with the output routed to the AudioOutputPWM, but what I get is only a kind of white noise. I set CPU speed ad 600MHz, also tried lower speeds but nothing seems change.
 
Last edited:
Just tried that and it should be fine - perhaps you swapped the resistors - the LSB output will sound like white noise if its not 256 times lower in
amplitude than the MSB output (pin 3). You diagram looks right, perhaps wrong resistor (I always check with a meter just to be sure with banded
resistors).

Try with pin 4 not connected to be doubly sure.
 
Yes MarkT, the resistors I used had not the same values of the schematics, I neglected they are critical; I tried with the only MSB connected, as you suggested, and it works fine! Now I can route the audio stream both to Audio Shield and to PWM; tomorrow I'll swap the resistors with new ones with more correct values and check what happens integrating PWM output in my project....Thank you so much for your precious help!!
 
Hi MarkT, I just replaced the resistors, now their values are the same of the schematics above.. But it doesn't change much: looks like only pin3 is significant, pin4 only adds noise... I also tried different couple of pins in output_pwm.cpp :
void AudioOutputPWM::begin(void) { begin(5, 6); }

but the result is the same, only the first signal/pin seems usefull.
I'll check with onother T41 and with a T40... let's see...
 
Last edited:
As I said the second pin needs to be at 1/256 times the level to work, anything else and yes it will add noise. If you look at the
'scope shot I posted above you can see the second pin output contains the detail part of the waveform which has to be squashed to 1 step
of the main pin to add detail correctly.
But if you can live with 8-bit quality the main pin may be enough.
 
Hi MarkT, my waveform is very different; this is the test code:

Code:
#include <Audio.h>
AudioSynthWaveformSine   Tone;
AudioOutputPWM           PWM;
AudioConnection          patchCord1(Tone, 0, PWM, 0);

void setup()
{
  AudioMemory(5);
  Tone.amplitude(1.0);
  Tone.frequency(1000);
}

void loop()
{
}


And this is the output with its FFT:
PWM_SCOPE_1.jpg

Filter components are: pin3 --> 468, pin4 --> 120K, ceramic: 10nF, electrolitic: 10uF. I'm surely doing some huge mistake, I'll find it.
But now I'm writing for a more important issue; I inserted the AudioOutputPWM object in my code where, among other stuff, I also use the standard MIDI.h library (only for reading MIDI, on pin 0), and everything blocks: do you know if there is some incompatibility between AudioOutputPWM.h and MIDI.h?
 
Last edited:
Back
Top