Example #1
0
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)
Example #2
0
 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)
Example #3
0
 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()
Example #4
0
 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()
Example #5
0
 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))
Example #6
0
    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)
Example #7
0
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)
Example #8
0
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()))
Example #9
0
    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()
Example #10
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()

# 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.)
Example #11
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))

Example #12
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)

# 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
Example #13
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)
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:
Example #14
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)

# 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()
Example #15
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)

# 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()
Example #16
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()

# 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 ...' %
Example #17
0
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,
Example #18
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)

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')
Example #19
0
                          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')
Example #20
0
    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()
Example #21
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)

# 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,
Example #22
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)
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)
Example #23
0
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)
Example #24
0
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()))
Example #25
0
    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)
Example #26
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')

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
Example #27
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)

# 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):
Example #28
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)

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()))
Example #30
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)
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')
Example #31
0
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)
Example #32
0
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)
Example #33
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()

# 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')
Example #34
0
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)
Example #35
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, 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()))
Example #36
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()

# 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)
Example #37
0
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')
Example #38
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)

# 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)
Example #39
0
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)
Example #40
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)
Example #41
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, 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
Example #42
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)

# 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()
Example #43
0
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)
Example #44
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')
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")
Example #45
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)

# 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
Example #46
0
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)
Example #47
0
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
Example #48
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'))

# 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',
Example #49
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)
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.)
Example #50
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.)
Example #51
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)
Example #52
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()))
Example #53
0
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
Example #54
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,
Example #55
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)

# 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
Example #56
0
    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()