Hi everyone,
It's been 3 days that I'm fighting with a signal problem and as I'm pretty begginer, I think I'm missing some subtilities. I'd be really grateful if someone could help me to understand what's wrong with my code.
What I want to do is : reading the microphone RMS value variation without reading the generated signal sent to the speaker (the microphone being close from the speaker).
So, I did a schema (attached) to illustrate what I had in mind when I wrote the code (much more clear that writing a novel here).
https://forum.pjrc.com/images/attach/jpg.gif
The big question I can't solve is how I could detect an accurate delay by scanning the change in RMS values on both signals, knowing that I need to scan RMS values every 50ms to have a pretty stable value.
Here is my current code :
It's been 3 days that I'm fighting with a signal problem and as I'm pretty begginer, I think I'm missing some subtilities. I'd be really grateful if someone could help me to understand what's wrong with my code.
What I want to do is : reading the microphone RMS value variation without reading the generated signal sent to the speaker (the microphone being close from the speaker).
So, I did a schema (attached) to illustrate what I had in mind when I wrote the code (much more clear that writing a novel here).
https://forum.pjrc.com/images/attach/jpg.gif
The big question I can't solve is how I could detect an accurate delay by scanning the change in RMS values on both signals, knowing that I need to scan RMS values every 50ms to have a pretty stable value.
Here is my current code :
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <MedianFilter.h> //https://github.com/daPhoosa/MedianFilter
#include <RunningAverage.h> //https://playground.arduino.cc/Main/RunningAverage
#include <Bounce.h>
// GUItool: begin automatically generated code
AudioSynthNoiseWhite noise1; //xy=82,272
AudioPlaySdWav playSdWav2; //xy=82,388
AudioPlaySdWav playSdWav1; //xy=83,357
AudioMixer4 mixer1; //xy=242,291
AudioMixer4 mixer2; //xy=245,370
AudioMixer4 mixer3; //xy=413,320
AudioInputI2S i2s2; //xy=554,155
AudioEffectDelay delay1; //xy=574,319
AudioOutputI2S i2s1; //xy=575,405
AudioAnalyzePeak peak_Mic; //xy=742,186
AudioAnalyzeRMS rms_Mic; //xy=747,149
AudioAnalyzeRMS rms_interne; //xy=813,274
AudioAnalyzePeak peak_interne; //xy=815,309
AudioConnection patchCord1(noise1, 0, mixer1, 0);
AudioConnection patchCord2(playSdWav2, 0, mixer2, 2);
AudioConnection patchCord3(playSdWav2, 1, mixer2, 3);
AudioConnection patchCord4(playSdWav1, 0, mixer2, 0);
AudioConnection patchCord5(playSdWav1, 1, mixer2, 1);
AudioConnection patchCord6(mixer1, 0, mixer3, 0);
AudioConnection patchCord7(mixer2, 0, mixer3, 1);
AudioConnection patchCord8(mixer3, delay1);
AudioConnection patchCord9(mixer3, 0, i2s1, 0);
AudioConnection patchCord10(i2s2, 0, rms_Mic, 0);
AudioConnection patchCord11(i2s2, 0, peak_Mic, 0);
AudioConnection patchCord12(delay1, 0, rms_interne, 0);
AudioConnection patchCord13(delay1, 0, peak_interne, 0);
AudioControlSGTL5000 sgtl5000_1; //xy=641,494
// GUItool: end automatically generated code
MedianFilter MedianGainCompens(30, 0);
elapsedMillis msecs;
//REGLAGES Variables :
int freqRms = 50; //SETTING
uint8_t PeakDetect = 0 ; // SETTING
// INIT :
uint8_t MicroRms;
uint8_t NoiseRms;
uint8_t Gaincompens;
uint8_t memMic;
uint8_t memNoise;
uint8_t Deriv_Mic;
uint8_t Deriv_Noise;
uint8_t Micro_Gaincompens;
uint8_t GainCompensMedian;
uint8_t InternalRms ;
float InternalPeak ;
float MicroPeak ;
String SoundFile, SoundType;
int resetMillis = 0;
int resetMillis1 = 0;
int resetMillis2 = 0;
int Delai_Compens = 0;
int condition;
int condition1;
int condition2;
int LastCondition = 0;
int LastCondition1 = 0;
int LastCondition2 = 0;
void setup() {
Serial.begin(9600);
AudioMemory(120); // Audio connections require memory to work. For more detailed information, see the MemoryAndCpuUsage example
SoundFile = String();
SoundType = String(".WAV");
sgtl5000_1.enable();
sgtl5000_1.volume(1);
sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
sgtl5000_1.micGain(20);
SPI.setMOSI(7);
SPI.setSCK(14);
noise1.amplitude(1);
delay(1000);
}
void loop() {
// MIC / INTERNAL SIGNAL CALIBRATION
// Gain Compensation Calibration
while (millis() < 5000) {
condition = millis() - resetMillis < freqRms;
// Scan RMS value every freqRms msecs.
if (condition) {
if (condition != LastCondition) {
InternalRms = rms_interne.read() * 1000;
MicroRms = rms_Mic.read() * 1000;
LastCondition = 1;
}
}
else {
LastCondition = 0;
resetMillis = millis();
}
Gaincompens = InternalRms - MicroRms;
MedianGainCompens.in(Gaincompens);
GainCompensMedian = MedianGainCompens.out();
}
// Delay Compensation Calibration
while (millis() > 5000 && millis() < 10000) {
// --------
// Burst Noise generation
// --------
if (millis() - resetMillis1 < 500) {
noise1.amplitude(0);
}
if (millis() - resetMillis1 > 500) {
noise1.amplitude(1);
}
if (millis() - resetMillis1 > 1000) {
resetMillis1 = millis();
}
//Calculate the delay between the 2 signals.
condition = millis() - resetMillis < freqRms;
// Scan RMS value every freqRms msecs.
if (condition) {
if (condition != LastCondition) {
InternalRms = rms_interne.read() * 1000;
MicroRms = rms_Mic.read() * 1000 + GainCompensMedian; //Microphone RMS value + the gain compensation found with the first calibration.
// Find the derivative in order to know sharp varations to be able to calculate the delay when the noise is playing.
Deriv_Noise = InternalRms - memNoise;
memNoise = InternalRms;
Deriv_Mic = Micro_Gaincompens - memMic ;
memMic = Micro_Gaincompens;
LastCondition = 1;
}
}
else {
LastCondition = 0;
resetMillis = millis();
}
//Threshold to detect a sharp variation
condition1 = Deriv_Noise > PeakDetect;
condition2 = Deriv_Mic > PeakDetect;
// Detect the delay between variation of both signals.
if (condition1) {
if (condition1 != LastCondition1) {
// Serial.println("PEAK Noise");
resetMillis2 = millis();
LastCondition1 = condition1;
}
}
else {
LastCondition1 = 0;
}
if (condition2) {
if (condition2 != LastCondition2) {
// Serial.println("PEAK Micro");
Delai_Compens = millis() - resetMillis2;
LastCondition2 = condition2;
}
}
else {
LastCondition2 = 0;
}
}
noise1.amplitude(0);
}
Last edited: