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