aloctavodia
aloctavodia

Reputation: 2070

How do I translate a numpy array to polyphonic music?

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
  1. Do you know an alternative to the write function that support polyphony?
  2. I am open to a complete alternative of my code. The important point is to generate (or play) polyphonic sounds from a numpy array. I am trying to do something like this: http://img44.imageshack.us/img44/6182/music.swf, but much simpler; not GUI; not interactive, just the same idea of a 1 and 0 array were the row have assigned and specific sound/note and the columns code for the time those notes are played.

Upvotes: 4

Views: 1381

Answers (1)

Isaac
Isaac

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

Related Questions