コード例 #1
0
def _setup():
    '''Initialize the module
    This adds a set of global variables
    '''
    global parser, args, config, r, response, patch, monitor, debug, ft_host, ft_port, ft_input

    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')

    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_input = FieldTrip.Client()
        ft_input.connect(ft_host, ft_port)
        monitor.success('Connected to FieldTrip buffer')
    except:
        raise RuntimeError("cannot connect to FieldTrip buffer")

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #2
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, stepsize, clock, prefix, scale_active, scale_transpose, scale_note, scale_duration, offset_active, offset_transpose, offset_note, offset_duration, lock, key, sequencethread

    # 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
    stepsize = patch.getfloat('general', 'delay')
    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)
    offset_transpose = patch.getfloat('offset', 'transpose', default=0)
    offset_note = patch.getfloat('offset', 'note', default=0)
    offset_duration = patch.getfloat('offset', 'duration', default=0)

    # this is to prevent two messages from being sent at the same time
    lock = threading.Lock()

    # the notes will be sent to Redis using this key
    key = "{}.note".format(prefix)

    # create and start the thread for the output
    sequencethread = SequenceThread(clock, key)
    sequencethread.start()

    monitor.update('scale_active', scale_active)
    monitor.update('scale_transpose', scale_transpose)
    monitor.update('scale_note', scale_note)
    monitor.update('scale_duration', scale_duration)
    monitor.update('offset_active', offset_active)
    monitor.update('offset_transpose', offset_transpose)
    monitor.update('offset_note', offset_note)
    monitor.update('offset_duration', offset_duration)

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #3
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
    global patch, monitor, debug, inputlist, enable, stepsize, window, numchannel, numhistory, history, historic, metrics_iqr, metrics_mad, metrics_max, metrics_max_att, metrics_mean, metrics_median, metrics_min, metrics_min_att, metrics_p03, metrics_p16, metrics_p84, metrics_p97, metrics_range, metrics_std

    # 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')
    inputlist = patch.getstring('input', 'channels', multiple=True)
    enable = patch.getint('history', 'enable', default=1)
    stepsize = patch.getfloat('history', 'stepsize')  # in seconds
    window = patch.getfloat('history', 'window')  # in seconds

    metrics_iqr = patch.getint('metrics', 'iqr', default=1) != 0
    metrics_mad = patch.getint('metrics', 'mad', default=1) != 0
    metrics_max = patch.getint('metrics', 'max', default=1) != 0
    metrics_max_att = patch.getint('metrics', 'max_att', default=1) != 0
    metrics_mean = patch.getint('metrics', 'mean', default=1) != 0
    metrics_median = patch.getint('metrics', 'median', default=1) != 0
    metrics_min = patch.getint('metrics', 'min', default=1) != 0
    metrics_min_att = patch.getint('metrics', 'min_att', default=1) != 0
    metrics_p03 = patch.getint('metrics', 'p03', default=1) != 0
    metrics_p16 = patch.getint('metrics', 'p16', default=1) != 0
    metrics_p84 = patch.getint('metrics', 'p84', default=1) != 0
    metrics_p97 = patch.getint('metrics', 'p97', default=1) != 0
    metrics_range = patch.getint('metrics', 'range', default=1) != 0
    metrics_std = patch.getint('metrics', 'std', default=1) != 0

    numchannel = len(inputlist)
    numhistory = int(round(window / stepsize))

    # this will contain the full list of historic values
    history = np.empty((numchannel, numhistory)) * np.NAN

    # this will contain the statistics of the historic values
    historic = {}

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #4
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, serialdevice, s, dmxsize, chanlist, chanvals, chanindx, chanstr, dmxframe, prevtime, START_VAL, END_VAL, TX_DMX_PACKET, FRAME_PAD

    # 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')

    # get the specified serial device, or the one that is the closest match
    serialdevice = patch.getstring('serial', 'device')
    serialdevice = EEGsynth.trimquotes(serialdevice)
    serialdevice = process.extractOne(serialdevice, [comport.device for comport in serial.tools.list_ports.comports()])[0]  # select the closest match

    try:
        s = serial.Serial(serialdevice, patch.getint('serial', 'baudrate'), timeout=3.0)
        monitor.info("Connected to serial port")
    except:
        raise RuntimeError("cannot connect to serial port")

    # 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 + 1

    # my fixture won't work if the frame size is too small
    dmxsize = max(dmxsize, 16)
    monitor.info("universe size = %d" % dmxsize)

    # make an empty frame
    dmxframe = [0] * dmxsize
    # blank out
    sendframe(s, dmxframe)

    # keep a timer to send a packet every now and then
    prevtime = time.time()

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #5
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, delay, winx, winy, winwidth, winheight, input_channel, input_image, app, window, triggers, timer

    # 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
    delay = patch.getfloat('general', 'delay')
    winx = patch.getfloat('display', 'xpos')
    winy = patch.getfloat('display', 'ypos')
    winwidth = patch.getfloat('display', 'width')
    winheight = patch.getfloat('display', 'height')

    # get the input options
    input_channel, input_image = list(zip(*config.items('input')))

    # start the graphical user interface
    app = QApplication(sys.argv)
    app.aboutToQuit.connect(_stop)
    signal.signal(signal.SIGINT, _stop)

    # Let the interpreter run every 400 ms
    # see https://stackoverflow.com/questions/4938723/what-is-the-correct-way-to-make-my-pyqt-application-quit-when-killed-from-the-co/6072360#6072360
    timer = QtCore.QTimer()
    timer.start(400)
    timer.timeout.connect(lambda: None)

    window = Window()
    window.show()

    triggers = []
    # make a trigger thread for each image
    for channel, image in zip(input_channel, input_image):
        triggers.append(TriggerThread(channel, image))

    # start the thread for each of the triggers
    for thread in triggers:
        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()))
