DonnellyOverflow
DonnellyOverflow

Reputation: 4195

Normalize values between -1 and 1 inclusive

I am trying to generate a .wav file in python using Numpy. I have voltages ranging between 0-5V and I need to normalize them between -1 and 1 to use them in a .wav file.

I have seen this website which uses numpy to generate a wav file but the algorithm used to normalize is no long available.

Can anyone explain how I would go about generating these values in Python on my Raspberry Pi.

Upvotes: 5

Views: 10124

Answers (4)

TiagoLr
TiagoLr

Reputation: 3074

Asking bing gave me the right answer:

enter image description here

First you need to calculate the max and min of your peaks:

min = 1;
max = -1;
for (value in samples) 
  min = Math.min(min, value);
  max = Math.max(max, value);

Then loop the samples again and apply the formula to each value

for (i, value in samples)
  samples[i] = 2 * ((value - min) / (max - min)) - 1

Upvotes: 1

U3.1415926
U3.1415926

Reputation: 900

The following function should do what you want, irrespective of the range of the input data, i.e., it works also if you have negative values.

import numpy as np
def my_norm(a):
    ratio = 2/(np.max(a)-np.min(a)) 
    #as you want your data to be between -1 and 1, everything should be scaled to 2, 
    #if your desired min and max are other values, replace 2 with your_max - your_min
    shift = (np.max(a)+np.min(a))/2 
    #now you need to shift the center to the middle, this is not the average of the values.
    return (a - shift)*ratio

my_norm(data)

Upvotes: 1

Fuehnix
Fuehnix

Reputation: 1

You can use the fit_transform method in sklearn.preprocessing.StandardScaler. This method will remove the mean from your data and scale your array to unit variance (-1,1)

from sklearn.preprocessing import StandardScaler
data = np.asarray([[0, 0, 0],
     [1, 1, 1],
     [2,1, 3]])
data = StandardScaler().fit_transform(data)

And if you print out data, you will now have:

[[-1.22474487 -1.41421356 -1.06904497]
[ 0.          0.70710678 -0.26726124]
[ 1.22474487  0.70710678  1.33630621]]

Upvotes: -1

tmdavison
tmdavison

Reputation: 69076

isn't this just a simple calculation? Divide by half the maximum value and minus 1:

In [12]: data=np.linspace(0,5,21)

In [13]: data
Out[13]: 
array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ,  1.25,  1.5 ,  1.75,  2.  ,
        2.25,  2.5 ,  2.75,  3.  ,  3.25,  3.5 ,  3.75,  4.  ,  4.25,
        4.5 ,  4.75,  5.  ])

In [14]: data/2.5-1.
Out[14]: 
array([-1. , -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1,  0. ,
        0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ])

Upvotes: 3

Related Questions