Problems setting up Teensy D Audio board on Teensy 4.0

Status
Not open for further replies.
Paul at Houston and Paul at JPRC, Houston, Thanks for the loan of the board pair. They worked first time with both guitar and stereo passthro'.
So the software worked ok and the fault was due finger trouble in my setup - not installing all libraries with teensyduino and possibly incorrect expansion of the Zip download file . I have already bought a replacement pair from Pimorini and will solder them when the female headers with the long pins arrive from the same company. Will return the pair v soon. What a relief ! The sound quality is impressive and I'm looking forward to slaving the boards from my guitar effects and FFT sketches. Will post the finished programs.
 
I took advice from Houston mainly (over several weeks) but also read the documents written by Paul Stoffregen and I now have a working development system though which I will eventually connect my Fender Tele. At the moment it performs duet chorus and delay effects (Watkins Copycat style) and I produce it here for anyone interested. My aim is to add FFT for which I have a working real time routine. I have been doing FFT since 1965 applying it then to infra red interferometers so it would be a great shame not to use it on my Fender ! Houston persuaded me to access the ADC and DAC by building a library object modelled on one of his designs I did just that and it now works fine. The sound quality is wonderful. I will update anyone interested in the development here but have to interface the guitar yet. Have done this many times with the Due so no problem. There is one outstanding problem in the code if anyone can help here. I use the Savitsky-Golay noise reduction algorithm (5 point quadratic least squares fit) and it produces white noise output . If anyone can spot the mistake then I would be grateful. I've used the same algorithm and coefficients to process GC signals in the past but not with a mix of uint16_t, short, and int variables.
Here goes :

==========================================================================================================

#include <Audio.h>
#include <Wire.h>
#include <SerialFlash.h>
#include <Bounce.h>
#include "enhanced.h"


AudioInputI2S i2s1;
AudioMixer4 mixer1;
AudioEffectEnhanced enhanced1;
AudioOutputI2S i2s2;
AudioConnection patchCord1(i2s1, 0, mixer1, 0);
AudioConnection patchCord2(i2s1, 1, mixer1, 1);
AudioConnection patchCord3(mixer1, enhanced1);
AudioConnection patchCord4(enhanced1, 0, i2s2, 0);
AudioConnection patchCord5(enhanced1, 0, i2s2, 1);
AudioControlSGTL5000 sgtl5000_1;

Bounce button0 = Bounce(0, 15);


int j =0;

void setup() {
Serial.begin(9600);
pinMode(0, INPUT_PULLUP);

AudioMemory(10);
sgtl5000_1.enable();
sgtl5000_1.volume(0.7);

mixer1.gain(0, 0.5);
mixer1.gain(1, 0.5);

// start the effect
enhanced1.begin();

enhanced1.setdelays(true,1,4400); //1/10 sec


enhanced1.configurechorus(2,0.05,4); // LFOsweep (secs),float midlag (secs),float LFOsweep, amplitudereduction of sine wave)
enhanced1.initchorus();

enhanced1.configureecho(2,0.1,100); // n echos, tap delay secs, % retention
enhanced1.initecho();

}

void loop() {
// read pushbuttons
button0.update();

// read knobs, scale to 0-1.0 numbers
float knobA3 = (float)analogRead(A3) / 1023.0;

// Button 0 starts nibble effect
if (button0.fallingEdge()) {
float msec = 100.0 + (knobA3 * 190.0); // Range 100 - 290
enhanced1.beginEnhanced(msec);
Serial.print("Begin Enhanced using ");
Serial.print(msec);
Serial.println(".");
}
if (button0.risingEdge()) {
enhanced1.stop();
}

// Continuously adjust the speed, based on the A3 pot
float msec = 100.0 + (knobA3 * 190.0); // Range 100 - 290
enhanced1.setDepth(msec);

// Print Max Memory usage every x cycles
if (j>10000){
Serial.print("Memory Max : ");
Serial.println(AudioMemoryUsage());
j=0;
}
j++;
}


==============================================================================================================================================

//effect_enhanced.h

#include "AudioStream.h"

class AudioEffectEnhanced : public AudioStream
{
public:

AudioEffectEnhanced(void): AudioStream(1,inputQueueArray) { }

void configurechorus(float LFOsweep,float midlag,float amplitudereduction);
void initchorus();
void configureecho(int n,float echolag,int attenuation);
void initecho();

void begin();
void setDepth(float depth) {}
void beginEnhanced(float grain_length) {
if (grain_length <= 0.0) return;
beginEnhanced_int(grain_length);
}
void stop();
void setdelays(bool active,int n,int delta);
virtual void update(void);



private:
void beginEnhanced_int(int n);
audio_block_t *inputQueueArray[1];

====================================================================================================================================

// effect_enhanced.cpp

#include <Arduino.h>
#include "enhanced.h"

const int heartbeat =13;

const uint16_t qsize = 1 <<15;
const uint16_t qmask = qsize-1;
short int q[qsize];
const int preludeblocks=(qsize/AUDIO_BLOCK_SAMPLES)+1;
int qinpt=0,lastqpt,lastsample;
int fillblockcount;

short sintab[360];
bool SavitskyGolay = false;
bool pulse=true;
int blockcount=0;

// shunt for signal smoothing by Savitsky-Golay convolution
int m2 = 0, m1 = 0, m0 = 0, p1 = 0, p2 = 0;
int ndelays,sampledelta;
bool delaysactive;

// echo data
bool echo=false;
long total;
int lag=4400,nechos=1,delaypt; // default 1 delay after 1/10 sec lag
int sustain=100; //%

// chorus data
bool chorus=true;
int LFOmodulationfrequency=88200; // 2 secs LFO
int chorusreduction=4; // sine amplitude -250 to +250
int middelay= 2205; // 1/20 sec average lag
// chorus working variables
int sinetab[360];
int LFOcount=0;
int offset;

void AudioEffectEnhanced::configurechorus(float LFOsweep,float midlag,float amplitudereduction)
{chorus=false;
LFOmodulationfrequency=(int)(LFOsweep*44100);
middelay=(int)(midlag*44100);
chorusreduction=(int)(amplitudereduction);
}
void AudioEffectEnhanced::initchorus()
{echo=false; chorus=true;}

void AudioEffectEnhanced::configureecho(int n,float echolag,int attenuation)
{echo=false;nechos=n; lag=(int)(echolag*44100); sustain=attenuation;}

void AudioEffectEnhanced::initecho()
{chorus=false; echo=true;}

void qplant(int16_t value)
{
lastsample=value; lastqpt=qinpt;
q[qinpt]=value; qinpt++; qinpt=qinpt & qmask;
}

void makesinetable()
{float sinval,radian;
for (int degrees=0; degrees<360;degrees++)
{
radian=(float)(degrees)*M_PI/180.0;
sinval=sin(radian); //-1 to +1
sintab[degrees]=(short)(sinval*1000.0);
}
}

void AudioEffectEnhanced::begin()
{
pinMode(heartbeat, OUTPUT);
fillblockcount=preludeblocks; // 1/10 sec
makesinetable();
}


void AudioEffectEnhanced::beginEnhanced_int(int dummy)
{
__disable_irq();
//??
__enable_irq();
}

void AudioEffectEnhanced::setdelays(bool initiate,int n,int delta)
{
ndelays=n; sampledelta=delta; delaysactive=initiate;
}

void AudioEffectEnhanced::stop()
{
}

void AudioEffectEnhanced::update(void)
{
audio_block_t *block;
int16_t input;
// get a block of sample data
block = receiveWritable(0);
if (block==false) return;
// fill queue with samples
if (fillblockcount>=0)
{ digitalWrite(heartbeat,HIGH);
for (int j = 0; j < AUDIO_BLOCK_SAMPLES; j++)
{ input = block->data[j];
qplant(input);
}
release(block);
fillblockcount--;
return;
} // end of queue initialisation

blockcount++;
if (blockcount == 35) {blockcount=0; pulse=!pulse; digitalWrite(heartbeat,pulse);} // 1 sec on 1 sec off

// after prelude
for (int j = 0; j < AUDIO_BLOCK_SAMPLES; j++)
{ input = block->data[j];
// smooth input values using 5pt quadratic least squares fit
if (SavitskyGolay)
{ m2=m1; m1=m0; m0=p1; p1=p2; p2=input;
m0=m0*17+(m1+p1)*12-(m2+p2)*3; //recoded as =>
input=m0/35;
}

qplant(input);
// echo previous entry echodelay elements stored in q[]
// fill current block with historic samples from q[]

delaypt=lastqpt;
total=lastsample;

if (echo)
{
for (int n=0; n<nechos;n++)
{delaypt=(delaypt-lag) & qmask;
total=total+q[delaypt]*sustain/100;
sustain=sustain*sustain/100;
}
}

if (chorus)
{
LFOcount++; if (LFOcount>=LFOmodulationfrequency) LFOcount=0;
offset=(lastqpt-middelay) & qmask;
total=lastsample;
offset=offset+sintab[(int)(LFOcount*359/LFOmodulationfrequency)]/chorusreduction;
total=(total+q[offset & qmask])/2;
}

block->data[j] = total;
}
// transmit the smoothed? delayed block data and release the curent block after the prelude fill
transmit(block);
release(block);
}





};
 
Status
Not open for further replies.
Back
Top