Skip to content

Commit

Permalink
Fixes for Alsa (#407)
Browse files Browse the repository at this point in the history
* Fixes for Alsa

When the asynchronous mic was introduced, some formatting changes
were made that were not copied into the Alsa audio engine plugin.

* Removed pyAudio code

Removed some pyaudio code that I copied into the alsa audio engine
plugin while fixing some of the formatting.
  • Loading branch information
aaronchantrill authored Jun 7, 2024
1 parent 9a348e7 commit eb79b80
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 16 deletions.
20 changes: 10 additions & 10 deletions naomi/audioengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, name):
self._slug = slugify.slugify(name)
self._input_rate = int(
profile.get_profile_var(
['audio', 'input_samplerate'],
['audio', 'input_rate'],
16000
)
)
Expand Down Expand Up @@ -134,11 +134,11 @@ def record(self, chunksize, *args):

def play_fp(self, fp, *args, **kwargs):
self._stop = False
if('chunksize' in kwargs):
if ('chunksize' in kwargs):
chunksize = kwargs['chunksize']
else:
chunksize = int(profile.get(['audio', 'output_chunksize'], 1024))
if('add_padding' in kwargs):
if ('add_padding' in kwargs):
add_padding = kwargs['add_padding']
else:
add_padding = profile.get(['audio', 'output_padding'], False)
Expand All @@ -149,14 +149,14 @@ def play_fp(self, fp, *args, **kwargs):
bits = w.getsampwidth() * 8
rate = w.getframerate()
with self.open_stream(
bits,
channels,
rate,
bits=bits,
channels=channels,
rate=rate,
chunksize=chunksize
) as stream:
data = w.readframes(chunksize)
datalen = len(data)
if(
if (
(add_padding)
and (datalen > 0)
and (datalen < (chunksize * samplewidth))
Expand All @@ -165,21 +165,21 @@ def play_fp(self, fp, *args, **kwargs):
datalen = len(data)
while data:
# Check to see if we need to stop
if(self._stop):
if (self._stop):
self._stop = False
break
stream.write(data)
data = w.readframes(chunksize)
datalen = len(data)
if(
if (
(add_padding)
and (datalen > 0)
and (datalen < (chunksize * samplewidth))
):
data += b'\00' * (chunksize * samplewidth - datalen)
datalen = len(data)
# pause before closing the stream (reduce clipping)
if(pause > 0):
if (pause > 0):
time.sleep(pause)
self._stop = False

Expand Down
55 changes: 49 additions & 6 deletions plugins/audioengine/alsa-ae/alsaaudioengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,23 @@ def supports_format(self, bits, channels, rate, output=True):
return True

@contextlib.contextmanager
def open_stream(self, bits, channels, rate, chunksize=1024, output=True):
def open_stream(self, *args, **kwargs):
bits = self._input_bits
if 'bits' in kwargs:
bits = kwargs['bits']
channels = self._input_channels
if 'channels' in kwargs:
channels = kwargs['channels']
rate = self._input_rate
if 'rate' in kwargs:
rate = kwargs['rate']
output = True
if 'output' in kwargs:
output = kwargs['output']
chunksize = self._input_chunksize
if 'chunksize' in kwargs:
chunksize = kwargs['chunksize']

# Check if format is supported
is_supported_fmt = self.supports_format(bits, channels, rate,
output=output)
Expand Down Expand Up @@ -117,8 +133,35 @@ def open_stream(self, bits, channels, rate, chunksize=1024, output=True):
self._logger.debug("%s stream closed on device '%s'",
"output" if output else "input", self.slug)

def record(self, chunksize, *args):
with self.open_stream(*args, chunksize=chunksize,
output=False) as stream:
while True:
yield stream.read()[1]
def record(self, *args, **kwargs):
# AJC 2018-08-02 Add a second while loop so if the stream
# gets closed, we immediately reopen it rather than continue
# to try to read from a closed stream
stream = None
if 'stream' in kwargs:
stream = kwargs['stream']
while True:
if stream:
try:
frame = stream.read()
except IOError as e:
self._logger.warning(e)
break
else:
yield frame[1]
else:
with self.open_stream(
bits=self._input_bits,
channels=self._input_channels,
rate=self._input_rate,
chunksize=self._input_chunksize,
output=False
) as stream:
while True:
try:
frame = stream.read()
except IOError as e:
self._logger.warning(e)
break
else:
yield frame[1]

0 comments on commit eb79b80

Please sign in to comment.