I would like to monitor an audio stream and detect when it is "active" and music is playing or when it is "inactive" and is silent. What is a good way to measure when an audio stream changes state and continues to be "active?"
Each audio stream is amplified with this circuit.
Each audio stream has a different baseline voltage when it is not playing and "silent", but that voltage tends to drift slightly and change. This may be an artifact of my amp. I don't have an OScope and my multimeter is rubbish for low voltage so I can't quite pin down where the drift is coming from.
Currently, I'm using the method shown below, but that isn't as effectivewhen the audio stream is loud (e.g. has a compressed dynamic range).
Also, low volume tracks (e.g. classical music) tends have too low of a dynamic range to measure accurately and I get a lot of false "off" states.
#include <elapsedMillis.h> //measure elapsed time
const int analogInPin = A0; //Analog input pin - reads from amplifyer circuit
const int statusLight = 10; //Digital output pin for indicator light
int sensorValueA = 0; //Sensor reading now
int sensorValueB = 0; //Previous sensor reading
int sensorDeltaA = 0; //Change in sensor reading
int sensorDeltaB = 0; //Record the last delta - useful for prefenting accidental triggering on start
int sensorThreshold = 50; //Threshold in delta to trigger action
elapsedMillis turnOverTime; //Timer for measuring the turnover between changes in sensor reading
void loop() {
//measure the analog input
sensorValueA = analogRead(analogInPin);
sensorDeltaA = abs(sensorValueA - sensorValueB);
//check if the data is over the threshold and switch on
if ((sensorDeltaA >= sensorThreshold) and (sensorDeltaB != 0)) {
turnOverTime = 0;
powerStateA = true;
}
sensorValueB = sensorValueA;
//check if no sensor data beyond the threshold has been returned within the delay window, switch off
if (turnOverTime >= delayTime) {
turnOverTime = 0;
powerStateA = false;
}
//if the powerstate changes act acordingly
if (powerStateA != powerStateB) {
digitalWrite(statusLight, powerStateA);
}
}