Post
by Peter » Mon May 29, 2017 7:12 am
Hi dBm,
I am a newbi when it comes to programming in Python (3). Let's start off what my intentions are: Create a 2 way audio link using RPI3's. Implementing audio compression (uLAW) and low sampling speeds. But first things first: How to get this running at normal speeds (48 kHz) and normal audio quality?
Your example to get samples (form the line input) has been quite helpful, although I re-wrote it into a Python Class, rather then your application running it as a recording device. So I think that this class is working. i.e. it seems to collect audio samples and converts them into 4 Byte floats. So far so good.
What I have not been able to resolve is how to get the samples to the audio output of the AudioInjector device on the other RPi3 (data is correctly received, as far as I can tell). Using the code as depicted in the example below, I get the following errors (errors are listed beneat the example code):
class AudioInjector:
"""Class which specifies the use of the Audio Injector Souncard HAT"""
def __init__(self):
global stream_mic
global stream_ls
global mic_audio
global p
self.CHUNK = 1024 # CHUNKS of bytes to read each time from mic
self.FORMAT = pyaudio.paInt32
self.CHANNELS = 1
self.RATE = 48000
def rx_audio(self): # Obtain audio from the Audio Injector INPUT (Microphone)
global p
p = pyaudio.PyAudio() # instantiate the pyaudio
# Create an input stream with this instance of pyaudio
stream_mic = p.open(format = self.FORMAT,
channels = self.CHANNELS,
rate = self.RATE,
input = True, # would be Output = True if this was an output stream
input_device_index = 0, # set to 0 if the built-in audio is disabled in config.txt
# while set to 1 if it isn't
# or possibly higher number if more audio devices are attached
frames_per_buffer = self.CHUNK
)
frames = [ ]
data = stream.read(self.CHUNK)
rcvr_audio = numpy.fromstring(data, 'Int32') # then convert to floating point numbers
# this is why we had to use 32 bit numbers above
# now do something with your floating point data here
stream_mic.close()
rcvr_ulaw_audio = audioop.lin2ulaw(rcvr_audio,4)
return rcvr_ulaw_audio
def tx_audio(self,audio_string_mono): # Send audio to the Audio Injector OUTPUT.
global p
p = pyaudio.PyAudio() # instantiate the pyaudio
# Create an output stream with this instance of pyaudio
stream_ls = p.open(format = self.FORMAT,
channels = self.CHANNELS,
rate = self.RATE,
output = True, # would be Output = True if this was an output stream
output_device_index = 0, # set to 0 if the built-in audio is disabled in config.txt
# while set to 1 if it isn't
# or possibly higher number if more audio devices are attached
frames_per_buffer = self.CHUNK
)
stream_ls.write(stream_ls.wav) # >>>>HERE THE CODE EXECUTION FAILS <<<<
stream_ls.close()
Error listing when I try to execute the "tx_audio" part of this class.
Expression 'ret' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1736
Expression 'AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 1904
Expression 'PaAlsaStreamComponent_Initialize( &self->playback, alsaApi, outParams, StreamDirection_Out, NULL != callback )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2175
Expression 'PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2840
I wonder if you, or someone else can shine some light on this matter: How to send streaming data to the Audio Injector.
Thanks!
Peter