aboutsummaryrefslogtreecommitdiff
path: root/client.py
diff options
context:
space:
mode:
authorGrissess <grissess@nexusg.org>2015-06-15 01:37:37 -0400
committerGrissess <grissess@nexusg.org>2015-06-15 01:37:37 -0400
commit3e7481519e35c670cbf75320e6a1bd4485e42400 (patch)
tree6543e3dcf68cd1bc8fbe57910a2acc7b40a12f1a /client.py
parentf1824fd539caac27bb91b74f56e24da0908da941 (diff)
Major functionality enhancements and bugfixes
Diffstat (limited to 'client.py')
-rw-r--r--client.py68
1 files changed, 55 insertions, 13 deletions
diff --git a/client.py b/client.py
index fb3db19..14cccef 100644
--- a/client.py
+++ b/client.py
@@ -8,21 +8,28 @@ import time
import math
import struct
import socket
+import optparse
from packet import Packet, CMD, stoi
-PORT = 13676
+parser = optparse.OptionParser()
+parser.add_option('-t', '--test', dest='test', action='store_true', help='Play a test sequence (440,<rest>,880,440), then exit')
+parser.add_option('-g', '--generator', dest='generator', default='math.sin', help='Set the generator (to a Python expression)')
+parser.add_option('-u', '--uid', dest='uid', default='', help='Set the UID (identifier) of this client in the network')
+parser.add_option('-p', '--port', dest='port', type='int', default=13676, help='Set the port to listen on')
+parser.add_option('-r', '--rate', dest='rate', type='int', default=44100, help='Set the sample rate of the audio device')
+
+options, args = parser.parse_args()
+
+PORT = options.port
STREAMS = 1
IDENT = 'TONE'
-if len(sys.argv) > 1:
- UID = sys.argv[1].ljust(24, '\x00')
-else:
- UID = '\x00'*24
+UID = options.uid
LAST_SAMP = 0
FREQ = 0
PHASE = 0
-RATE = 44100
+RATE = options.rate
FPB = 64
Z_SAMP = '\x00\x00\x00\x00'
@@ -30,24 +37,48 @@ MAX = 0x7fffffff
AMP = MAX
MIN = -0x80000000
+def lin_interp(frm, to, p):
+ return p*to + (1-p)*frm
+
+# Generator functions--should be cyclic within [0, 2*math.pi) and return [-1, 1]
+
+def tri_wave(theta):
+ if theta < math.pi/2:
+ return lin_interp(0, 1, theta/(math.pi/2))
+ elif theta < 3*math.pi/2:
+ return lin_interp(1, -1, (theta-math.pi/2)/math.pi)
+ else:
+ return lin_interp(-1, 0, (theta-3*math.pi/2)/(math.pi/2))
+
+def square_wave(theta):
+ if theta < math.pi:
+ return 1
+ else:
+ return -1
+
+#generator = math.sin
+#generator = tri_wave
+#generator = square_wave
+generator = eval(options.generator)
+
def sigalrm(sig, frm):
global FREQ
FREQ = 0
-def lin_interp(frm, to, cnt):
+def lin_seq(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)
+ samps[i] = int(lin_interp(frm, to, p))
return samps
-def sine(freq, phase, cnt):
+def samps(freq, phase, cnt):
global RATE, AMP
samps = [0]*cnt
for i in xrange(cnt):
- samps[i] = int(AMP * math.sin(phase + 2 * math.pi * freq * i / RATE))
- return samps, phase + 2 * math.pi * freq * cnt / RATE
+ samps[i] = int(AMP * generator((phase + 2 * math.pi * freq * i / RATE) % (2*math.pi)))
+ return samps, (phase + 2 * math.pi * freq * cnt / RATE) % (2*math.pi)
def to_data(samps):
return struct.pack('i'*len(samps), *samps)
@@ -58,16 +89,27 @@ def gen_data(data, frames, time, status):
PHASE = 0
if LAST_SAMP == 0:
return (Z_SAMP*frames, pyaudio.paContinue)
- fdata = lin_interp(LAST_SAMP, 0, frames)
+ fdata = lin_seq(LAST_SAMP, 0, frames)
LAST_SAMP = fdata[-1]
return (to_data(fdata), pyaudio.paContinue)
- fdata, PHASE = sine(FREQ, PHASE, frames)
+ fdata, PHASE = samps(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)
+if options.test:
+ FREQ = 440
+ time.sleep(1)
+ FREQ = 0
+ time.sleep(1)
+ FREQ = 880
+ time.sleep(1)
+ FREQ = 440
+ time.sleep(2)
+ exit()
+
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', PORT))