diff options
Diffstat (limited to 'client.py')
-rw-r--r-- | client.py | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/client.py b/client.py new file mode 100644 index 0000000..d965cae --- /dev/null +++ b/client.py @@ -0,0 +1,84 @@ +# A simple client that generates sine waves via python-pyaudio + +import signal +import pyaudio +import sys +import socket +import time +import math +import struct +import socket + +from packet import Packet, CMD + +PORT = 13676 + +LAST_SAMP = 0 +FREQ = 0 +PHASE = 0 +RATE = 44100 +FPB = 64 + +Z_SAMP = '\x00\x00\x00\x00' +MAX = 0x7fffffff +MIN = -0x80000000 + +def sigalrm(sig, frm): + global FREQ + FREQ = 0 + +def lin_interp(frm, to, cnt): + step = (to-frm)/float(cnt) + samps = [0]*cnt + for i in xrange(cnt): + p = i / float(cnt-1) + samps[i] = int(p*to + (1-p)*frm) + return samps + +def sine(freq, phase, cnt): + global RATE, MAX + samps = [0]*cnt + for i in xrange(cnt): + samps[i] = int(MAX * math.sin(phase + 2 * math.pi * freq * i / RATE)) + return samps, phase + 2 * math.pi * freq * cnt / RATE + +def to_data(samps): + return struct.pack('i'*len(samps), *samps) + +def gen_data(data, frames, time, status): + global FREQ, PHASE, Z_SAMP, LAST_SAMP + if FREQ == 0: + PHASE = 0 + if LAST_SAMP == 0: + return (Z_SAMP*frames, pyaudio.paContinue) + fdata = lin_interp(LAST_SAMP, 0, frames) + LAST_SAMP = fdata[-1] + return (to_data(fdata), pyaudio.paContinue) + fdata, PHASE = sine(FREQ, PHASE, frames) + LAST_SAMP = fdata[-1] + return (to_data(fdata), pyaudio.paContinue) + +pa = pyaudio.PyAudio() +stream = pa.open(rate=RATE, channels=1, format=pyaudio.paInt32, output=True, frames_per_buffer=FPB, stream_callback=gen_data) + +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + +signal.signal(signal.SIGALRM, sigalrm) + +while True: + data, cli = sock.recvfrom(4096) + pkt = Packet.FromStr(data) + print 'From', cli, 'command', pkt.cmd + if pkt.cmd == KA: + pass + elif pkt.cmd == PING: + sock.sendto(data, cli) + elif pkt.cmd == CMD.QUIT: + break + elif pkt.cmd == CMD.PLAY: + dur = pkt.data[0]+pkt.data[1]/1000000.0 + FREQ = pkt.data[2] + AMP = MAX * (pkt.data[2]/255.0) + signal.setitimer(signal.ITIMER_REAL, dur) + else: + print 'Unknown cmd', pkt.cmd |