// Requires the prop-shield
// This example code is in the public domain.
#include <string.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <play_sd_mp3.h>
#include <play_sd_aac.h>
#include <play_sd_flac.h>
// GUItool: begin automatically generated code
AudioPlaySdMp3 playMp3; //xy=154,422
AudioPlaySdWav playWav; //xy=154,422
AudioPlaySdRaw playRaw; //xy=154,422
AudioPlaySdAac playAac; //xy=154,422
AudioPlaySdFlac playFlac;
AudioMixer4 mixer1; //xy=323,326
AudioMixer4 mixer2; //xy=323,326
AudioMixer4 mixer3;
AudioOutputI2S audioOutput;
AudioConnection patchCord1(playMp3, 0, mixer1, 0);
AudioConnection patchCord2(playMp3, 1, mixer1, 1);
AudioConnection patchCord3(playWav, 0, mixer1, 2);
AudioConnection patchCord4(playWav, 1, mixer1, 3);
AudioConnection patchCord5(playAac, 0, mixer2, 0);
AudioConnection patchCord6(playAac, 1, mixer2, 1);
AudioConnection patchCord7(playRaw, 0, mixer2, 2);
AudioConnection patchCord8(playFlac, 0, mixer3, 0);
AudioConnection patchCord9(playFlac, 1, mixer3, 1);
AudioConnection patchCord10(mixer1, audioOutput);
AudioConnection patchCord11(mixer2, audioOutput);
AudioConnection patchCord12(mixer3, audioOutput);
AudioControlSGTL5000 sgtl5000_1;
// Use these with the Teensy 3.x Audio Shield
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 11
#define SDCARD_SCK_PIN 13
float volume = 0.5f;
File root, entry;
void setup() {
AudioMemory(40);
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
delay(100);
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!(SD.begin(SDCARD_CS_PIN))) {
// stop here, but print a message repetitively
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
Serial.println("initialization done.");
root = SD.open("/");
}
void playFile(const char *filename)
{
int filetype;
filetype = 0;
if (strstr(filename, ".MP3") != NULL) {
filetype = 1;
} else if (strstr(filename, ".WAV") != NULL ) {
filetype = 2;
} else if (strstr(filename, ".AAC") != NULL ) {
filetype = 3;
} else if (strstr(filename, ".RAW") != NULL ) {
filetype = 4;
} else if (strstr(filename, ".FLA") != NULL ) {
filetype = 5;
} else
filetype = 0;
if (filetype > 0) {
Serial.print("Playing file: ");
Serial.println(filename);
switch (filetype) {
case 1 :
mixer1.gain(0, volume);
mixer1.gain(1, volume);
mixer1.gain(2, 0.0f);
mixer1.gain(3, 0.0f);
playMp3.play(filename);
delay(5);
while (playMp3.isPlaying()) {
}
break;
case 2 :
mixer1.gain(0, 0.0f);
mixer1.gain(1, 0.0f);
mixer1.gain(2, volume);
mixer1.gain(3, volume);
playWav.play(filename);
delay(5);
while (playWav.isPlaying()) {
}
break;
case 3 :
mixer2.gain(0, volume);
mixer2.gain(1, volume);
mixer2.gain(2, 0.0f);
playAac.play(filename);
delay(5);
while (playAac.isPlaying()) {
}
break;
case 4 :
mixer2.gain(0, 0.0f);
mixer2.gain(1, 0.0f);
mixer2.gain(2, volume);
playRaw.play(filename);
delay(5);
while (playRaw.isPlaying()) {
}
break;
case 5 :
mixer3.gain(0, volume);
mixer3.gain(1, volume);
playFlac.play(filename);
delay(5);
while (playFlac.isPlaying()) {
}
break;
}
}
}
void loop() {
playAll(root);
}
void playAll(File dir){
char filename[64];
char filnam[64];
while(true) {
entry = dir.openNextFile();
if (! entry) {
// no more files
// rewind to begining of directory and start over
dir.rewindDirectory();
break;
}
//Serial.print(entry.name());
if (entry.isDirectory()) {
//Serial.println("Directory/");
//do nothing for now
Serial.println(entry.name());
playAll(entry);
} else {
// files have sizes, directories do not
//Serial.print("\t\t");
//Serial.println(entry.size(), DEC);
// files have sizes, directories do not
strcpy(filename, dir.name());
strcat(filename, "/");
strcat(filename, strcpy(filnam, entry.name()));
playFile(filename);
}
entry.close();
}
}
I wished the final T4 had a bigger flash,
Me too. Sadly, this is the largest one we could buy in a 6 sq mm package. The next largest package is 12 sq mm, and the smallest package that goes up to substantially higher capacity is 40 sq mm.
After 4.0 is released, I'm considering making a larger (and more expensive) board using this same processor, but with one of those bigger flash chips, an audio codec chip, and probably an ethernet phy chip, and some way to break out more of the I/O pins.
...
Anyway, when it comes time to do the pinout card, given we don't have a DAC, and I2S is expected to be used for sound. It would be helpful to users if one or both of the I2S ports and the SPIDF port will be on the pinout card. I assume the crossbar and flexio pins will also be listed.
It certainly would also be helpful if somewhere on the card we mentioned I2C needing pull-up resistors. I realize the card is already getting crowed, and if it doesn't go in, it isn't the end of the world.
Of course it probably means the library section needs to be re-vamped also, to add any more qualifiers for T4.
In terms of the pinout card, if we have more special CS pins like we did in T3.x, it might be nice to put them on the card too, but as before, it is hard to explain (particularly for the pin overlaps).
If someone want to try resampling: there is a very good resampler (uses "sinc") in the speex codec - it is already optimized of ARM Cortex M4 and uses the DSP extensions - and if I read the license correctly, we can use it.
Sounds great! Will be fun to work with...After 4.0 is released, I'm considering making a larger (and more expensive) board using this same processor, but with one of those bigger flash chips, an audio codec chip, and probably an ethernet phy chip, and some way to break out more of the I/O pins.
Here's the Aliexpress link for those 3.5 inch, 480x320 displays. Right now is Chinese New Year, so expect any order to take a couple extra weeks.
https://www.aliexpress.com/item/3-5...reen-with-Touch-Panel-Driver/32908809356.html
Sounds great! Will be fun to work with...
At some point it would be great if it also somehow could do WIFI... But not sure how doable that is without adding a bunch of other stuff. I know some boards have done it by adding ESP... Again sorry if not specific to this Alpha/Beta...
Could you please post this as a new thread, with a link to the code?
I'd like to save it on my audio library wish list (not calling it a "todo" list at this point).
//
// 16-tap minimum-phase equiripple FIR
// passband = 18KHz gain = -1.25dB +- 0.25dB
// stopband = 26KHz attn = -90dB
// coefs = Q15 with sum(abs(coef)) < 65536
//
static const int16_t filter_4_1[4][NTAPS] = {
{ 57, -681, -497, 845, -1472, 2162, -2734, 2873, -2152, -77, 4489, -10987, 13872, 18409, 3388, 36 },
{ 52, -373, -938, 1031, -1367, 1541, -1357, 559, 1090, -3802, 7377, -10282, 6354, 21285, 6171, 192 },
{ 29, -131, -1084, 733, -684, 335, 428, -1708, 3481, -5547, 7139, -6303, -1540, 21825, 9926, 634 },
{ 10, 8, -961, 135, 190, -840, 1780, -2943, 4095, -4805, 4178, -676, -7853, 19340, 14267, 1608 },
};
static int SRCFilter(SRC *s, int16_t *src0, int16_t *src1, int16_t *dst0, int16_t *dst1, int inframes)
{
int16_t *src0_end = src0 + inframes;
int16_t *dst0_old = dst0;
int phase = s->phase;
ASSERT(NTAPS == 16);
while (src0 < src0_end) {
const int16_t *coef = s->filter[phase];
int32_t x0, x1, c0, c1;
int32_t acc0, acc1;
c0 = _SIMD32_OFFSET(coef+0);
c1 = _SIMD32_OFFSET(coef+2);
x0 = _SIMD32_OFFSET(src0+0);
x1 = _SIMD32_OFFSET(src0+2);
acc0 = __SMUAD(x0, c0); // Q15 * Q15 = Q30
acc0 = __SMLAD(x1, c1, acc0);
x0 = _SIMD32_OFFSET(src1+0);
x1 = _SIMD32_OFFSET(src1+2);
acc1 = __SMUAD(x0, c0);
acc1 = __SMLAD(x1, c1, acc1);
c0 = _SIMD32_OFFSET(coef+4);
c1 = _SIMD32_OFFSET(coef+6);
x0 = _SIMD32_OFFSET(src0+4);
x1 = _SIMD32_OFFSET(src0+6);
acc0 = __SMLAD(x0, c0, acc0);
acc0 = __SMLAD(x1, c1, acc0);
x0 = _SIMD32_OFFSET(src1+4);
x1 = _SIMD32_OFFSET(src1+6);
acc1 = __SMLAD(x0, c0, acc1);
acc1 = __SMLAD(x1, c1, acc1);
c0 = _SIMD32_OFFSET(coef+8);
c1 = _SIMD32_OFFSET(coef+10);
x0 = _SIMD32_OFFSET(src0+8);
x1 = _SIMD32_OFFSET(src0+10);
acc0 = __SMLAD(x0, c0, acc0);
acc0 = __SMLAD(x1, c1, acc0);
x0 = _SIMD32_OFFSET(src1+8);
x1 = _SIMD32_OFFSET(src1+10);
acc1 = __SMLAD(x0, c0, acc1);
acc1 = __SMLAD(x1, c1, acc1);
c0 = _SIMD32_OFFSET(coef+12);
c1 = _SIMD32_OFFSET(coef+14);
x0 = _SIMD32_OFFSET(src0+12);
x1 = _SIMD32_OFFSET(src0+14);
acc0 = __SMLAD(x0, c0, acc0);
acc0 = __SMLAD(x1, c1, acc0);
x0 = _SIMD32_OFFSET(src1+12);
x1 = _SIMD32_OFFSET(src1+14);
acc1 = __SMLAD(x0, c0, acc1);
acc1 = __SMLAD(x1, c1, acc1);
*dst0++ = __QADD(acc0, acc0) >> 16; // Q30 -> Q15 with saturation
*dst1++ = __QADD(acc1, acc1) >> 16;
// phase step
src0 += s->srcstep[phase];
src1 += s->srcstep[phase];
phase += s->phasestep;
if (phase >= s->up)
phase -= s->up;
}
s->phase = phase;
return dst0 - dst0_old; // outframes produced
}
At the moment I can only say something about the SPDIF input: Normally you can't select the sample rate for consumer electronics. Here, downsampling from the usual rates (multiples of 48 and 44.1 KHZ - up to 192KHz) to 44.1KHz would be useful to process it on the teensy. It can be useful for wav-files and other formats, too.Just curious, what would be the specs on the resampling you want to do?
For what it is worth: I just hooked it up to my T4...
My connections are: Display-T4
1-GND, 2-+3.3v, 21-7, 23-10, 24-13, 25-9, 27-11, 28-12, 29-8
I updated the sketch a little to turn the LED on and to change the pin numbers...
Sketch here …
And it run! With stuff on the display
ESP32 with SPI ILI9488 Touch LCD
I have created a test setup and have found that the SDO line sticks low and does not go tristate even if the TFT chip select is high. This means that the SDO line must not be connected up if the SPI bus is to be shared with other devices. Disconnecting the SDO line also means that the TFT read functions will no longer operate correctly.
Following is an rPi_ILI9488 issue - not T4 - same behavior on T_3.6:Here is the now renamed Touch Example - no XPT2046 change needed: View attachment ILI9488Test.zip
Works on T_3.6 with KurtE's lib, but not T4, with display MISO not connected
Slight mod - should run Graphics testText [Groop] then show when Touched (removed clear screen && increased Font Size)
KurtE - slight pixel remains on right edge of X,Y digit display edit line #80 to 'tft.fillRect(100, 150, 142, 60, ILI9488_BLACK);'
That's the same display that I was using and never could get it to work, I was complaining about the same thing - no DC. That's why I order the one KurtE has and the one Paul showed. Haven't done anything yet with them thoughdefragster said:<edit>Was about to declare this a tft issue - but now seeing TFT text with T_3.6. Screen reports X,Y location on TFT and then No Touch per misnamed example. Going back to T4 fails to display.
Here is the now renamed Touch Example - no XPT2046 change needed: ILI9488Test.zip
Works on T_3.6 with KurtE's lib, but not T4, with display MISO not connected
Slight mod - should run Graphics testText [Groop] then show when Touched (removed clear screen && increased Font Size)
KurtE - slight pixel remains on right edge of X,Y digit display edit line #80 to 'tft.fillRect(100, 150, 142, 60, ILI9488_BLACK);'
Following is an rPi_ILI9488 issue - not T4 - same behavior on T_3.6:
I ran wires to the rPi ready display I got - Touch works, but nothing ever displays. It does not have the D/C pin broken out like the ILI9341 and other 9488. May be in 16 bit color mode?
TMR1_SCTRL2 0x1440
TMR1_CSCTRL2 0x340
TMR1_CTRL2 0x3520
TMR1_LOAD2 0x0
TMR1_COMP12 0xFFFF
TMR1_CMPLD12 0xFFFF
TMR1_COMP22 0x0
TMR1_CMPLD22 0x0
ticks 6 oflows 1 v0 63688 v1 6518
ticks 5061 oflows 573 v0 57896 v1 726
ticks 10116 oflows 1146 v0 53498 v1 61864
ticks 15170 oflows 1718 v0 47706 v1 56072
ticks 20225 oflows 2290 v0 41914 v1 50280
ticks 25275 oflows 2862 v0 37516 v1 44488
Re: PIT-controlled ADC with DMAat least analog input would be important.