Ver Fonte

Added client.py

Grissess há 10 anos atrás
pai
commit
af3e084f8f
5 ficheiros alterados com 111 adições e 16 exclusões
  1. 2 0
      .gitignore
  2. 2 16
      broadcast.py
  3. 84 0
      client.py
  4. 23 0
      packet.py
  5. BIN
      packet.pyc

+ 2 - 0
.gitignore

@@ -1,3 +1,5 @@
 client
 *.iv
 *.xml
+*.swp
+*.swo

+ 2 - 16
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)
 

+ 84 - 0
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

+ 23 - 0
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)

BIN
packet.pyc