Esempio n. 1
0
def sendMidi(name, code, val):
    global previous

    if name == 'pitchwheel':
        # the value should be limited between -8192 to 8191
        val = EEGsynth.limit(val, -8192, 8191)
        val = int(val)
    else:
        # the value should be limited between 0 and 127
        val = EEGsynth.limit(val, 0, 127)
        val = int(val)

    if name == 'note':
        # note_on and note_off messages are dealt with in another function
        SetNoteOn(val, velocity_note)
        return
    elif name.startswith('note'):
        # note_on and note_off messages are dealt with in another function
        SetNoteOn(code, val)
        return

    monitor.info(str(name) + " " + str(code) + " " + str(val))

    if name.startswith('control'):
        if midichannel is None:
            msg = mido.Message('control_change', control=code, value=val)
        else:
            msg = mido.Message('control_change',
                               control=code,
                               value=val,
                               channel=midichannel)
    elif name.startswith('polytouch'):
        if midichannel is None:
            msg = mido.Message('polytouch', note=code, value=val)
        else:
            msg = mido.Message('polytouch',
                               note=code,
                               value=val,
                               channel=midichannel)
    elif name == 'aftertouch':
        if midichannel is None:
            msg = mido.Message('aftertouch', value=val)
        else:
            msg = mido.Message('aftertouch', value=val, channel=midichannel)
    elif name == 'pitchwheel':
        if midichannel is None:
            msg = mido.Message('pitchwheel', pitch=val)
        else:
            msg = mido.Message('pitchwheel', pitch=val, channel=midichannel)
    # the following MIDI messages are not channel specific
    elif name == 'start':
        msg = mido.Message('start')
    elif name == 'continue':
        msg = mido.Message('continue')
    elif name == 'stop':
        msg = mido.Message('stop')
    elif name == 'reset':
        msg = mido.Message('reset')
    # send the MIDI message
    outputport.send(msg)
