def forward_handler(addr, tags, data, source): global prefix global scake global offset if debug > 1: print("---") print("source %s" % OSC.getUrlStr(source)) print("addr %s" % addr) print("tags %s" % tags) print("data %s" % data) if addr[0] != '/': # ensure it starts with a slash addr = '/' + addr if tags == 'f' or tags == 'i': # it is a single value key = prefix + addr.replace('/', '.') val = EEGsynth.rescale(data[0], slope=scale, offset=offset) patch.setvalue(key, val) else: for i in range(len(data)): # it is a list, send it as multiple scalar control values # append the index to the key, this starts with 0 key = prefix + addr.replace('/', '.') + '.%i' % i val = EEGsynth.rescale(data[i], slope=scale, offset=offset) patch.setvalue(key, val)
def run(self): pubsub = r.pubsub() pubsub.subscribe('OUTPUTMIDI_UNBLOCK') # this message unblocks the redis listen command pubsub.subscribe(self.redischannel) # this message contains the note while self.running: for item in pubsub.listen(): if not self.running or not item['type'] == 'message': break if item['channel']==self.redischannel: if debug>1: print(item['channel'], '=', item['data']) # map the Redis values to MIDI values val = item['data'] val = EEGsynth.rescale(val, slope=input_scale, offset=input_offset) val = EEGsynth.limit(val, 0, 127) val = int(val) sendMidi(self.name, self.code, val)
def run(self): pubsub = r.pubsub() pubsub.subscribe('VOLCAKEYS_UNBLOCK') # this message unblocks the redis listen command pubsub.subscribe(self.redischannel) # this message contains the note while self.running: for item in pubsub.listen(): if not self.running or not item['type'] == 'message': break if item['channel']==self.redischannel: # map the Redis values to MIDI values val = EEGsynth.rescale(item['data'], slope=scale, offset=offset) val = EEGsynth.limit(val, 0, 127) val = int(val) if debug>1: print item['channel'], "=", val msg = mido.Message('note_on', note=self.note, velocity=val, channel=midichannel) lock.acquire() outputport.send(msg) lock.release()
def run(self): pubsub = r.pubsub() # this message unblocks the Redis listen command pubsub.subscribe('OUTPUTCVGATE_UNBLOCK') # this message triggers the event pubsub.subscribe(self.redischannel) while self.running: for item in pubsub.listen(): if not self.running or not item['type'] == 'message': break if item['channel'] == self.redischannel: # switch to the value specified in the event, it can be 0 or 1 val = float(item['data']) > 0 SetGate(self.gate, val) if self.duration != None: # schedule a timer to switch it off after the specified duration duration = patch.getfloat('duration', self.duration) duration = EEGsynth.rescale(duration, slope=duration_scale, offset=duration_offset) # some minimal time is needed for the delay duration = EEGsynth.limit(duration, 0.05, float('Inf')) t = threading.Timer(duration, SetGate, args=[self.gate, False]) t.start()
def run(self): pubsub = r.pubsub() pubsub.subscribe('RECORDTRIGGER_UNBLOCK') # this message unblocks the Redis listen command pubsub.subscribe(self.redischannel) # this message triggers the event while self.running: for item in pubsub.listen(): timestamp = datetime.datetime.now().isoformat() if not self.running or not item['type'] == 'message': break if item['channel']==self.redischannel: # the trigger value should also be saved val = item['data'] val = EEGsynth.rescale(val, slope=input_scale, offset=input_offset) if not f.closed: lock.acquire() f.write("%s\t%g\t%s\n" % (self.redischannel, val, timestamp)) lock.release() if debug>0: print("%s\t%g\t%s" % (self.redischannel, val, timestamp))
def run(self): pubsub = r.pubsub() pubsub.subscribe('SEQUENCER_UNBLOCK') # this message unblocks the redis listen command pubsub.subscribe(self.redischannel) # this message contains the note while self.running: for item in pubsub.listen(): if not self.running or not item['type'] == 'message': break if item['channel'] == self.redischannel: now = time.time() if self.prevtime != None: self.steptime = now - self.prevtime self.prevtime = now if len(self.sequence) > 0: # the sequence can consist of a list of values or a list of Redis channels val = self.sequence[self.step % len(self.sequence)] try: # convert the string from the ini to floating point val = float(val) except: # get the value from Redis val = r.get(val) if val == None: val = 0. else: # convert the string from Redis to floating point val = float(val) # apply the scaling, offset and transpose the note val = EEGsynth.rescale(val, slope=scale_note, offset=offset_note) val += self.transpose # send it as sequencer.note with the note as value patch.setvalue(self.key, val, duration=self.duration*self.steptime) if val>=1.: # send it also as sequencer.noteXXX with value 1.0 key = '%s%03d' % (self.key, val) patch.setvalue(key, 1., duration=self.duration*self.steptime) if debug>0: print "step %2d :" % (self.step + 1), self.key, "=", val # increment to the next step self.step = (self.step + 1) % len(self.sequence)
args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') # this is the timeout for the FieldTrip buffer timeout = patch.getfloat('input_fieldtrip', 'timeout') try: ftc_host = patch.getstring('input_fieldtrip', 'hostname') ftc_port = patch.getint('input_fieldtrip', 'port') if debug > 0: print('Trying to connect to buffer on %s:%i ...' % (ftc_host, ftc_port)) ft_input = FieldTrip.Client() ft_input.connect(ftc_host, ftc_port)
def _loop_once(): '''Run the main loop once This uses the global variables from setup and start, and adds a set of global variables ''' global parser, args, config, r, response, patch, monitor, debug, ft_host, ft_port, ft_input global timeout, hdr_input, start, channel, window, threshold, lrate, debounce, key_beat, key_rate, curvemin, curvemean, curvemax, prev, begsample, endsample global dat, negrange, posrange, thresh, prevsample, sample, last, bpm, duration, duration_scale, duration_offset hdr_input = ft_input.getHeader() if (hdr_input.nSamples-1)<endsample: raise RuntimeError("buffer reset detected") if hdr_input.nSamples < window: # there are not yet enough samples in the buffer monitor.info('Waiting for data to arrive...') return # process the last window begsample = hdr_input.nSamples - int(window) endsample = hdr_input.nSamples - 1 dat = ft_input.getData([begsample,endsample]).astype(np.double) dat = dat[:,channel] if np.isnan(curvemin): curvemin = np.min(dat) curvemean = np.mean(dat) curvemax = np.max(dat) else: # the learning rate determines how fast the threshold auto-scales (0=never, 1=immediate) curvemin = (1 - lrate) * curvemin + lrate * np.min(dat) curvemean = (1 - lrate) * curvemean + lrate * np.mean(dat) curvemax = (1 - lrate) * curvemax + lrate * np.max(dat) # both are defined as positive negrange = curvemean - curvemin posrange = curvemax - curvemean if negrange>posrange: thresh = (curvemean - dat) > threshold * negrange else: thresh = (dat - curvemean) > threshold * posrange if not np.isnan(prev): prevsample = int(round(prev * hdr_input.fSample)) - begsample if prevsample>0 and prevsample<len(thresh): thresh[0:prevsample] = False # determine samples that are true and where the previous sample is false thresh = np.logical_and(thresh[1:], np.logical_not(thresh[0:-1])) sample = np.where(thresh)[0]+1 if len(sample)<1: # no beat was detected return # determine the last beat in the window last = sample[-1] last = (last + begsample) / hdr_input.fSample if np.isnan(prev): # the first beat has not been detected yet prev = last return if last-prev>debounce: # require a minimum time between beats bpm = 60./(last-prev) prev = last if not np.isnan(bpm): # this is to schedule a timer that switches the gate off duration = patch.getfloat('general', 'duration', default=0.1) duration_scale = patch.getfloat('scale', 'duration', default=1) duration_offset = patch.getfloat('offset', 'duration', default=0) duration = EEGsynth.rescale(duration, slope=duration_scale, offset=duration_offset) patch.setvalue(key_rate, bpm) patch.setvalue(key_beat, bpm, duration=duration) # there should not be any local variables in this function, they should all be global if len(locals()): print('LOCALS: ' + ', '.join(locals().keys()))
def run(self): pubsub = r.pubsub() pubsub.subscribe('KEYBOARD_UNBLOCK' ) # this message unblocks the Redis listen command pubsub.subscribe(self.onset) # this message triggers the note while self.running: for item in pubsub.listen(): if not self.running or not item['type'] == 'message': break if item['channel'] == self.onset: # the trigger may contain a value that should be mapped to MIDI val = item['data'] val = EEGsynth.rescale(val, slope=input_scale, offset=input_offset) val = EEGsynth.limit(val, 0, 127) val = int(val) if self.velocity == None: # use the value of the onset trigger velocity = val elif type(self.velocity) == str: velocity = float(r.get(self.velocity)) velocity = EEGsynth.rescale(velocity, slope=scale_velocity, offset=offset_velocity) velocity = EEGsynth.limit(velocity, 0, 127) velocity = int(velocity) else: velocity = self.velocity if type(self.pitch) == str: pitch = float(r.get(self.pitch)) pitch = EEGsynth.rescale(pitch, slope=scale_pitch, offset=offset_pitch) pitch = EEGsynth.limit(pitch, 0, 127) pitch = int(pitch) else: pitch = self.pitch if type(self.duration) == str: duration = float(r.get(self.duration)) duration = EEGsynth.rescale(duration, slope=scale_duration, offset=offset_duration) duration = EEGsynth.limit( duration, 0.05, float('Inf') ) # some minimal time is needed for the delay else: duration = self.duration if debug > 1: print '----------------------------------------------' print "onset ", self.onset, "=", val print "velocity", self.velocity, "=", velocity print "pitch ", self.pitch, "=", pitch print "duration", self.duration, "=", duration if midichannel is None: msg = mido.Message('note_on', note=pitch, velocity=velocity) else: msg = mido.Message('note_on', note=pitch, velocity=velocity, channel=midichannel) SendMessage(msg) if duration != None: # schedule a delayed MIDI message to be sent to switch the note off if midichannel is None: msg = mido.Message('note_on', note=pitch, velocity=0) else: msg = mido.Message('note_on', note=pitch, velocity=0, channel=midichannel) t = threading.Timer(duration, SendMessage, args=[msg]) t.start()
config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) response = r.client_list() except redis.ConnectionError: raise RuntimeError("cannot connect to Redis server") # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor() # get the options from the configuration file debug = patch.getint('general', 'debug') delay = patch.getfloat('general', 'delay') number = patch.getint('switch', 'number', default=3) prefix = patch.getstring('output', 'prefix') # the scale and offset are used to map the Redis values to internal values scale_input = patch.getfloat('scale', 'input', default=1.) scale_time = patch.getfloat('scale', 'time', default=1.) scale_precision = patch.getfloat('scale', 'precision', default=1.) offset_input = patch.getfloat('offset', 'input', default=0.)
exit() # wiringpi.wiringPiSetup() wiringpi.wiringPiSetupGpio() pinR = config.getint('output', 'red') pinG = config.getint('output', 'green') pinB = config.getint('output', 'blue') wiringpi.pinMode(pinR, wiringpi.OUTPUT) wiringpi.pinMode(pinG, wiringpi.OUTPUT) wiringpi.pinMode(pinB, wiringpi.OUTPUT) wiringpi.softPwmCreate(pinR, 0, 127) wiringpi.softPwmCreate(pinG, 0, 127) wiringpi.softPwmCreate(pinB, 0, 127) while True: time.sleep(config.getfloat('general', 'delay')) valR = EEGsynth.getint('input', 'red', config, r) * EEGsynth.getfloat('scaling', 'red', config, r) valG = EEGsynth.getint('input', 'green', config, r) * EEGsynth.getfloat('scaling', 'green', config, r) valB = EEGsynth.getint('input', 'blue', config, r) * EEGsynth.getfloat('scaling', 'blue', config, r) print valR, valG, valB wiringpi.softPwmWrite(pinR, int(valR)) wiringpi.softPwmWrite(pinG, int(valG)) wiringpi.softPwmWrite(pinB, int(valB))
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') # this is the timeout for the FieldTrip buffer timeout = patch.getfloat('input_fieldtrip', 'timeout') # this can be used to selectively show parameters that have changed def show_change(key, val): if (key not in show_change.previous) or (show_change.previous[key]!=val): print(key, "=", val) show_change.previous[key] = val return True else: return False
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) del config # this determines how much debugging information gets printed debug = patch.getint('general','debug') try: ftc_host = patch.getstring('fieldtrip','hostname') ftc_port = patch.getint('fieldtrip','port') if debug>0: print 'Trying to connect to buffer on %s:%i ...' % (ftc_host, ftc_port) ft_output = FieldTrip.Client() ft_output.connect(ftc_host, ftc_port) if debug>0: print "Connected to output FieldTrip buffer" except:
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general','debug') # the list of MIDI commands is the only aspect that is specific to the Volca Keys # see http://media.aadl.org/files/catalog_guides/1444140_chart.pdf control_name = ['portamento', 'expression', 'voice', 'octave', 'detune', 'vco_eg_int', 'vcf_cutoff', 'vcf_eg_int', 'lfo_rate', 'lfo_pitch_int', 'lfo_cutoff_int', 'eg_attack', 'eg_decay_release', 'eg_sustain', 'delay_time', 'delay_feedback'] control_code = [5, 11, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53] note_name = ['C0', 'Db0', 'D0', 'Eb0', 'E0', 'F0', 'Gb0', 'G0', 'Ab0', 'A0', 'Bb0', 'B0', 'C1', 'Db1', 'D1', 'Eb1', 'E1', 'F1', 'Gb1', 'G1', 'Ab1', 'A1', 'Bb1', 'B1', 'C2', 'Db2', 'D2', 'Eb2', 'E2', 'F2', 'Gb2', 'G2', 'Ab2', 'A2', 'Bb2', 'B2', 'C3', 'Db3', 'D3', 'Eb3', 'E3', 'F3', 'Gb3', 'G3', 'Ab3', 'A3', 'Bb3', 'B3', 'C4', 'Db4', 'D4', 'Eb4', 'E4', 'F4', 'Gb4', 'G4', 'Ab4', 'A4', 'Bb4', 'B4', 'C5', 'Db5', 'D5', 'Eb5', 'E5', 'F5', 'Gb5', 'G5', 'Ab5', 'A5', 'Bb5', 'B5', 'C6', 'Db6', 'D6', 'Eb6', 'E6', 'F6', 'Gb6', 'G6', 'Ab6', 'A6', 'Bb6', 'B6', 'C7', 'Db7', 'D7', 'Eb7', 'E7', 'F7', 'Gb7', 'G7', 'Ab7', 'A7', 'Bb7', 'B7', 'C8', 'Db8', 'D8', 'Eb8', 'E8', 'F8', 'Gb8', 'G8', 'Ab8', 'A8', 'Bb8', 'B8', 'C9', 'Db9', 'D9', 'Eb9', 'E9', 'F9', 'Gb9', 'G9', 'Ab9', 'A9', 'Bb9', 'B9', 'C10', 'Db10', 'D10', 'Eb10', 'E10', 'F10', 'Gb10', 'G10', 'Ab10', 'A10', 'Bb10', 'B10'] note_code = [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143] midichannel = patch.getint('midi', 'channel')-1 # channel 1-16 get mapped to 0-15 outputport = EEGsynth.midiwrapper(config) outputport.open_output()
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general','debug') try: s = serial.Serial() s.port=patch.getstring('serial','device') s.baudrate=patch.getstring('serial','baudrate') s.bytesize=8 s.parity='N' s.stopbits=2 s.timeout=3.0 # xonxoff=0 # rtscts=0 s.open()
config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) response = r.client_list() except redis.ConnectionError: raise RuntimeError("cannot connect to Redis server") # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor() # get the options from the configuration file debug = patch.getint('general', 'debug') # this is the timeout for the FieldTrip buffer timeout = patch.getfloat('fieldtrip', 'timeout', default=30) try: ft_input_host = patch.getstring('fieldtrip', 'hostname') ft_input_port = patch.getint('fieldtrip', 'port') if debug > 0: print('Trying to connect to buffer on %s:%i ...' %
args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') # the list of MIDI commands is the only aspect that is specific to the Volca Beats # see http://media.aadl.org/files/catalog_guides/1445131_chart.pdf control_name = [ 'kick_level', 'snare_level', 'lo_tom_level', 'hi_tom_level', 'closed_hat_level', 'open_hat_level', 'clap_level', 'claves_level', 'agogo_level', 'crash_level', 'clap_speed', 'claves_speed', 'agogo_speed', 'crash_speed', 'stutter_time', 'stutter_depth', 'tom_decay', 'closed_hat_decay', 'open_hat_decay', 'hat_gra in' ] control_code = [ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) debug = patch.getint('general', 'debug') # this determines how much debugging information gets printed timeout = patch.getfloat('input_fieldtrip', 'timeout') # this is the timeout for the FieldTrip buffer sample_rate = patch.getfloat('sonification', 'sample_rate') f_shift = patch.getstring('sonification', 'f_shift') f_offset = patch.getfloat('sonification', 'f_offset') f_order = patch.getint('sonification', 'f_order', default=15) window = patch.getfloat('sonification', 'window') sideband = patch.getstring('sonification', 'sideband') left = patch.getint('sonification', 'left', multiple=True) right = patch.getint('sonification', 'right', multiple=True) # these are for multiplying/attenuating the output signal scaling = patch.getfloat('sonification', 'scaling') scaling_method = patch.getstring('sonification', 'scaling_method')
decode_responses=True) response = r.client_list() except redis.ConnectionError: raise RuntimeError("cannot connect to Redis server") try: context = zmq.Context() socket = context.socket(zmq.SUB) socket.connect( "tcp://%s:%i" % (config.get('zeromq', 'hostname'), config.getint('zeromq', 'port'))) except: raise RuntimeError("cannot connect to ZeroMQ") # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor(name=name, debug=patch.getint('general', 'debug')) # get the options from the configuration file debug = patch.getint('general', 'debug') prefix = patch.getstring('output', 'prefix') # the scale and offset are used to map OSC values to Redis values output_scale = patch.getfloat('output', 'scale', default=1) output_offset = patch.getfloat('output', 'offset', default=0) input_channels = patch.getstring('input', 'channels', multiple=True) if len(input_channels) == 0: monitor.info('subscribed to everything')
def run(self): pubsub = r.pubsub() # this message unblocks the Redis listen command pubsub.subscribe('OUTPUTCVGATE_UNBLOCK') # this message triggers the event pubsub.subscribe(self.redischannel) while self.running: for item in pubsub.listen(): if not self.running or not item['type'] == 'message': break if item['channel'] == self.redischannel: chanval = float(item['data']) if self.chanstr.startswith('cv'): # the value should be between 0 and 4095 scale = patch.getfloat('scale', self.chanstr, default=4095) offset = patch.getfloat('offset', self.chanstr, default=0) # apply the scale and offset chanval = EEGsynth.rescale(chanval, slope=scale, offset=offset) chanval = EEGsynth.limit(chanval, lo=0, hi=4095) chanval = int(chanval) SetControl(self.chanindx, chanval) monitor.update(self.chanstr, chanval) elif self.chanstr.startswith('gate'): # the value should be 0 or 1 scale = patch.getfloat('scale', self.chanstr, default=1) offset = patch.getfloat('offset', self.chanstr, default=0) # apply the scale and offset chanval = EEGsynth.rescale(chanval, slope=scale, offset=offset) chanval = int(chanval > 0) SetGate(self.chanindx, chanval) monitor.update(self.chanstr, chanval) # schedule a timer to switch the gate off after the specified duration duration = patch.getfloat('duration', self.chanstr, default=None) if duration != None: duration = EEGsynth.rescale(duration, slope=duration_scale, offset=duration_offset) # some minimal time is needed for the delay duration = EEGsynth.limit(duration, 0.05, float('Inf')) t = threading.Timer(duration, SetGate, args=[self.chanindx, False]) t.start()
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # make a dictionary that maps GPIOs to the WiringPi number pin = { "gpio0": 0, "gpio1": 1, "gpio2": 2, "gpio3": 3, "gpio4": 4, "gpio5": 5, "gpio6": 6, "gpio7": 7, "gpio21": 21, "gpio22": 22, "gpio23": 23, "gpio24": 24,
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) del config # this determines how much debugging information gets printed debug = patch.getint('general','debug') # this is the timeout for the FieldTrip buffer timeout = patch.getfloat('fieldtrip','timeout') try: ftc_host = patch.getstring('fieldtrip', 'hostname') ftc_port = patch.getint('fieldtrip', 'port') if debug > 0: print 'Trying to connect to buffer on %s:%i ...' % (ftc_host, ftc_port) ft_input = FieldTrip.Client() ft_input.connect(ftc_host, ftc_port)
parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to selectively show parameters that have changed def show_change(key, val): if (key not in show_change.previous) or (show_change.previous[key]!=val): print key, "=", val show_change.previous[key] = val return True else: return False show_change.previous = {} # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') delay = patch.getfloat('general', 'delay') number = patch.getint('switch', 'number', default=3)
def _loop_once(): '''Run the main loop once This uses the global variables from setup and start, and adds a set of global variables ''' global parser, args, config, r, response, patch, monitor, debug, ft_host, ft_port, ft_output global nchannels, fsample, shape, scale_frequency, scale_amplitude, scale_offset, scale_noise, scale_dutycycle, offset_frequency, offset_amplitude, offset_offset, offset_noise, offset_dutycycle, blocksize, datatype, block, begsample, endsample, stepsize, timevec, phasevec global start, frequency, amplitude, offset, noise, dutycycle, signal, dat_output, chan, elapsed, naptime if patch.getint('signal', 'rewind', default=0): monitor.info("Rewind pressed, jumping back to start of signal") # the sample number and phase should be 0 upon the start of the signal sample = 0 phase = 0 if not patch.getint('signal', 'play', default=1): monitor.info("Stopped") time.sleep(0.1) # the sample number and phase should be 0 upon the start of the signal sample = 0 phase = 0 return if patch.getint('signal', 'pause', default=0): monitor.info("Paused") time.sleep(0.1) return monitor.debug("Generating block " + str(block) + ' from ' + str(begsample) + ' to ' + str(endsample)) frequency = patch.getfloat('signal', 'frequency', default=10) amplitude = patch.getfloat('signal', 'amplitude', default=0.8) # the DC component of the output signal offset = patch.getfloat('signal', 'offset', default=0) noise = patch.getfloat('signal', 'noise', default=0.1) dutycycle = patch.getfloat('signal', 'dutycycle', default=0.5) # for the square wave # map the Redis values to signal parameters frequency = EEGsynth.rescale(frequency, slope=scale_frequency, offset=offset_frequency) amplitude = EEGsynth.rescale(amplitude, slope=scale_amplitude, offset=offset_amplitude) offset = EEGsynth.rescale(offset, slope=scale_offset, offset=offset_offset) noise = EEGsynth.rescale(noise, slope=scale_noise, offset=offset_noise) dutycycle = EEGsynth.rescale(dutycycle, slope=scale_dutycycle, offset=offset_dutycycle) monitor.update("frequency", frequency) monitor.update("amplitude", amplitude) monitor.update("offset ", offset) monitor.update("noise ", noise) monitor.update("dutycycle", dutycycle) # compute the phase of each sample in this block phasevec = 2 * np.pi * frequency * timevec + phasevec[-1] if shape == 'sin': signal = np.sin(phasevec) * amplitude + offset elif shape == 'square': signal = sp.square(phasevec, dutycycle) * amplitude + offset elif shape == 'triangle': signal = sp.sawtooth(phasevec, 0.5) * amplitude + offset elif shape == 'sawtooth': signal = sp.sawtooth(phasevec, 1) * amplitude + offset elif shape == 'dc': signal = phasevec * 0. + offset dat_output = np.random.randn(blocksize, nchannels) * noise for chan in range(nchannels): dat_output[:, chan] += signal # write the data to the output buffer if datatype == 'uint8': ft_output.putData(dat_output.astype(np.uint8)) elif datatype == 'int8': ft_output.putData(dat_output.astype(np.int8)) elif datatype == 'uint16': ft_output.putData(dat_output.astype(np.uint16)) elif datatype == 'int16': ft_output.putData(dat_output.astype(np.int16)) elif datatype == 'uint32': ft_output.putData(dat_output.astype(np.uint32)) elif datatype == 'int32': ft_output.putData(dat_output.astype(np.int32)) elif datatype == 'float32': ft_output.putData(dat_output.astype(np.float32)) elif datatype == 'float64': ft_output.putData(dat_output.astype(np.float64)) begsample += blocksize endsample += blocksize block += 1 # there should not be any local variables in this function, they should all be global if len(locals()): print("LOCALS: " + ", ".join(locals().keys()))
def drawpanel(self, panel, list): for item in list: try: # read the previous value from Redis key = '%s.%s' % (prefix, item[0]) val = float(patch.redis.get(key)) # sliders and dials have an internal value between 0 and 127 val = int( EEGsynth.rescale(val, slope=output_scale, offset=output_offset, reverse=True)) # buttons have an internal value of 0, 1, 2, 3, 4 if item[1] == 'slap': val = int(1. * val / 127.) elif item[1] == 'toggle1': val = int(1. * val / 127.) elif item[1] == 'toggle2': val = int(2. * val / 127.) elif item[1] == 'toggle3': val = int(3. * val / 127.) elif item[1] == 'toggle4': val = int(4. * val / 127.) if debug > 0: print(key, val) except: # set the default initial value to 0 val = 0 if item[1] == 'label': l = QLabel(item[0]) l.setAlignment(Qt.AlignHCenter) l.setStyleSheet('color: rgb(200,200,200);') panel.addWidget(l) elif item[1] == 'slider': s = QSlider(Qt.Vertical) s.name = item[0] s.type = item[1] s.setMinimum(0) s.setMaximum(127) # default is 100 s.setValue(val) s.setTickInterval(1) s.setTickPosition(QSlider.NoTicks) s.setStyleSheet('background-color: rgb(64,64,64);') s.valueChanged.connect(self.changevalue) l = QLabel(s.name) l.setAlignment(Qt.AlignHCenter) l.setStyleSheet('color: rgb(200,200,200);') # position the label under the slider sl = QVBoxLayout() sl.addWidget(s) sl.setAlignment(s, Qt.AlignHCenter) sl.addWidget(l) sl.setAlignment(l, Qt.AlignHCenter) panel.addLayout(sl) elif item[1] == 'dial': s = QDial() s.name = item[0] s.type = item[1] s.setMinimum(0) s.setMaximum(127) # default is 100 s.setValue(val) s.setStyleSheet('background-color: rgb(64,64,64);') s.valueChanged.connect(self.changevalue) l = QLabel(s.name) l.setAlignment(Qt.AlignHCenter) l.setStyleSheet('color: rgb(200,200,200);') # position the label under the dial sl = QVBoxLayout() sl.addWidget(s) sl.setAlignment(s, Qt.AlignHCenter) sl.addWidget(l) sl.setAlignment(l, Qt.AlignHCenter) panel.addLayout(sl) elif item[1] in [ 'push', 'slap', 'toggle1', 'toggle2', 'toggle3', 'toggle4' ]: b = QPushButton(item[0]) b.name = item[0] b.type = item[1] b.value = val if item[1] == 'slap' or item[1] == 'push': b.pressed.connect(self.changevalue) # push down b.released.connect(self.changevalue) # release else: b.pressed.connect(self.changevalue) # push down b.released.connect(self.changecolor) # release self.setcolor(b) panel.addWidget(b)
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) del config # this determines how much debugging information gets printed debug = patch.getint('general','debug') inputlist = patch.getstring('input', 'channels', multiple=True) stepsize = patch.getfloat('calibration', 'stepsize') # in seconds prefix = patch.getstring('output', 'prefix') numchannel = len(inputlist) # this will contain the initial and calibrated values value = np.empty((numchannel)) * np.NAN while True: # determine the start of the actual processing
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') # these are for mapping the Redis values to internal values scale_rate = patch.getfloat('scale', 'rate') offset_rate = patch.getfloat('offset', 'rate') scale_shift = patch.getfloat('scale', 'shift') offset_shift = patch.getfloat('offset', 'shift') scale_ppqn = patch.getfloat('scale', 'ppqn') offset_ppqn = patch.getfloat('offset', 'ppqn') # this can be used to selectively show parameters that have changed def show_change(key, val):
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) debug = patch.getint('general', 'debug') # this determines how much debugging information gets printed timeout = patch.getfloat('input_fieldtrip', 'timeout') # this is the timeout for the FieldTrip buffer sample_rate = patch.getfloat('sonification', 'sample_rate') f_shift = patch.getstring('sonification', 'f_shift') f_offset = patch.getfloat('sonification', 'f_offset') f_order = patch.getint('sonification', 'f_order', default=15) window = patch.getfloat('sonification', 'window') sideband = patch.getstring('sonification', 'sideband') left = patch.getint('sonification', 'left', multiple=True) right = patch.getint('sonification', 'right', multiple=True) # these are for multiplying/attenuating the output signal scaling = patch.getfloat('sonification', 'scaling') scaling_method = patch.getstring('sonification', 'scaling_method')
def _loop_once(): """Run the main loop once This uses the global variables from setup and start, and adds a set of global variables """ global parser, args, config, r, response, patch global monitor, stepsize, scale_frequency, scale_amplitude, scale_offset, scale_noise, scale_dutycycle, offset_frequency, offset_amplitude, offset_offset, offset_noise, offset_dutycycle, sample, phase global frequency, amplitude, offset, noise, dutycycle, key, val, elapsed, naptime if patch.getint('signal', 'rewind', default=0): monitor.info("Rewind pressed, jumping back to start of signal") # the sample number and phase should be 0 upon the start of the signal sample = 0 phase = 0 if not patch.getint('signal', 'play', default=1): monitor.info("Stopped") time.sleep(0.1) # the sample number and phase should be 0 upon the start of the signal sample = 0 phase = 0 return if patch.getint('signal', 'pause', default=0): monitor.info("Paused") time.sleep(0.1) return frequency = patch.getfloat('signal', 'frequency', default=0.2) amplitude = patch.getfloat('signal', 'amplitude', default=0.3) offset = patch.getfloat('signal', 'offset', default=0.5) noise = patch.getfloat('signal', 'noise', default=0.1) dutycycle = patch.getfloat('signal', 'dutycycle', default=0.5) # for the square wave # map the Redis values to signal parameters frequency = EEGsynth.rescale(frequency, slope=scale_frequency, offset=offset_frequency) amplitude = EEGsynth.rescale(amplitude, slope=scale_amplitude, offset=offset_amplitude) offset = EEGsynth.rescale(offset, slope=scale_offset, offset=offset_offset) noise = EEGsynth.rescale(noise, slope=scale_noise, offset=offset_noise) dutycycle = EEGsynth.rescale(dutycycle, slope=scale_dutycycle, offset=offset_dutycycle) monitor.update("frequency", frequency) monitor.update("amplitude", amplitude) monitor.update("offset ", offset) monitor.update("noise ", noise) monitor.update("dutycycle", dutycycle) # compute the phase of this sample phase = phase + 2 * np.pi * frequency * stepsize key = patch.getstring('output', 'prefix') + '.sin' val = np.sin(phase) * amplitude + offset + np.random.randn(1) * noise patch.setvalue(key, val[0]) key = patch.getstring('output', 'prefix') + '.square' val = signal.square( phase, dutycycle) * amplitude + offset + np.random.randn(1) * noise patch.setvalue(key, val[0]) key = patch.getstring('output', 'prefix') + '.triangle' val = signal.sawtooth( phase, 0.5) * amplitude + offset + np.random.randn(1) * noise patch.setvalue(key, val[0]) key = patch.getstring('output', 'prefix') + '.sawtooth' val = signal.sawtooth(phase, 1) * amplitude + offset + np.random.randn(1) * noise patch.setvalue(key, val[0]) sample += 1 # there should not be any local variables in this function, they should all be global if len(locals()): print("LOCALS: " + ", ".join(locals().keys()))
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) del config # this determines how much debugging information gets printed debug = patch.getint('general','debug') # this is only for debugging print('------ INPUT ------') for port in mido.get_input_names(): print(port) print('------ OUTPUT ------') for port in mido.get_output_names(): print(port) print('-------------------------') mididevice = patch.getstring('midi', 'device')
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(path, os.path.splitext(file)[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) response = r.client_list() except redis.ConnectionError: raise RuntimeError("cannot connect to Redis server") # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor() # get the options from the configuration file debug = patch.getint('general', 'debug') # the scale and offset are used to map the Redis values to internal values scale_rate = patch.getfloat('scale', 'rate', default=1) scale_spread = patch.getfloat('scale', 'spread', default=1) offset_rate = patch.getfloat('offset', 'rate', default=0) offset_spread = patch.getfloat('offset', 'spread', default=0) # read them once, they will be constantly updated in the main loop rate = patch.getfloat('interval', 'rate', default=60)
import EEGsynth config = ConfigParser.ConfigParser() config.read(os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini')) # this determines how much debugging information gets printed debug = config.getint('general','debug') try: r = redis.StrictRedis(host=config.get('redis','hostname'),port=config.getint('redis','port'),db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() pattern = EEGsynth.getint('input','pattern', config, r, default=0) previous = pattern try: sequence = config.get('sequence',"pattern{:d}".format(pattern)) except: sequence = '0' print pattern, sequence try: while True: for note in sequence.split(): note = int(note)
config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) response = r.client_list() except redis.ConnectionError: raise RuntimeError("cannot connect to Redis server") # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor() # get the options from the configuration file debug = patch.getint('general', 'debug') timeout = patch.getfloat('fieldtrip', 'timeout', default=30) device = patch.getint('audio', 'device') window = patch.getfloat('audio', 'window', default=1) # in seconds lrate = patch.getfloat('clock', 'learning_rate', default=0.05) # these are for multiplying/attenuating the signal scaling_method = patch.getstring('audio', 'scaling_method') scaling = patch.getfloat('audio', 'scaling') outputrate = patch.getint('audio', 'rate')
def update(): global specmax_curr, specmin_curr, specmax_hist, specmin_hist, fft_prev, fft_hist, redfreq, redwidth, bluefreq, bluewidth, counter, history # get last data last_index = ft_input.getHeader().nSamples begsample = (last_index - window) endsample = (last_index - 1) data = ft_input.getData([begsample, endsample]) print "reading from sample %d to %d" % (begsample, endsample) # demean and detrend data before filtering to reduce edge artefacts and center timecourse data = detrend(data, axis=0) # Notch filter - DOES NOT WORK # data = notch_filter(data, 10, hdr_input.fSample, 30) # taper data taper = np.hanning(len(data)) data = data * taper[:, np.newaxis] # shift data to next sample history = np.roll(history, 1, axis=2) for ichan in range(numchannel): channr = int(chanarray[ichan]) # estimate FFT at current moment, apply some temporal smoothing fft_temp = abs(fft(data[:, channr])) fft_curr[ichan] = fft_temp * lrate + fft_prev[ichan] * (1 - lrate) fft_prev[ichan] = fft_curr[ichan] # update FFT history with current estimate history[ichan, :, numhistory - 1] = fft_temp fft_hist = np.nanmean(history, axis=2) # user-selected frequency band arguments_freqrange = patch.getfloat('arguments', 'freqrange', multiple=True) freqrange = np.greater(freqaxis, arguments_freqrange[0]) & np.less_equal( freqaxis, arguments_freqrange[1]) # update panels spect_curr[ichan].setData(freqaxis[freqrange], fft_curr[ichan][freqrange]) spect_hist[ichan].setData(freqaxis[freqrange], fft_hist[ichan][freqrange]) # adapt the vertical scale to the running mean of min/max specmax_curr[ichan] = float(specmax_curr[ichan]) * ( 1 - lrate) + lrate * max(fft_curr[ichan][freqrange]) specmin_curr[ichan] = float(specmin_curr[ichan]) * ( 1 - lrate) + lrate * min(fft_curr[ichan][freqrange]) specmax_hist[ichan] = float(specmax_hist[ichan]) * ( 1 - lrate) + lrate * max(fft_hist[ichan][freqrange]) specmin_hist[ichan] = float(specmin_hist[ichan]) * ( 1 - lrate) + lrate * min(fft_hist[ichan][freqrange]) freqplot_curr[ichan].setYRange(specmin_curr[ichan], specmax_curr[ichan]) freqplot_hist[ichan].setYRange(specmin_hist[ichan], specmax_hist[ichan]) # update plotted lines redfreq = patch.getfloat('input', 'redfreq', default=10. / arguments_freqrange[1]) redfreq = EEGsynth.rescale(redfreq, slope=scale_red, offset=offset_red) * arguments_freqrange[1] redwidth = patch.getfloat('input', 'redwidth', default=1. / arguments_freqrange[1]) redwidth = EEGsynth.rescale(redwidth, slope=scale_red, offset=offset_red) * arguments_freqrange[1] bluefreq = patch.getfloat('input', 'bluefreq', default=20. / arguments_freqrange[1]) bluefreq = EEGsynth.rescale( bluefreq, slope=scale_blue, offset=offset_blue) * arguments_freqrange[1] bluewidth = patch.getfloat('input', 'bluewidth', default=4. / arguments_freqrange[1]) bluewidth = EEGsynth.rescale( bluewidth, slope=scale_blue, offset=offset_blue) * arguments_freqrange[1] redleft_curr[ichan].setData( x=[redfreq - redwidth, redfreq - redwidth], y=[specmin_curr[ichan], specmax_curr[ichan]]) redright_curr[ichan].setData( x=[redfreq + redwidth, redfreq + redwidth], y=[specmin_curr[ichan], specmax_curr[ichan]]) blueleft_curr[ichan].setData( x=[bluefreq - bluewidth, bluefreq - bluewidth], y=[specmin_curr[ichan], specmax_curr[ichan]]) blueright_curr[ichan].setData( x=[bluefreq + bluewidth, bluefreq + bluewidth], y=[specmin_curr[ichan], specmax_curr[ichan]]) redleft_hist[ichan].setData( x=[redfreq - redwidth, redfreq - redwidth], y=[specmin_hist[ichan], specmax_hist[ichan]]) redright_hist[ichan].setData( x=[redfreq + redwidth, redfreq + redwidth], y=[specmin_hist[ichan], specmax_hist[ichan]]) blueleft_hist[ichan].setData( x=[bluefreq - bluewidth, bluefreq - bluewidth], y=[specmin_hist[ichan], specmax_hist[ichan]]) blueright_hist[ichan].setData( x=[bluefreq + bluewidth, bluefreq + bluewidth], y=[specmin_hist[ichan], specmax_hist[ichan]]) # update labels at plotted lines text_redleft.setText('%0.1f' % (redfreq - redwidth)) text_redleft.setPos(redfreq - redwidth, specmax_curr[0]) text_redright.setText('%0.1f' % (redfreq + redwidth)) text_redright.setPos(redfreq + redwidth, specmax_curr[0]) text_blueleft.setText('%0.1f' % (bluefreq - bluewidth)) text_blueleft.setPos(bluefreq - bluewidth, specmax_curr[0]) text_blueright.setText('%0.1f' % (bluefreq + bluewidth)) text_blueright.setPos(bluefreq + bluewidth, specmax_curr[0]) text_redleft_hist.setText('%0.1f' % (redfreq - redwidth)) text_redleft_hist.setPos(redfreq - redwidth, specmax_hist[0]) text_redright_hist.setText('%0.1f' % (redfreq + redwidth)) text_redright_hist.setPos(redfreq + redwidth, specmax_hist[0]) text_blueleft_hist.setText('%0.1f' % (bluefreq - bluewidth)) text_blueleft_hist.setPos(bluefreq - bluewidth, specmax_hist[0]) text_blueright_hist.setText('%0.1f' % (bluefreq + bluewidth)) text_blueright_hist.setPos(bluefreq + bluewidth, specmax_hist[0]) key = "%s.%s.%s" % (prefix, 'redband', 'low') patch.setvalue(key, redfreq - redwidth) key = "%s.%s.%s" % (prefix, 'redband', 'high') patch.setvalue(key, redfreq + redwidth) key = "%s.%s.%s" % (prefix, 'blueband', 'low') patch.setvalue(key, bluefreq - bluewidth) key = "%s.%s.%s" % (prefix, 'blueband', 'high') patch.setvalue(key, bluefreq + bluewidth)
def _start(): """Start the module This uses the global variables from setup and adds a set of global variables """ global parser, args, config, r, response, patch, name global monitor, debug, device, fsample, blocksize, channels, batterythreshold, nchans, startfeedback, countfeedback, ft_host, ft_port, ft_output, datatype, digitalOutput # this can be used to show parameters that have changed monitor = EEGsynth.monitor(name=name, debug=patch.getint("general", "debug")) # get the options from the configuration file debug = patch.getint("general", "debug") device = patch.getstring("bitalino", "device") fsample = patch.getfloat("bitalino", "fsample", default=1000) blocksize = patch.getint("bitalino", "blocksize", default=10) channels = patch.getint("bitalino", "channels", multiple=True) # these should be one-offset batterythreshold = patch.getint("bitalino", "batterythreshold", default=30) # switch from one-offset to zero-offset nchans = len(channels) for i in range(nchans): channels[i] -= 1 monitor.info("fsample = " + str(fsample)) monitor.info("channels = " + str(channels)) monitor.info("nchans = " + str(nchans)) monitor.info("blocksize = " + str(blocksize)) try: ft_host = patch.getstring("fieldtrip", "hostname") ft_port = patch.getint("fieldtrip", "port") monitor.success("Trying to connect to buffer on %s:%i ..." % (ft_host, ft_port)) ft_output = FieldTrip.Client() ft_output.connect(ft_host, ft_port) monitor.success("Connected to output FieldTrip buffer") except: raise RuntimeError("cannot connect to output FieldTrip buffer") datatype = FieldTrip.DATATYPE_FLOAT32 ft_output.putHeader(nchans, float(fsample), datatype) try: # Connect to BITalino device = BITalino(device) monitor.success((device.version())) except: raise RuntimeError("cannot connect to BITalino") # Set battery threshold device.battery(batterythreshold) # Start Acquisition device.start(fsample, channels) # Turn BITalino led on digitalOutput = [1, 1] device.trigger(digitalOutput) startfeedback = time.time() countfeedback = 0 # there should not be any local variables in this function, they should all be global if len(locals()): print("LOCALS: " + ", ".join(locals().keys()))
config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) response = r.client_list() except redis.ConnectionError: raise RuntimeError("cannot connect to Redis server") # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor() # get the options from the configuration file debug = patch.getint('general', 'debug') clock = patch.getstring('sequence', 'clock') # the clock signal for the sequence prefix = patch.getstring('output', 'prefix') # these scale and offset parameters are used to map between Redis and internal values scale_active = patch.getfloat('scale', 'active', default=127) scale_transpose = patch.getfloat('scale', 'transpose', default=127) scale_note = patch.getfloat('scale', 'note', default=1) scale_duration = patch.getfloat('scale', 'duration', default=1)
args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print 'Error: cannot connect to redis server' exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # del config # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') # this is only for debugging print('------ INPUT ------') for port in mido.get_input_names(): print(port) print('------ OUTPUT ------') for port in mido.get_output_names(): print(port) print('-------------------------') mididevice = patch.getstring('midi', 'device')
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general','debug') # the list of MIDI commands is the only aspect that is specific to the Volca Bass # see http://media.aadl.org/files/catalog_guides/1444141_chart.pdf control_name = ['slide_time', 'expression', 'octave', 'lfo_rate', 'lfo_int', 'vco_pitch1', 'vco_pitch2', 'vco_pitch3', 'attack', 'decay_release', 'cutoff_intensity', 'gate_time'] control_code = [5, 11, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] note_name = ['C0', 'Db0', 'D0', 'Eb0', 'E0', 'F0', 'Gb0', 'G0', 'Ab0', 'A0', 'Bb0', 'B0', 'C1', 'Db1', 'D1', 'Eb1', 'E1', 'F1', 'Gb1', 'G1', 'Ab1', 'A1', 'Bb1', 'B1', 'C2', 'Db2', 'D2', 'Eb2', 'E2', 'F2', 'Gb2', 'G2', 'Ab2', 'A2', 'Bb2', 'B2', 'C3', 'Db3', 'D3', 'Eb3', 'E3', 'F3', 'Gb3', 'G3', 'Ab3', 'A3', 'Bb3', 'B3', 'C4', 'Db4', 'D4', 'Eb4', 'E4', 'F4', 'Gb4', 'G4', 'Ab4', 'A4', 'Bb4', 'B4', 'C5', 'Db5', 'D5', 'Eb5', 'E5', 'F5', 'Gb5', 'G5', 'Ab5', 'A5', 'Bb5', 'B5', 'C6', 'Db6', 'D6', 'Eb6', 'E6', 'F6', 'Gb6', 'G6', 'Ab6', 'A6', 'Bb6', 'B6', 'C7', 'Db7', 'D7', 'Eb7', 'E7', 'F7', 'Gb7', 'G7', 'Ab7', 'A7', 'Bb7', 'B7', 'C8', 'Db8', 'D8', 'Eb8', 'E8', 'F8', 'Gb8', 'G8', 'Ab8', 'A8', 'Bb8', 'B8', 'C9', 'Db9', 'D9', 'Eb9', 'E9', 'F9', 'Gb9', 'G9', 'Ab9', 'A9', 'Bb9', 'B9', 'C10', 'Db10', 'D10', 'Eb10', 'E10', 'F10', 'Gb10', 'G10', 'Ab10', 'A10', 'Bb10', 'B10'] note_code = [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143] # this is only for debugging, and check which MIDI devices are accessible print('------ OUTPUT ------') for port in mido.get_output_names(): print(port)
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(path, name + '.ini'), help="name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) response = r.client_list() except redis.ConnectionError: raise RuntimeError("cannot connect to Redis server") # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor(name=name, debug=patch.getint('general','debug')) # get the options from the configuration file debug = patch.getint('general', 'debug') clock = patch.getstring('sequence', 'clock') # the clock signal for the sequence prefix = patch.getstring('output', 'prefix') # these scale and offset parameters are used to map between Redis and internal values scale_active = patch.getfloat('scale', 'active', default=127) scale_transpose = patch.getfloat('scale', 'transpose', default=127) scale_note = patch.getfloat('scale', 'note', default=1) scale_duration = patch.getfloat('scale', 'duration', default=1) offset_active = patch.getfloat('offset', 'active', default=0)
def run(self): while self.running: ################################################################################ # these are to map the Redis values to MIDI values ################################################################################ scale_vco_pitch = patch.getfloat('scale', 'vco_pitch') offset_vco_pitch = patch.getfloat('offset', 'vco_pitch') ################################################################################ # VCO ################################################################################ vco_pitch = patch.getfloat('control', 'vco_pitch', default=60) vco_sin = patch.getfloat('control', 'vco_sin', default=0.75) vco_tri = patch.getfloat('control', 'vco_tri', default=0.00) vco_saw = patch.getfloat('control', 'vco_saw', default=0.25) vco_sqr = patch.getfloat('control', 'vco_sqr', default=0.00) # map the Redis values to MIDI values vco_pitch = EEGsynth.rescale(vco_pitch, scale_vco_pitch, offset_vco_pitch) vco_total = vco_sin + vco_tri + vco_saw + vco_sqr if vco_total > 0: # these are all scaled relatively to each other vco_sin = vco_sin / vco_total vco_tri = vco_tri / vco_total vco_saw = vco_saw / vco_total vco_sqr = vco_sqr / vco_total ################################################################################ # LFO ################################################################################ lfo_frequency = patch.getfloat('control', 'lfo_frequency', default=2) lfo_depth = patch.getfloat('control', 'lfo_depth', default=0.5) ################################################################################ # ADSR ################################################################################ adsr_attack = patch.getfloat('control', 'adsr_attack', default=0.25) adsr_decay = patch.getfloat('control', 'adsr_decay', default=0.25) adsr_sustain = patch.getfloat('control', 'adsr_sustain', default=0.5) adsr_release = patch.getfloat('control', 'adsr_release', default=0.25) # convert from value between 0 and 1 into time in samples adsr_attack *= float(rate) adsr_decay *= float(rate) adsr_sustain *= float(rate) adsr_release *= float(rate) ################################################################################ # VCA ################################################################################ vca_envelope = patch.getfloat('control', 'vca_envelope', default=0.5) ################################################################################ # store the control values in the local object ################################################################################ lock.acquire() self.vco_pitch = vco_pitch self.vco_sin = vco_sin self.vco_tri = vco_tri self.vco_saw = vco_saw self.vco_sqr = vco_sqr self.lfo_depth = lfo_depth self.lfo_frequency = lfo_frequency self.adsr_attack = adsr_attack self.adsr_decay = adsr_decay self.adsr_sustain = adsr_sustain self.adsr_release = adsr_release self.vca_envelope = vca_envelope lock.release() if debug > 2: print('----------------------------------') print('vco_pitch =', vco_pitch) print('vco_sin =', vco_sin) print('vco_tri =', vco_tri) print('vco_saw =', vco_saw) print('vco_sqr =', vco_sqr) print('lfo_depth =', lfo_depth) print('lfo_frequency =', lfo_frequency) print('adsr_attack =', adsr_attack) print('adsr_decay =', adsr_decay) print('adsr_sustain =', adsr_sustain) print('adsr_release =', adsr_release) print('vca_envelope =', vca_envelope)
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) del config # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') # this is only for debugging, and check which MIDI devices are accessible print('------ INPUT ------') for port in mido.get_input_names(): print(port) print('------ OUTPUT ------') for port in mido.get_output_names(): print(port) print('-------------------------') # on windows the input and output are different, on unix they are the same
args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') # determine the size of the universe dmxsize = 0 chanlist, chanvals = list(map(list, list(zip(*config.items('input'))))) for chanindx in range(0, 512): chanstr = "channel%03d" % (chanindx + 1) if chanstr in chanlist: # the last channel determines the size dmxsize = chanindx # my fixture won't work if the frame size is too small dmxsize = max(dmxsize, 16)
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) del config # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') timeout = patch.getfloat('fieldtrip', 'timeout', 30) try: ftc_host = patch.getstring('fieldtrip', 'hostname') ftc_port = patch.getint('fieldtrip', 'port') if debug > 0: print('Trying to connect to buffer on %s:%i ...' % (ftc_host, ftc_port)) ft_input = FieldTrip.Client() ft_input.connect(ftc_host, ftc_port) if debug > 0: print("Connected to input FieldTrip buffer")
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') outputport = EEGsynth.midiwrapper(config) outputport.open_output() # this is to prevent two messages from being sent at the same time lock = threading.Lock() class TriggerThread(threading.Thread): def __init__(self, redischannel, midichannel): threading.Thread.__init__(self) self.redischannel = redischannel self.midichannel = midichannel
def update(): global specmax_curr, specmin_curr, specmax_hist, specmin_hist, fft_prev, fft_hist, redfreq, redwidth, bluefreq, bluewidth, counter, history # get last data last_index = ft_input.getHeader().nSamples begsample = (last_index - window) endsample = (last_index - 1) data = ft_input.getData([begsample, endsample]) if debug>0: print("reading from sample %d to %d" % (begsample, endsample)) # demean and detrend data before filtering to reduce edge artefacts and center timecourse data = detrend(data, axis=0) # taper data taper = np.hanning(len(data)) data = data * taper[:, np.newaxis] # shift data to next sample history = np.roll(history, 1, axis=2) for ichan in range(numchannel): channr = int(chanarray[ichan]) # estimate FFT at current moment, apply some temporal smoothing fft_temp = abs(fft(data[:, channr])) fft_curr[ichan] = fft_temp * lrate + fft_prev[ichan] * (1 - lrate) fft_prev[ichan] = fft_curr[ichan] # update FFT history with current estimate history[ichan, :, numhistory - 1] = fft_temp fft_hist = np.nanmean(history, axis=2) # user-selected frequency band arguments_freqrange = patch.getfloat('arguments', 'freqrange', multiple=True) freqrange = np.greater(freqaxis, arguments_freqrange[0]) & np.less_equal(freqaxis, arguments_freqrange[1]) # update panels spect_curr[ichan].setData(freqaxis[freqrange], fft_curr[ichan][freqrange]) spect_hist[ichan].setData(freqaxis[freqrange], fft_hist[ichan][freqrange]) # adapt the vertical scale to the running mean of min/max specmax_curr[ichan] = float(specmax_curr[ichan]) * (1 - lrate) + lrate * max(fft_curr[ichan][freqrange]) specmin_curr[ichan] = float(specmin_curr[ichan]) * (1 - lrate) + lrate * min(fft_curr[ichan][freqrange]) specmax_hist[ichan] = float(specmax_hist[ichan]) * (1 - lrate) + lrate * max(fft_hist[ichan][freqrange]) specmin_hist[ichan] = float(specmin_hist[ichan]) * (1 - lrate) + lrate * min(fft_hist[ichan][freqrange]) freqplot_curr[ichan].setXRange(arguments_freqrange[0], arguments_freqrange[1]) freqplot_hist[ichan].setXRange(arguments_freqrange[0], arguments_freqrange[1]) freqplot_curr[ichan].setYRange(specmin_curr[ichan], specmax_curr[ichan]) freqplot_hist[ichan].setYRange(specmin_hist[ichan], specmax_hist[ichan]) # update plotted lines redfreq = patch.getfloat('input', 'redfreq', default=10. / arguments_freqrange[1]) redfreq = EEGsynth.rescale(redfreq, slope=scale_red, offset=offset_red) * arguments_freqrange[1] redwidth = patch.getfloat('input', 'redwidth', default=1. / arguments_freqrange[1]) redwidth = EEGsynth.rescale(redwidth, slope=scale_red, offset=offset_red) * arguments_freqrange[1] bluefreq = patch.getfloat('input', 'bluefreq', default=20. / arguments_freqrange[1]) bluefreq = EEGsynth.rescale(bluefreq, slope=scale_blue, offset=offset_blue) * arguments_freqrange[1] bluewidth = patch.getfloat('input', 'bluewidth', default=4. / arguments_freqrange[1]) bluewidth = EEGsynth.rescale(bluewidth, slope=scale_blue, offset=offset_blue) * arguments_freqrange[1] if showred: redleft_curr[ichan].setData(x=[redfreq - redwidth, redfreq - redwidth], y=[specmin_curr[ichan], specmax_curr[ichan]]) redright_curr[ichan].setData(x=[redfreq + redwidth, redfreq + redwidth], y=[specmin_curr[ichan], specmax_curr[ichan]]) if showblue: blueleft_curr[ichan].setData(x=[bluefreq - bluewidth, bluefreq - bluewidth], y=[specmin_curr[ichan], specmax_curr[ichan]]) blueright_curr[ichan].setData(x=[bluefreq + bluewidth, bluefreq + bluewidth], y=[specmin_curr[ichan], specmax_curr[ichan]]) if showred: redleft_hist[ichan].setData(x=[redfreq - redwidth, redfreq - redwidth], y=[specmin_hist[ichan], specmax_hist[ichan]]) redright_hist[ichan].setData(x=[redfreq + redwidth, redfreq + redwidth], y=[specmin_hist[ichan], specmax_hist[ichan]]) if showblue: blueleft_hist[ichan].setData(x=[bluefreq - bluewidth, bluefreq - bluewidth], y=[specmin_hist[ichan], specmax_hist[ichan]]) blueright_hist[ichan].setData(x=[bluefreq + bluewidth, bluefreq + bluewidth], y=[specmin_hist[ichan], specmax_hist[ichan]]) # update labels at plotted lines if showred: text_redleft.setText('%0.1f' % (redfreq - redwidth)) text_redleft.setPos(redfreq - redwidth, specmax_curr[0]) text_redright.setText('%0.1f' % (redfreq + redwidth)) text_redright.setPos(redfreq + redwidth, specmax_curr[0]) else: text_redleft.setText("") text_redright.setText("") if showblue: text_blueleft.setText('%0.1f' % (bluefreq - bluewidth)) text_blueleft.setPos(bluefreq - bluewidth, specmax_curr[0]) text_blueright.setText('%0.1f' % (bluefreq + bluewidth)) text_blueright.setPos(bluefreq + bluewidth, specmax_curr[0]) else: text_blueleft.setText("") text_blueright.setText("") if showred: text_redleft_hist.setText('%0.1f' % (redfreq - redwidth)) text_redleft_hist.setPos(redfreq - redwidth, specmax_hist[0]) text_redright_hist.setText('%0.1f' % (redfreq + redwidth)) text_redright_hist.setPos(redfreq + redwidth, specmax_hist[0]) else: text_redleft_hist.setText("") text_redright_hist.setText("") if showblue: text_blueleft_hist.setText('%0.1f' % (bluefreq - bluewidth)) text_blueleft_hist.setPos(bluefreq - bluewidth, specmax_hist[0]) text_blueright_hist.setText('%0.1f' % (bluefreq + bluewidth)) text_blueright_hist.setPos(bluefreq + bluewidth, specmax_hist[0]) else: text_blueleft_hist.setText("") text_blueright_hist.setText("") key = "%s.%s.%s" % (prefix, 'redband', 'low') patch.setvalue(key, redfreq - redwidth) key = "%s.%s.%s" % (prefix, 'redband', 'high') patch.setvalue(key, redfreq + redwidth) key = "%s.%s.%s" % (prefix, 'blueband', 'low') patch.setvalue(key, bluefreq - bluewidth) key = "%s.%s.%s" % (prefix, 'blueband', 'high') patch.setvalue(key, bluefreq + bluewidth)
debug = config.getint('general', 'debug') try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() if debug > 0: print "Connected to redis server" except redis.ConnectionError: print "Error: cannot connect to redis server" exit() midichannel = config.getint('midi', 'channel') - 1 # channel 1-16 get mapped to 0-15 outputport = EEGsynth.midiwrapper(config) outputport.open_output() # this is to prevent two messages from being sent at the same time lock = threading.Lock() class TriggerThread(threading.Thread): def __init__(self, redischannel, note): threading.Thread.__init__(self) self.redischannel = redischannel self.note = note self.running = True def stop(self): self.running = False
config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) response = r.client_list() except redis.ConnectionError: raise RuntimeError("cannot connect to Redis server") # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor(name=name, debug=patch.getint('general', 'debug')) # the list of MIDI commands is the only aspect that is specific to the Volca Keys # see http://media.aadl.org/files/catalog_guides/1444140_chart.pdf control_name = [ 'portamento', 'expression', 'voice', 'octave', 'detune', 'vco_eg_int', 'vcf_cutoff', 'vcf_eg_int', 'lfo_rate', 'lfo_pitch_int', 'lfo_cutoff_int', 'eg_attack', 'eg_decay_release', 'eg_sustain', 'delay_time', 'delay_feedback' ] control_code = [5, 11, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53] note_name = [ 'C0', 'Db0', 'D0', 'Eb0', 'E0', 'F0', 'Gb0', 'G0', 'Ab0', 'A0', 'Bb0',
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) del config # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') # these scale and offset parameters are used to map between Redis and internal values scale_active = patch.getfloat('scale', 'active', default=127.) scale_transpose = patch.getfloat('scale', 'transpose', default=127.) scale_note = patch.getfloat('scale', 'note', default=1.) scale_duration = patch.getfloat('scale', 'duration', default=1.) offset_active = patch.getfloat('offset', 'active', default=0.) offset_transpose = patch.getfloat('offset', 'transpose', default=0.) offset_note = patch.getfloat('offset', 'note', default=0.) offset_duration = patch.getfloat('offset', 'duration', default=0.)
config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0, charset='utf-8', decode_responses=True) response = r.client_list() except redis.ConnectionError: raise RuntimeError("cannot connect to Redis server") # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this can be used to show parameters that have changed monitor = EEGsynth.monitor(name=name, debug=patch.getint('general', 'debug')) # get the options from the configuration file debug = patch.getint('general', 'debug') delay = patch.getfloat('general', 'delay') number = patch.getint('switch', 'number', default=3) prefix = patch.getstring('output', 'prefix') # the scale and offset are used to map the Redis values to internal values scale_input = patch.getfloat('scale', 'input', default=1.) scale_time = patch.getfloat('scale', 'time', default=1.) scale_precision = patch.getfloat('scale', 'precision', default=1.) offset_input = patch.getfloat('offset', 'input', default=0.)
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) del config # this determines how much debugging information gets printed debug = patch.getint('general','debug') # this is only for debugging print('------ INPUT ------') for port in mido.get_input_names(): print(port) print('-------------------------') # the scale and offset are used to map MIDI values to Redis values scale = patch.getfloat('output', 'scale', default=127) offset = patch.getfloat('output', 'offset', default=0)
def _start(): '''Start the module This uses the global variables from setup and adds a set of global variables ''' global parser, args, config, r, response, patch, name global monitor, pin, debug, delay, scale_duration, offset_duration, lock, trigger # this can be used to show parameters that have changed monitor = EEGsynth.monitor(name=name, debug=patch.getint('general', 'debug')) # make a dictionary that maps GPIOs to the WiringPi number pin = { "gpio0": 0, "gpio1": 1, "gpio2": 2, "gpio3": 3, "gpio4": 4, "gpio5": 5, "gpio6": 6, "gpio7": 7, "gpio21": 21, "gpio22": 22, "gpio23": 23, "gpio24": 24, "gpio25": 25, "gpio26": 26, "gpio27": 27, "gpio28": 28, "gpio29": 29, } # get the options from the configuration file debug = patch.getint('general', 'debug') delay = patch.getfloat('general', 'delay') # values between 0 and 1 work well for the duration scale_duration = patch.getfloat('scale', 'duration', default=1) offset_duration = patch.getfloat('offset', 'duration', default=0) # this is to prevent two triggers from being activated at the same time lock = threading.Lock() # use the WiringPi numbering, see http://wiringpi.com/reference/setup/ wiringpi.wiringPiSetup() # set up PWM for the control channels previous_val = {} for gpio, channel in config.items('control'): monitor.info("control " + channel + " " + gpio) wiringpi.softPwmCreate(pin[gpio], 0, 100) # control values are only relevant when different from the previous value previous_val[gpio] = None # create the threads that deal with the triggers trigger = [] for gpio, channel in config.items('trigger'): wiringpi.pinMode(pin[gpio], 1) duration = patch.getstring('duration', gpio) trigger.append(TriggerThread(channel, gpio, duration)) monitor.info("trigger " + channel + " " + gpio) # start the thread for each of the triggers for thread in trigger: thread.start() # there should not be any local variables in this function, they should all be global if len(locals()): print('LOCALS: ' + ', '.join(locals().keys()))
parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') # this determines frequency at which the control values are sampled delay = patch.getfloat('general', 'delay') try: fileformat = patch.getstring('recording', 'format') except: fname = patch.getstring('recording', 'file') name, ext = os.path.splitext(fname) fileformat = ext[1:] filenumber = 0
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = ConfigParser.ConfigParser() config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print "Error: cannot connect to redis server" exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # make a dictionary that maps GPIOs to the WiringPi number pin = { "gpio0": 0, "gpio1": 1, "gpio2": 2, "gpio3": 3, "gpio4": 4, "gpio5": 5, "gpio6": 6, "gpio7": 7, "gpio21": 21, "gpio22": 22, "gpio23": 23, "gpio24": 24,
parser = argparse.ArgumentParser() parser.add_argument("-i", "--inifile", default=os.path.join(installed_folder, os.path.splitext(os.path.basename(__file__))[0] + '.ini'), help="optional name of the configuration file") args = parser.parse_args() config = configparser.ConfigParser(inline_comment_prefixes=('#', ';')) config.read(args.inifile) try: r = redis.StrictRedis(host=config.get('redis', 'hostname'), port=config.getint('redis', 'port'), db=0) response = r.client_list() except redis.ConnectionError: print("Error: cannot connect to redis server") exit() # combine the patching from the configuration file and Redis patch = EEGsynth.patch(config, r) # this determines how much debugging information gets printed debug = patch.getint('general', 'debug') # keep track of the number of received triggers count = 0 class TriggerThread(threading.Thread): def __init__(self, redischannel, rate): threading.Thread.__init__(self) self.redischannel = redischannel self.rate = rate self.key = "d%d.%s" % (rate, redischannel) self.count = 0 self.running = True
def run(self): pubsub = r.pubsub() pubsub.subscribe('KEYBOARD_UNBLOCK') # this message unblocks the Redis listen command pubsub.subscribe(self.onset) # this message triggers the note while self.running: for item in pubsub.listen(): if not self.running or not item['type'] == 'message': break if item['channel']==self.onset: # the trigger may contain a value that should be mapped to MIDI val = item['data'] val = EEGsynth.rescale(val, slope=input_scale, offset=input_offset) val = EEGsynth.limit(val, 0, 127) val = int(val) if self.velocity == None: # use the value of the onset trigger velocity = val elif type(self.velocity) == str: velocity = float(r.get(self.velocity)) velocity = EEGsynth.rescale(velocity, slope=scale_velocity, offset=offset_velocity) velocity = EEGsynth.limit(velocity, 0, 127) velocity = int(velocity) else: velocity = self.velocity if type(self.pitch) == str: pitch = float(r.get(self.pitch)) pitch = EEGsynth.rescale(pitch, slope=scale_pitch, offset=offset_pitch) pitch = EEGsynth.limit(pitch, 0, 127) pitch = int(pitch) else: pitch = self.pitch if type(self.duration) == str: duration = float(r.get(self.duration)) duration = EEGsynth.rescale(duration, slope=scale_duration, offset=offset_duration) duration = EEGsynth.limit(duration, 0.05, float('Inf')) # some minimal time is needed for the delay else: duration = self.duration if debug>1: print '----------------------------------------------' print "onset ", self.onset, "=", val print "velocity", self.velocity, "=", velocity print "pitch ", self.pitch, "=", pitch print "duration", self.duration, "=", duration if midichannel is None: msg = mido.Message('note_on', note=pitch, velocity=velocity) else: msg = mido.Message('note_on', note=pitch, velocity=velocity, channel=midichannel) SendMessage(msg) if duration != None: # schedule a delayed MIDI message to be sent to switch the note off if midichannel is None: msg = mido.Message('note_on', note=pitch, velocity=0) else: msg = mido.Message('note_on', note=pitch, velocity=0, channel=midichannel) t = threading.Timer(duration, SendMessage, args=[msg]) t.start()