3

I would like to record a tone with sounddevice i created numpy and write it into a wav file. here is the code:

import numpy 
import sounddevice as sd
import soundfile as sf
import sys

duration = 3
amplitude = 0.3
sampling_frequency = 44100

time = numpy.arange(int(numpy.ceil(duration * sampling_frequency))) /   sampling_frequency

frequency1 = 500
tone1 = amplitude * numpy.sin(2* numpy.pi * frequency1 * time)

frequency2 = 700
tone2 = amplitude * numpy.sin(2* numpy.pi * frequency1 * time)
frequency3 = 1500
tone3 = amplitude * numpy.sin(3* numpy.pi * frequency1 * time)
frequency4 = 400
tone4 = amplitude * numpy.sin(4* numpy.pi * frequency1 * time)

result = tone1
result2 = tone2
result3 = tone3
result4 = tone4

sd.play(result + result2 + result3 + result4, sampling_frequency)

filename = 'output.wav'

mydata = sd.rec(int(result + result2 + result3 + result4),sampling_frequency,channels=2, blocking=True)
sf.write(filename, mydata, sampling_frequency)

I get this error: only length-1 arrays can be converted to Python scalars What's wrong with the code? I'm a newbie with python

1
  • It would be helpful if you added the full error message, as it specifies which line yields the error. Commented Nov 25, 2017 at 19:09

3 Answers 3

2

Your second-to-last line is

mydata = sd.rec(int(result + result2 + result3 + result4),sampling_frequency,channels=2, blocking=True)

Where you try to cast the sum of the result1 etc variables to an integer. However, they are actually numpy arrays, since time is an array. You cannot convert an array into a single integer, since it has multiple values. I'm not sure why you are trying to do that, you probably just want to remove the int(), and change it to

mydata = sd.rec(result + result2 + result3 + result4, sampling_frequency, channels=2, blocking=True)
Sign up to request clarification or add additional context in comments.

Comments

1

sd.rec() is used to record sound from a sound device and output an array. It expects an integer of how long the recording should be. That is why it was throwing "TypeError: 'list' object cannot be interpreted as an integer".
https://python-sounddevice.readthedocs.io/en/0.3.7/#recording

You don't have to record the data, because you already have the data (your result variables). So you should just replace

mydata = sd.rec(int(result + result2 + result3 + result4),sampling_frequency,channels=2, blocking=True)

with

mydata = result + result2 + result3 + result4

Comments

0

Fyi, your "tone" formulas all use "frequency1" in them, instead of 1, 2, 3, & 4. This code works for me, tho I wasn't sure if you wanted to overlap the tones, or play them in sequence, so I did both:

import numpy as np
import sounddevice as sd
import soundfile as sf
import sys

duration = 3
amplitude = 0.3
sampling_frequency = 44100

frequency1 = 500
frequency2 = 700
frequency3 = 1500
frequency4 = 400

time = np.arange(int(np.ceil(duration * sampling_frequency))) / sampling_frequency

tone1 = amplitude * np.sin(2* np.pi * frequency1 * time)
tone2 = amplitude * np.sin(2* np.pi * frequency2 * time)
tone3 = amplitude * np.sin(3* np.pi * frequency3 * time)
tone4 = amplitude * np.sin(4* np.pi * frequency4 * time)

result = tone1 + tone2 + tone3 + tone4

# overlaps the tones
sd.play(result, sampling_frequency)
sd.wait()
sf.write('tone.wav', result, sampling_frequency)

sequence = np.append(tone1, [tone2, tone3, tone4])

# plays each tone in sequence
sd.play(sequence, sampling_frequency)
sd.wait()
sf.write('sequence.wav', sequence, sampling_frequency)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.