Reputation: 30677
I would like to generate consecutive audio tones in iPython. I've seen pyo
but I can only get it to work in the terminal
...I'd prefer to test out compositions in iPython
if possible.
I recently found iPython.display.Audio
and thought it could be a useful way to generate tones for animations.
# Generate a sound
from IPython.display import Audio
import numpy as np
def waveform(freq,sec=1,sample_rate=44100):
t = np.linspace(0,sec,sample_rate*sec)
return(np.sin(np.pi*freq*t))
scale = [440, 493.88, 523.25, 587.33, 659.25, 698.46, 783.99, 880.00]
sample_rate = 44100
Audio(waveform(440,sec=2),rate=sample_rate,autoplay=True)
So this works, it makes a little soundbox GUI that plays my tone. . . but I can't generate multiple tones when I try:
for note in scale:
Audio(waveform(note,sec=2),rate=sample_rate,autoplay=True)
I'd really like to get iPython.display.Audio
to work but I'm open to using other modules if it plays the tones in realtime (instead of just writing to file). I've heard of pyaudio
and pygame
but I'm not sure if the sounds can be generated on the fly.
Upvotes: 0
Views: 848
Reputation: 2885
[edit] I realize I misread your question. My original answer was about combining tones, which you may still find useful so I left it below. You need to append your audio vectors to make one long tone, like this:
sequence = np.array([])
for note in scale:
sequence = np.append(sequence, waveform(note, sec))
Audio(sequence,rate=sample_rate,autoplay=True)
If you want multiple tones to be played at once, keep reading.
Audio waves follow the superposition principle, so the combination of multiple waves is a linear sum of all the parts. This is super cool because it means you can combine multiple sounds by literally summing them, since you already have them in a nice vector form.
sec = 2
chord = waveform(0, sec) # silence
for note in scale:
chord += waveform(note, sec)
Audio(chord,rate=sample_rate,autoplay=True)
Here's a pretty nice page on superposition of waves as it relates to audio.
Upvotes: 2