Esempio n. 2
0
 def run(self):
     pubsub = r.pubsub()
     # this message unblocks the Redis listen command
     pubsub.subscribe('OUTPUTGPIO_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:
                 # the scale and offset options are channel specific and can be changed on the fly
                 scale = patch.getfloat('scale', self.gpio, default=100)
                 offset = patch.getfloat('offset', self.gpio, default=0)
                 # switch to the PWM value specified in the event
                 val = float(item['data'])
                 val = EEGsynth.rescale(val, slope=scale, offset=offset)
                 val = int(val)
                 SetGPIO(self.gpio, val)
                 if self.duration != None:
                     # schedule a timer to switch it off after the specified duration
                     duration = patch.getfloat('duration', self.gpio)
                     duration = EEGsynth.rescale(duration,
                                                 slope=scale_duration,
                                                 offset=offset_duration)
                     # some minimal time is needed for the delay
                     duration = EEGsynth.limit(duration, 0.05, float('Inf'))
                     t = threading.Timer(duration,
                                         SetGPIO,
                                         args=[self.gpio, 0])
                     t.start()
Esempio n. 3
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
    global monitor, control_name, control_code, note_name, note_code, debug, port, midichannel, mididevice, outputport, scale, offset, lock, trigger, code, this, thread, previous_val
    global cmd, val, msg

    for name, cmd in zip(control_name, control_code):
        # loop over the control values
        val = patch.getfloat('control', name)
        if val == None:
            continue  # it should be skipped when not present
        if val == previous_val[name]:
            continue  # it should be skipped when identical to the previous value
        previous_val[name] = val
        # map the Redis values to MIDI values
        val = EEGsynth.rescale(val, slope=scale, offset=offset)
        val = EEGsynth.limit(val, 0, 127)
        val = int(val)
        msg = mido.Message('control_change',
                           control=cmd,
                           value=val,
                           channel=midichannel)
        monitor.debug(cmd, val, name)
        with lock:
            outputport.send(msg)

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
Esempio n. 4
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

    for gpio, channel in config.items('control'):
        val = patch.getfloat('control', gpio)

        if val == None:
            continue  # it should be skipped when not present
        if val == previous_val[gpio]:
            continue  # it should be skipped when identical to the previous value
        previous_val[gpio] = val
        # the scale and offset options are channel specific and can be changed on the fly
        scale = patch.getfloat('scale', gpio, default=100)
        offset = patch.getfloat('offset', gpio, default=0)
        val = EEGsynth.rescale(val, slope=scale, offset=offset)
        val = EEGsynth.limit(val, 0, 100)
        val = int(val)
        with lock:
            wiringpi.softPwmWrite(pin[gpio], val)

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
Esempio n. 5
0
 def run(self):
     global monitor, scale, offset
     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:
                 monitor.trace(item)
                 # map the Redis values to MIDI values
                 val = EEGsynth.rescale(float(item['data']),
                                        slope=scale,
                                        offset=offset)
                 val = EEGsynth.limit(val, 0, 127)
                 val = int(val)
                 monitor.update(item['channel'], val)
                 msg = mido.Message('note_on',
                                    note=self.note,
                                    velocity=val,
                                    channel=midichannel)
                 with lock:
                     outputport.send(msg)
Esempio n. 6
0
    def paintEvent(self, e):
        qp = QtGui.QPainter()
        qp.begin(self)

        green = QtGui.QColor(10, 255, 10)
        red = QtGui.QColor(255, 10, 10)

        w = qp.window().width()
        h = qp.window().height()

        # determine the width (x) and height (y) of each bar
        barx = int(w / len(input_name))
        bary = h
        # subtract some padding from each side
        padx = int(barx / 10)
        pady = int(h / 20)
        barx -= 2 * padx
        bary -= 2 * pady

        # this is the position for the first bar
        x = padx

        for name in input_name:
            scale = patch.getfloat('scale', name, default=1)
            offset = patch.getfloat('offset', name, default=0)
            val = patch.getfloat('input', name, default=np.nan)
            val = EEGsynth.rescale(val, slope=scale, offset=offset)

            monitor.update(name, val)

            threshold = patch.getfloat('threshold', name, default=1)
            threshold = EEGsynth.rescale(threshold, slope=scale, offset=offset)

            if val >= 0 and val <= threshold:
                qp.setBrush(green)
                qp.setPen(green)
            else:
                qp.setBrush(red)
                qp.setPen(red)

            if not np.isnan(val):
                val = EEGsynth.limit(val, 0, 1)
                r = QtCore.QRect(x, pady + (1 - val) * bary, barx, val * bary)
                qp.drawRect(r)

            r = QtCore.QRect(x, pady, barx, bary)
            qp.setPen(QtGui.QColor('white'))
            qp.drawText(r, QtCore.Qt.AlignCenter | QtCore.Qt.AlignBottom, name)

            # update the position for the next bar
            x += 2 * padx + barx

        # add horizontal lines every 10%
        for i in range(1, 10):
            qp.setPen(QtGui.QColor('black'))
            y = h - pady - float(i) / 10 * bary
            qp.drawLine(0, y, w, y)

        qp.end()
        self.show()
Esempio n. 7
0
 def run(self):
     pubsub = r.pubsub()
     pubsub.subscribe('VOLCABASS_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()
Esempio n. 8
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()
Esempio n. 9
0
 def run(self):
     global modulation, frequencies, control, channame, scale_amplitude, offset_amplitude, scale_frequency, offset_frequency
     pubsub = r.pubsub()
     # this message unblocks the Redis listen command
     pubsub.subscribe('MODULATETONE_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'])
                 with lock:
                     if modulation == 'am':
                         chanval = EEGsynth.rescale(chanval,
                                                    slope=scale_amplitude,
                                                    offset=offset_amplitude)
                         chanval = EEGsynth.limit(chanval, lo=0, hi=1)
                     elif modulation == 'fm':
                         chanval = EEGsynth.rescale(chanval,
                                                    slope=scale_frequency,
                                                    offset=offset_frequency)
                     control[self.tone, self.audiochannel] = chanval
                 monitor.update(
                     channame[self.audiochannel] + " tone" +
                     str(self.tone + 1), chanval)
Esempio n. 10
0
def UpdateDuration():
    global duration_note
    duration_note = patch.getfloat('duration', 'note', default=None)
    if duration_note != None:
        duration_note = EEGsynth.rescale(duration_note,
                                         slope=scale_duration,
                                         offset=offset_duration)
        # some minimal time is needed for the duration
        duration_note = EEGsynth.limit(duration_note, 0.05, float('Inf'))
Esempio n. 11
0
def UpdateParameters():
    global patch, velocity_note, scale_velocity, offset_velocity, duration_note, scale_duration, offset_duration
    velocity_note = patch.getfloat('velocity', 'note', default=64)
    velocity_note = int(EEGsynth.rescale(velocity_note, slope=scale_velocity, offset=offset_velocity))
    duration_note = patch.getfloat('duration', 'note', default=None)
    if duration_note != None:
        duration_note = EEGsynth.rescale(duration_note, slope=scale_duration, offset=offset_duration)
        # some minimal time is needed for the duration
        duration_note = EEGsynth.limit(duration_note, 0.05, float('Inf'))
Esempio n. 12
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()
Esempio n. 13
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
    global monitor, duration_scale, duration_offset, serialdevice, s, lock, trigger, chanindx, chanstr, redischannel, thread

    monitor.loop()
    time.sleep(patch.getfloat('general', 'delay'))

    # loop over the control voltages
    for chanindx in range(1, 5):
        chanstr = "cv%d" % chanindx
        # this returns None when the channel is not present
        chanval = patch.getfloat('input', chanstr)

        if chanval == None:
            # the value is not present in Redis, skip it
            monitor.trace(chanstr, 'not available')
            continue

        # the scale and offset options are channel specific
        scale = patch.getfloat('scale', chanstr, default=4095)
        offset = patch.getfloat('offset', chanstr, default=0)
        # apply the scale and offset
        chanval = EEGsynth.rescale(chanval, slope=scale, offset=offset)
        # ensure that it is within limits
        chanval = EEGsynth.limit(chanval, lo=0, hi=4095)
        chanval = int(chanval)

        SetControl(chanindx, chanval)
        monitor.update(chanstr, chanval)

    # loop over the gates
    for chanindx in range(1, 5):
        chanstr = "gate%d" % chanindx
        chanval = patch.getfloat('input', chanstr)

        if chanval == None:
            # the value is not present in Redis, skip it
            monitor.trace(chanstr, 'not available')
            continue

        # the scale and offset options are channel specific
        scale = patch.getfloat('scale', chanstr, default=4095)
        offset = patch.getfloat('offset', chanstr, default=0)
        # apply the scale and offset
        chanval = EEGsynth.rescale(chanval, slope=scale, offset=offset)
        # the value for the gate should be 0 or 1
        chanval = int(chanval > 0)

        SetGate(chanindx, chanval)
        monitor.update(chanstr, chanval)
Esempio n. 14
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
    global monitor, debug, address, artnet, dmxsize, dmxframe, prevtime
    global update, chanindx, chanstr, chanval, scale, offset

    update = False

    # loop over the control values, these are 1-offset in the ini file
    for chanindx in range(0, dmxsize):
        chanstr = "channel%03d" % (chanindx + 1)
        # this returns None when the channel is not present
        chanval = patch.getfloat('input', chanstr)

        if chanval == None:
            # the value is not present in Redis, skip it
            continue

        # the scale and offset options are channel specific
        scale = patch.getfloat('scale', chanstr, default=255)
        offset = patch.getfloat('offset', chanstr, default=0)
        # apply the scale and offset
        chanval = EEGsynth.rescale(chanval, slope=scale, offset=offset)
        # ensure that it is within limits
        chanval = EEGsynth.limit(chanval, lo=0, hi=255)
        chanval = int(chanval)

        # only update if the value has changed
        if dmxframe[chanindx] != chanval:
            monitor.info("DMX channel%03d = %g" % (chanindx, chanval))
            dmxframe[chanindx] = chanval
            update = True

    if update:
        artnet.broadcastDMX(dmxframe, address)
        prevtime = time.time()

    elif (time.time() - prevtime) > 0.5:
        # send a maintenance frame every 0.5 seconds
        artnet.broadcastDMX(dmxframe, address)
        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()))
