Reputation: 3804
I'm trying to get the following code to work in Python 3. It is fine in Python 2. I have changed the xrange
s to range
, but there is a problem with this line: data = ''.join(struct.pack('f', samp) for samp in tone)
:
sequence item 0: expected str instance, bytes found.
I found this answer but couldn't work out how to apply it to my situation. Any help much appreciated.
import math
import struct
import pyaudio
def play_tone(frequency, amplitude, duration, fs, stream):
N = int(fs / frequency)
T = int(frequency * duration) # repeat for T cycles
dt = 1.0 / fs
# 1 cycle
tone = (amplitude * math.sin(2 * math.pi * frequency * n * dt)
for n in xrange(N))
# todo: get the format from the stream; this assumes Float32
data = ''.join(struct.pack('f', samp) for samp in tone)
for n in xrange(T):
stream.write(data)
fs = 48000
p = pyaudio.PyAudio()
stream = p.open(
format=pyaudio.paFloat32,
channels=1,
rate=fs,
output=True)
# play the C major scale
scale = [130.8, 146.8, 164.8, 174.6, 195.0, 220.0, 246.9, 261.6]
for tone in scale:
play_tone(tone, 0.5, 0.75, fs, stream)
# up an octave
for tone in scale[1:]:
play_tone(2*tone, 0.5, 0.75, fs, stream)
stream.close()
p.terminate()
Upvotes: 3
Views: 1870
Reputation: 104842
The issue is that the empty string you're joining on is in fact a str
instance (a Unicode string), but the values you're joining together (that you get from struct.pack
) are bytes
instances. Python 3 doesn't let you mix the different string types together like that.
Change the ''
to b''
and it should work: data = b''.join(struct.pack('f', samp) for samp in tone)
Upvotes: 3