Audio Compressor

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Audio Compressor

yamane
Hi,

Is there an Audio Compressor available in Octave?

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);
  ==================== 

Thanks in advance,
Renato 


Reply | Threaded
Open this post in threaded view
|

Re: Audio Compressor

Doug Stewart-4


On Tue, Aug 18, 2020 at 9:41 AM Renato S. Yamane <[hidden email]> wrote:
Hi,

Is there an Audio Compressor available in Octave?

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);
  ==================== 

Thanks in advance,
Renato 

There are many ways to do Audio Compression.
Tell us more about what you want to accomplish.


--
DASCertificate for 206392



Reply | Threaded
Open this post in threaded view
|

Re: Audio Compressor

yamane
Em ter., 18 de ago. de 2020 às 15:12, Doug Stewart <[hidden email]> escreveu:
On Tue, Aug 18, 2020 at 9:41 AM Renato S. Yamane <[hidden email]> wrote:
Is there an Audio Compressor available in Octave?

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);
  ==================== 
 
There are many ways to do Audio Compression.
Tell us more about what you want to accomplish.

Hi, thanks for your feedback.
I just need to the user define the crest factor (first line of the code above) and the script must generate the noise (wav file) with the respective crest factor without clipping.
I'm expecting the user define the Crest Factor between -6 to -12dB.

Many thanks,
Renato


Reply | Threaded
Open this post in threaded view
|

Re: Audio Compressor

Ian McCallion
In reply to this post by yamane
On Tue, 18 Aug 2020 at 14:41, Renato S. Yamane <[hidden email]> wrote:
Hi,

Is there an Audio Compressor available in Octave?

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


Reply | Threaded
Open this post in threaded view
|

Re: Audio Compressor

Doug Stewart-4
In reply to this post by yamane


On Tue, Aug 18, 2020 at 11:26 AM Renato S. Yamane <[hidden email]> wrote:
Em ter., 18 de ago. de 2020 às 15:12, Doug Stewart <[hidden email]> escreveu:
On Tue, Aug 18, 2020 at 9:41 AM Renato S. Yamane <[hidden email]> wrote:
Is there an Audio Compressor available in Octave?

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);
  ==================== 
 
There are many ways to do Audio Compression.
Tell us more about what you want to accomplish.

Hi, thanks for your feedback.
I just need to the user define the crest factor (first line of the code above) and the script must generate the noise (wav file) with the respective crest factor without clipping.
I'm expecting the user define the Crest Factor between -6 to -12dB.

Many thanks,
Renato

But crest factor and clipping are 2 independent things. you can have a crest factor of some value  and still have clipping or no clipping.


--
DASCertificate for 206392



Reply | Threaded
Open this post in threaded view
|

Re: Audio Compressor

yamane
In reply to this post by Ian McCallion
Hi,

Em ter., 18 de ago. de 2020 às 16:27, Ian McCallion <[hidden email]> escreveu:
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.

Without the "while" will not be possible get the Crest Factor desired, because when I just set everything greater than 1 to 1, and everything lower than -1 to -1, the RMS level will be changed.
The "while" function will check the newer RMS level and calculated it again.
 
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.

This is why I'm using the "while" function, to reduce the number of samples greater than 1 & lower than -1
 
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;

In your example, I'm getting a Crest Factor of -6,36 instead of -6 (this 0,36dB is too much) and almost 20000 samples clipped.
I would like to avoid this approach "normalized(normalized > 1) = 1" to avoid a hard clipping.
What I'm looking for is a kind of Hard Limiter instead of a Hard Clipping.

Many thanks,
Renato