I am trying to do something like a walkie talkie. 1 device is my laptop and the other being the raspberry pi.
What I have working. I am able to record the microphone, transmit it over a socket and save the recording audio into a wav file.
Only issue I am having is playing the audio live while being sent by the socket. It seems to always breaking in sound. It gets like maybe a 1/4 second of audio then just breaks and then hear another random sound it tried to play, but doesn't.
When I take these scripts and run them both on the same machine there is no issue. So, my thought is there is something going wrong when sending it over or it isn't reading it quick enough or trying to do too much at a time.
Could be how much data that is being transfer that is the issue in which it is failing to play the sound properly.
I have been able to save the wav file and play it with aplay
and can confirm the speakers do work and that audio data is at least being transmitted.
Edit:
I tried the suggested UDP method, but kept getting desync audio. Completely inaudible. Just sounded like pieces of audio just were completely gone, which makes sense, but no clue how I can stitch the sound together to even sound close to the original sound.
I was able to sort of getting it to work with TCP.
On the client side I end up randomly getting [Errno -9981] Input overflowed
at some point which then closes the stream. [Errno -9988] Stream closed
.
Not much has change on the code. CHUNK sizes requires playing with sometimes.
I can hear my voice, but after couple of seconds the stream closes due to the errors and I tried having a handle for it, but still goes about closing the stream.
The server tends to spit out this in the terminal
Increasing the CHUNK
helps with the underrun issue, however the stream still closes on its own.
Server.py (PI)
import Queue
import socket
import wave
import pyaudio
CHUNK = 8192
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
WAVE_OUTPUT_FILENAME = "server_output.wav"
WIDTH = 2
HOST = '192.168.2.90' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(WIDTH),
channels=CHANNELS,
rate=RATE,
output=True,
frames_per_buffer=CHUNK)
q = Queue.Queue()
frames = []
stream.start_stream()
def main():
data = conn.recv(CHUNK)
while data != '':
q.put(data)
if not q.empty():
stream.write(q.get())
# stream.write(data)
data = conn.recv(CHUNK)
frames.append(data)
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
stream.stop_stream()
stream.close()
p.terminate()
conn.close()
if __name__ == '__main__':
main()
Client.py
import socket
import pyaudio
CHUNK = 8192
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 5
HOST = '192.168.2.90' # The remote host
PORT = 50007 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
stream.start_stream()
def main():
print("*_>recording")
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
try:
data = stream.read(CHUNK)
except Exception as e:
print e
data = '\x00' * CHUNK
print len(data)
s.sendall(data)
print("*_>done recording")
stream.stop_stream()
stream.close()
p.terminate()
s.close()
print("*_>closed")
if __name__ == '__main__':
main()