sensorium / Mozzi

sound synthesis library for Arduino

Home Page:https://sensorium.github.io/Mozzi/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

I2S dacs config in Mozzi2

poetaster opened this issue · comments

I had tested several with mozzi 1.x and had success with the PT8211 and the PCM5102 with mozzi. I hadn't tried the MAX9898357 yet, but it worked with pschatzmann's audio-tools.

Now, I've switched to Mozzi2 and I can't seem to get I2S working on the rp2040, pico. But, I'm probably just doing it wrong. The configuration has changed a lot, so I just tried to follow the PT8211 examble. I checked the Datasheet on the 5102 first: https://www.ti.com/lit/ds/symlink/pcm5102.pdf It states: the audio input interface format is left justified and Audio Data format, MSB First, 2’s Complement. I proceeded with:

#include "MozziConfigValues.h"  // for named option values
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_I2S_DAC
#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED
// all of these are the defaults on RP2040 outputting on I2S, anyway, thus commented
#define MOZZI_AUDIO_BITS 16
#define MOZZI_I2S_PIN_BCK 20
#define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21
#define MOZZI_I2S_PIN_DATA 22
#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>

My hardware designs for the rp2040 are all setup so that 20,21, 22 are free to be assigned this was (can alternately be used for sda/scl video and 22 for pwm).

This does not work. What I missing. Do I need to specify some combination of:

or

MOZZI_I2S_FORMAT_PLAIN

``` ??

I had tried LSBJ just for the hell of it, but wasn't certain.

#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_I2S_DAC
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED

You will need either the former, or the latter, but the combination does not make sense. Try removing the second line. You should get at least something on the I2S pins (if the format is wrong, you'll generally get terrible distortion. In that case try adding #define MOZZI_I2S_FORMAT MOZZI_I2S_FORMAT_LSBJ).

Hi,

To add on this, the PT8211 is expecting LSBJ format. If you are using a pico, there is actually a config example in Mozzi2:

/* Configuration example

This example is targetted at the RP2040 (raspberry Pi pico) platform only!

Configure the Raspberry Pico to output sound in mono on a I2S DAC on LSBJ format (like the PT8211). */


#include "MozziConfigValues.h"  // for named option values

#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_I2S_DAC
#define MOZZI_I2S_FORMAT MOZZI_I2S_FORMAT_LSBJ // PT8211 is on LSBJ format

// all of these are the defaults on RP2040 outputting on I2S, anyway, thus commented
#define MOZZI_AUDIO_BITS 16
#define MOZZI_I2S_PIN_BCK 20
#define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21
#define MOZZI_I2S_PIN_DATA 22

Hi,

To add on this, the PT8211 is expecting LSBJ format. If you are using a pico, there is actually a config example in Mozzi2:

/* Configuration example

I did in fact start with this example. But I'm not sure if I still had #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED in place.

#define WS_pin 21   // channel select pin for the DAC

But I had tried with the example which uses SPI and that generates an error:

redefinition of 'void audioOutput(MonoOutput)'

Removing the function works ! I had been uncertain about the example, but, just removing the spi stuff and the PT8211_Stereo, with return MonoOutput::from16Bit(aCos1.next() * env1); and removing the SPI stuff works as it did in Mozzi1. Thanks!

How do I get it do do stereo :) I get cannot convert StereoOutput to int errors if I try....

Ok, after removing

#define MOZZI_I2S_FORMAT MOZZI_I2S_FORMAT_LSBJ // PT8211 is on LSBJ format

I also got it working with one of the PCM5102s. Oddly, the PT although being fed one channel gave me stereo? The PCM5102 is just oututting left channel. It's a bit noisy. PWM is cleaner and I tried running from battery power as well.

Not surprisingly,

  pinMode(23, OUTPUT); // thi is to switch to PWM for power to avoid ripple noise
  digitalWrite(23, HIGH);

doesn't have the effect it does with PWM output.

Without change to the functioning 5102 sketch, the MAX9898357, running on 3.3 volts powers a 3watt speaker (4 ohm). Gain needs to be adjusted, but it's quite clean outpu!

I am a bit confused about what works for you and what does not. I won't have the occasion to test the Pico+PT8211 in the next days but I am fairly sure the example config worked when we added it (quite some things changed).

Specifically for the PT, you should not need SPI as the pico supports I2S (which is why the output mode is MOZZI_OUTPUT_I2S_DAC and not MOZZI_OUTPUT_EXTERNAL_TIMED).

Oddly, the PT although being fed one channel gave me stereo?

This is a clear symptom of an incorrect I2S mode:

The main difference is that, for the LSBJ the MSB is sent right after the change of WS (Word Select) whereas in I2S the LSB is sent there (quickly followed by the next MSB). (from earlephilhower/arduino-pico#1094).

Hence, with the incorrect mode, you have one MSB (or one LSB, did not try to figure out which way) which leaks to the other channel.

Ok, I didn't get StereoOutput working but mono works on all DACs, The following was used for two PCM 5102s and the MAX9898357 ... the PT had the additional line you have above
#define MOZZI_I2S_FORMAT MOZZI_I2S_FORMAT_LSBJ // PT8211 is on LSBJ format

The sketch:

#include "MozziConfigValues.h"  // for named option values
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_I2S_DAC
// all of these are the defaults on RP2040 outputting on I2S, anyway, thus commented
#define MOZZI_AUDIO_BITS 16
#define MOZZI_I2S_PIN_BCK 20
#define MOZZI_I2S_PIN_WS (MOZZI_I2S_PIN_BCK+1) // CANNOT BE CHANGED, HAS TO BE NEXT TO pBCLK, i.e. default is 21
#define MOZZI_I2S_PIN_DATA 22
#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
// Synthesis part
Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aCos1(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aCos2(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kEnv1(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kEnv2(COS2048_DATA);
void setup() {
  aCos1.setFreq(440.f);
  aCos2.setFreq(220.f);
  kEnv1.setFreq(0.25f);
  kEnv2.setFreq(0.30f);
  startMozzi(CONTROL_RATE);
}
// Carry enveloppes
int env1, env2;
void updateControl() {
  env1 = kEnv1.next();
  env2 = kEnv2.next();
}
AudioOutput_t updateAudio() {
  return MonoOutput::from16Bit(aCos1.next() * env1);
}
void loop() {
  audioHook();
}

Ok, found the config for stereo:
added:

#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO 

and

 return StereoOutput::from16Bit(aCos1.next() * env1,aCos2.next() * env2);

And presto stereo. It's pretty noisy though. I'm comparing, for instace to running minidexed with the same PCM5102 dacs. PWM is actually cleaner.

I made a recording (time machine, linux, raw audio) https://poetaster.de/media/tm-2024-04-09T.w64

But, I think the original issue with not getting config right, is resolved. I don't think the the audio input interface format (left justified) or Audio Data format, (MSB First, 2’s Complement) on 2 of the dacs I'm using a an issue and it seems just the basic config works.

Closing as any details about noise are probably not a mozzi issue.