Python SoundDeviceStream write/read underflow/overflow errors











up vote
0
down vote

favorite












Using Raspberry Pi Model B+ running Raspbian GNU/Linux 8 (jessie) with Blue "Snowball" usb mic and powered speakers connected to 3.5mm jack output. Trying to run pushtotalk.py, a Google Assistant sample from GassistPi. Sample runs but produces multiple underflow errors and choppy audio out. Git search revealed this similar issue and points to buffer parameter settings in audio_helpers.py, (full code here) and possible CPU issues. Code snippets below show parameter settings and also code that produce the error message. Looked through the more detailed explanation of python-sounddevice here but it is way beyond me (only just started to learn Python!). Looking for a succinct (and relatively simple) answer to the question, what determines the values of the parameter settings and how can the code/parameters be modified to prevent/reduce the underflow errors?



Code snippet #1 Parameter setting in audio_helpers.py sample:



import sounddevice as sd


DEFAULT_AUDIO_SAMPLE_RATE = 16000
DEFAULT_AUDIO_SAMPLE_WIDTH = 2
DEFAULT_AUDIO_ITER_SIZE = 3200
DEFAULT_AUDIO_DEVICE_BLOCK_SIZE = 6400
DEFAULT_AUDIO_DEVICE_FLUSH_SIZE = 25600


def normalize_audio_buffer(buf, volume_percentage, sample_width=2):
"""Adjusts the loudness of the audio data in the given buffer.


Code snippet #2 Error reporting code in audio_helpers.py sample:



class SoundDeviceStream(object):
"""Audio stream based on an underlying sound device.

It can be used as an audio source (read) and a audio sink (write).

Args:
sample_rate: sample rate in hertz.
sample_width: size of a single sample in bytes.
block_size: size in bytes of each read and write operation.
flush_size: size in bytes of silence data written during flush operation.
"""
def __init__(self, sample_rate, sample_width, block_size, flush_size):
if sample_width == 2:
audio_format = 'int16'
else:
raise Exception('unsupported sample width:', sample_width)
self._audio_stream = sd.RawStream(
samplerate=sample_rate, dtype=audio_format, channels=1,
blocksize=int(block_size/2), # blocksize is in number of frames.
)
self._block_size = block_size
self._flush_size = flush_size
self._sample_rate = sample_rate

def read(self, size):
"""Read bytes from the stream."""
buf, overflow = self._audio_stream.read(size)
if overflow:
logging.warning('SoundDeviceStream read overflow (%d, %d)',
size, len(buf))
return bytes(buf)

def write(self, buf):
"""Write bytes to the stream."""
underflow = self._audio_stream.write(buf)
if underflow:
logging.warning('SoundDeviceStream write underflow (size: %d)',
len(buf))
return len(buf)


and finally the warning output when running pushtotalk.py



WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)




UPDATE OK with a bit of tinkering I have managed to reduce the choppy audio out by commenting out code in audio_helpers.py that generates the warning message output for the underflow and overflow conditions. It seems that when an under/overflow condition is detected, logging.warning is outputting to the terminal (stdout?) and this is causing the audio playback to briefly be interrupted. You can still detect a slight choppiness in the audio out but it is considerably better than before. Ideally, instead of preventing the output of the warning messages, it would be much better to prevent the under/overflow conditions occurring in the first place!



Code snippet below shows the two logging.warning functions commented out in audio_helpers.py. This file is located at /home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc on my setup.



    def read(self, size):
"""Read bytes from the stream."""
buf, overflow = self._audio_stream.read(size)
# if overflow:
# logging.warning('SoundDeviceStream read overflow (%d, %d)',
# size, len(buf))"""
return bytes(buf)

def write(self, buf):
"""Write bytes to the stream."""
underflow = self._audio_stream.write(buf)
# if underflow:
# logging.warning('SoundDeviceStream write underflow (size: %d)',
# len(buf))"""
return len(buf)


