Reputation: 2070
I want to use an array to play music/sounds. The output music/sounds needs to be polyphonic.
I tried this:
from scipy.io.wavfile import write
import numpy as np
duration=0.24
amp=1E4
rate=44100
def note(freq, duration, amp, rate):
t = np.linspace(0, duration, duration * rate)
data = np.sin(2*np.pi*freq*t)*amp
return data.astype(np.int16) # two byte integers
tone0 = note(0, duration, amp, rate) #silence
tone1 = note(261.63, duration, amp, rate) # C4
tone2 = note(329.63, duration, amp, rate) # E4
tone3 = note(392.00, duration, amp, rate) # G4
seq1 = np.concatenate((tone1,tone0,tone0,tone0, tone1),axis=1)
seq2 = np.concatenate((tone0,tone2,tone0,tone0, tone2),axis=1)
seq3 = np.concatenate((tone0,tone0,tone3,tone0, tone3),axis=1)
song = np.dstack((seq1,seq2,seq3))
write('song.wav', 44100, song)
I would like to play the song.wav file and hear the notes C, E and G one after the other then a silence and then the C chord (C,E,G notes play at the same time).
What I get, instead is an error by the write function. And that's ok because the write function (as far as I know it can´t create polyphonic wav files).
Just in case, the error is:
Traceback (most recent call last):
File "music2.py", line 26, in <module>
write('song.wav', 44100, song)
File "/usr/lib/python2.7/dist-packages/scipy/io/wavfile.py", line 168, in write
fid.write(struct.pack('<ihHIIHH', 16, 1, noc, rate, sbytes, ba, bits))
struct.error: 'I' format requires 0 <= number <= 4294967295
Upvotes: 4
Views: 1381
Reputation: 3616
The error you're getting is due to write
wanting only a 1- or 2-dimensional array. You are passing it a 3-dimensional array (the output of dstack
is 3D).
I'm not sure I get what you mean by polyphonic, but if you simply mean that you want to have different tones overlaid on each-other then all you need to do is superimpose the waveforms:
song = seq1 + seq2 + seq3 # Assumes seqs are of same length
In the end you probably want to be passing a 1-D array. 2-D arrays are for if you want to write stereo sounds.
Upvotes: 3