diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | broadcast.py | 18 | ||||
-rw-r--r-- | client.py | 84 | ||||
-rw-r--r-- | packet.py | 23 | ||||
-rw-r--r-- | packet.pyc | bin | 0 -> 1423 bytes |
5 files changed, 111 insertions, 16 deletions
@@ -1,3 +1,5 @@ client *.iv *.xml +*.swp +*.swo diff --git a/broadcast.py b/broadcast.py index 0483a67..f244aa6 100644 --- a/broadcast.py +++ b/broadcast.py @@ -5,6 +5,8 @@ import time import xml.etree.ElementTree as ET import threading +from packet import Packet, CMD + PORT = 13676 if len(sys.argv) > 2: factor = float(sys.argv[2]) @@ -13,22 +15,6 @@ else: print 'Factor:', factor -class Packet(object): - def __init__(self, cmd, *data): - self.cmd = cmd - self.data = data - if len(data) >= 8: - raise ValueError('Too many data') - self.data = list(self.data) + [0] * (8-len(self.data)) - def __str__(self): - return struct.pack('>L'+('L'*len(self.data)), self.cmd, *self.data) - -class CMD: - KA = 0 # No important data - PING = 1 # Data are echoed exactly - QUIT = 2 # No important data - PLAY = 3 # seconds, microseconds, frequency (Hz), amplitude (0-255) - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 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 diff --git a/packet.py b/packet.py new file mode 100644 index 0000000..951425c --- /dev/null +++ b/packet.py @@ -0,0 +1,23 @@ +#Simple packet type for the simple protocol + +import struct + +class Packet(object): + def __init__(self, cmd, *data): + self.cmd = cmd + self.data = data + if len(data) >= 8: + raise ValueError('Too many data') + self.data = list(self.data) + [0] * (8-len(self.data)) + @classmethod + def FromStr(cls, s): + parts = struct.unpack('>9L', s) + return cls(parts[0], *parts[1:]) + def __str__(self): + return struct.pack('>L'+('L'*len(self.data)), self.cmd, *self.data) + +class CMD: + KA = 0 # No important data + PING = 1 # Data are echoed exactly + QUIT = 2 # No important data + PLAY = 3 # seconds, microseconds, frequency (Hz), amplitude (0-255) diff --git a/packet.pyc b/packet.pyc Binary files differnew file mode 100644 index 0000000..ea0785b --- /dev/null +++ b/packet.pyc |