Use of Doc-String """ now changed to # for commented out sections



UPDATE 2
At @Matthias suggestion, details of how pushtotalk.pyis started and also results of using switch --audio-block-size



pi@raspberrypi:~ $ /home/pi/env/bin/googlesamples-assistant-pushtotalk --project-id 'gassistpi-xxxxx' --device-model-id 'gassistpi-xxxxx-gassistpi-xxxxx' --audio-block-size -77
Traceback (most recent call last):
File "/home/pi/env/bin/googlesamples-assistant-pushtotalk", line 11, in <module>
sys.exit(main())
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc/pushtotalk.py", line 351, in main
flush_size=audio_flush_size
File "/home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc/audio_helpers.py", line 190, in __init__
blocksize=int(block_size/2), # blocksize is in number of frames.
File "/home/pi/env/lib/python3.5/site-packages/sounddevice.py", line 1264, in __init__
**_remove_self(locals()))
File "/home/pi/env/lib/python3.5/site-packages/sounddevice.py", line 779, in __init__
callback_ptr, userdata),
OverflowError: can't convert negative number to unsigned
pi@raspberrypi:~ $


I also tried (valid binary) values for --audio-block-size ranging from 1024 through to 65536 and also 0 for good measure. All produced the same original result or runtime errors.










share|improve this question
























  • How are you starting the "pushtotalk" application? Did you try the --audio-block-size parameter? Did you try --help?
    – Matthias
    Nov 11 at 11:00










  • BTW, a normal Python comment starts with a # sign. Instead of commenting, you were creating multi-line strings with """, which effectively disables the quoted lines, but normally, you would just add a # at the beginning of each line. The multi-line strings directly below the line with the def are not mere comments, they are so-called "docstrings".
    – Matthias
    Nov 11 at 11:06










  • @Matthias Starting with pi@raspberrypi:~ $ /home/pi/env/bin/googlesamples-assistant-pushtotalk --project-id 'gassistpi-xxxx' --device-model-id 'gassistpi-xxxx-gassistpi-xxxxx' --audio-block-size 1024 Tried valued 1024 through to 65536 - No change. Looked through --help and read the docs but I can't work out what " Output_Underflow. Indicates that output data (or a gap) was inserted, possibly because the stream callback is using too much CPU time." means exactly or what I need to do to correct it . Hence my question.
    – Colin M
    Nov 11 at 19:18












  • OK, then I don't know, sorry. You should update your issue (github.com/googlesamples/assistant-sdk-python/issues/303) with this information. And you should make sure that you undo all changes you made to the source files. BTW, did you try some illegal value, like --audio-block-size -77? If this doesn't raise a meaningful error, then there is something wrong ...
    – Matthias
    Nov 12 at 9:03










  • @Matthias Will update the issue as suggested and illegal values does indeed throw an error (see updated issue). Thank you for trying to help. Whilst originally searching for an answer your name came up quite a lot so (as you are obviously a "python sound" guru) I had my hopes pinned on you. What I find frustrating is the explanation (or not!) of the error in the [Read_The_Docs] (python-sounddevice.readthedocs.io/en/0.3.12). What exactly is defined as a "gap" and how do you work out what the "stream callback" is!
    – Colin M
    Nov 12 at 12:44

















up vote
0
down vote

favorite












Using Raspberry Pi Model B+ running Raspbian GNU/Linux 8 (jessie) with Blue "Snowball" usb mic and powered speakers connected to 3.5mm jack output. Trying to run pushtotalk.py, a Google Assistant sample from GassistPi. Sample runs but produces multiple underflow errors and choppy audio out. Git search revealed this similar issue and points to buffer parameter settings in audio_helpers.py, (full code here) and possible CPU issues. Code snippets below show parameter settings and also code that produce the error message. Looked through the more detailed explanation of python-sounddevice here but it is way beyond me (only just started to learn Python!). Looking for a succinct (and relatively simple) answer to the question, what determines the values of the parameter settings and how can the code/parameters be modified to prevent/reduce the underflow errors?



Code snippet #1 Parameter setting in audio_helpers.py sample:



import sounddevice as sd


DEFAULT_AUDIO_SAMPLE_RATE = 16000
DEFAULT_AUDIO_SAMPLE_WIDTH = 2
DEFAULT_AUDIO_ITER_SIZE = 3200
DEFAULT_AUDIO_DEVICE_BLOCK_SIZE = 6400
DEFAULT_AUDIO_DEVICE_FLUSH_SIZE = 25600


def normalize_audio_buffer(buf, volume_percentage, sample_width=2):
"""Adjusts the loudness of the audio data in the given buffer.


Code snippet #2 Error reporting code in audio_helpers.py sample:



class SoundDeviceStream(object):
"""Audio stream based on an underlying sound device.

It can be used as an audio source (read) and a audio sink (write).

Args:
sample_rate: sample rate in hertz.
sample_width: size of a single sample in bytes.
block_size: size in bytes of each read and write operation.
flush_size: size in bytes of silence data written during flush operation.
"""
def __init__(self, sample_rate, sample_width, block_size, flush_size):
if sample_width == 2:
audio_format = 'int16'
else:
raise Exception('unsupported sample width:', sample_width)
self._audio_stream = sd.RawStream(
samplerate=sample_rate, dtype=audio_format, channels=1,
blocksize=int(block_size/2), # blocksize is in number of frames.
)
self._block_size = block_size
self._flush_size = flush_size
self._sample_rate = sample_rate

def read(self, size):
"""Read bytes from the stream."""
buf, overflow = self._audio_stream.read(size)
if overflow:
logging.warning('SoundDeviceStream read overflow (%d, %d)',
size, len(buf))
return bytes(buf)

def write(self, buf):
"""Write bytes to the stream."""
underflow = self._audio_stream.write(buf)
if underflow:
logging.warning('SoundDeviceStream write underflow (size: %d)',
len(buf))
return len(buf)


and finally the warning output when running pushtotalk.py



WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)




UPDATE OK with a bit of tinkering I have managed to reduce the choppy audio out by commenting out code in audio_helpers.py that generates the warning message output for the underflow and overflow conditions. It seems that when an under/overflow condition is detected, logging.warning is outputting to the terminal (stdout?) and this is causing the audio playback to briefly be interrupted. You can still detect a slight choppiness in the audio out but it is considerably better than before. Ideally, instead of preventing the output of the warning messages, it would be much better to prevent the under/overflow conditions occurring in the first place!



Code snippet below shows the two logging.warning functions commented out in audio_helpers.py. This file is located at /home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc on my setup.



    def read(self, size):
"""Read bytes from the stream."""
buf, overflow = self._audio_stream.read(size)
# if overflow:
# logging.warning('SoundDeviceStream read overflow (%d, %d)',
# size, len(buf))"""
return bytes(buf)

def write(self, buf):
"""Write bytes to the stream."""
underflow = self._audio_stream.write(buf)
# if underflow:
# logging.warning('SoundDeviceStream write underflow (size: %d)',
# len(buf))"""
return len(buf)


Use of Doc-String """ now changed to # for commented out sections



UPDATE 2
At @Matthias suggestion, details of how pushtotalk.pyis started and also results of using switch --audio-block-size



pi@raspberrypi:~ $ /home/pi/env/bin/googlesamples-assistant-pushtotalk --project-id 'gassistpi-xxxxx' --device-model-id 'gassistpi-xxxxx-gassistpi-xxxxx' --audio-block-size -77
Traceback (most recent call last):
File "/home/pi/env/bin/googlesamples-assistant-pushtotalk", line 11, in <module>
sys.exit(main())
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc/pushtotalk.py", line 351, in main
flush_size=audio_flush_size
File "/home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc/audio_helpers.py", line 190, in __init__
blocksize=int(block_size/2), # blocksize is in number of frames.
File "/home/pi/env/lib/python3.5/site-packages/sounddevice.py", line 1264, in __init__
**_remove_self(locals()))
File "/home/pi/env/lib/python3.5/site-packages/sounddevice.py", line 779, in __init__
callback_ptr, userdata),
OverflowError: can't convert negative number to unsigned
pi@raspberrypi:~ $


I also tried (valid binary) values for --audio-block-size ranging from 1024 through to 65536 and also 0 for good measure. All produced the same original result or runtime errors.










share|improve this question
























  • How are you starting the "pushtotalk" application? Did you try the --audio-block-size parameter? Did you try --help?
    – Matthias
    Nov 11 at 11:00










  • BTW, a normal Python comment starts with a # sign. Instead of commenting, you were creating multi-line strings with """, which effectively disables the quoted lines, but normally, you would just add a # at the beginning of each line. The multi-line strings directly below the line with the def are not mere comments, they are so-called "docstrings".
    – Matthias
    Nov 11 at 11:06










  • @Matthias Starting with pi@raspberrypi:~ $ /home/pi/env/bin/googlesamples-assistant-pushtotalk --project-id 'gassistpi-xxxx' --device-model-id 'gassistpi-xxxx-gassistpi-xxxxx' --audio-block-size 1024 Tried valued 1024 through to 65536 - No change. Looked through --help and read the docs but I can't work out what " Output_Underflow. Indicates that output data (or a gap) was inserted, possibly because the stream callback is using too much CPU time." means exactly or what I need to do to correct it . Hence my question.
    – Colin M
    Nov 11 at 19:18












  • OK, then I don't know, sorry. You should update your issue (github.com/googlesamples/assistant-sdk-python/issues/303) with this information. And you should make sure that you undo all changes you made to the source files. BTW, did you try some illegal value, like --audio-block-size -77? If this doesn't raise a meaningful error, then there is something wrong ...
    – Matthias
    Nov 12 at 9:03










  • @Matthias Will update the issue as suggested and illegal values does indeed throw an error (see updated issue). Thank you for trying to help. Whilst originally searching for an answer your name came up quite a lot so (as you are obviously a "python sound" guru) I had my hopes pinned on you. What I find frustrating is the explanation (or not!) of the error in the [Read_The_Docs] (python-sounddevice.readthedocs.io/en/0.3.12). What exactly is defined as a "gap" and how do you work out what the "stream callback" is!
    – Colin M
    Nov 12 at 12:44















up vote
0
down vote

favorite









up vote
0
down vote

favorite











Using Raspberry Pi Model B+ running Raspbian GNU/Linux 8 (jessie) with Blue "Snowball" usb mic and powered speakers connected to 3.5mm jack output. Trying to run pushtotalk.py, a Google Assistant sample from GassistPi. Sample runs but produces multiple underflow errors and choppy audio out. Git search revealed this similar issue and points to buffer parameter settings in audio_helpers.py, (full code here) and possible CPU issues. Code snippets below show parameter settings and also code that produce the error message. Looked through the more detailed explanation of python-sounddevice here but it is way beyond me (only just started to learn Python!). Looking for a succinct (and relatively simple) answer to the question, what determines the values of the parameter settings and how can the code/parameters be modified to prevent/reduce the underflow errors?



Code snippet #1 Parameter setting in audio_helpers.py sample:



import sounddevice as sd


DEFAULT_AUDIO_SAMPLE_RATE = 16000
DEFAULT_AUDIO_SAMPLE_WIDTH = 2
DEFAULT_AUDIO_ITER_SIZE = 3200
DEFAULT_AUDIO_DEVICE_BLOCK_SIZE = 6400
DEFAULT_AUDIO_DEVICE_FLUSH_SIZE = 25600


def normalize_audio_buffer(buf, volume_percentage, sample_width=2):
"""Adjusts the loudness of the audio data in the given buffer.


Code snippet #2 Error reporting code in audio_helpers.py sample:



class SoundDeviceStream(object):
"""Audio stream based on an underlying sound device.

It can be used as an audio source (read) and a audio sink (write).

Args:
sample_rate: sample rate in hertz.
sample_width: size of a single sample in bytes.
block_size: size in bytes of each read and write operation.
flush_size: size in bytes of silence data written during flush operation.
"""
def __init__(self, sample_rate, sample_width, block_size, flush_size):
if sample_width == 2:
audio_format = 'int16'
else:
raise Exception('unsupported sample width:', sample_width)
self._audio_stream = sd.RawStream(
samplerate=sample_rate, dtype=audio_format, channels=1,
blocksize=int(block_size/2), # blocksize is in number of frames.
)
self._block_size = block_size
self._flush_size = flush_size
self._sample_rate = sample_rate

def read(self, size):
"""Read bytes from the stream."""
buf, overflow = self._audio_stream.read(size)
if overflow:
logging.warning('SoundDeviceStream read overflow (%d, %d)',
size, len(buf))
return bytes(buf)

def write(self, buf):
"""Write bytes to the stream."""
underflow = self._audio_stream.write(buf)
if underflow:
logging.warning('SoundDeviceStream write underflow (size: %d)',
len(buf))
return len(buf)


and finally the warning output when running pushtotalk.py



WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)




UPDATE OK with a bit of tinkering I have managed to reduce the choppy audio out by commenting out code in audio_helpers.py that generates the warning message output for the underflow and overflow conditions. It seems that when an under/overflow condition is detected, logging.warning is outputting to the terminal (stdout?) and this is causing the audio playback to briefly be interrupted. You can still detect a slight choppiness in the audio out but it is considerably better than before. Ideally, instead of preventing the output of the warning messages, it would be much better to prevent the under/overflow conditions occurring in the first place!



Code snippet below shows the two logging.warning functions commented out in audio_helpers.py. This file is located at /home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc on my setup.



    def read(self, size):
"""Read bytes from the stream."""
buf, overflow = self._audio_stream.read(size)
# if overflow:
# logging.warning('SoundDeviceStream read overflow (%d, %d)',
# size, len(buf))"""
return bytes(buf)

def write(self, buf):
"""Write bytes to the stream."""
underflow = self._audio_stream.write(buf)
# if underflow:
# logging.warning('SoundDeviceStream write underflow (size: %d)',
# len(buf))"""
return len(buf)


Use of Doc-String """ now changed to # for commented out sections



UPDATE 2
At @Matthias suggestion, details of how pushtotalk.pyis started and also results of using switch --audio-block-size



pi@raspberrypi:~ $ /home/pi/env/bin/googlesamples-assistant-pushtotalk --project-id 'gassistpi-xxxxx' --device-model-id 'gassistpi-xxxxx-gassistpi-xxxxx' --audio-block-size -77
Traceback (most recent call last):
File "/home/pi/env/bin/googlesamples-assistant-pushtotalk", line 11, in <module>
sys.exit(main())
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc/pushtotalk.py", line 351, in main
flush_size=audio_flush_size
File "/home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc/audio_helpers.py", line 190, in __init__
blocksize=int(block_size/2), # blocksize is in number of frames.
File "/home/pi/env/lib/python3.5/site-packages/sounddevice.py", line 1264, in __init__
**_remove_self(locals()))
File "/home/pi/env/lib/python3.5/site-packages/sounddevice.py", line 779, in __init__
callback_ptr, userdata),
OverflowError: can't convert negative number to unsigned
pi@raspberrypi:~ $


I also tried (valid binary) values for --audio-block-size ranging from 1024 through to 65536 and also 0 for good measure. All produced the same original result or runtime errors.










share|improve this question















Using Raspberry Pi Model B+ running Raspbian GNU/Linux 8 (jessie) with Blue "Snowball" usb mic and powered speakers connected to 3.5mm jack output. Trying to run pushtotalk.py, a Google Assistant sample from GassistPi. Sample runs but produces multiple underflow errors and choppy audio out. Git search revealed this similar issue and points to buffer parameter settings in audio_helpers.py, (full code here) and possible CPU issues. Code snippets below show parameter settings and also code that produce the error message. Looked through the more detailed explanation of python-sounddevice here but it is way beyond me (only just started to learn Python!). Looking for a succinct (and relatively simple) answer to the question, what determines the values of the parameter settings and how can the code/parameters be modified to prevent/reduce the underflow errors?



Code snippet #1 Parameter setting in audio_helpers.py sample:



import sounddevice as sd


DEFAULT_AUDIO_SAMPLE_RATE = 16000
DEFAULT_AUDIO_SAMPLE_WIDTH = 2
DEFAULT_AUDIO_ITER_SIZE = 3200
DEFAULT_AUDIO_DEVICE_BLOCK_SIZE = 6400
DEFAULT_AUDIO_DEVICE_FLUSH_SIZE = 25600


def normalize_audio_buffer(buf, volume_percentage, sample_width=2):
"""Adjusts the loudness of the audio data in the given buffer.


Code snippet #2 Error reporting code in audio_helpers.py sample:



class SoundDeviceStream(object):
"""Audio stream based on an underlying sound device.

It can be used as an audio source (read) and a audio sink (write).

Args:
sample_rate: sample rate in hertz.
sample_width: size of a single sample in bytes.
block_size: size in bytes of each read and write operation.
flush_size: size in bytes of silence data written during flush operation.
"""
def __init__(self, sample_rate, sample_width, block_size, flush_size):
if sample_width == 2:
audio_format = 'int16'
else:
raise Exception('unsupported sample width:', sample_width)
self._audio_stream = sd.RawStream(
samplerate=sample_rate, dtype=audio_format, channels=1,
blocksize=int(block_size/2), # blocksize is in number of frames.
)
self._block_size = block_size
self._flush_size = flush_size
self._sample_rate = sample_rate

def read(self, size):
"""Read bytes from the stream."""
buf, overflow = self._audio_stream.read(size)
if overflow:
logging.warning('SoundDeviceStream read overflow (%d, %d)',
size, len(buf))
return bytes(buf)

def write(self, buf):
"""Write bytes to the stream."""
underflow = self._audio_stream.write(buf)
if underflow:
logging.warning('SoundDeviceStream write underflow (size: %d)',
len(buf))
return len(buf)


and finally the warning output when running pushtotalk.py



WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)
WARNING:root:SoundDeviceStream write underflow (size: 4000)




UPDATE OK with a bit of tinkering I have managed to reduce the choppy audio out by commenting out code in audio_helpers.py that generates the warning message output for the underflow and overflow conditions. It seems that when an under/overflow condition is detected, logging.warning is outputting to the terminal (stdout?) and this is causing the audio playback to briefly be interrupted. You can still detect a slight choppiness in the audio out but it is considerably better than before. Ideally, instead of preventing the output of the warning messages, it would be much better to prevent the under/overflow conditions occurring in the first place!



Code snippet below shows the two logging.warning functions commented out in audio_helpers.py. This file is located at /home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc on my setup.



    def read(self, size):
"""Read bytes from the stream."""
buf, overflow = self._audio_stream.read(size)
# if overflow:
# logging.warning('SoundDeviceStream read overflow (%d, %d)',
# size, len(buf))"""
return bytes(buf)

def write(self, buf):
"""Write bytes to the stream."""
underflow = self._audio_stream.write(buf)
# if underflow:
# logging.warning('SoundDeviceStream write underflow (size: %d)',
# len(buf))"""
return len(buf)