Esempio n. 15
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)
Esempio n. 16
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)
Esempio n. 17
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
    global monitor, debug, address, artnet, dmxdata, prevtime
    global chanindx, chanstr, chanval, scale, offset

    monitor.loop()
    time.sleep(patch.getfloat('general', 'delay'))

    # loop over the control values, these are 1-offset in the ini file
    for chanindx in range(1, 512):
        chanstr = "channel%03d" % chanindx
        # this returns None when the channel is not present
        chanval = patch.getfloat('input', chanstr)

        if chanval==None:
            # the value is not present in Redis, skip it
            monitor.trace(chanstr, 'not available')
            continue

        # the scale and offset options are channel specific
        scale  = patch.getfloat('scale', chanstr, default=255)
        offset = patch.getfloat('offset', chanstr, default=0)
        # apply the scale and offset
        chanval = EEGsynth.rescale(chanval, slope=scale, offset=offset)
        # ensure that it is within limits
        chanval = EEGsynth.limit(chanval, lo=0, hi=255)
        chanval = int(chanval)

        if dmxdata[chanindx-1]!=chanval:
            # update the DMX value for this channel
            dmxdata[chanindx-1] = chanval
            monitor.debug("DMX channel%03d" % chanindx, '=', chanval)
            artnet.broadcastDMX(dmxdata,address)
        elif (time.time()-prevtime)>1:
            # send a maintenance packet now and then
            artnet.broadcastDMX(dmxdata,address)
            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()))
Esempio n. 18
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
    global monitor, stepsize, clock, prefix, scale_active, scale_transpose, scale_note, scale_duration, offset_active, offset_transpose, offset_note, offset_duration, lock, key, sequencethread
    global active, sequence, transpose, duration, elapsed, naptime

    # the active sequence is specified as an integer between 0 and 127
    active = patch.getfloat('sequence', 'active', default=0)
    active = EEGsynth.rescale(active, slope=scale_active, offset=offset_active)
    active = int(active)

    # get the corresponding sequence as a list
    sequence = "sequence%03d" % (active)
    sequence = patch.getstring('sequence', sequence, multiple=True)

    transpose = patch.getfloat('sequence', 'transpose', default=0.)
    transpose = EEGsynth.rescale(transpose,
                                 slope=scale_transpose,
                                 offset=offset_transpose)

    # the duration is relative to the time between clock ticks
    duration = patch.getfloat('sequence', 'duration', default=0.)
    duration = EEGsynth.rescale(duration,
                                slope=scale_duration,
                                offset=offset_duration)
    if duration > 0:
        # a duration of 0 or less means that the note will not switch off
        duration = EEGsynth.limit(duration, 0.1, 0.9)

    # show the parameters whose value has changed
    monitor.update("active", active)
    monitor.update("sequence", sequence)
    monitor.update("transpose", transpose)
    monitor.update("duration", duration)

    sequencethread.setSequence(sequence)
    sequencethread.setTranspose(transpose)
    sequencethread.setDuration(duration)

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print('LOCALS: ' + ', '.join(locals().keys()))
Esempio n. 19
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()
Esempio n. 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:
                 # 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()
Esempio n. 21
0
            f.setnchannels(nchans)
            f.setnframes(0)
            f.setsampwidth(4)  # 1, 2 or 4
            f.setframerate(1. / delay)
        else:
            raise NotImplementedError('unsupported file format')

    if recording:
        D = []
        for chan in channels:
            xval = r.get(chan)
            try:
                xval = float(xval)
            except ValueError:
                xval = 0.
            xval = EEGsynth.limit(xval, physical_min, physical_max)
            D.append([xval])
        sample += 1

        if (sample % synchronize) == 0:
            patch.setvalue("recordcontrol.synchronize", sample)

        if debug > 1:
            print "Writing", D
        elif debug > 0:
            print "Writing sample", sample, "as", np.shape(D)

        if fileformat == 'edf':
            f.writeBlock(D)
        elif fileformat == 'wav':
            D = np.asarray(D)
Esempio n. 22
0
    while True:
        monitor.loop()
        time.sleep(patch.getfloat('general', 'delay'))

        for gpio, channel in config.items('control'):
            val = patch.getfloat('control', gpio)

            if val == None:
                continue  # it should be skipped when not present
            if val == previous_val[gpio]:
                continue  # it should be skipped when identical to the previous value
            previous_val[gpio] = val
            # the scale and offset options are channel specific and can be changed on the fly
            scale = patch.getfloat('scale', gpio, default=100)
            offset = patch.getfloat('offset', gpio, default=0)
            val = EEGsynth.rescale(val, slope=scale, offset=offset)
            val = EEGsynth.limit(val, 0, 100)
            val = int(val)
            lock.acquire()
            wiringpi.softPwmWrite(pin[gpio], val)
            lock.release()

except KeyboardInterrupt:
    monitor.success('Closing threads')
    for thread in trigger:
        thread.stop()
    r.publish('OUTPUTGPIO_UNBLOCK', 1)
    for thread in trigger:
        thread.join()
    sys.exit()
Esempio n. 23
0
                    print name, 'not available'
                continue

            # the scale and offset options are channel specific
            scale  = patch.getfloat('scale', name, default=1)
            offset = patch.getfloat('offset', name, default=0)

            # map the Redis values to MIDI pitch values
            val = EEGsynth.rescale(val, slope=scale, offset=offset)

            # portamento range is hardcoded 0-127, so no need for user-config
            port_val = EEGsynth.rescale(port_val, slope=127, offset=0)

            # ensure that values are within limits
            if patch.getstring('general', 'mode') == 'note':
                val = EEGsynth.limit(val, lo=0, hi=127)
                val = int(val)
                port_val = EEGsynth.limit(port_val, lo=0, hi=127)
                port_val = int(port_val)
            elif patch.getstring('general', 'mode') == 'pitchbend':
                val = EEGsynth.limit(val, lo=-8192, hi=8191)
                val = int(val)
            else:
                print 'No output mode (note or pitchbend) specified!'
                break

            if val != previous_val[name] or not val: # it should be skipped when identical to the previous value

                previous_val[name] = val

                if debug > 0:
Esempio n. 24
0
            patch.getfloat('recording', 'physical_max')
        ]
        chan_info['digital_min'] = nchans * [-32768]
        chan_info['digital_max'] = nchans * [32768]
        chan_info['ch_names'] = channelz
        chan_info['n_samps'] = nchans * [1]
        # write the header to file
        if debug > 0:
            print "Opening", fname
        f = EDF.EDFWriter(fname)
        f.writeHeader((meas_info, chan_info))

    if recording:
        D = []
        for chan in channels:
            xval = EEGsynth.limit(r.get(chan),
                                  patch.getfloat('recording', 'physical_min'),
                                  patch.getfloat('recording', 'physical_max'))
            D.append([xval])

        if debug > 1:
            print "Writing", D

        f.writeBlock(D)
        time.sleep(adjust * delay)

        elapsed = time.time() - now
        # adjust the relative delay for the next iteration
        # the adjustment factor should only change a little per iteration
        adjust = 0.1 * delay / elapsed + 0.9 * adjust
Esempio n. 25
0
                    print name, 'not available'
                continue

            # the scale and offset options are channel specific
            scale = patch.getfloat('scale', name, default=1)
            offset = patch.getfloat('offset', name, default=0)

            # map the Redis values to MIDI pitch values
            val = EEGsynth.rescale(val, slope=scale, offset=offset)

            # portamento range is hardcoded 0-127, so no need for user-config
            port_val = EEGsynth.rescale(port_val, slope=127, offset=0)

            # ensure that values are within limits
            if patch.getstring('general', 'mode') == 'note':
                val = EEGsynth.limit(val, lo=0, hi=127)
                val = int(val)
                port_val = EEGsynth.limit(port_val, lo=0, hi=127)
                port_val = int(port_val)
            elif patch.getstring('general', 'mode') == 'pitchbend':
                val = EEGsynth.limit(val, lo=-8192, hi=8191)
                val = int(val)
            else:
                print 'No output mode (note or pitchbend) specified!'
                break

            if val != previous_val[
                    name] or not val:  # it should be skipped when identical to the previous value

                previous_val[name] = val
Esempio n. 26
0
            midithread.setEnabled(False)
            previous_midi_play = False

        # do something whenever the value changes
        if midi_start and not previous_midi_start:
            if midiport != None:
                midiport.send(mido.Message('start'))
            previous_midi_start = True
        elif not midi_start and previous_midi_start:
            if midiport != None:
                midiport.send(mido.Message('stop'))
            previous_midi_start = False

        rate  = patch.getfloat('input', 'rate', default=0)
        rate  = EEGsynth.rescale(rate, slope=scale_rate, offset=offset_rate)
        rate  = EEGsynth.limit(rate, 30., 240.)

        shift = patch.getfloat('input', 'shift', default=0)
        shift = EEGsynth.rescale(shift, slope=scale_shift, offset=offset_shift)
        shift = int(shift)

        ppqn  = patch.getfloat('input', 'ppqn', default=0)
        ppqn  = EEGsynth.rescale(ppqn, slope=scale_ppqn, offset=offset_ppqn)
        ppqn  = find_nearest_value([1, 2, 3, 4, 6, 8, 12, 24], ppqn)

        if debug>0:
            # show the parameters whose value has changed
            show_change("redis_play",    redis_play)
            show_change("midi_play",     midi_play)
            show_change("midi_start",    midi_start)
            show_change("rate",          rate)
Esempio n. 27
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
    global monitor, debug, mididevice, outputport, lock, trigger, port, channel, previous_val, previous_port_val
    global name, val, port_val, scale, offset, midichannel, msg

    # loop over the control values
    for channel in range(0, 16):
        # channels are one-offset in the ini file, zero-offset in the code
        name = 'channel{}'.format(channel + 1)
        val = patch.getfloat('control', name)
        port_val = patch.getfloat('portamento', name, default=0)

        if val is None:
            # the value is not present in Redis, skip it
            monitor.trace(name + ' is not available')
            continue

        if port_val is None:
            # the value is not present in Redis, skip it
            monitor.trace(name + ' is not available')
            continue

        # the scale and offset options are channel specific
        scale = patch.getfloat('scale', name, default=1)
        offset = patch.getfloat('offset', name, default=0)

        # map the Redis values to MIDI pitch values
        val = EEGsynth.rescale(val, slope=scale, offset=offset)

        # portamento range is hardcoded 0-127, so no need for user-config
        port_val = EEGsynth.rescale(port_val, slope=127, offset=0)

        # ensure that values are within limits
        if patch.getstring('general', 'mode') == 'note':
            val = EEGsynth.limit(val, lo=0, hi=127)
            val = int(val)
            port_val = EEGsynth.limit(port_val, lo=0, hi=127)
            port_val = int(port_val)
        elif patch.getstring('general', 'mode') == 'pitchbend':
            val = EEGsynth.limit(val, lo=-8192, hi=8191)
            val = int(val)
        else:
            monitor.info('No output mode (note or pitchbend) specified!')
            break

        if val != previous_val[name] or not val:  # it should be skipped when identical to the previous value
            previous_val[name] = val

            # midi channels in the inifile are 1-16, in the code 0-15
            midichannel = channel

            if patch.getstring('general', 'mode') == 'pitchbend':
                msg = mido.Message('pitchwheel', pitch=val, channel=midichannel)
            elif patch.getstring('general', 'mode') == 'note':
                msg = mido.Message('note_on', note=val, velocity=127, time=0, channel=midichannel)

            monitor.debug(msg)

            with lock:
                outputport.send(msg)

            # keep it at the present value for a minimal amount of time
            time.sleep(patch.getfloat('general', 'pulselength'))

        # it should be skipped when identical to the previous value
        if port_val != previous_port_val[name] and patch.getstring('general', 'mode') != 'note' or not port_val:
            previous_port_val[name] = port_val

            # CC#5 sets portamento
            msg = mido.Message('control_change', control=5, value=int(port_val), channel=midichannel)

            monitor.debug(msg)

            with lock:
                outputport.send(msg)

            # keep it at the present value for a minimal amount of time
            time.sleep(patch.getfloat('general', 'pulselength'))

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print("LOCALS: " + ", ".join(locals().keys()))
Esempio n. 28
0
for thread in trigger:
    thread.start()


try:
    while True:
        time.sleep(patch.getfloat('general', 'delay'))

        for gpio, channel in config.items('control'):
            val = patch.getfloat('control', gpio)
            if val == None:
                continue  # it should be skipped when not present
            if val == previous_val[gpio]:
                continue  # it should be skipped when identical to the previous value
            previous_val[gpio] = val
            val = EEGsynth.rescale(val, slope=input_scale, offset=input_offset)
            val = EEGsynth.limit(val, 0, 100)
            val = int(val)
            lock.acquire()
            wiringpi.softPwmWrite(pin[gpio], val)
            lock.release()

except KeyboardInterrupt:
    print("Closing threads")
    for thread in trigger:
        thread.stop()
    r.publish('OUTPUTGPIO_UNBLOCK', 1)
    for thread in trigger:
        thread.join()
    sys.exit()
Esempio n. 29
0
            serialthread.disable()
            previous_use_serial = False

        if use_redis and not previous_use_redis:
            redisthread.enable()
            previous_use_redis = True
        elif not use_redis and previous_use_redis:
            redisthread.disable()
            previous_use_redis = False

        rate = patch.getfloat('input', 'rate', default=60./127)
        scale_rate = patch.getfloat('scale', 'rate', default=127)
        offset_rate = patch.getfloat('offset', 'rate', default=0)
        rate = EEGsynth.rescale(rate, slope=scale_rate, offset=offset_rate)
        # ensure that the rate is within meaningful limits
        rate = EEGsynth.limit(rate, 40., 240.)

        multiply = patch.getfloat('input', 'multiply', default=0.5)
        scale_multiply = patch.getfloat('scale', 'multiply', default=4)
        offset_multiply = patch.getfloat('offset', 'multiply', default=-2.015748031495)
        multiply = EEGsynth.rescale(multiply, slope=scale_multiply, offset=offset_multiply)
        # map the multiply value exponentially, i.e. -1 becomes 1/2, 0 becomes 1, 1 becomes 2
        multiply = math.pow(2, multiply)
        # it should be 1, 2, 3, 4 or 1/2, 1/3, 1/4, etc
        if multiply>1:
            multiply = round(multiply)
        elif multiply<1:
            multiply = 1.0/round(1.0/multiply);

        # this is for the analog trigger on the CV/Gate, expressed in seconds
        duration = patch.getfloat('general', 'duration')
Esempio n. 30
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
    global monitor, stepsize, scale_rate, offset_rate, scale_shift, offset_shift, scale_ppqn, offset_ppqn, lock, clock, i, clockthread, midithread, redisthread, midiport, previous_midi_play, previous_midi_start, previous_redis_play
    global start, redis_play, midi_play, midi_start, rate, shift, ppqn, elapsed, naptime

    redis_play = patch.getint('redis', 'play')
    midi_play = patch.getint('midi', 'play')
    midi_start = patch.getint('midi', 'start')

    if previous_redis_play is None and redis_play is not None:
        previous_redis_play = not (redis_play)

    if previous_midi_play is None and midi_play is not None:
        previous_midi_play = not (midi_play)

    if previous_midi_start is None and midi_start is not None:
        previous_midi_start = not (midi_start)

    # the MIDI port should only be opened once, and only if needed
    if midi_play and midiport == None:
        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")

    # do something whenever the value changes
    if redis_play and not previous_redis_play:
        redisthread.setEnabled(True)
        previous_redis_play = True
    elif not redis_play and previous_redis_play:
        redisthread.setEnabled(False)
        previous_redis_play = False

    # do something whenever the value changes
    if midi_play and not previous_midi_play:
        midithread.setEnabled(True)
        previous_midi_play = True
    elif not midi_play and previous_midi_play:
        midithread.setEnabled(False)
        previous_midi_play = False

    # do something whenever the value changes
    if midi_start and not previous_midi_start:
        if midiport != None:
            midiport.send(mido.Message('start'))
        previous_midi_start = True
    elif not midi_start and previous_midi_start:
        if midiport != None:
            midiport.send(mido.Message('stop'))
        previous_midi_start = False

    rate = patch.getfloat('input', 'rate', default=0)
    rate = EEGsynth.rescale(rate, slope=scale_rate, offset=offset_rate)
    rate = EEGsynth.limit(rate, 30., 240.)

    shift = patch.getfloat('input', 'shift', default=0)
    shift = EEGsynth.rescale(shift, slope=scale_shift, offset=offset_shift)
    shift = int(shift)

    ppqn = patch.getfloat('input', 'ppqn', default=0)
    ppqn = EEGsynth.rescale(ppqn, slope=scale_ppqn, offset=offset_ppqn)
    ppqn = find_nearest_value([1, 2, 3, 4, 6, 8, 12, 24], ppqn)

    # show the parameters whose value has changed
    monitor.update("redis_play", redis_play)
    monitor.update("midi_play", midi_play)
    monitor.update("midi_start", midi_start)
    monitor.update("rate", rate)
    monitor.update("shift", shift)
    monitor.update("ppqn", ppqn)

    # update the clock and redis
    clockthread.setRate(rate)
    redisthread.setShift(shift)
    redisthread.setPpqn(ppqn)

    # there should not be any local variables in this function, they should all be global
    if len(locals()):
        print("LOCALS: " + ", ".join(locals().keys()))
Esempio n. 31
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()
Esempio n. 32
0
try:
    while True:
        monitor.loop()
        time.sleep(patch.getfloat('general', 'delay'))

        for name, cmd in zip(control_name, control_code):
            # loop over the control values
            val = patch.getfloat('control', name)
            if val == None:
                continue  # it should be skipped when not present
            if val == previous_val[name]:
                continue  # it should be skipped when identical to the previous value
            previous_val[name] = val
            # map the Redis values to MIDI values
            val = EEGsynth.rescale(val, slope=scale, offset=offset)
            val = EEGsynth.limit(val, 0, 127)
            val = int(val)
            msg = mido.Message('control_change',
                               control=cmd,
                               value=val,
                               channel=midichannel)
            monitor.debug(cmd, val, name)
            lock.acquire()
            outputport.send(msg)
            lock.release()

except KeyboardInterrupt:
    monitor.success('Closing threads')
    for thread in trigger:
        thread.stop()
    r.publish('VOLCABASS_UNBLOCK', 1)
Esempio n. 33
0
        active = EEGsynth.rescale(active, slope=scale_active, offset=offset_active)
        active = int(active)

        # get the corresponding sequence as a single string
        try:
            sequence = patch.getstring('sequence', "sequence%03d" % active, multiple=True)
        except:
            sequence = []

        transpose = patch.getfloat('sequence', 'transpose', default=0.)
        transpose = EEGsynth.rescale(transpose, slope=scale_transpose, offset=offset_transpose)

        # the duration is relative to the time between clock ticks
        duration = patch.getfloat('sequence', 'duration', default=0.)
        duration = EEGsynth.rescale(duration, slope=scale_duration, offset=offset_duration)
        duration = EEGsynth.limit(duration, 0.1, 0.9)

        if debug > 0:
            # show the parameters whose value has changed
            show_change("active",    active)
            show_change("sequence",  sequence)
            show_change("transpose", transpose)
            show_change("duration",  duration)

        sequencethread.setSequence(sequence)
        sequencethread.setTranspose(transpose)
        sequencethread.setDuration(duration)

        elapsed = time.time() - now
        naptime = patch.getfloat('general', 'delay') - elapsed
        if naptime > 0:
Esempio n. 34
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()
Esempio n. 35
0
            # this returns None when the channel is not present
            chanval = patch.getfloat('input', chanstr)

            if chanval==None:
                # the value is not present in Redis, skip it
                if debug>2:
                    print chanstr, 'not available'
                continue

            # the scale and offset options are channel specific
            scale  = patch.getfloat('scale', chanstr, default=255)
            offset = patch.getfloat('offset', chanstr, default=0)
            # apply the scale and offset
            chanval = EEGsynth.rescale(chanval, slope=scale, offset=offset)
            # ensure that it is within limits
            chanval = EEGsynth.limit(chanval, lo=0, hi=255)
            chanval = int(chanval)

            if dmxdata[chanindx]!=chr(chanval):
                if debug>0:
                    print "DMX channel%03d" % chanindx, '=', chanval
                # update the DMX value for this channel
                dmxdata = senddmx(dmxdata,chanindx,chanval)
            elif (time.time()-prevtime)>1:
                # send a maintenance packet now and then
                dmxdata = senddmx(dmxdata,chanindx,chanval)
                prevtime = time.time()

except KeyboardInterrupt:
    if debug>0:
        print "closing..."
Esempio n. 36
0
            # this returns None when the channel is not present
            chanval = patch.getfloat('input', chanstr)

            if chanval == None:
                # the value is not present in Redis, skip it
                if debug > 2:
                    print(chanstr, 'not available')
                continue

            # the scale and offset options are channel specific
            scale = patch.getfloat('scale', chanstr, default=255)
            offset = patch.getfloat('offset', chanstr, default=0)
            # apply the scale and offset
            chanval = EEGsynth.rescale(chanval, slope=scale, offset=offset)
            # ensure that it is within limits
            chanval = EEGsynth.limit(chanval, lo=0, hi=255)
            chanval = int(chanval)

            if dmxdata[chanindx - 1] != chanval:
                # update the DMX value for this channel
                dmxdata[chanindx - 1] = chanval
                if debug > 1:
                    print("DMX channel%03d" % chanindx, '=', chanval)
                artnet.broadcastDMX(dmxdata, address)
            elif (time.time() - prevtime) > 1:
                # send a maintenance packet now and then
                artnet.broadcastDMX(dmxdata, address)
                prevtime = time.time()

except KeyboardInterrupt:
    # blank out