コード例 #6
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, prefix, winx, winy, winwidth, winheight, output_scale, output_offset

    # 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')
    winx = patch.getfloat('display', 'xpos')
    winy = patch.getfloat('display', 'ypos')
    winwidth = patch.getfloat('display', 'width')
    winheight = patch.getfloat('display', 'height')

    # the scale and offset are used to map internal values to Redis values
    output_scale = patch.getfloat('output', 'scale', default=1. /
                                  127)  # internal values are from 0 to 127
    output_offset = patch.getfloat(
        'output', 'offset', default=0.)  # internal values are from 0 to 127

    if 'initial' in config.sections():
        # assign the initial values
        for item in config.items('initial'):
            val = patch.getfloat('initial', item[0])
            patch.setvalue(item[0], val)
            monitor.update(item[0], val)

    # start the graphical user interface
    app = QApplication(sys.argv)
    app.aboutToQuit.connect(_stop)
    signal.signal(signal.SIGINT, _stop)

    # Let the interpreter run every 200 ms
    # see https://stackoverflow.com/questions/4938723/what-is-the-correct-way-to-make-my-pyqt-application-quit-when-killed-from-the-co/6072360#6072360
    timer = QtCore.QTimer()
    timer.start(400)
    timer.timeout.connect(lambda: None)

    ex = Window()
    ex.show()
    sys.exit(app.exec_())
コード例 #7
0
ファイル: quantizer.py プロジェクト: licy07/eegsynth
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, input_scale, input_offset, output_scale, output_offset, input_channel, input_name, output_name, output_value, i, index, input_value

    # 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')

    # the input scale and offset are used to map Redis values to internal values
    input_scale = patch.getfloat('input', 'scale', default=127)
    input_offset = patch.getfloat('input', 'offset', default=0)
    # the output scale and offset are used to map internal values to Redis values
    output_scale = patch.getfloat('output', 'scale', default=1. / 127)
    output_offset = patch.getfloat('output', 'offset', default=0)

    # get the input and output options
    input_channel, input_name = list(
        map(list, list(zip(*config.items('input')))))
    output_name, output_value = list(
        map(list, list(zip(*config.items('quantization')))))

    # remove the scale and offset from the input list
    del input_channel[input_channel.index('scale')]
    del input_channel[input_channel.index('offset')]

    # get the list of values for each of the input values for quantization
    for i, name in enumerate(output_name):
        output_value[i] = patch.getfloat('quantization', name, multiple=True)

    # find the input value to which the data is to be quantized
    index = output_name.index('value')
    input_value = output_value[index]
    # remove the value from the output list
    del output_name[index]
    del output_value[index]

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #8
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, lsl_name, lsl_type, lsl_id, lsl_format, info, outlet, trigger, item, lock, thread, previous_val

    # 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')

    lsl_name = patch.getstring('lsl', 'name', default='eegsynth')
    lsl_type = patch.getstring('lsl', 'type', default='Markers')
    lsl_id = patch.getstring('lsl', 'id', default=randomStringDigits())
    lsl_format = patch.getstring('lsl', 'format')

    # create an outlet stream
    info = StreamInfo(lsl_name, lsl_type, 1, 0, 'string', lsl_id)
    outlet = StreamOutlet(info)

    # create the background threads that deal with the triggers
    trigger = []
    monitor.info("Setting up threads for each trigger")
    for item in config.items('trigger'):
        trigger.append(TriggerThread(item[1], item[0]))
        monitor.debug(str(item[0]) + " " + str(item[1]) + " OK")

    # this is to prevent two messages from being sent at the same time
    lock = threading.Lock()

    # start the thread for each of the triggers
    for thread in trigger:
        thread.start()

    previous_val = {}
    for item in config.items('control'):
        key = item[0]
        previous_val[key] = None

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #9
0
ファイル: outputartnet.py プロジェクト: licy07/eegsynth
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, address, artnet, dmxsize, dmxframe, prevtime

    # 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')

    # prepare the data for a single universe
    address = [0, 0, patch.getint('artnet', 'universe')]
    artnet = ArtNet.ArtNet(ip=patch.getstring('artnet', 'broadcast'),
                           port=patch.getint('artnet', 'port'))

    # 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 + 1

    # FIXME the artnet code fails if the size is smaller than 512
    dmxsize = 512
    monitor.info("universe size = %d" % dmxsize)

    # make an empty frame
    dmxframe = [0] * dmxsize
    # blank out
    artnet.broadcastDMX(dmxframe, address)

    # keep a timer to send a packet every now and then
    prevtime = time.time()

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #10
0
    def __init__(self, path, name):

        # Configuration.
        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)

        # Redis.
        try:
            rds = redis.StrictRedis(host=config.get('redis', 'hostname'),
                                    port=config.getint('redis', 'port'),
                                    db=0,
                                    charset='utf-8',
                                    decode_responses=True)
        except redis.ConnectionError as e:
            raise RuntimeError(e)

        self.patch = EEGsynth.patch(
            config, rds)  # combine patching from configuration file and Redis.

        # Monitor.
        self.monitor = EEGsynth.monitor(name=name,
                                        debug=self.patch.getint(
                                            'general', 'debug'))

        # FieldTrip.
        try:
            ft_host = self.patch.getstring('fieldtrip', 'hostname')
            ft_port = self.patch.getint('fieldtrip', 'port')
            self.monitor.success(
                "Trying to connect to buffer on {0}{1}.".format(
                    ft_host, ft_port))
            self.ft_input = FieldTrip.Client()
            self.ft_input.connect(ft_host, ft_port)
            self.monitor.success('Connected to input FieldTrip buffer.')
        except:
            raise RuntimeError("Cannot connect to input FieldTrip buffer.")