Use of Doc-String """ now changed to # for commented out sections



UPDATE 2
At @Matthias suggestion, details of how pushtotalk.pyis started and also results of using switch --audio-block-size



pi@raspberrypi:~ $ /home/pi/env/bin/googlesamples-assistant-pushtotalk --project-id 'gassistpi-xxxxx' --device-model-id 'gassistpi-xxxxx-gassistpi-xxxxx' --audio-block-size -77
Traceback (most recent call last):
File "/home/pi/env/bin/googlesamples-assistant-pushtotalk", line 11, in <module>
sys.exit(main())
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/pi/env/lib/python3.5/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc/pushtotalk.py", line 351, in main
flush_size=audio_flush_size
File "/home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/grpc/audio_helpers.py", line 190, in __init__
blocksize=int(block_size/2), # blocksize is in number of frames.
File "/home/pi/env/lib/python3.5/site-packages/sounddevice.py", line 1264, in __init__
**_remove_self(locals()))
File "/home/pi/env/lib/python3.5/site-packages/sounddevice.py", line 779, in __init__
callback_ptr, userdata),
OverflowError: can't convert negative number to unsigned
pi@raspberrypi:~ $


I also tried (valid binary) values for --audio-block-size ranging from 1024 through to 65536 and also 0 for good measure. All produced the same original result or runtime errors.







python raspberry-pi google-assist-api python-sounddevice






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 at 13:56

























asked Nov 9 at 11:21









Colin M

85




85












  • How are you starting the "pushtotalk" application? Did you try the --audio-block-size parameter? Did you try --help?
    – Matthias
    Nov 11 at 11:00










  • BTW, a normal Python comment starts with a # sign. Instead of commenting, you were creating multi-line strings with """, which effectively disables the quoted lines, but normally, you would just add a # at the beginning of each line. The multi-line strings directly below the line with the def are not mere comments, they are so-called "docstrings".
    – Matthias
    Nov 11 at 11:06










  • @Matthias Starting with pi@raspberrypi:~ $ /home/pi/env/bin/googlesamples-assistant-pushtotalk --project-id 'gassistpi-xxxx' --device-model-id 'gassistpi-xxxx-gassistpi-xxxxx' --audio-block-size 1024 Tried valued 1024 through to 65536 - No change. Looked through --help and read the docs but I can't work out what " Output_Underflow. Indicates that output data (or a gap) was inserted, possibly because the stream callback is using too much CPU time." means exactly or what I need to do to correct it . Hence my question.
    – Colin M
    Nov 11 at 19:18












  • OK, then I don't know, sorry. You should update your issue (github.com/googlesamples/assistant-sdk-python/issues/303) with this information. And you should make sure that you undo all changes you made to the source files. BTW, did you try some illegal value, like --audio-block-size -77? If this doesn't raise a meaningful error, then there is something wrong ...
    – Matthias
    Nov 12 at 9:03










  • @Matthias Will update the issue as suggested and illegal values does indeed throw an error (see updated issue). Thank you for trying to help. Whilst originally searching for an answer your name came up quite a lot so (as you are obviously a "python sound" guru) I had my hopes pinned on you. What I find frustrating is the explanation (or not!) of the error in the [Read_The_Docs] (python-sounddevice.readthedocs.io/en/0.3.12). What exactly is defined as a "gap" and how do you work out what the "stream callback" is!
    – Colin M
    Nov 12 at 12:44




















  • How are you starting the "pushtotalk" application? Did you try the --audio-block-size parameter? Did you try --help?
    – Matthias
    Nov 11 at 11:00










  • BTW, a normal Python comment starts with a # sign. Instead of commenting, you were creating multi-line strings with """, which effectively disables the quoted lines, but normally, you would just add a # at the beginning of each line. The multi-line strings directly below the line with the def are not mere comments, they are so-called "docstrings".
    – Matthias
    Nov 11 at 11:06










  • @Matthias Starting with pi@raspberrypi:~ $ /home/pi/env/bin/googlesamples-assistant-pushtotalk --project-id 'gassistpi-xxxx' --device-model-id 'gassistpi-xxxx-gassistpi-xxxxx' --audio-block-size 1024 Tried valued 1024 through to 65536 - No change. Looked through --help and read the docs but I can't work out what " Output_Underflow. Indicates that output data (or a gap) was inserted, possibly because the stream callback is using too much CPU time." means exactly or what I need to do to correct it . Hence my question.
    – Colin M
    Nov 11 at 19:18












  • OK, then I don't know, sorry. You should update your issue (github.com/googlesamples/assistant-sdk-python/issues/303) with this information. And you should make sure that you undo all changes you made to the source files. BTW, did you try some illegal value, like --audio-block-size -77? If this doesn't raise a meaningful error, then there is something wrong ...
    – Matthias
    Nov 12 at 9:03










  • @Matthias Will update the issue as suggested and illegal values does indeed throw an error (see updated issue). Thank you for trying to help. Whilst originally searching for an answer your name came up quite a lot so (as you are obviously a "python sound" guru) I had my hopes pinned on you. What I find frustrating is the explanation (or not!) of the error in the [Read_The_Docs] (python-sounddevice.readthedocs.io/en/0.3.12). What exactly is defined as a "gap" and how do you work out what the "stream callback" is!
    – Colin M
    Nov 12 at 12:44


















