Reputation: 3804
I'm really baffled by this. I asked a few years back how to generate a tone with Python using something like playTone(freq, duration) and was overwhelmed by the complexity of the responses, and the lack of any simple solution.
The winsound module is inadequate as it trips over itself after a few notes, and is too limited in other ways (maybe 2 notes at a time would be nice, or a choice of wave types).
As a teacher, it makes a huge amount of sense to me to use sound to illustrate programming principles such as loops and randomness, as many people are auditory learners.
This kind of thing was incredibly simple with early home computers running Basic, where you could create 4 channel master pieces with ease. I just don't understand why such a thing isn't easily available with Python, which is meant to be a so well suited to learners.
JavaScript now can do this relatively easily with the audio context and its oscillators, but I want to use Python, and in particular to combine the visual power and simplicity of turtle graphics with an auditory component that doesn't require in depth knowledge of computer hardware and physics to produce.
Can anyone help me to find a simple up-to-date (late 2016) solution for this please?
Upvotes: 0
Views: 1935
Reputation: 11473
There are various ways to do it. Here is an simple implementation using pyaudio
module.
You can install pyaudio using
pip install pyaudio
#for windows and
sudo apt-get install python-pyaudio
#For linux
Following program has playTone
function that gets two inputs; frequency
and duarion
. You can vary those to get the desired audible frequency tones and "bearable" duration.
If you are planning to create multi-channel complex audio , then you may want to look into pygame. There are ample examples on SO for that.
import pyaudio
import math
def playTone( freq , length):
bit_rate = 16000 #number of frames per second/frameset.
frequency = freq #in Hz, waves per second
play_time = length #in seconds to play sound
if frequency > bit_rate:
bit_rate = frequency+100
num_frames = int(bit_rate * play_time)
total_frames = num_frames % bit_rate
wave_info = ''
for x in xrange(num_frames):
wave_info = wave_info+chr(int(math.sin(x/((bit_rate/frequency)/math.pi))*127+128))
for x in xrange(total_frames):
wave_info = wave_info+chr(128)
p = PyAudio()
stream = p.open(format = p.get_format_from_width(1),
channels = 1,
rate = bit_rate,
output = True)
stream.write(wave_info)
stream.stop_stream()
stream.close()
p.terminate()
if __name__ == '__main__':
frequency = 1500 #Hz
duration = 2 #seconds
PyAudio = pyaudio.PyAudio
#Function to play frequency for given duration
playTone(frequency , duration)
Upvotes: 1