Hey Arduino and MCU Lovers! I recently thought about implementing a small I2S Arduino program to output a sine or pulse wave, because I have trouble doing so with my university project MCUs...
However as much I can read the Arduino I2S Library reference Link:https://www.arduino.cc/en/Reference/I2S refers only to SAMD21 based boards. But why? Why there is this restriction. As much as I know to implement the I2S protocol you only have to make sure the right Data Pins are on the correct values for the correct times.
So you have a "Word Select (WS)", a "Serial Clock (SCK)" and a "Serial Data (SD)" Pin which you control in an interrupt routine which be fired at the frequency See:https://en.wikipedia.org/wiki/I²S
The 2 at the end is because you need 2 Interrupts to transfer 1 Bit of Data. 1 Interrupt for the clock to get high and 1 interrupt for it to get low. So you need twice as many interrupts for this as your bit cock frequency.
And again. I don't understand why this restriction exists and hope someone which better understand of hard or software could maybe give me a quick tipp
As far as I know you can not bit bang an I2S interface, you need special hardware on the processor that will implement it with the correct output impedance.
Wikipedia says:-
The I²S connection was not intended to be used via cables, and most integrated circuits will not have the correct impedance for coaxial cables. As the impedance adaptation error, associate with the different line length, can cause difference of propagation delay between the clocks line and data line, this can result in synchronization problem between the SCK, WS and data signals, mainly at high sampling frequency and bitrate. As the I²S doesn't have any error detection mechanism, this can cause important decoding error.
gruftgrabbler:
However as much I can read the Arduino I2S Library reference Link:https://www.arduino.cc/en/Reference/I2S refers only to SAMD21 based boards. But why? Why there is this restriction.
Because most other Arduino boards don't have an I2S hardware peripheral.
Have you tried plugging some numbers into that formula?
For "CD quality" audio, you need a data rate of 44.1 kHz at 16 bits per word, for two channels, which means the bit clock has to be around 2.8 MHz. On a typical AVR-based Arduino, that's 5 clock cycles, which is way too little to do anything useful.
Even on faster CPUs, you don't want to handle interrupts at 2.8 MHz, context switches take time. The only reasonable way to pump out that amount of data without locking up your entire CPU is by using DMA (direct memory access), another feature many Arduinos lack.
You could try bit-banging the I2S pins at a much lower rate, but even then you might run into trouble. DACs often contain digital interpolation filters and sigma-delta modulators, and these need a clean clock signal at a rate much higher than the bit clock.
Some DACs generate this clock themselves based on the bit clock using a PLL, but that requires a stable bit clock, often in a specific frequency range, which is hard to achieve if you're doing it in software.
If you want to use I2S, get a board with I2S hardware peripherals and DMA support. The software support for SAMD21 Arduino boards is very lacking. I'd recommend using a Teensy or an ESP32 instead. On Teensy, you can use the Teensy Audio library, on ESP32, you can use the ESP-ADF.
The comment was mostly about I2S. Maybe I haven't found the right resources yet, but the "Audio project" support for Teensy boards is much better in my experience: the Audio library is really powerful and easy to use, and there's an active community over at the PJRC forums as well.
I don't think there are many beginner-friendly resources available for I2S and DMA in general, but I think the main difference is that with the Audio library, everything happens behind the scenes without having to worry about it, whereas if you look at the examples for the other I2S libraries (Arduino or Adafruit), the basic examples are too basic to be useful, and to successfully integrate it with other audio components, you pretty much have to dig into the library source and really understand most of it.
Thanks! I was wondering because, although Teensy's software support is always excellent, I haven't gotten the same impression from my limited experience with ESP32. Meanwhile, the SAMD support seems to be getting really good now. However, I don't have a lot of experience with audio applications, and none with I2S (though I did recently get an I2S mic and amp so that I can start playing with it).
pert:
I haven't gotten the same impression from my limited experience with ESP32.
You're right, I think the ESP32 is generally less beginner friendly. On the other hand, it's a very popular board and its features are well-documented.
For example, the Programming Guide, the documentation and the many examples in the ESP-ADF (Espressif Audio Development Framework).
It's not quite on the same level as the Teensy Audio library, and definitely not as easy to use, but it's a good choice for a more serious audio project.
pert:
Meanwhile, the SAMD support seems to be getting really good now. However, I don't have a lot of experience with audio applications, and none with I2S
Indeed, but I think I2S is simply too advanced and too niche (for now at least). And I don't blame the Arduino developers at all for not focusing on things like that.
Teensy has the advantage of having Paul Stoffregen who knows the hardware inside out, and who seems to be interested in audio applications as well.
pert:
(though I did recently get an I2S mic and amp so that I can start playing with it).
Let's hope more people start playing with it so good I2S support becomes more mainstream
I think there's potential in things like music visualization, DIY guitar effects and other audio projects that are becoming more and more accessible, I, for one, definitely enjoy tinkering around with stuff like that.
I2S isn't very complex, but its very fast and requires stable jitter-free frequencies that are not related to 16MHz.
A typical I2S setup uses a bit clock at 1.4112/2.8224MHz or 1.536/3.072/6.144MHz, and a master clock of 11.2896MHz or 12.288MHz
These are multiples of the common sampling frequencies of 44.1kHz, 48kHz and 96kHz, and must be low jitter for ADCs and DACs to function at all, or at least without gross error.
This means you need either a programmable PLL on the chip, or use a 6.144/11.2896/12.288MHz crystal as the chip's clock.
And the only sensible processor architecture to support a constant datastream at megabit rates is DMA, so you need that too, plus a shedload of RAM and fast I/O channels (SD native mode for instance). Actually the fast I/O isn't needed if you are just being a synthesizer, but otherwise yes.
So, yes, you do need special hardware for I2S, quite a lot of it.
Thanks all for this diverse inputs! I will think about some of these additions for sure. The goal of my project is a super simple and cheap 1 sample Rompler (a Sampler without recording functionality) for my university students laboratory internship. This will be implemented via a Padauk PFS173 an an I2S DAC. Unfortunately I have problems doing so, so I will try to implement this on a Teensy first. The goal is not really high sound quality more to understand what's going on. So the sample frequency will be extremely low, maybe 1kHz or something like that and the bit depth will be 6Bit. So I think I even can bit bang the protocol, for my needs. THX
If you sample at 1kHz you'll have massively audible artifacts. 6 bit is harsh and nasty sounding and all DACs are at least 8 bit anyway.
Sounds like I2S is not what you should be using (you certainly can't run any I2S device at 1kSPS),
but 1kSPS/6 bit is not what you should be using either.
I'd suggest 22kSPS and 8 bit using an SPI DAC as a possible middle ground. This will put alias frequencies
up where the ear is less sensitive - check up on Nyquist's sampling theorem and aiasing.
Most Arduino's have SPI hardware than can transmit a byte in a microsecond or too, perfectly achievable to
drive an SPI DAC at audio rates.
If you do go with I2S, you'll be using 44.1kSPS / stereo as a minimum.
The PFS173 seems to be no more powerful than the ATmega328 and doesn't mention SPI support.
Hi, Paul here ... the guy who wrote the Teensy Audio Library. If you do get a Teensy, I hope you'll have an easy & fun experience creating sounds. If you need help, we have a forum for Teensy, which is the place to ask for help (if using Teensy, of course). This summer I hope to get back into really adding more audio library features, after a 2 year break to develop Teensy 4.x. Even though the library offers a lot of functionality, there's an amazingly long list of features people have requested. I hope to add more of those soon.
About the original question of I2S on other boards, long ago Open Music Labs created an audio codec shield. They put a lot of work into using SPI to sort-of implement I2S on Arduino Uno. Here is the website.
I recall they did publish several several examples which synthesized basic waveforms and even a couple that did simple real-time effects like a delay. Frankly, that's a pretty amazing feat for a 16 MHz 8 bit AVR. Hopefully the code is still available somewhere.