ref: a8024fd6adcfe5456bea55e1ebd8f7e608c986da
parent: 12b9daba425a3cd0584930390d6a7e105b63cd29
author: cbagwell <cbagwell>
date: Sat Nov 10 12:01:46 EST 2001
Changed silence to use RMS values to smooth out noise.
--- a/Changelog
+++ b/Changelog
@@ -36,7 +36,8 @@
o Silence effect was broken on stereo files. Also, made thresholds
relative to original bit percision of audio data. When 16-bit audio
is scaled up to 32-bits, a little bit of noise starts to look like a
- large amplitude of noise.
+ large amplitude of noise. Also, now using RMS values to smooth out
+ clicks. RMS rolling window size is 1/10 of sample rate.
o Changed Floats into a type of encoding instead of a size of audio data.
o Put a flush at the end of OSS driver so that no old data would be
left in internal buffers after changing audio format parameters.
--- a/src/silence.c
+++ b/src/silence.c
@@ -62,6 +62,12 @@
st_size_t stop_holdoff_end;
int stop_found_periods;
+ int64_t *window;
+ int64_t *window_current;
+ int64_t *window_end;
+ st_size_t window_size;
+ double rms_sum;
+
/* State Machine */
char mode;
} *silence_t;
@@ -242,6 +248,23 @@
{
silence_t silence = (silence_t) effp->priv;
+ silence->window_size = (effp->ininfo.rate / 10) * effp->ininfo.channels;
+ silence->window = (int64_t *)malloc(silence->window_size *
+ sizeof(int64_t));
+
+ if (!silence->window)
+ {
+ st_fail("Unable to allocate memory");
+ return(ST_EOF);
+ }
+
+ memset(silence->window, 0,
+ silence->window_size * sizeof(int64_t));
+
+ silence->window_current = silence->window;
+ silence->window_end = silence->window + silence->window_size;
+ silence->rms_sum = 0;
+
/* Now that we now sample rate, reparse duration. */
if (silence->start)
{
@@ -326,6 +349,30 @@
return rc;
}
+st_sample_t compute_rms(eff_t effp, st_sample_t sample)
+{
+ silence_t silence = (silence_t) effp->priv;
+ double new_sum;
+ st_sample_t rms;
+
+ new_sum = silence->rms_sum;
+ new_sum -= *silence->window_current;
+ new_sum += ((double)sample * (double)sample);
+
+ rms = sqrt(new_sum / silence->window_size);
+
+ return (rms);
+}
+
+void update_rms(eff_t effp, st_sample_t sample)
+{
+ silence_t silence = (silence_t) effp->priv;
+
+ silence->window_current++;
+ if (silence->window_current >= silence->window_end)
+ silence->window_current = silence->window;
+}
+
/* Process signed long samples from ibuf to obuf. */
/* Return number of samples processed in isamp and osamp. */
int st_silence_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
@@ -353,7 +400,8 @@
threshold = 0;
for (j = 0; j < effp->ininfo.channels; j++)
{
- threshold |= aboveThreshold(effp, ibuf[j],
+ threshold |= aboveThreshold(effp,
+ compute_rms(effp, ibuf[j]),
silence->start_threshold,
silence->start_unit);
}
@@ -363,6 +411,7 @@
/* Add to holdoff buffer */
for (j = 0; j < effp->ininfo.channels; j++)
{
+ update_rms(effp, *ibuf);
silence->start_holdoff[
silence->start_holdoff_end++] = *ibuf++;
nrOfInSamplesRead++;
@@ -387,6 +436,10 @@
else /* !above Threshold */
{
silence->start_holdoff_end = 0;
+ for (j = 0; j < effp->ininfo.channels; j++)
+ {
+ update_rms(effp, ibuf[j]);
+ }
ibuf += effp->ininfo.channels;
nrOfInSamplesRead += effp->ininfo.channels;
}
@@ -442,7 +495,8 @@
threshold = 1;
for (j = 0; j < effp->ininfo.channels; j++)
{
- threshold &= aboveThreshold(effp, ibuf[j],
+ threshold &= aboveThreshold(effp,
+ compute_rms(effp, ibuf[j]),
silence->stop_threshold,
silence->stop_unit);
}
@@ -462,6 +516,7 @@
/* Not holding off so copy into output buffer */
for (j = 0; j < effp->ininfo.channels; j++)
{
+ update_rms(effp, *ibuf);
*obuf++ = *ibuf++;
nrOfInSamplesRead++;
nrOfOutSamplesWritten++;
@@ -472,6 +527,7 @@
/* Add to holdoff buffer */
for (j = 0; j < effp->ininfo.channels; j++)
{
+ update_rms(effp, *ibuf);
silence->stop_holdoff[
silence->stop_holdoff_end++] = *ibuf++;
nrOfInSamplesRead++;
@@ -588,6 +644,11 @@
{
silence_t silence = (silence_t) effp->priv;
- free(silence->stop_holdoff);
+ if (silence->window)
+ free(silence->window);
+ if (silence->start_holdoff)
+ free(silence->start_holdoff);
+ if (silence->stop_holdoff)
+ free(silence->stop_holdoff);
return(ST_SUCCESS);
}