How are you starting the "pushtotalk" application? Did you try the --audio-block-size parameter? Did you try --help?
– Matthias
Nov 11 at 11:00




How are you starting the "pushtotalk" application? Did you try the --audio-block-size parameter? Did you try --help?
– Matthias
Nov 11 at 11:00












BTW, a normal Python comment starts with a # sign. Instead of commenting, you were creating multi-line strings with """, which effectively disables the quoted lines, but normally, you would just add a # at the beginning of each line. The multi-line strings directly below the line with the def are not mere comments, they are so-called "docstrings".
– Matthias
Nov 11 at 11:06




BTW, a normal Python comment starts with a # sign. Instead of commenting, you were creating multi-line strings with """, which effectively disables the quoted lines, but normally, you would just add a # at the beginning of each line. The multi-line strings directly below the line with the def are not mere comments, they are so-called "docstrings".
– Matthias
Nov 11 at 11:06












@Matthias Starting with pi@raspberrypi:~ $ /home/pi/env/bin/googlesamples-assistant-pushtotalk --project-id 'gassistpi-xxxx' --device-model-id 'gassistpi-xxxx-gassistpi-xxxxx' --audio-block-size 1024 Tried valued 1024 through to 65536 - No change. Looked through --help and read the docs but I can't work out what " Output_Underflow. Indicates that output data (or a gap) was inserted, possibly because the stream callback is using too much CPU time." means exactly or what I need to do to correct it . Hence my question.
– Colin M
Nov 11 at 19:18






@Matthias Starting with pi@raspberrypi:~ $ /home/pi/env/bin/googlesamples-assistant-pushtotalk --project-id 'gassistpi-xxxx' --device-model-id 'gassistpi-xxxx-gassistpi-xxxxx' --audio-block-size 1024 Tried valued 1024 through to 65536 - No change. Looked through --help and read the docs but I can't work out what " Output_Underflow. Indicates that output data (or a gap) was inserted, possibly because the stream callback is using too much CPU time." means exactly or what I need to do to correct it . Hence my question.
– Colin M
Nov 11 at 19:18














OK, then I don't know, sorry. You should update your issue (github.com/googlesamples/assistant-sdk-python/issues/303) with this information. And you should make sure that you undo all changes you made to the source files. BTW, did you try some illegal value, like --audio-block-size -77? If this doesn't raise a meaningful error, then there is something wrong ...
– Matthias
Nov 12 at 9:03




OK, then I don't know, sorry. You should update your issue (github.com/googlesamples/assistant-sdk-python/issues/303) with this information. And you should make sure that you undo all changes you made to the source files. BTW, did you try some illegal value, like --audio-block-size -77? If this doesn't raise a meaningful error, then there is something wrong ...
– Matthias
Nov 12 at 9:03












@Matthias Will update the issue as suggested and illegal values does indeed throw an error (see updated issue). Thank you for trying to help. Whilst originally searching for an answer your name came up quite a lot so (as you are obviously a "python sound" guru) I had my hopes pinned on you. What I find frustrating is the explanation (or not!) of the error in the [Read_The_Docs] (python-sounddevice.readthedocs.io/en/0.3.12). What exactly is defined as a "gap" and how do you work out what the "stream callback" is!
– Colin M
Nov 12 at 12:44






@Matthias Will update the issue as suggested and illegal values does indeed throw an error (see updated issue). Thank you for trying to help. Whilst originally searching for an answer your name came up quite a lot so (as you are obviously a "python sound" guru) I had my hopes pinned on you. What I find frustrating is the explanation (or not!) of the error in the [Read_The_Docs] (python-sounddevice.readthedocs.io/en/0.3.12). What exactly is defined as a "gap" and how do you work out what the "stream callback" is!
– Colin M
Nov 12 at 12:44



















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53224787%2fpython-sounddevicestream-write-read-underflow-overflow-errors%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53224787%2fpython-sounddevicestream-write-read-underflow-overflow-errors%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Florida Star v. B. J. F.

Error while running script in elastic search , gateway timeout

Adding quotations to stringified JSON object values