DIYLAB
Well-known member
Uses:
Teensy 4.0 (600MHz clock)
Audio Adaptor Rev.D
Display ILI9341 240x320
Display Driver: ILI9341_t3n
Teensyduino, Version 1.54
---------------------------------------------------
Houston, we have a problem ;o)
This small and executable program is a spin-off from a project, edited to the most necessary for the forum.
In the whole project there are some modules which use AudioLib and need FFT, RMS, PEAK.
In this extraction only RMS and PEAK are interesting.
The original looks like this (an analog VU meter is drawn):
The SGTL5000 scheme of the whole project:
In the test program the display shows RMS1, RMS2, PEAK1 and PEAK2 and only every 500000 frames to calm the display for you.
Now to the problem:
If I don't fetch the samples in the main loop and comment out getSamples(1);, no more RMS and PEAK arrive!
I would love to stop the queue completely for this module and only turn it back on for modules that really need it, but that doesn't work properly either, the stopped queue doesn't always restart.
So the goal is to run the queue and still get RMS and PEAK reliably when getSamples(1); is not present in the main loop .
What am I doing wrong?
Teensy 4.0 (600MHz clock)
Audio Adaptor Rev.D
Display ILI9341 240x320
Display Driver: ILI9341_t3n
Teensyduino, Version 1.54
---------------------------------------------------
Houston, we have a problem ;o)
This small and executable program is a spin-off from a project, edited to the most necessary for the forum.
Code:
#include <Wire.h>
#include "SPI.h"
#include <Audio.h>
#include <ILI9341_t3n.h>
#include <ili9341_t3n_font_Arial.h>
#include <ili9341_t3n_font_ArialBold.h>
#define TFT_DC 9
#define TFT_CS 10
#define TFT_RESET 255 // vcc
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RESET);
// GUItool: begin automatically generated code
AudioInputI2S i2s1; //xy=205,270
AudioOutputI2S i2s2; //xy=233.00000381469727,400.0000057220459
AudioAnalyzeFFT1024 fft1024_1; //xy=425.00000762939453,132.00000190734863
AudioAnalyzeFFT1024 fft1024_2; //xy=426.00000381469727,320.0000047683716
AudioAnalyzeRMS rms1; //xy=431.00000381469727,93.00000190734863
AudioRecordQueue queue2; //xy=431.00000381469727,280.00000381469727
AudioAnalyzePeak peak1; //xy=432.00000762939453,54.000003814697266
AudioRecordQueue queue1; //xy=432.00000381469727,171.00000381469727
AudioMixer4 mixer1; //xy=432.00000381469727,225.00000381469727
AudioAnalyzeRMS rms2; //xy=433.00000762939453,359.0000047683716
AudioAnalyzePeak peak2; //xy=435.00000762939453,399.0000057220459
AudioAnalyzeFFT1024 fft1024_3; //xy=566.0000076293945,225.00000286102295
AudioConnection patchCord1(i2s1, 0, queue1, 0);
AudioConnection patchCord2(i2s1, 0, peak1, 0);
AudioConnection patchCord3(i2s1, 0, rms1, 0);
AudioConnection patchCord4(i2s1, 0, fft1024_1, 0);
AudioConnection patchCord5(i2s1, 0, mixer1, 0);
AudioConnection patchCord6(i2s1, 0, i2s2, 0);
AudioConnection patchCord7(i2s1, 1, queue2, 0);
AudioConnection patchCord8(i2s1, 1, fft1024_2, 0);
AudioConnection patchCord9(i2s1, 1, rms2, 0);
AudioConnection patchCord10(i2s1, 1, peak2, 0);
AudioConnection patchCord11(i2s1, 1, mixer1, 1);
AudioConnection patchCord12(i2s1, 1, i2s2, 1);
AudioConnection patchCord13(mixer1, fft1024_3);
AudioControlSGTL5000 sgtl5000_1; //xy=216,96.00000667572021
// GUItool: end automatically generated code
// Sample Buffers
int16_t samplesLeft[2048] = { 0 };
int16_t samplesRight[2048] = { 0 };
// FrameCounter
uint32_t fcl = 0, fcr = 0;
void setup() {
// Audio
AudioMemory(32);
sgtl5000_1.enable();
sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
sgtl5000_1.lineOutLevel(13); // 3.16 Volts p-p
sgtl5000_1.volume(.7); // 0.8 corresponds to the maximum undistorted output for a full scale signal.
sgtl5000_1.lineInLevel(0); // 3.12 Volts p-p
// Start sample queue.
queue1.begin();
queue2.begin();
// Display
tft.begin();
tft.fillScreen(ILI9341_BLACK);
tft.setFont(Arial_10_Bold);
tft.setTextColor(ILI9341_ORANGE, ILI9341_BLACK);
tft.drawString("LEFT CHANNEL", 8, 30);
tft.drawString("RIGHT CHANNEL", 8, 100);
tft.setFont(Arial_10);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.drawString("rms1:", 8, 50);
tft.drawString("peak1:", 8, 70);
tft.drawString("rms2:", 8, 120);
tft.drawString("peak2:", 8, 140);
}
void loop() {
getSamples(1);
drawNeedleLeft();
drawNeedleRight();
}
/// <summary>
/// Get samples for left and right channel.
/// </summary>
/// <param name="blocks"></param>
void getSamples(byte blocks) {
if (queue1.available() >= blocks && queue2.available() >= blocks) {
for (byte i = 0; i < blocks; i++) {
memcpy(&samplesLeft[i * 128], queue1.readBuffer(), 256);
memcpy(&samplesRight[i * 128], queue2.readBuffer(), 256);
queue1.freeBuffer();
queue2.freeBuffer();
}
}
}
/// <summary>
/// Draw left Side
/// </summary>
void drawNeedleLeft() {
if (++fcl > 500000 && rms1.available() && peak1.available()) {
tft.drawFloat(rms1.read(), 3, 70, 50);
tft.drawFloat(peak1.read(), 3, 70, 70);
fcl = 0;
}
}
/// <summary>
/// Draw right Side
/// </summary>
void drawNeedleRight() {
if (++fcr > 500000 && rms2.available() && peak2.available()) {
tft.drawFloat(rms2.read(), 3, 70, 120);
tft.drawFloat(peak2.read(), 3, 70, 140);
fcr = 0;
}
}
In the whole project there are some modules which use AudioLib and need FFT, RMS, PEAK.
In this extraction only RMS and PEAK are interesting.
The original looks like this (an analog VU meter is drawn):
The SGTL5000 scheme of the whole project:
In the test program the display shows RMS1, RMS2, PEAK1 and PEAK2 and only every 500000 frames to calm the display for you.
Now to the problem:
If I don't fetch the samples in the main loop and comment out getSamples(1);, no more RMS and PEAK arrive!
I would love to stop the queue completely for this module and only turn it back on for modules that really need it, but that doesn't work properly either, the stopped queue doesn't always restart.
So the goal is to run the queue and still get RMS and PEAK reliably when getSamples(1); is not present in the main loop .
What am I doing wrong?
Last edited: