Skip to content

Instantly share code, notes, and snippets.

@battlecow
Created July 14, 2020 00:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save battlecow/58aa707a9b612c8accba56a9cb2826ca to your computer and use it in GitHub Desktop.
Save battlecow/58aa707a9b612c8accba56a9cb2826ca to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# playback.py
# 2016-12-23
# Public Domain
import os
import sys
import time
import pigpio
mapping = [None] * 32
def usage():
print(
"""
Usage: {} file GPIO<=GPIO>*
E.g. {} rec.txt 5 7=10
means play 5 (source 5) and 7 (source 10) from samples in rec.txt
""".format(sys.argv[0], sys.argv[0]))
def validate_gpioarg(arg):
# 5 => g_to = 5, g_from = 5
# 3=9 => g_to = 3, g_from = 9
gpio = arg.split("=")
if len(gpio) > 2:
return (-1, -1)
try:
g_to = int(gpio[0])
except:
return (-1, -1)
g_from = g_to
if len(gpio) > 1:
try:
g_from = int(gpio[1])
except:
return (-1, -1)
if g_to < 0 or g_to > 31 or g_from < 0 or g_from > 31:
return (-1, -1)
return (g_to, g_from)
def validate_args():
ok = True
args = len(sys.argv)
if args < 2:
usage()
return False
filename = sys.argv[1]
if not os.path.isfile(filename):
print("Bad file: {}".format(filename))
ok = False
if args < 3:
usage()
return False
for i in range(args-2):
arg = sys.argv[i+2]
(g_to, g_from) = validate_gpioarg(arg)
if g_to == -1:
print("Bad gpio: {}".format(arg))
ok = False
else:
mapping[g_to] = g_from
return ok
if not validate_args():
exit(1)
# condense gpio assignments to a list
GPIO = []
for i in range(32):
if mapping[i] is not None:
GPIO.append((i, 1<<i, 1<<mapping[i]))
wf = []
with open(sys.argv[1], 'r') as f:
first = True
for line in f:
if line[0] != '#':
fields = line.split()
stamp = int(fields[0])
levels = int(fields[1],16)
if first:
first = False
on = 0
off = 0
for g in GPIO:
if g[2] & levels:
on = on | g[1]
else:
off = off | g[1]
last_on = off
last_off = on
else:
if on == last_on and off == last_off:
p = wf.pop()
delay = p.delay
else:
delay = 0
wf.append(pigpio.pulse(on, off, (stamp-last_stamp)+delay))
last_on = on
last_off = off
on = 0
off = 0
for g in GPIO:
if g[2] & levels:
on = on | g[1]
else:
off = off | g[1]
last_stamp = stamp
if on != last_on or off != last_off:
wf.append(pigpio.pulse(on, off, 0))
else:
p = wf.pop()
p.delay = 0
wf.append(p)
f.close()
pi = pigpio.pi() # Connect to local Pi.
if not pi.connected:
exit()
for g in GPIO:
pi.set_mode(g[0], pigpio.OUTPUT) # Need to be outputs for wave to work
pi.wave_add_new()
pi.wave_add_generic(wf)
wid = pi.wave_create()
if wid >= 0:
pi.wave_send_once(wid)
while pi.wave_tx_busy():
time.sleep(0.01)
pi.wave_delete(wid)
pi.stop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment