Measure voltage changes with unknown baseline
An audio signal consists of two main components:


An AC signal
A DC offset


What you are interested in is the AC signal, but not the DC offset.  That DC offset is what is drifting in your current model.

So you need to AC couple the signal. That is, couple the signal to your Arduino in such a way that only the AC portion gets through.

The simplest way is with a capacitor.

But the Arduino can't handle negative voltages, and an AC signal has negative voltages. So you need to get rid of them.

The simplest way is to add a DC offset.

But didn't we just get rid of a DC offset that we didn't want? Yep. But that was an unknown DC offset. If we then add in a DC offset that we do know, and is stable, then we can work with it.

Here's a very simple circuit:







simulate this circuit &ndash; Schematic created using CircuitLab

The capacitor C1 removes the existing DC offset.  R1 and R2 then form a voltage divider giving 2.5V (half of 5V), which is then added to the pure AC signal.

That means that the signal now varies around 2.5V.  Silence is 2.5V, and noise is other values above and below that.

Since 2.5V is half of the 5V the Arduino runs on, silence should read at somewhere near half the ADC value. That's about 512.  Sound will be both above and below that value.

So if you subtract 512 from your analog reading you will effectively be subtracting the DC offset you just added, giving you a value that can be either positive or negative.

For simplicity, since you don't care whether it's positive or negative, you can then remove the sign from the number to just give you a magnitude.

int audio = analogRead(A0); // Get a sample
audio = audio - 512; // Remove DC offset
audio = abs(audio); // Remove sign


You can now compare that to a threshold value:

if (audio &gt; 100) {
    // do something
}