コード例 #11
0
ファイル: plottopo.py プロジェクト: stephenwhitmarsh/eegsynth
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, delay, winx, winy, winwidth, winheight, input_name, input_variable, variable, app, window, timer, colormap, labelposition, labelcolor

    # 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
    delay           = patch.getfloat('general', 'delay')
    winx            = patch.getfloat('display', 'xpos')
    winy            = patch.getfloat('display', 'ypos')
    winwidth        = patch.getfloat('display', 'width')
    winheight       = patch.getfloat('display', 'height')
    colormap        = patch.getstring('display', 'colormap', default='parula')
    labelposition   = patch.getstring('display', 'labelposition', default='center')
    labelcolor      = patch.getstring('display', 'labelcolor', default='inverse')

    # get the input options
    input_name, input_variable = list(zip(*config.items('input')))

    for name,variable in zip(input_name, input_variable):
        monitor.info("%s = %s" % (name, variable))

    # start the graphical user interface
    app = QApplication(sys.argv)
    app.aboutToQuit.connect(_stop)
    signal.signal(signal.SIGINT, _stop)

    window = Window()
    window.show()

    # Set timer for update
    timer = QtCore.QTimer()
    timer.timeout.connect(_loop_once)
    timer.setInterval(10)            # timeout in milliseconds
    timer.start(int(delay * 1000))   # in milliseconds

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #12
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, input_name, input_variable, output_name, output_equation, variable, equation

    # this can be used to show parameters that have changed
    monitor = EEGsynth.monitor(name=name,
                               debug=patch.getint('general', 'debug'))

    if 'initial' in config.sections():
        # assign the initial values
        for item in config.items('initial'):
            val = patch.getfloat('initial', item[0])
            patch.setvalue(item[0], val)
            monitor.update(item[0], val)

    # get the input and output options
    if len(config.items('input')):
        input_name, input_variable = list(zip(*config.items('input')))
    else:
        input_name, input_variable = ([], [])
    if len(config.items('output')):
        output_name, output_equation = list(zip(*config.items('output')))
    else:
        output_name, output_equation = ([], [])

    # make the equations robust against sub-string replacements
    output_equation = [sanitize(equation) for equation in output_equation]

    monitor.info('===== input variables =====')
    for name, variable in zip(input_name, input_variable):
        monitor.info(name + ' = ' + variable)
    monitor.info('===== output equations =====')
    for name, equation in zip(output_name, output_equation):
        monitor.info(name + ' = ' + equation)
    monitor.info('============================')

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #13
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, delay, input_scale, input_offset, filename, fileformat, f, recording, filenumber, lock, trigger, item, thread

    # 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')
    input_scale = patch.getfloat('input', 'scale', default=None)
    input_offset = patch.getfloat('input', 'offset', default=None)
    filename = patch.getstring('recording', 'file')
    fileformat = 'tsv'

    # start with a temporary file which is immediately closed
    f = tempfile.TemporaryFile().close()
    recording = False
    filenumber = 0

    # this is to prevent two triggers from being saved at the same time
    lock = threading.Lock()

    # create the background threads that deal with the triggers
    trigger = []
    monitor.info("Setting up threads for each trigger")
    for item in config.items('trigger'):
        trigger.append(TriggerThread(item[0]))
        monitor.debug(item[0] + ' = OK')

    # 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()))
コード例 #14
0
ファイル: geomixer.py プロジェクト: licy07/eegsynth
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, stepsize, number, prefix, scale_input, scale_time, scale_precision, offset_input, offset_time, offset_precision, channel_name, vertex, dwelltime, edge, previous

    # 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')
    stepsize = 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.)
    offset_time = patch.getfloat('offset', 'time', default=0.)
    offset_precision = patch.getfloat('offset', 'precision', default=0.)

    channel_name = []
    for vertex in range(number):
        # each vertex of the geometry has an output value
        # the output names are like "geomixer.spectral.channel1.alpha.vertex1"
        channel_name.append(
            '%s.%s.vertex%d' %
            (prefix, patch.getstring('input', 'channel'), vertex + 1))

    dwelltime = 0.
    edge = 0
    previous = 'no'

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print("LOCALS: " + ", ".join(locals().keys()))
コード例 #15
0
ファイル: buffer.py プロジェクト: stephenwhitmarsh/eegsynth
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
    global monitor, debug, delay, port, server

    # 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', default=0.010)
    port = patch.getint('fieldtrip', 'port', multiple=True)
    
    server = []
    for p in port:
        monitor.info("starting server on %d" % p)
        s = FieldTrip.Server()
        s.connect(hostname='localhost', port=p)
        s.timeout = 0 # the server main loop should not wait, as it would block the other instances
        server.append(s);
    del p, s
