Matteo Nazzario
Matteo Nazzario

Reputation: 11

How to normalize a raw audio file with python

I'm working in audio streaming from a robot. I'm using python and I'm saving the streaming result in .raw file. When I try to reproduce the file it is very noisy. I need to normalize the raw audio and save the new cleaned audio in a ndarray that I will save to a new raw file.

I saw that if I import the raw file to audacity and then apply the effect normalize the noise is removed and the audio is perfectly audible.(in the Audacity effect normalize I setted the Normalize maximun amplitude to -1.0 dB)

This is the content of the raw data (out_1_2.raw is the file that contains audio that I imported in Audacity)

A = np.fromfile('out_1_2.raw', dtype='int16')
print(A.shape)
print("A MAX --> "+ str(max(abs(A))))

The output of this code is:

(1638400,)
[    0     0  7168 16560     0     0  1024 16561     0     0]
A MAX --> 32704

After importing in Audacity the out_1_2.raw and applying the normalize effect as explained above, I exported from Audacity the new audible wave to a new raw file (out_1_2_normalized.raw) and the resulting file have the below content:

B = np.fromfile('out_1_2_normalized.raw', dtype='int16')
print(B.shape)
print("B MAX --> "+ str(max(abs(B))))

The output of this code is:

(1638400,)
[     0 -16384 -22494  16316      0   8192  17813  16318      0  24576]
B MAX --> 32767

I expect to know what is the algorthm that has to be used for this transformation so I can applied it inside my python code. If I need to implement the algorithm from zero or if there is a python lib that can be used.

Here is a sample of the raw audio file

Upvotes: 1

Views: 8769

Answers (1)

Andrés Marafioti
Andrés Marafioti

Reputation: 952

You wav signal is a digital 16 bits signal with range -32768 to +32767. The max you get after normalizing tells me you are normalizing to have the peak value equal the maximum value of the range. In order to do that in numpy, you can usually simply do:


not_normalized_signal = np.array([np.random.randint(-32768, 32767) for sample in range(16)], np.int16)  # Just a random 16 sample signal in the wav range with appropriate type.
print(np.max(np.abs(not_normalized_signal)))

normalized_signal = np.array([(not_normalized_signal / np.max(np.abs(not_normalized_signal))) * 32767], np.int16)

print(np.max(np.abs(normalized_signal)))

The normalization first divides the signal by its maximum absolute value. This will project it to the [-1, 1] space, and then by multiplying with the maximum value from the wav range, you project it back. Finally, I created a new array with the appropriate dtype just to make sure we still have a valid 16bit wav array.

I hope this helps!

Upvotes: 2

Related Questions