'NumPy adds a dot after each element of an array which I can’t strip
I am trying to write code which generates a sound file based on a series of frequencies I give it, but I have reached a point where compiling the arrays of integer values together puts a decimal point after each one which corrupts the sound file I'm generating.
I've tried converting it into a list, turning all elements into integer values, and then converting it back. This removes the dots, but it still corrupts the file.
Here is my code:
import numpy as np
from scipy.io.wavfile import write
# Samples per second
sps = 44100
# Duration
duration = 0.1
def wavegen(build):
final_array = np.array([])
for i in build:
freq = i
eachnum = np.arange(duration * sps)
waveform = np.sin(2 * np.pi * eachnum * freq / sps)
waveform_quiet = waveform * 0.3
waveform_integers = np.int16(waveform_quiet * 32767)
final_array = np.append(final_array, waveform_integers)
print(final_array)
write('sine.wav', sps, final_array)
wavegen([100, 50, 100, 50])
And the array generated looks like this:
[ 0. 140. 280. ... -210. -140. -70.]
Solution 1:[1]
The reason that you are getting the decimal places is because final_array = np.array([])
is creating a float type array. When you append your integer array waveform_integers
with the float type array final_array
, you get a float type array because final_array
is set to use floats.
To fix this, you can use final_array = np.array([], dtype='int16')
which will make it so that both arrays in np.append
are int16
arrays and the result is also an int16
array.
Solution 2:[2]
The use of np.append
in a loop is inefficient. List append is better, since it works in-place. np.append
is a cover function for np.concatenate
, which makes a whole new array (with all the involved copying) each call.
def wavegen(build):
alist = []
for i in build:
freq = i
eachnum = np.arange(duration * sps)
waveform = np.sin(2 * np.pi * eachnum * freq / sps)
waveform_quiet = waveform * 0.3
alist.append(waveform_integers * 32767)
final_array = np.array(alist) # 2d result
# or final_array = np.hstack(alist) # 1d
final_array = final_array.astype(np.int16) # change the dtype just once
return final_array
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Peter Mortensen |
Solution 2 |