Ok, looking at this mutable instruments schematic:
https://imgur.com/a/OGNZrDd
i understand where to plug the SCL, SDA and SCK, what i dont know is where to plug (or if it«s necessary)the LRCKs and SIN on teensy
Any thoughts?
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#define ENABLE_CODEC
constexpr const int IN_BUILT_LED_PIN(13);
#ifdef ENABLE_CODEC
AudioInputI2S audio_input; //serial output works again if I comment these out
AudioOutputI2S audio_output;
AudioControlWM8731 wm8731;
#else // !ENABLE_CODE
AudioInputAnalog audio_input;
AudioOutputAnalog audio_output;
#endif // !ENABLE_CODE
AudioSynthWaveformSine sine_generator;
AudioConnection patch_cord_1( sine_generator, 0, audio_output, 0 );
void setup()
{
#ifdef ENABLE_CODEC
wm8731.enable();
#endif
AudioMemory( 256 );
pinMode( IN_BUILT_LED_PIN, OUTPUT );
sine_generator.amplitude(1.0f);
sine_generator.frequency(440.0f);
#ifdef ENABLE_CODEC
wm8731.volume(1.0f);
#endif
Serial.begin(9600);
Serial.println("Setup finished!");
}
void loop()
{
digitalWrite( IN_BUILT_LED_PIN, HIGH );
delay( 1000 );
digitalWrite( IN_BUILT_LED_PIN, LOW );
delay( 1000 );
//wm8731.enable();
}
constexpr const int IN_BUILT_LED_PIN(13);
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#define ENABLE_CODEC
//constexpr const int IN_BUILT_LED_PIN(13);
#ifdef ENABLE_CODEC
AudioInputI2S audio_input;
AudioOutputI2S audio_output;
//AudioInputAnalog audio_input;
//AudioOutputAnalog audio_output;
AudioControlWM8731 wm8731;
#else // !ENABLE_CODE
AudioInputAnalog audio_input;
AudioOutputAnalog audio_output;
#endif // !ENABLE_CODE
AudioSynthWaveformSine sine_generator;
AudioConnection patch_cord_1( sine_generator, 0, audio_output, 0 );
void setup()
{
#ifdef ENABLE_CODEC
wm8731.enable();
#endif
AudioMemory( 256 );
sine_generator.amplitude(1.0f);
sine_generator.frequency(440.0f);
#ifdef ENABLE_CODEC
wm8731.volume(1.0f);
#endif
Serial.begin(9600);
Serial.println("Setup finished!");
}
void loop()
{
delay( 1000 );
Serial.println("loop");
}
I must confess, I haven't used WM8731 in slave mode (Teensy as I2S master) since the very earliest days of the audio library. Before we had the STGL5000, I did some of the earliest development using a MicroE-506 hacked for master mode, where I desoldered the crystal and connected MCLK. But that hardware suffered a "learning experience" not long after the first SGTL5000 prototype which later became the audio shield we sell today. Since then I've bought a couple more of those MikroElektronia WM8731 boards, replaced the crystal (for 44.1 kHz use), and only used them in their intended master mode (Teensy as I2S slave).
Interesting reading, thanks Paul! I'd be really interested to hear from anyone that has got the WM8731 codec working in slave mode (Teensy as IS2 master) using the teensy audio library.
As mentioned above, my BALibrary uses the WM8731 in slave mode. I provide a replacement for the default AudioControlWM8731 called BAAudioControlWM8731. It provides some robustness enhancement on the I2C bus as well as exposes a few more features.
Thanks @blackaddr, I plan to try this out next. Does my schematic look correct to you?
I don't see any obvious difference vs my design for the I2S/I2C lines other than the pullups for I2C. 4.7K is a little weak for 3.3V, mine are in the 2K range. This shouldn't be a big problem though. You need to figure out if it's the I2C that's not working our just the I2S. When you use the codec control class in the Teensy library, it will silently fail if there are bus errors (missing ACKs, etc.). You can either modify the Teensy Audio library to report any errors, or you can look at my class mentioned above which will at least retry on an error. You can modify my class to print if errors occur.
If the I2C is working fine with no bus errors reported, try putting the device in analog bypass mode and feed an analog signal to the codec input. This can check the analog audio path without needing the I2S bus working. IF all that checks out, you know there is something wrong with the I2S stuff.
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioSynthWaveform waveform1; //xy=245,160
AudioInputI2S i2s1; //xy=265,252
AudioOutputI2S i2s2; //xy=429,158
AudioAnalyzeRMS rms2; //xy=436,323
AudioAnalyzeRMS rms1; //xy=444,265
AudioConnection patchCord1(waveform1, 0, i2s2, 0);
AudioConnection patchCord2(waveform1, 0, i2s2, 1);
AudioConnection patchCord3(i2s1, 0, rms1, 0);
AudioConnection patchCord4(i2s1, 1, rms2, 0);
AudioControlWM8731 wm8731m1; //xy=292,379
// GUItool: end automatically generated code
void setup() {
wm8731m1.enable();
AudioMemory(15);
waveform1.begin(WAVEFORM_SINE);
waveform1.frequency(440);
waveform1.amplitude(0.9);
wm8731m1.volume(0.50);
wm8731m1.inputSelect(AUDIO_INPUT_MIC);
// wm8731m1.inputSelect(AUDIO_INPUT_LINEIN); // not connected on MikroE-506
}
elapsedMillis msec;
// Print a simple level meter
void loop() {
if (msec > 40) {
if (rms1.available() && rms2.available()) {
msec = 0;
int level_left = rms1.read() * 30.0;
int level_right = rms2.read() * 30.0;
printchar(' ', 30 - level_left);
printchar('<', level_left);
Serial.print("||");
printchar('>', level_right);
Serial.println();
}
}
}
void printchar(char c, int num) {
for (int i=0; i < num; i++) {
Serial.write(c);
}
}
I don't see any obvious difference vs my design for the I2S/I2C lines other than the pullups for I2C. 4.7K is a little weak for 3.3V, mine are in the 2K range. This shouldn't be a big problem though. You need to figure out if it's the I2C that's not working our just the I2S. When you use the codec control class in the Teensy library, it will silently fail if there are bus errors (missing ACKs, etc.). You can either modify the Teensy Audio library to report any errors, or you can look at my class mentioned above which will at least retry on an error. You can modify my class to print if errors occur.
If the I2C is working fine with no bus errors reported, try putting the device in analog bypass mode and feed an analog signal to the codec input. This can check the analog audio path without needing the I2S bus working. IF all that checks out, you know there is something wrong with the I2S stuff.
Hi everybody,
I've been away from the forum for many months for health reasons, and because I was unable to solve the audio board quadrature bug in which the two channels are randomly offset by a single sample on power-up or program reload.
BUT now I'm back, and last night I stumbled across this thread.
As it happens I am faced with exactly the same problem. In yet another attempt to solve the quadrature offset problem I've been trying to use a WM8731 codec - so far unsuccessfully. I decided against using the Mikroe board because of the lack of line-out connections. Instead, I'm working with the WM8731 chip directly, mounted on an Adafruit 28 pin TSSOP breakout board. I have also made an adapter board that has the same pinout as the Teensy Audio board and plugs in directly in the sockets on all my T3.6 and T3.2 boards. The WM8731 works (or at least should!) in slave mode.
Right now all the timing and data signals seem to be correct (MCLK, BLCK, the two LRC signals, and the I2Sout from the Teensy) as seen on the 'scope. The timing looks good. BUT there is no response on the WM8731 output pins. I've checked the I2C connection lines and they are active during the enable phase... It's equally catatonic on both Teensy 3.2 and 3.6...
My plan for today is 1) try another WM8731 chip, 2) try using the BALibrary enable/set-up, and 3) continue to scratch my head. I'll post a couple of photos of the setup.
Derek
If all else fails, maybe grab one of those MicroE-506 boards and wire it up the same as msg #16. They you'll be able to make side-by-side comparison of the hardware to see what's different.
There is something about the Teensy/WM8731 combination that had issues.