コード例 #16
0
ファイル: slewlimiter.py プロジェクト: sangfrois/eegsynth
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, prefix, input_name, input_variable, previous_val

    # 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
    prefix = patch.getstring('output', 'prefix')

    # get the list of input variables
    input_name, input_variable = list(map(list, list(zip(*config.items('input')))))

    previous_val = {}
    for name in input_name:
        previous_val[name] = None

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #17
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, scale_rate, scale_spread, offset_rate, offset_spread, rate, spread, lock, t

    # 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')

    # 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)
    spread = patch.getfloat('interval', 'spread', default=10)
    rate = EEGsynth.rescale(rate, slope=scale_rate, offset=offset_rate)
    spread = EEGsynth.rescale(spread, slope=scale_spread, offset=offset_spread)

    # this is to prevent the trigger function from accessing the parameters while they are being updated
    lock = threading.Lock()

    # make an initial timer object, this is needed in case parameters are updated prior to the execution of the first trigger
    t = threading.Timer(0, None)

    # start the chain of triggers, the first one does not have to be sent
    trigger(send=False)

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print("LOCALS: " + ", ".join(locals().keys()))
コード例 #18
0
ファイル: inputmidi.py プロジェクト: licy07/eegsynth
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, mididevice, output_scale, output_offset, port, inputport

    # 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')
    mididevice = patch.getstring('midi', 'device')
    mididevice = EEGsynth.trimquotes(mididevice)

    # the scale and offset are used to map MIDI values to Redis values
    output_scale = patch.getfloat('output', 'scale', default=1. /
                                  127)  # MIDI values are from 0 to 127
    output_offset = patch.getfloat('output', 'offset',
                                   default=0.)  # MIDI values are from 0 to 127

    # this is only for debugging, check which MIDI devices are accessible
    monitor.info('------ INPUT ------')
    for port in mido.get_input_names():
        monitor.info(port)
    monitor.info('-------------------------')

    try:
        inputport = mido.open_input(mididevice)
        monitor.success('Connected to MIDI input')
    except:
        raise RuntimeError("Cannot connect to MIDI input")

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #19
0
    def __init__(self, path, name):
        # Configuration.
        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)

        # Redis.
        try:
            rds = redis.StrictRedis(host=config.get('redis', 'hostname'),
                                    port=config.getint('redis', 'port'),
                                    db=0,
                                    charset='utf-8',
                                    decode_responses=True)
        except redis.ConnectionError as e:
            raise RuntimeError(e)

        # Combine the patching from the configuration file and Redis.
        self.patch = EEGsynth.patch(config, rds)

        # BLE client.
        self.loop = asyncio.get_event_loop()

        self.ble_client = BleakClient(self.patch.getstring("input", "uuid"),
                                      loop=self.loop)

        self.monitor = EEGsynth.monitor(name=name,
                                        debug=self.patch.getint(
                                            "general", "debug"))

        self.loop.run_until_complete(self.discover())
コード例 #20
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, delay, prefix, input_name, input_variable

    # 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')
    prefix = patch.getstring('output', 'prefix')

    # get the input options
    input_name, input_variable = list(zip(*config.items('input')))

    for name, variable in zip(input_name, input_variable):
        monitor.info("%s = %s" % (name, variable))

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print("LOCALS: " + ", ".join(locals().keys()))
コード例 #21
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
    global patch, monitor, debug, channels, multipliers, lrate, count, triggers, channel, multiplier, thread

    # 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')
    channels = patch.getstring('clock', 'channel', multiple=True)
    multipliers = patch.getint('clock', 'rate', multiple=True)
    lrate = patch.getfloat('clock', 'learning_rate', default=1)

    # for keeping track of the number of received triggers
    count = 0

    triggers = []
    for channel in channels:
        for multiplier in multipliers:
            triggers.append(TriggerThread(channel, multiplier, lrate))
            monitor.debug("x%d.%s" % (multiplier, channel))

    # start the thread for each of the triggers
    for thread in triggers:
        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()))
コード例 #22
0
ファイル: plotcontrol.py プロジェクト: licy07/eegsynth
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, delay, historysize, window, winx, winy, winwidth, winheight, input_name, input_variable, ylim_name, ylim_value, counter, app, win, inputhistory, inputplot, inputcurve, iplot, name, ylim, variable, linecolor, icurve, timer, timeaxis

    # 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
    delay = patch.getfloat('general', 'delay')
    window = patch.getfloat('general', 'window')  # in seconds
    winx = patch.getfloat('display', 'xpos')
    winy = patch.getfloat('display', 'ypos')
    winwidth = patch.getfloat('display', 'width')
    winheight = patch.getfloat('display', 'height')

    historysize = int(window / delay)  # in steps
    timeaxis = np.linspace(-window, 0, historysize)

    input_name, input_variable = list(zip(*config.items('input')))
    ylim_name, ylim_value = list(zip(*config.items('ylim')))

    # count the total number of curves to be drawm
    counter = 0
    for iplot, name in enumerate(input_name):
        for control in input_variable[iplot].split(','):
            counter += 1

    # initialize graphical window
    app = QtGui.QApplication([])
    win = pg.GraphicsWindow(title="EEGsynth plotcontrol")
    win.setWindowTitle('EEGsynth plotcontrol')
    win.setGeometry(winx, winy, winwidth, winheight)

    # Enable antialiasing for prettier plots
    pg.setConfigOptions(antialias=True)

    # Initialize variables
    inputhistory = np.ones((counter, historysize))
    inputplot = []
    inputcurve = []

    # Create panels for each channel
    for iplot, name in enumerate(input_name):

        inputplot.append(win.addPlot(title="%s" % name))
        inputplot[iplot].setLabel('bottom', text='Time (s)')
        inputplot[iplot].showGrid(x=False, y=True, alpha=0.5)

        ylim = patch.getfloat('ylim', name, multiple=True, default=None)
        if ylim == [] or ylim == None:
            monitor.info("Ylim empty, will let it flow")
        else:
            monitor.info("Setting Ylim according to specified range")
            inputplot[iplot].setYRange(ylim[0], ylim[1])

        variable = input_variable[iplot].split(",")
        linecolor = patch.getstring('linecolor',
                                    name,
                                    multiple=True,
                                    default='w,' * len(variable))
        for icurve in range(len(variable)):
            inputcurve.append(inputplot[iplot].plot(pen=linecolor[icurve]))

        win.nextRow()

        signal.signal(signal.SIGINT, _stop)

        # Set timer for update
        timer = QtCore.QTimer()
        timer.timeout.connect(_loop_once)
        timer.setInterval(10)  # timeout in milliseconds
        timer.start(int(delay * 1000))  # in milliseconds
コード例 #23
0
ファイル: volcakeys.py プロジェクト: licy07/eegsynth
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, control_name, control_code, note_name, note_code, debug, port, midichannel, mididevice, outputport, scale, offset, lock, trigger, code, this, thread, previous_val

    # 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',
        '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
    ]

    # get the options from the configuration file
    debug = patch.getint('general', 'debug')

    # this is only for debugging, check which MIDI devices are accessible
    monitor.info('------ OUTPUT ------')
    for port in mido.get_output_names():
        monitor.info(port)
    monitor.info('-------------------------')

    midichannel = patch.getint(
        'midi', 'channel') - 1  # channel 1-16 get mapped to 0-15
    mididevice = patch.getstring('midi', 'device')
    mididevice = EEGsynth.trimquotes(mididevice)
    mididevice = process.extractOne(
        mididevice, mido.get_output_names())[0]  # select the closest match

    try:
        outputport = mido.open_output(mididevice)
        monitor.success('Connected to MIDI output')
    except:
        raise RuntimeError("cannot connect to MIDI output")

    # the scale and offset are used to map Redis values to MIDI values
    scale = patch.getfloat('input', 'scale', default=127)
    offset = patch.getfloat('input', 'offset', default=0)

    # this is to prevent two messages from being sent at the same time
    lock = threading.Lock()

    # each of the notes that can be played is mapped onto a different trigger
    trigger = []
    for name, code in zip(note_name, note_code):
        if config.has_option('note', name):
            # start the background thread that deals with this note
            this = TriggerThread(patch.getstring('note', name), code)
            trigger.append(this)
            monitor.debug(name + ' trigger configured')

    # start the thread for each of the notes
    for thread in trigger:
        thread.start()

    # control values are only relevant when different from the previous value
    previous_val = {}
    for name in control_name:
        previous_val[name] = None

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #24
0
ファイル: geomixer.py プロジェクト: sangfrois/eegsynth
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.)
offset_time = patch.getfloat('offset', 'time', default=0.)
offset_precision = patch.getfloat('offset', 'precision', default=0.)
コード例 #25
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, push, toggle1, toggle2, toggle3, toggle4, slap, scale_note, scale_control, offset_note, offset_control, mididevice_input, mididevice_output, port, inputport, Off, Red_Low, Red_Full, Amber_Low, Amber_Full, Yellow_Full, Green_Low, Green_Full, ledcolor, note_list, status_list, note, state0change, state0color, state0value, state1change, state1color, state1value, state2change, state2color, state2value, state3change, state3color, state3value, state4change, state4color, state4value, state5change, state5color, state5value, midichannel, outputport

    # 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
    push = patch.getint('button', 'push', multiple=True)  # push-release button
    toggle1 = patch.getint('button', 'toggle1', multiple=True)  # on-off button
    toggle2 = patch.getint('button', 'toggle2',
                           multiple=True)  # on1-on2-off button
    toggle3 = patch.getint('button', 'toggle3',
                           multiple=True)  # on1-on2-on3-off button
    toggle4 = patch.getint('button', 'toggle4',
                           multiple=True)  # on1-on2-on3-on4-off button
    slap = patch.getint('button', 'slap', multiple=True)  # slap button
    midichannel = patch.getint('midi', 'channel', default=None)

    # the scale and offset are used to map MIDI values to Redis values
    scale_note = patch.getfloat('scale', 'note', default=1. / 127)
    scale_control = patch.getfloat('scale', 'control', default=1. / 127)
    offset_note = patch.getfloat('offset', 'note', default=0)
    offset_control = patch.getfloat('offset', 'control', default=0)

    # on windows the input and output are different, on unix they are the same
    # use "input/output" when specified, otherwise use "device" for both
    try:
        mididevice_input = patch.getstring('midi', 'input')
        mididevice_input = EEGsynth.trimquotes(mididevice_input)
    except:
        mididevice_input = patch.getstring('midi', 'device')  # fallback
        mididevice_input = EEGsynth.trimquotes(mididevice_input)
    try:
        mididevice_output = patch.getstring('midi', 'output')
        mididevice_output = EEGsynth.trimquotes(mididevice_output)
    except:
        mididevice_output = patch.getstring('midi', 'device')  # fallback
        mididevice_output = EEGsynth.trimquotes(mididevice_output)

    mididevice_input = process.extractOne(
        mididevice_input,
        mido.get_input_names())[0]  # select the closest match
    mididevice_output = process.extractOne(
        mididevice_output,
        mido.get_output_names())[0]  # select the closest match

    # this is only for debugging, check which MIDI devices are accessible
    monitor.info('------ INPUT ------')
    for port in mido.get_input_names():
        monitor.info(port)
    monitor.info('------ OUTPUT ------')
    for port in mido.get_output_names():
        monitor.info(port)
    monitor.info('-------------------------')

    try:
        inputport = mido.open_input(mididevice_input)
        monitor.info("Connected to MIDI input")
    except:
        raise RuntimeError("cannot connect to MIDI input")

    try:
        outputport = mido.open_output(mididevice_output)
        monitor.info("Connected to MIDI output")
    except:
        raise RuntimeError("cannot connect to MIDI output")

    # channel 1-16 in the ini file should be mapped to 0-15
    if not midichannel is None:
        midichannel -= 1
    monitor.update('midichannel', midichannel)

    # these are the MIDI values for the LED color
    Off = 12
    Red_Low = 13
    Red_Full = 15
    Amber_Low = 29
    Amber_Full = 63
    Yellow_Full = 62
    Green_Low = 28
    Green_Full = 60

    # concatenate all buttons
    note_list = push + toggle1 + toggle2 + toggle3 + toggle4 + slap
    status_list = [0] * len(note_list)

    # ensure that all buttons and published messages start in the Off state
    for note in note_list:
        ledcolor(note, Off)

    # the button handling is implemented using an internal representation and state changes
    # whenever the actual button is pressed or released

    # push    button sequence P-R                   results in state change 0-1-0
    # toggle1 button sequence P-R-P-R               results in state change 0-11-12-13-0
    # toggle2 button sequence P-R-P-R-P-R           results in state change 0-21-22-23-24-25-0
    # toggle3 button sequence P-R-P-R-P-R-P-R       results in state change 0-31-32-33-34-35-36-37-0
    # toggle4 button sequence P-R-P-R-P-R-P-R-P-R   results in state change 0-41-42-43-44-45-46-47-48-49-0
    # slap    button sequence P-R                   results in state change 0-51-0

    state0change = {0: 1, 1: 0}
    state0color = {0: Off, 1: Red_Full}
    state0value = {0: 0, 1: 127}

    state1change = {0: 11, 11: 12, 12: 13, 13: 0}
    state1color = {0: Off, 11: Red_Full}  # don't change color on 12,13
    state1value = {0: 0, 11: 127}  # don't send message on 12,13

    state2change = {0: 21, 21: 22, 22: 23, 23: 24, 24: 25, 25: 0}
    state2color = {
        0: Off,
        21: Red_Full,
        23: Yellow_Full
    }  # don't change color on 22,24,25
    state2value = {
        0: 0,
        21: int(127 * 1 / 2),
        23: int(127 * 2 / 2)
    }  # don't send message on 22,24,25

    state3change = {
        0: 31,
        31: 32,
        32: 33,
        33: 34,
        34: 35,
        35: 36,
        36: 37,
        37: 0
    }
    state3color = {0: Off, 31: Red_Full, 33: Yellow_Full, 35: Green_Full}
    state3value = {
        0: 0,
        31: int(127 * 1 / 3),
        33: int(127 * 2 / 3),
        35: int(127 * 3 / 3)
    }

    state4change = {
        0: 41,
        41: 42,
        42: 43,
        43: 44,
        44: 45,
        45: 46,
        46: 47,
        47: 48,
        48: 49,
        49: 0
    }
    state4color = {
        0: Off,
        41: Red_Full,
        43: Yellow_Full,
        45: Green_Full,
        47: Amber_Full
    }
    state4value = {
        0: 0,
        41: int(127 * 1 / 4),
        43: int(127 * 2 / 4),
        45: int(127 * 3 / 4),
        47: int(127 * 4 / 4)
    }

    state5change = {0: 1, 1: 0}
    state5color = {0: Off, 1: Amber_Full}
    state5value = {0: None, 1: 127}  # don't send message on button release

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #26
0
ファイル: accelerometer.py プロジェクト: PeterZhouSZ/eegsynth
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')
timeout = patch.getfloat('fieldtrip', 'timeout', default=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))
    ftc = FieldTrip.Client()
    ftc.connect(ftc_host, ftc_port)
    if debug > 0:
        print("Connected to FieldTrip buffer")
