Hi, I wondered whether anyone might be able to give some guidance on using Teensy to receive audio from a RaPi over i2s.
Much of the project is fairly straightforward. I'm using an audio board with a Teensy 3.2 to play wav data from an SD card in the slot on the audio board. Sensors attached to the board will play trigger different files to be played.
However I am also playing mp3 files via a Raspberry Pi. These files will change regularly in response to user input etc. etc. which is why they can't be on the same SD card as the others.
The media player on the RaPi is controlled through serial over USB which is working well. I'm using a HiFi Berry DAC+ standard (https://www.hifiberry.com/products/dacplus/) rather than the 3.5mm output. At the moment, I'm feeding this into the line-in on the audio board. This means that I can easily control the mix of the two sounds and mute inputs when they're not in use etc. It works pretty well but I'd like to see if this could working using i2s to link the Pi and Teensy because:
1. I'm finding that there's a bit more noise (hiss) than I'd like when the audio in on the Teensy is unmuted. This is present regardless of whether it's connected to the Pi. Of course, this will be less noticeable once sound is playing but it would be great if things could be a bit quieter.
2. It seems a shame to use a RaPi HAT to take an i2s feed through a DAC over some copper, back in through an ADC and out through another DAC.
I've had a look into this, of course, but am having trouble getting my head around some things, mainly how one would go about connecting this to the Teensy. I wondered whether if I included a i2s quad input device and used pin 30 to connect to the Pi, whether this might be a good starting point. Presumably I'd have to set the RaPi up as a slave, somehow...
Thanks in advance of any pointers.
David
Much of the project is fairly straightforward. I'm using an audio board with a Teensy 3.2 to play wav data from an SD card in the slot on the audio board. Sensors attached to the board will play trigger different files to be played.
However I am also playing mp3 files via a Raspberry Pi. These files will change regularly in response to user input etc. etc. which is why they can't be on the same SD card as the others.
The media player on the RaPi is controlled through serial over USB which is working well. I'm using a HiFi Berry DAC+ standard (https://www.hifiberry.com/products/dacplus/) rather than the 3.5mm output. At the moment, I'm feeding this into the line-in on the audio board. This means that I can easily control the mix of the two sounds and mute inputs when they're not in use etc. It works pretty well but I'd like to see if this could working using i2s to link the Pi and Teensy because:
1. I'm finding that there's a bit more noise (hiss) than I'd like when the audio in on the Teensy is unmuted. This is present regardless of whether it's connected to the Pi. Of course, this will be less noticeable once sound is playing but it would be great if things could be a bit quieter.
2. It seems a shame to use a RaPi HAT to take an i2s feed through a DAC over some copper, back in through an ADC and out through another DAC.
I've had a look into this, of course, but am having trouble getting my head around some things, mainly how one would go about connecting this to the Teensy. I wondered whether if I included a i2s quad input device and used pin 30 to connect to the Pi, whether this might be a good starting point. Presumably I'd have to set the RaPi up as a slave, somehow...
Thanks in advance of any pointers.
David
Code:
#include <MPR121.h>
#include <Wire.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14
#define number_of_touch_sensors 12
#define default_volume 1
AudioSynthWaveformSine hello;
AudioEffectFade fade_hello,
fade_sd;
AudioPlaySdWav sd_card_1,
sd_card_2,
sd_card_3,
sd_card_4;
AudioSynthToneSweep sweep;
AudioMixer4 mixer_sd,
mixer_in,
mixer_out;
AudioOutputI2S soundcard;
AudioInputI2S audio_in;
AudioConnection patchcords[]={
AudioConnection(hello,0,fade_hello,0),
AudioConnection(fade_hello,0,mixer_out,0),
AudioConnection(sd_card_1,0,mixer_sd,0),
AudioConnection(sd_card_2,0,mixer_sd,1),
AudioConnection(sd_card_3,0,mixer_sd,2),
AudioConnection(sd_card_4,0,mixer_sd,3),
AudioConnection(mixer_sd,0,fade_sd,0),
AudioConnection(fade_sd,0,mixer_out,1),
AudioConnection(audio_in,0,mixer_in,0),
AudioConnection(audio_in,1,mixer_in,1),
// AudioConnection(audio_in,2,mixer_in,2),
// AudioConnection(audio_in,3,mixer_in,3),
AudioConnection(mixer_in,0,mixer_out,2),
AudioConnection(sweep,0,mixer_out,3),
AudioConnection(mixer_out,0,soundcard,0),
AudioConnection(mixer_out,0,soundcard,1)
};
AudioControlSGTL5000 sgtl5000_1;
//AudioControlSGTL5000 sgtl5000_2;
int iMaxPressure=0,
iMinPressure=0,
iPressureDelta=0;
unsigned long ulLastMeasure;
boolean bInOnOff=true;
String aSamples[]={
"",
"ear.wav",
"",
"eye_1.wav",
"",
"eye_2.wav",
"",
"nose.wav"
};
void fHelloSound(){
fade_hello.fadeOut(1);
delay(500);
hello.amplitude(1);
hello.frequency(220);
fade_hello.fadeIn(100);
delay(200);
fade_hello.fadeOut(250);
delay(250);
hello.frequency(392);
fade_hello.fadeIn(100);
delay(200);
fade_hello.fadeOut(250);
delay(250);
hello.amplitude(0);
}
void fChannelTest() {
mixer_out.gain(0,default_volume);
fHelloSound();
mixer_out.gain(0,0);
}
void setup() {
Serial.begin(57600);
Wire.begin();
/*
// 0x5C is the MPR121 I2C address on the Bare Touch Board
if(!MPR121.begin(0x5A)){
Serial.println("error setting up MPR121");
switch(MPR121.getError()){
case NO_ERROR:
Serial.println("no error");
break;
case ADDRESS_UNKNOWN:
Serial.println("incorrect address");
break;
case READBACK_FAIL:
Serial.println("readback failure");
break;
case OVERCURRENT_FLAG:
Serial.println("overcurrent on REXT pin");
break;
case OUT_OF_RANGE:
Serial.println("electrode out of range");
break;
case NOT_INITED:
Serial.println("not initialised");
break;
default:
Serial.println("unknown error");
break;
}
while(1);
}
MPR121.setInterruptPin(4);
MPR121.setTouchThreshold(40);
MPR121.setReleaseThreshold(20);
MPR121.updateTouchData();
*/
pinMode(A2, INPUT);
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!(SD.begin(SDCARD_CS_PIN))) Serial.println("Unable to access the SD card");
AudioMemory(100);
// Enable the first audio shield, select input, and enable output
sgtl5000_1.setAddress(LOW);
sgtl5000_1.enable();
sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
sgtl5000_1.volume(0.5);
sgtl5000_1.adcHighPassFilterDisable();
sgtl5000_1.lineInLevel(0);
/*
// Enable the second audio shield, select input, and enable output
sgtl5000_2.setAddress(HIGH);
sgtl5000_2.enable();
sgtl5000_2.inputSelect(AUDIO_INPUT_LINEIN);
sgtl5000_2.volume(0.5);
sgtl5000_2.adcHighPassFilterDisable();
sgtl5000_2.lineInLevel(0);
*/
mixer_sd.gain(0,default_volume);
mixer_sd.gain(1,default_volume);
mixer_in.gain(0,default_volume);
mixer_in.gain(1,0);
//fChannelTest();
mixer_out.gain(1,default_volume);
mixer_out.gain(2,default_volume);
mixer_out.gain(3,default_volume);
}
void loop() {
if(!sd_card_1.isPlaying()) {
//delay(1000);
//sweep.play(1,220,880,0.25);
delay(1000);
sd_card_1.play("15s.WAV");
delay(300);
}
if(!sweep.isPlaying()) {
//sweep.play(1,880,220,2);
/*float flLevel=bInOnOff?0.25:0;
Serial.print("level=");
Serial.print(flLevel);
Serial.println();
mixer_in.gain(0,flLevel);
mixer_in.gain(1,flLevel);
bInOnOff=bInOnOff^1;
*/
}
if(MPR121.touchStatusChanged()){
MPR121.updateTouchData();
for(int iSensor=0; iSensor<number_of_touch_sensors; iSensor++){
if(MPR121.isNewTouch(iSensor)){
Serial.print("TOUCH ON: ");
Serial.print(iSensor, DEC);
Serial.println();
sd_card_1.play(aSamples[iSensor].c_str());
} else if(MPR121.isNewRelease(iSensor)){
Serial.print("TOUCH OFF: ");
Serial.print(iSensor, DEC);
Serial.println();
}
}
}
}