0

I have written a code to send audio over sockets in python using TCP, however audio received on the other end is not clear and I cant understand why.

Here is my code:

import socket
import pyaudio
import wave
import sys
import pickle
import time

HOST=""
PORT=1061
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 3


def record(sock):   
    def callback_record(in_data, frame_count, time_info, status):
        #print len(in_data)
        sock.sendall(in_data)       

        return (in_data, pyaudio.paContinue)

    p = pyaudio.PyAudio()
    stream = p.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    output=False,
                    stream_callback=callback_record)

    stream.start_stream()
    return stream

def play(sock):
    def callback_play(in_data, frame_count, time_info, status):
        #msg=recv_all(sock)
        in_data=sock.recv(5000)
        return (in_data, pyaudio.paContinue)

    p = pyaudio.PyAudio()
    stream = p.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    input=False,
                    output=True,
                    stream_callback=callback_play)

    stream.start_stream()
    return stream

def recv_all(sock):
    data=sock.recv(5000)
    return data


if sys.argv[1] == 'server':
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind((HOST, PORT))
    s.listen(10)
    while(True):
        print "Listening at:", s.getsockname()
        sc, addr=s.accept()
        print "Connection established with:", addr

        while True:
            stream_record=record(sc)
            #stream_play=play(sc)
            while stream_record.is_active():# or stream_play.is_active():
                #time.sleep(0.0)
                pass
            #stream_record.stop_stream()
            #stream_record.close()
        #stream_play.stop_stream()
        #stream_play.close()

elif sys.argv[1]=='client':
    s.connect((HOST, PORT))
    while True:     
        stream_play=play(s)

        while stream_play.is_active():#stream_record.is_active() or 
            #time.sleep(0.0)
            pass

        #stream_record.stop_stream()
        #stream_record.close()
        #stream_play.stop_stream()
        #stream_play.close()

Usage: python filename.py server/client

I have read this and it works absolutely fine, but I cant understand why my code doesnt.

Edit: Made some changes to callback_play function as suggested but still it doesnt work as expected.

def callback_play(in_data, frame_count, time_info, status):
        #msg=recv_all(sock)
        #in_data=sock.recv(4096*10)
        data=""
        while len(data)<50000:
            data+=sock.recv(MAX)
        in_data=data

        return (in_data, pyaudio.paContinue)
Community
  • 1
  • 1
shiva
  • 2,535
  • 2
  • 18
  • 32
  • 1
    You should implement some kind of buffering on the client side. You can try writing the data you receive from the network to a [queue.Queue](https://docs.python.org/3/library/queue.html) and reading from it in the audio callback. You should not start playback before the queue is filled with some data. – Matthias Mar 29 '16 at 13:05
  • Tried it, but didnt work. I accumulated data in a string before returning it in "callback_play" function. – shiva Mar 30 '16 at 10:36
  • Show what you tried, and probably somebody can tell you why it didn't work. The link in you question uses a buffer, there it's called `frames`. – Matthias Mar 30 '16 at 13:18

0 Answers0