except:
コード例 #27
0
ファイル: lsl2ft.py プロジェクト: sangfrois/eegsynth
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, timeout, lsl_name, lsl_type, ft_host, ft_port, ft_output, start, selected, streams, stream, inlet, type, source_id, match, lsl_id, channel_count, channel_format, nominal_srate, samples, blocksize

    # 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
    timeout = patch.getfloat('lsl', 'timeout', default=30)
    lsl_name = patch.getstring('lsl', 'name')
    lsl_type = patch.getstring('lsl', 'type')

    try:
        ft_host = patch.getstring('fieldtrip', 'hostname')
        ft_port = patch.getint('fieldtrip', 'port')
        monitor.info('Trying to connect to buffer on %s:%i ...' %
                     (ft_host, ft_port))
        ft_output = FieldTrip.Client()
        ft_output.connect(ft_host, ft_port)
        monitor.info("Connected to output FieldTrip buffer")
    except:
        raise RuntimeError("cannot connect to output FieldTrip buffer")

    monitor.success("looking for an LSL stream...")
    start = time.time()
    selected = []
    while len(selected) < 1:
        if (time.time() - start) > timeout:
            monitor.error("Error: timeout while waiting for LSL stream")
            raise SystemExit

        # find the desired stream on the lab network
        streams = lsl.resolve_streams()
        for stream in streams:
            inlet = lsl.StreamInlet(stream)
            name = inlet.info().name()
            type = inlet.info().type()
            source_id = inlet.info().source_id()
            # determine whether this stream should be further processed
            match = True
            if len(lsl_name):
                match = match and lsl_name == name
            if len(lsl_type):
                match = match and lsl_type == type
            if match:
                # select this stream for further processing
                selected.append(stream)
                monitor.success('-------- STREAM(*) ------')
            else:
                monitor.success('-------- STREAM ---------')
            monitor.info("name", name)
            monitor.info("type", type)
        monitor.success('-------------------------')

    # create a new inlet from the first (and hopefully only) selected stream
    inlet = lsl.StreamInlet(selected[0])

    # give some feedback
    lsl_name = inlet.info().name()
    lsl_type = inlet.info().type()
    lsl_id = inlet.info().source_id()
    monitor.success('connected to LSL stream %s (type = %s, id = %s)' %
                    (lsl_name, lsl_type, lsl_id))

    channel_count = inlet.info().channel_count()
    channel_format = inlet.info().channel_format()
    nominal_srate = inlet.info().nominal_srate()

    ft_output.putHeader(channel_count, nominal_srate,
                        FieldTrip.DATATYPE_FLOAT32)

    # this is used for feedback
    samples = 0
    blocksize = 1

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #28
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, note_name, note_code, debug, midichannel, mididevice, input_scale, input_offset, scale_velocity, scale_pitch, scale_duration, offset_velocity, offset_pitch, offset_duration, output_scale, output_offset, port, inputport, outputport, lock, trigger, code, onset, velocity, pitch, duration, thread

    # 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 specific to the implementation for a full-scale keyboard
    # see https://newt.phys.unsw.edu.au/jw/notes.html
    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]

    # get the options from the configuration file
    debug = patch.getint('general', 'debug')
    midichannel = patch.getint('midi', 'channel', default=None)
    mididevice = patch.getstring('midi', 'device')
    mididevice = EEGsynth.trimquotes(mididevice)
    mididevice = process.extractOne(mididevice, mido.get_input_names())[0]  # select the closest match

    # the input scale and offset are used to map Redis values to MIDI values
    input_scale = patch.getfloat('input', 'scale', default=127)
    input_offset = patch.getfloat('input', 'offset', default=0)

    scale_velocity = patch.getfloat('scale', 'velocity', default=127)
    scale_pitch = patch.getfloat('scale', 'pitch', default=127)
    scale_duration = patch.getfloat('scale', 'duration', default=2.0)
    offset_velocity = patch.getfloat('offset', 'velocity', default=0)
    offset_pitch = patch.getfloat('offset', 'pitch', default=0)
    offset_duration = patch.getfloat('offset', 'duration', default=0)

    # the output scale and offset are used to map MIDI values to Redis values
    output_scale = patch.getfloat('output', 'scale', default=1. / 127)
    output_offset = patch.getfloat('output', 'offset', default=0)

    # this is only for debugging, check which MIDI devices are accessible
    monitor.info('------ INPUT ------')
    for port in mido.get_input_names():
        monitor.info(port)
    monitor.info('------ OUTPUT ------')
    for port in mido.get_output_names():
        monitor.info(port)
    monitor.info('-------------------------')

    try:
        inputport = mido.open_input(mididevice)
        monitor.success('Connected to MIDI input')
    except:
        raise RuntimeError("cannot connect to MIDI input")

    try:
        outputport = mido.open_output(mididevice)
        monitor.success('Connected to MIDI output')
    except:
        raise RuntimeError("cannot connect to MIDI output")

    # channel 1-16 in the ini file should be mapped to 0-15
    if not midichannel is None:
        midichannel -= 1
    monitor.update('midichannel', midichannel)

    # this is to prevent two messages from being sent at the same time
    lock = threading.Lock()

    # the keyboard notes can be linked to separate triggers, where the trigger value corresponds to the velocity
    trigger = []
    for name, code in zip(note_name, note_code):
        if config.has_option('input', name):
            # start the background thread that deals with this note
            onset = patch.getstring('input', name)
            velocity = None  # use the value of the onset trigger
            pitch = code
            duration = None
            trigger.append(TriggerThread(onset, velocity, pitch, duration))
            monitor.debug(name + ' = OK')

    try:
        # the keyboard notes can also be controlled using a single trigger
        onset = patch.getstring('input', 'onset')
        velocity = patch.getstring('input', 'velocity')
        pitch = patch.getstring('input', 'pitch')
        duration = patch.getstring('input', 'duration')
        trigger.append(TriggerThread(onset, velocity, pitch, duration))
        monitor.debug('onset, velocity, pitch and duration OK')
    except:
        pass

    # start the thread for each of the notes
    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()))