Esempio n. 37
0
        except:
            sequence = []

        transpose = patch.getfloat('sequence', 'transpose', default=0.)
        transpose = EEGsynth.rescale(transpose,
                                     slope=scale_transpose,
                                     offset=offset_transpose)

        # the duration is relative to the time between clock ticks
        duration = patch.getfloat('sequence', 'duration', default=0.)
        duration = EEGsynth.rescale(duration,
                                    slope=scale_duration,
                                    offset=offset_duration)
        if duration > 0:
            # a duration of 0 or less means that the note will not switch off
            duration = EEGsynth.limit(duration, 0.1, 0.9)

        if debug > 0:
            # show the parameters whose value has changed
            show_change("active", active)
            show_change("sequence", sequence)
            show_change("transpose", transpose)
            show_change("duration", duration)

        sequencethread.setSequence(sequence)
        sequencethread.setTranspose(transpose)
        sequencethread.setDuration(duration)

        elapsed = time.time() - now
        naptime = patch.getfloat('general', 'delay') - elapsed
        if naptime > 0:
Esempio n. 38
0
            # this returns None when the channel is not present
            chanval = patch.getfloat('input', chanstr)

            if chanval == None:
                # the value is not present in Redis, skip it
                if debug > 2:
                    print(chanstr, 'not available')
                continue

            # the scale and offset options are channel specific
            scale = patch.getfloat('scale', chanstr, default=4095)
            offset = patch.getfloat('offset', chanstr, default=0)
            # apply the scale and offset
            chanval = EEGsynth.rescale(chanval, slope=scale, offset=offset)
            # ensure that it is within limits
            chanval = EEGsynth.limit(chanval, lo=0, hi=4095)
            chanval = int(chanval)

            if debug > 0:
                show_change(chanstr, chanval)

            lock.acquire()
            s.write('*c%dv%04d#' % (chanindx, chanval))
            lock.release()

        for chanindx in range(1, 5):
            chanstr = "gate%d" % chanindx
            chanval = patch.getfloat('input', chanstr)

            if chanval == None:
                # the value is not present in Redis, skip it
Esempio n. 39
0
            midithread.setEnabled(False)
            previous_midi_play = False

        # do something whenever the value changes
        if midi_start and not previous_midi_start:
            if midiport != None:
                midiport.send(mido.Message('start'))
            previous_midi_start = True
        elif not midi_start and previous_midi_start:
            if midiport != None:
                midiport.send(mido.Message('stop'))
            previous_midi_start = False

        rate = patch.getfloat('input', 'rate', default=0)
        rate = EEGsynth.rescale(rate, slope=scale_rate, offset=offset_rate)
        rate = EEGsynth.limit(rate, 30., 240.)

        shift = patch.getfloat('input', 'shift', default=0)
        shift = EEGsynth.rescale(shift, slope=scale_shift, offset=offset_shift)
        shift = int(shift)

        ppqn = patch.getfloat('input', 'ppqn', default=0)
        ppqn = EEGsynth.rescale(ppqn, slope=scale_ppqn, offset=offset_ppqn)
        ppqn = find_nearest_value([1, 2, 3, 4, 6, 8, 12, 24], ppqn)

        if debug > 0:
            # show the parameters whose value has changed
            show_change("redis_play", redis_play)
            show_change("midi_play", midi_play)
            show_change("midi_start", midi_start)
            show_change("rate", rate)
Esempio n. 40
0
try:
    while True:
        time.sleep(patch.getfloat('general', 'delay'))

        for name, cmd in zip(control_name, control_code):
            # loop over the control values
            val = patch.getfloat('control', name)
            if val==None:
                continue # it should be skipped when not present
            if val==previous_val[name]:
                continue # it should be skipped when identical to the previous value
            previous_val[name] = val
            # map the Redis values to MIDI values
            val = EEGsynth.rescale(val, slope=scale, offset=offset)
            val = EEGsynth.limit(val, 0, 127)
            val = int(val)
            msg = mido.Message('control_change', control=cmd, value=val, channel=midichannel)
            if debug>1:
                print cmd, val, name
            lock.acquire()
            outputport.send(msg)
            lock.release()

except KeyboardInterrupt:
    print "Closing threads"
    for thread in trigger:
        thread.stop()
    r.publish('VOLCAKEYS_UNBLOCK', 1)
    for thread in trigger:
        thread.join()
Esempio n. 41
0
            name = 'channel{}'.format(channel + 1)
            val = patch.getfloat('control', name)

            if val is None:
                # the value is not present in Redis, skip it
                if debug > 2:
                    print name, 'not available'
                continue

            # the scale and offset options are channel specific
            scale = patch.getfloat('scale', name, default=1)
            offset = patch.getfloat('offset', name, default=0)
            # map the Redis values to MIDI pitch values
            val = EEGsynth.rescale(val, slope=scale, offset=offset)
            # ensure that it is within limits
            val = EEGsynth.limit(val, lo=-8192, hi=8191)
            val = int(val)

            if val == previous_val[name]:
                continue  # it should be skipped when identical to the previous value
            else:
                previous_val[name] = val

            if debug > 0:
                print name, val

            # midi channels in the inifile are 1-16, in the code 0-15
            midichannel = channel
            msg = mido.Message('pitchwheel', pitch=val, channel=midichannel)
            if debug > 1:
                print msg