aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--broadcast.py18
-rw-r--r--client.py84
-rw-r--r--packet.py23
-rw-r--r--packet.pycbin0 -> 1423 bytes
5 files changed, 111 insertions, 16 deletions
diff --git a/.gitignore b/.gitignore
index 66b9aca..58448e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
new file mode 100644
index 0000000..ea0785b
--- /dev/null
+++ b/packet.pyc
Binary files differ