コード例 #29
0
ファイル: plottrigger.py プロジェクト: sangfrois/eegsynth
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, delay, window, value, winx, winy, winwidth, winheight, data, lock, trigger, number, i, this, thread, app, win, plot

    # 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')  # in seconds
    window = patch.getfloat('general', 'window')  # in seconds
    value = patch.getint('general', 'value', default=0)  # boolean
    winx = patch.getfloat('display', 'xpos')
    winy = patch.getfloat('display', 'ypos')
    winwidth = patch.getfloat('display', 'width')
    winheight = patch.getfloat('display', 'height')

    # Initialize variables
    data = {}

    # this is to prevent two messages from being sent at the same time
    lock = threading.Lock()

    trigger = []
    number = []
    # each of the gates that can be triggered is mapped onto a different message
    for i in range(1, 17):
        name = 'channel{}'.format(i)
        if config.has_option('gate', name):
            number.append(i)
            data[i] = []
            # start the background thread that deals with this channel
            this = TriggerThread(patch.getstring('gate', name), i)
            trigger.append(this)
            monitor.info(name, 'OK')
    if len(trigger) == 0:
        monitor.warning('no gates were specified in the ini file')

    # start the thread for each of the notes
    for thread in trigger:
        thread.start()

    # initialize graphical window
    app = QtGui.QApplication([])
    win = pg.GraphicsWindow(title="EEGsynth plottrigger")
    win.setWindowTitle('EEGsynth plottrigger')
    win.setGeometry(winx, winy, winwidth, winheight)

    # Enable antialiasing for prettier plots
    pg.setConfigOptions(antialias=True)

    plot = win.addPlot()
    plot.setLabel('left', text='Channel')
    plot.setLabel('bottom', text='Time (s)')
    plot.setXRange(-window, 0)
    plot.setYRange(0.5, len(trigger) + 0.5)

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
コード例 #30
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, filename, fileformat, ext, ft_host, ft_port, ft_output, H, MININT8, MAXINT8, MININT16, MAXINT16, MININT32, MAXINT32, f, chanindx, labels, A, blocksize, begsample, endsample, block

    # 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
    filename = patch.getstring('playback', 'file')
    fileformat = patch.getstring('playback', 'format')

    if fileformat is None:
        # determine the file format from the file name
        name, ext = os.path.splitext(filename)
        fileformat = ext[1:]

    monitor.info('Reading data from ' + filename)

    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 FieldTrip buffer')
    except:
        raise RuntimeError('cannot connect to FieldTrip buffer')

    H = FieldTrip.Header()

    MININT8 = -np.power(2., 7)
    MAXINT8 = np.power(2., 7) - 1
    MININT16 = -np.power(2., 15)
    MAXINT16 = np.power(2., 15) - 1
    MININT32 = -np.power(2., 31)
    MAXINT32 = np.power(2., 31) - 1

    if fileformat == 'edf':
        f = EDF.EDFReader()
        f.open(filename)
        for chanindx in range(f.getNSignals()):
            if f.getSignalFreqs()[chanindx] != f.getSignalFreqs()[0]:
                raise AssertionError('unequal SignalFreqs')
            if f.getNSamples()[chanindx] != f.getNSamples()[0]:
                raise AssertionError('unequal NSamples')
        H.nChannels = len(f.getSignalFreqs())
        H.fSample = f.getSignalFreqs()[0]
        H.nSamples = f.getNSamples()[0]
        H.nEvents = 0
        H.dataType = FieldTrip.DATATYPE_FLOAT32
        # the channel labels will be written to the buffer
        labels = f.getSignalTextLabels()
        # read all the data from the file
        A = np.ndarray(shape=(H.nSamples, H.nChannels), dtype=np.float32)
        for chanindx in range(H.nChannels):
            monitor.info('reading channel ' + str(chanindx))
            A[:, chanindx] = f.readSignal(chanindx)
        f.close()

    elif fileformat == 'wav':
        try:
            physical_min = patch.getfloat('playback', 'physical_min')
        except:
            physical_min = -1
        try:
            physical_max = patch.getfloat('playback', 'physical_max')
        except:
            physical_max = 1
        f = wave.open(filename, 'r')
        resolution = f.getsampwidth()  # 1, 2 or 4
        # 8-bit samples are stored as unsigned bytes, ranging from 0 to 255.
        # 16-bit samples are stored as signed integers in 2's-complement.
        H.nChannels = f.getnchannels()
        H.fSample = f.getframerate()
        H.nSamples = f.getnframes()
        H.nEvents = 0
        H.dataType = FieldTrip.DATATYPE_FLOAT32
        # there are no channel labels
        labels = None
        # read all the data from the file
        x = f.readframes(f.getnframes() * f.getnchannels())
        f.close()
        # convert and calibrate
        if resolution == 2:
            x = struct.unpack_from('%dh' % f.getnframes() * f.getnchannels(), x)
            x = np.asarray(x).astype(np.float32).reshape(f.getnframes(), f.getnchannels())
            y = x / float(MAXINT16)
        elif resolution == 4:
            x = struct.unpack_from('%di' % f.getnframes() * f.getnchannels(), x)
            x = np.asarray(x).astype(np.float32).reshape(f.getnframes(), f.getnchannels())
            y = x / float(MAXINT32)
        else:
            raise NotImplementedError('unsupported resolution')
        A = y * ((physical_max - physical_min) / 2)

    else:
        raise NotImplementedError('unsupported file format')

    monitor.debug('nChannels = ' + str(H.nChannels))
    monitor.debug('nSamples = ' + str(H.nSamples))
    monitor.debug('fSample = ' + str(H.fSample))
    monitor.debug('labels = ' + str(labels))

    ft_output.putHeader(H.nChannels, H.fSample, H.dataType, labels=labels)

    blocksize = int(patch.getfloat('playback', 'blocksize') * H.fSample)
    begsample = 0
    endsample = blocksize - 1
    block = 0

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))