[enh] clitools: new filter redilysis

This commit is contained in:
alban 2020-09-29 23:07:24 +02:00
parent e6aa595b4b
commit 59a8dfe4b3
1 changed files with 149 additions and 0 deletions

149
clitools/filters/redilysis.py Executable file
View File

@ -0,0 +1,149 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
redilysis
v0.1.0
A complex effect that depends on redis keys for audio analysis
see https://git.interhacker.space/teamlase/redilysis for more informations
about the redilysis project
LICENCE : CC
by cocoa
'''
from __future__ import print_function
import argparse
import ast
import os
import math
import random
import redis
import sys
import time
name = "filters::redilysis"
def debug(*args, **kwargs):
if( verbose == False ):
return
print(*args, file=sys.stderr, **kwargs)
def now():
return time.time() * 1000
# The list of available modes and the redis keys they need
oModeList = {
"rms_noise": ["rms"],
"rms_bounce": ["rms"]
}
CHAOS = 1
REDIS_FREQ = 300
# General Args
argsparser = argparse.ArgumentParser(description="Redilysis filter")
argsparser.add_argument("-v","--verbose",action="store_true",help="Verbose")
# Redis Args
argsparser.add_argument("-i","--ip",help="IP address of the Redis server ",default="127.0.0.1",type=str)
argsparser.add_argument("-p","--port",help="Port of the Redis server ",default="6379",type=str)
argsparser.add_argument("-s","--redis-freq",help="Query Redis every x (in milliseconds). Default:{}".format(REDIS_FREQ),default=REDIS_FREQ,type=int)
# General args
argsparser.add_argument("-x","--centerX",help="geometrical center X position",default=300,type=int)
argsparser.add_argument("-y","--centerY",help="geometrical center Y position",default=300,type=int)
argsparser.add_argument("-f","--fps",help="Frame Per Second",default=30,type=int)
# Modes And Common Modes Parameters
argsparser.add_argument("-m","--modelist",required=True,help="Comma separated list of modes to use from: {}".format("i, ".join(oModeList.keys())),type=str)
argsparser.add_argument("--chaos",help="How much disorder to bring. High value = More chaos. Default {}".format(CHAOS), default=CHAOS, type=str)
args = argsparser.parse_args()
ip = args.ip
port = args.port
redisFreq = args.redis_freq
verbose = args.verbose
fps = args.fps
centerX = args.centerX
centerY = args.centerY
chaos = float(args.chaos)
optimal_looptime = 1 / fps
modeList = args.modelist.split(",")
redisKeys = []
for mode in modeList:
if not mode in oModeList:
print("Mode '{}' is invalid. Exiting.".format(mode))
sys.exit(2)
redisKeys += oModeList[mode]
redisKeys = list(set(redisKeys))
debug(name,"Redis Keys:{}".format(redisKeys))
redisData = {}
redisLastHit = now() - redisFreq
r = redis.Redis(
host=ip,
port=port)
def rms_bounce( pl ):
rms = float(redisData["rms"])
for i, point in enumerate(pl):
#debug(name,"rms_noise chaos:{} rms:{}".format(chaos, rms))
angle=math.atan2(point[0],point[1])
l = point[1] / math.cos(angle)
new_l = l + rms * chaos
new_x = math.sin(angle) * new_l
new_y = math.cos(angle) * new_l
debug(name,"x,y:({},{}) x',y':({},{})".format(point[0],point[1],new_x,new_y))
pl[i][0] += new_x
pl[i][1] += new_y
#debug( name,"rms_noise output:{}".format(pl))
return pl
def rms_noise( pl ):
rms = float(redisData["rms"])
for i, point in enumerate(pl):
#debug(name,"rms_noise chaos:{} rms:{}".format(chaos, rms))
xRandom = random.uniform(-1,1) * rms * chaos
yRandom = random.uniform(-1,1) * rms * chaos
#debug(name,"rms_noise xRandom:{} yRandom:{}".format(xRandom, yRandom))
pl[i][0] += xRandom
pl[i][1] += yRandom
#debug( name,"rms_noise output:{}".format(pl))
return pl
def updateRedis():
global redisLastHit
global redisData
for key in redisKeys:
redisData[key] = r.get(key).decode('ascii')
debug("name","updateRedis key:{} value:{}".format(key,redisData[key]))
if key == 'bpm':
redisData['bpm_ttl'] = r.pttl(key)
debug(name,"redisData:{}".format(redisData))
try:
while True:
# it is time to query redis
if now() - redisLastHit > redisFreq:
updateRedis()
start = time.time()
line = sys.stdin.readline()
if line == "":
time.sleep(0.01)
line = line.rstrip('\n')
pointsList = ast.literal_eval(line)
# Do the filter
for mode in modeList:
pointsList = locals()[mode](pointsList)
print( pointsList, flush=True )
looptime = time.time() - start
# debug(name+" looptime:"+str(looptime))
if( looptime < optimal_looptime ):
time.sleep( optimal_looptime - looptime)
# debug(name+" micro sleep:"+str( optimal_looptime - looptime))
except EOFError:
debug(name+" break")# no more information