Reputation: 31
(I'm new at python)
I'm trying to run a simple code about pyaudio. I just copied and pasted a code that I found on the pyaudio web site.
I get this error:
OSError Traceback (most recent call last)
<ipython-input-7-3fc52ceecbf3> in <module>()
15 channels=wf.getnchannels(),
16 rate=wf.getframerate(),
---> 17 output=True)
18
19 # read data
/home/gustavolg/anaconda3/lib/python3.5/site-packages/pyaudio.py in open(self, *args, **kwargs)
748 """
749
--> 750 stream = Stream(self, *args, **kwargs)
751 self._streams.add(stream)
752 return stream
/home/gustavolg/anaconda3/lib/python3.5/site-packages/pyaudio.py in __init__(self, PA_manager, rate, channels, format, input, output, input_device_index, output_device_index, frames_per_buffer, start, input_host_api_specific_stream_info, output_host_api_specific_stream_info, stream_callback)
439
440 # calling pa.open returns a stream object
--> 441 self._stream = pa.open(**arguments)
442
443 self._input_latency = self._stream.inputLatency
OSError: [Errno -9996] Invalid output device (no default output device)
I can not figure out how to solve this error. I don't know if this has something to do with audio driver or if the code needs an output declaration. I mean, if I have to select an output.
The code:
import pyaudio
import wave
import sys
CHUNK = 1024
wf = wave.open("/home/gustavolg/anaconda3/aPython/file.wav", 'rb')
# instantiate PyAudio (1)
p = pyaudio.PyAudio()
# open stream (2)
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
# read data
data = wf.readframes(CHUNK)
# play stream (3)
while len(data) > 0:
stream.write(data)
data = wf.readframes(CHUNK)
# stop stream (4)
stream.stop_stream()
stream.close()
# close PyAudio (5)
p.terminate()
I'm using python3 on Jupyter notebook.
Upvotes: 3
Views: 25415
Reputation: 111
This may not be the issue that OP ran into, but I found a cause and fix of the [Errno -996] exception (and I thought I'd share this here since Google results lead here). Attempting to play multiple sounds with pyaudio at the same time can cause such a crash. For example, with something like this:
def playSound( self, soundName ):
audioFilePath = self._soundBank.get( soundName )
if not audioFilePath:
audioFilePath = os.path.join( globalData.paths['audioFolder'], soundName + ".wav" )
if not os.path.exists( audioFilePath ):
print( 'Invalid or missing sound file for', soundName )
return
self._soundBank[soundName] = audioFilePath
# Play the audio clip in a separate thread so that it's non-blocking
audioThread = Thread( target=self._playSoundHelper, args=(audioFilePath,) )
audioThread.start()
def _playSoundHelper( self, soundFilePath ):
""" Helper (thread-target) function for playSound(). Runs in a separate
thread to prevent audio playback from blocking anything else. """
p = None
wf = None
stream = None
try:
# Instantiate PyAudio and open the target audio file
p = pyaudio.PyAudio()
wf = wave.open( soundFilePath, 'rb' )
# Open an audio data stream
stream = p.open( format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True )
# Continuously read/write data from the file to the stream until there is no data left
data = wf.readframes( 1024 )
while len( data ) > 0:
stream.write( data )
data = wf.readframes( 1024 )
except AttributeError:
pass # Program probably closed while playing audio
except Exception as err:
soundFileName = os.path.basename( soundFilePath )
print( 'Unable to play "{}" sound.'.format(soundFileName) )
print( err )
# Stop the stream
if stream:
stream.stop_stream()
stream.close()
# Close PyAudio
if p:
p.terminate()
# Close the wav file
if wf:
wf.close()
Above, if playSound() is called too soon after another playSound(), the program will crash. However, this can be resolved by using an Event() object to mediate initialization of pyaudio and the stream so that only one may be initialized at a time, while still allowing the sounds to play back for-the-most-part simultaneously or 'on top' of each other (i.e the work in the data read/write loop portion of the thread). I added this like so:
def __init( self ):
self.audioGate = Event()
self.audioGate.set()
def _playSoundHelper( self, soundFilePath ):
""" Helper (thread-target) function for playSound(). Runs in a separate
thread to prevent audio playback from blocking anything else. """
p = None
wf = None
stream = None
try:
# Prevent race conditions on multiple sounds playing at once (can cause a crash); only allow one file to begin playing at a time
self.audioGate.wait() # Blocks until the following is done (event is re-set)
self.audioGate.clear()
# Instantiate PyAudio and open the target audio file
p = pyaudio.PyAudio()
wf = wave.open( soundFilePath, 'rb' )
# Open an audio data stream
stream = p.open( format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True )
self.audioGate.set() # Allow a new sound to be opened/initialized
# Continuously read/write data from the file to the stream until there is no data left
data = wf.readframes( 1024 )
while len( data ) > 0:
stream.write( data )
data = wf.readframes( 1024 )
except AttributeError:
pass # Program probably closed while playing audio
except Exception as err:
soundFileName = os.path.basename( soundFilePath )
print( 'Unable to play "{}" sound.'.format(soundFileName) )
print( err )
# Stop the stream
if stream:
stream.stop_stream()
stream.close()
# Close PyAudio
if p:
p.terminate()
# Close the wav file
if wf:
wf.close()
You could similarly use the Event to instead cancel any existing audio playback (by checking in the loop) before starting the latest one.
Upvotes: 1
Reputation: 91
check the following steps:
>>> import pyaudio
>>> pa = pyaudio.PyAudio()
>>> pa.get_default_input_device_info()
{'defaultLowOutputLatency': 0.008707482993197279,
'maxOutputChannels': 32,
'hostApi': 0,
'defaultSampleRate': 44100.0,
'defaultHighOutputLatency': 0.034829931972789115,
'name': 'default',
'index': 15,
'maxInputChannels': 32,
'defaultHighInputLatency': 0.034829931972789115,
'defaultLowInputLatency': 0.008707482993197279,
'structVersion': 2}
>>> pyaudio.pa.__file__
'/root/.virtualenvs/py3k/lib/python3.4/site-packages/_portaudio.cpython-34m.so'
make sure you have a default input device,if not you can refer to here
I want it's useful for you!
Upvotes: 7