Re: Audio Compressor

Ian McCallion <[email protected]>
Newsgroups gmane.comp.gnu.octave.general
Message-ID <CAFgLC_HVmT9sPfrWFOfaD8uVC1MJhnNthhDTM5UJujhzQyhN=A@mail.gmail.com>
On Tue, 18 Aug 2020 at 14:41, Renato S. Yamane <[email protected]>
wrote:

> Hi,
>
> Is there an Audio Compressor available in Octave?
> https://www.mathworks.com/help/audio/ref/compressor-system-object.html
>
> I'm compressing my noises in the worst way, as you can see in the "while"
> condition on the example below.
>
> In my way, the peaks will be "clipped", and I would like to avoid my
> stupid workaround:
>
> ====================
> crest_factor = 6;
> typenoise = noise(10*44100, 1, 'pink');
> [z, p, k] = butter(4, [100/(44100/2), 500/(44100/2)]);
> sos = zp2sos (z, p, k);
> filtered = sosfilt(sos, typenoise);
> normalized = filtered / (rms(filtered) / 10^(-crest_factor/20));
>
> #{
> Now I'm making an stupid workaround, as the audio file must be in
> a range from -1 to +1:
> #}
>
> while (normalized(normalized > 1) || normalized(normalized < -1))
>   normalized(normalized > 1) = 1;
>   normalized(normalized < -1) = -1;
>   normalized = normalized / (rms(normalized) / 10^(-crest_factor/20));
> endwhile
>
> audiowrite ('AudioFile.wav', normalized, 44100);
>

I'm not aware there is an equivalent function on Octave to the
Matlab compressor, but if I might make a couple of comments on the code:

1. Your while loop looks very strange to me and I believe the identical
result would be achieved much faster by simply omitting the while and
endwhile statements.

2.  The statement:
         normalized = filtered / (rms(filtered) / 10^(-crest_factor/20));
     normalises the signal to an RMS level of -6dB below 1. An RMS below 1
does not of
     course guarantee there will be no samples greater than 1, but unless
your signal is very
     peculiar I would expect there to be very few or none.

Possibly therefore the following code would meet your needs without the
need for complex compression.

crest_factor = 6;
typenoise = noise(10*44100, 1, 'pink');
[z, p, k] = butter(4, [100/(44100/2), 500/(44100/2)]);
sos = zp2sos (z, p, k);
filtered = sosfilt(sos, typenoise);
normalized = filtered / (rms(filtered) / 10^(-crest_factor/20));
NumberOfClippedSamples = nnz( normalized > 1 |normalized<-1)
normalized(normalized > 1) = 1;
normalized(normalized < -1) = -1;

I hope this helps.

Cheers... Ian
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.