コード例 #1
0
    def __init__(self, surf, **kwds):
        RootWidget.__init__(self, surf, **kwds)
        self.bg_color = (255,255,255)
        self.redraw_every_frame = True
        self.set_timer(50)

        self.recording_in_progress = False

        # signal buffer stores 6 seconds of data
        self.sig_buf = SignalBuffer(768, 14)

        # add status update callbacks to the device monitor
        mon.callbacks.append(self.update_device_status)
        mon.callbacks.append(self.start_device_reader)

        self.gyrox_label = Label('', width = 80, height = 30, bg_color = (30, 30, 255))
        self.gyroy_label = Label('', width = 80, height = 30, bg_color = (30, 30, 255))
        self.signal_mag_label = Label('', width = 80, height = 30)

        small_font = pygame.font.SysFont('Ubuntu', 12)

        self.renderer = SignalRendererWidget(counter_to_sensor_id,
                                             dev,
                                             self.sig_buf,
                                             Rect(0, 0, 880, 660))
        self.add(self.renderer)

        c = Column([
                Button("Start REC",
                       action = self.start_recording,
                       enabled = lambda: not self.recording_in_progress,
                       bg_color = (0, 0, 128),
                       height = 30,
                       margin = 3),
                Button("Stop REC",
                       action = self.stop_recording,
                       enabled = lambda: self.recording_in_progress,
                       bg_color = (0, 0, 128),
                       height = 30,
                       margin = 3),
                Widget(height = 70),
                Label('Gyro Data', height = 30),
                self.gyrox_label,
                self.gyroy_label,
                Button("Cursor",
                       action = self.toggle_cursor_rendering,
                       bg_color = (255, 0, 0),
                       height = 30,
                       margin = 3),
#                Widget(height = 30),
                Label('EEG Mag', height = 30),
                Row( [
                        Button("+",
                               action = lambda: self.renderer.update_magnification(+0.2),
                               bg_color = (80, 100, 40),
                               width = 30,
                               margin = 5),
                        Button("-",
                               action = lambda: self.renderer.update_magnification(-0.2),
                               bg_color = (80, 100, 40),
                               margin = 5,
                               width = 30) ]),
                self.signal_mag_label,
                Button("Clear",
                       action = lambda: self.sig_buf.clear(),
                       bg_color = (255, 0, 0),
                       height = 30,
                       margin = 5),
                Label('Channels', width = 100, bg_color = (50, 50, 255)),
                Grid([ [ Button("F3", font = small_font, action = lambda: self.renderer.toggle_channel(0)),
                         Button("FC5", font = small_font, action = lambda: self.renderer.toggle_channel(1)),
                         Button("AF3", font = small_font, action = lambda: self.renderer.toggle_channel(2)),
                         Button("F7", font = small_font, action = lambda: self.renderer.toggle_channel(3)) ],
                       [ Button("T7", font = small_font, action = lambda: self.renderer.toggle_channel(4)),
                         Button("P7", font = small_font, action = lambda: self.renderer.toggle_channel(5)),
                         Button("O1", font = small_font, action = lambda: self.renderer.toggle_channel(6)),
                         Button("O2", font = small_font, action = lambda: self.renderer.toggle_channel(7)) ],
                       [ Button("P8", font = small_font, action = lambda: self.renderer.toggle_channel(8)),
                         Button("T8", font = small_font, action = lambda: self.renderer.toggle_channel(9)),
                         Button("F8", font = small_font, action = lambda: self.renderer.toggle_channel(10)),
                         Button("AF4", font = small_font, action = lambda: self.renderer.toggle_channel(11)) ],
                       [ Button("FC6", font = small_font, action = lambda: self.renderer.toggle_channel(12)),
                         Button("F4", font = small_font, action = lambda: self.renderer.toggle_channel(13)) ] ],
                     row_spacing = 5,
                     column_spacing = 8,
                     width = 100),
#                Widget(height = 55),
                Button("  QUIT  ",
                       action = self.quit,
                       bg_color = (200, 0, 64),
                       margin = 5
                       )],
                   align = 'c',
                   spacing = 20,
                   bg_color = (50, 50, 50),
                   rect = Rect(880, 0, 120, 690),
                   height = 690,
                   expand = True,
                   margin = 5)

        self.stat_label = Label('', 100, margin = 3)
        self.packet_speed_label = Label('', 100, margin = 3)
        self.recording_label = Label('NOT RECORDING', 400, margin = 3)
        self.battery_label = Label('NO DATA', 100, margin = 3)
        r = Row([ self.stat_label, self.packet_speed_label, self.battery_label, self.recording_label, Widget(width = 50, height = 30) ],
                rect = Rect(0, 660, 880, 30),
                width = 880,
                height = 30,
                expand = True,
                margin = 5,
                spacing = 20,
                bg_color = (50, 50, 50))

        self.add(c)
        self.add(r)

        # first update is manual
        self.update_device_status(mon.check_connected())

        # eeg rendering widget
        self.renderer = SignalRendererWidget(counter_to_sensor_id,
                                             dev,
                                             self.sig_buf,
                                             Rect(0, 0, 880, 660))
        self.add(self.renderer)

        self.update_ps_counter = 0
        self.rec = None

        self.render_cursor = False
        self.sq_pos = (400, 300)
コード例 #2
0
class WaveRiderGUI(RootWidget):
    """
    The GUI elements of the main screen for wave rider.
    """
    
    def __init__(self, surf, **kwds):
        RootWidget.__init__(self, surf, **kwds)
        self.bg_color = (255,255,255)
        self.redraw_every_frame = True
        self.set_timer(50)

        self.recording_in_progress = False

        # signal buffer stores 6 seconds of data
        self.sig_buf = SignalBuffer(768, 14)

        # add status update callbacks to the device monitor
        mon.callbacks.append(self.update_device_status)
        mon.callbacks.append(self.start_device_reader)

        self.gyrox_label = Label('', width = 80, height = 30, bg_color = (30, 30, 255))
        self.gyroy_label = Label('', width = 80, height = 30, bg_color = (30, 30, 255))
        self.signal_mag_label = Label('', width = 80, height = 30)

        small_font = pygame.font.SysFont('Ubuntu', 12)

        self.renderer = SignalRendererWidget(counter_to_sensor_id,
                                             dev,
                                             self.sig_buf,
                                             Rect(0, 0, 880, 660))
        self.add(self.renderer)

        c = Column([
                Button("Start REC",
                       action = self.start_recording,
                       enabled = lambda: not self.recording_in_progress,
                       bg_color = (0, 0, 128),
                       height = 30,
                       margin = 3),
                Button("Stop REC",
                       action = self.stop_recording,
                       enabled = lambda: self.recording_in_progress,
                       bg_color = (0, 0, 128),
                       height = 30,
                       margin = 3),
                Widget(height = 70),
                Label('Gyro Data', height = 30),
                self.gyrox_label,
                self.gyroy_label,
                Button("Cursor",
                       action = self.toggle_cursor_rendering,
                       bg_color = (255, 0, 0),
                       height = 30,
                       margin = 3),
#                Widget(height = 30),
                Label('EEG Mag', height = 30),
                Row( [
                        Button("+",
                               action = lambda: self.renderer.update_magnification(+0.2),
                               bg_color = (80, 100, 40),
                               width = 30,
                               margin = 5),
                        Button("-",
                               action = lambda: self.renderer.update_magnification(-0.2),
                               bg_color = (80, 100, 40),
                               margin = 5,
                               width = 30) ]),
                self.signal_mag_label,
                Button("Clear",
                       action = lambda: self.sig_buf.clear(),
                       bg_color = (255, 0, 0),
                       height = 30,
                       margin = 5),
                Label('Channels', width = 100, bg_color = (50, 50, 255)),
                Grid([ [ Button("F3", font = small_font, action = lambda: self.renderer.toggle_channel(0)),
                         Button("FC5", font = small_font, action = lambda: self.renderer.toggle_channel(1)),
                         Button("AF3", font = small_font, action = lambda: self.renderer.toggle_channel(2)),
                         Button("F7", font = small_font, action = lambda: self.renderer.toggle_channel(3)) ],
                       [ Button("T7", font = small_font, action = lambda: self.renderer.toggle_channel(4)),
                         Button("P7", font = small_font, action = lambda: self.renderer.toggle_channel(5)),
                         Button("O1", font = small_font, action = lambda: self.renderer.toggle_channel(6)),
                         Button("O2", font = small_font, action = lambda: self.renderer.toggle_channel(7)) ],
                       [ Button("P8", font = small_font, action = lambda: self.renderer.toggle_channel(8)),
                         Button("T8", font = small_font, action = lambda: self.renderer.toggle_channel(9)),
                         Button("F8", font = small_font, action = lambda: self.renderer.toggle_channel(10)),
                         Button("AF4", font = small_font, action = lambda: self.renderer.toggle_channel(11)) ],
                       [ Button("FC6", font = small_font, action = lambda: self.renderer.toggle_channel(12)),
                         Button("F4", font = small_font, action = lambda: self.renderer.toggle_channel(13)) ] ],
                     row_spacing = 5,
                     column_spacing = 8,
                     width = 100),
#                Widget(height = 55),
                Button("  QUIT  ",
                       action = self.quit,
                       bg_color = (200, 0, 64),
                       margin = 5
                       )],
                   align = 'c',
                   spacing = 20,
                   bg_color = (50, 50, 50),
                   rect = Rect(880, 0, 120, 690),
                   height = 690,
                   expand = True,
                   margin = 5)

        self.stat_label = Label('', 100, margin = 3)
        self.packet_speed_label = Label('', 100, margin = 3)
        self.recording_label = Label('NOT RECORDING', 400, margin = 3)
        self.battery_label = Label('NO DATA', 100, margin = 3)
        r = Row([ self.stat_label, self.packet_speed_label, self.battery_label, self.recording_label, Widget(width = 50, height = 30) ],
                rect = Rect(0, 660, 880, 30),
                width = 880,
                height = 30,
                expand = True,
                margin = 5,
                spacing = 20,
                bg_color = (50, 50, 50))

        self.add(c)
        self.add(r)

        # first update is manual
        self.update_device_status(mon.check_connected())

        # eeg rendering widget
        self.renderer = SignalRendererWidget(counter_to_sensor_id,
                                             dev,
                                             self.sig_buf,
                                             Rect(0, 0, 880, 660))
        self.add(self.renderer)

        self.update_ps_counter = 0
        self.rec = None

        self.render_cursor = False
        self.sq_pos = (400, 300)


    def start_device_reader(self, status):
        if status:
            dev.start_reader()


    def update_device_status(self, status):
        self.stat_label.text = 'ONLINE' if status else 'OFFLINE'
        self.stat_label.bg_color = (50, 255, 50) if status else (255, 30, 30)
        self.stat_label.invalidate()


    def update_packet_speed_label(self):
        if self.update_ps_counter > 10:
            self.packet_speed_label.text = '%.1f S/sec' % dev.packet_speed if dev.packet_speed > 0 else 'NO DATA'
            self.packet_speed_label.bg_color = (50, 255, 50) if dev.packet_speed > 0 else (255, 30, 30)
            self.packet_speed_label.invalidate()
            self.update_ps_counter = 0
        else:
            self.update_ps_counter += 1

    def update_gyro_labels(self):
        if dev.gyro_x is not None:
            self.gyrox_label.text = 'X = %d' % dev.gyro_x
        if dev.gyro_y is not None:
            self.gyroy_label.text = 'Y = %d' % dev.gyro_y
        

    def toggle_cursor_rendering(self):
        if self.render_cursor == False:
            self.sq_pos = (400, 300)
            
        self.render_cursor = not self.render_cursor


    def begin_frame(self):
        self.update_packet_speed_label()
        self.update_gyro_labels()

        self.signal_mag_label.text = 'mag: %gx' % self.renderer.multiplier
        self.signal_mag_label.invalidate()

        if dev.battery is not None:
            self.battery_label.text = 'BATT: %d%%' % (dev.battery * 100) 
        else:
            self.battery_label.text = 'NO DATA'
        self.battery_label.invalidate()

        # no sense in updating if we are not going to use it
        if self.render_cursor and (dev.gyro_x is not None) and (dev.gyro_y is not None):
            new_pos_x = max(20, min(800, self.sq_pos[0] + (105 - dev.gyro_x) * 4)) if abs(dev.gyro_x - 105) > 1 else self.sq_pos[0]
            new_pos_y = max(20, min(600, self.sq_pos[1] + (dev.gyro_y - 105) * 4)) if abs(dev.gyro_y - 105) > 1 else self.sq_pos[1]
            self.sq_pos = new_pos_x, new_pos_y

        RootWidget.begin_frame(self)


    def draw_all(self, surf):

        # draw the root widgets
        Widget.draw_all(self, surf)

        # only render the cursor if required
        if self.render_cursor:
            pos = self.sq_pos
            pygame.draw.rect(display, (0, 0, 0), Rect(pos[0] - 10, pos[1] - 10, 20, 20))



    def start_recording(self):
        if self.rec is not None:
            albow.dialogs.alert('Recording in progress!')
            return

        fname = albow.file_dialogs.request_new_filename("Select output file ...", suffix = "csv", directory = 'data')
        if fname is None:
            return

        # start the recording
        self.rec = SignalWriter()
        self.rec.open(fname)

        if not self.rec.ready():
            albow.dialogs.alert("File cannot be opened, cancelling recording.")
            self.rec = None
            return

        # update the recording label
        self.recording_label.text = 'Recording to [%s]' % os.path.basename(fname)
        self.recording_label.bg_color = (255, 30, 30)
        self.recording_label.invalidate()

        dev.subscribe(self.rec.write_packet)


    def stop_recording(self):
        if self.rec is None:
            albow.dialogs.alert("There is no recording in progress.")
            return

        # stop the recording
        dev.unsubscribe(self.rec.write_packet)

        self.rec.close()
        self.rec = None
        
        # update the recording label
        self.recording_label.text = 'NOT RECORDING'
        self.recording_label.bg_color = (50, 50, 50)
        self.recording_label.invalidate()
  

    def confirm_quit(self):
        """
        Check if we really want to quit.
        """
        if self.rec is not None:
            albow.dialogs.alert("You are recording! Stop the recording before exiting.")
            return

        return albow.dialogs.ask("Are you sure you want to quit?", ["Yes", "No"]) == "Yes"
        

    def exit_cmd(self):
        self.quit()

    def quit(self):

        if not self.confirm_quit():
            return

        # we're quitting
        mon.stop()
        dev.stop_reader()
        pygame.quit()
        sys.exit(0)
コード例 #3
0
from emotiv_device import EmotivDevice
from emotiv_data_packet import EmotivDataPacket
from signal_buffer import SignalBuffer



if __name__ == '__main__':
    
    print("Setting up device ...")

    dev = EmotivDevice('SN20120229000254')
    
    print("Starting reader ...")

    dev.start_reader()

    rb = SignalBuffer(64, 14)
    
    for rbp in range(10):
        pp = rb.pull_packets(dev)
        print("Pulled %d packets." % pp)
        print rb.buffer().shape
        time.sleep(0.2)

    print("Stopping reader ...")

    dev.stop_reader()

    print("Done.")
コード例 #4
0

if __name__ == '__main__':

    # signal writer for storing samples
    sw = SignalWriter()
    sw.open('signal.csv')
    print("Signal writer is ready: %s" % sw.ready())

    # initialize the devices & buffer
    dev = EmotivDevice('SN20120229000254')
    dev.subscribe(sw.write_packet)
    dev.start_reader()

    # signal buffer for reading samples from the EEG
    eeg = SignalBuffer(750, 14)

    # PyGame subsystem init
    pygame.init()
    Clock = pygame.time.Clock()

    try:
        screen = pygame.display.set_mode((800, 600))

        myFont = pygame.font.SysFont("Ubuntu", 20, True)

        chan_names = []
        for s in range(len(counter_to_sensor_id)):
            chan_names.append(myFont.render(counter_to_sensor_id[s], 1, (0, 0, 0)))

        while mainloop:
コード例 #5
0
def main():
    parser = argparse.ArgumentParser(description="Stream audio data from pipe")
    parser.add_argument("--inputs", "-i", type=int)
    parser.add_argument("--outputs", "-o", action="append", type=int)
    parser.add_argument(
        "--framelength",
        "-fl",
        type=float,
        default=25.,
        help="Frame length in milliseconds (default: {})".format(25.))
    parser.add_argument(
        "--frameshift",
        "-fs",
        type=float,
        default=10.,
        help="Frame shift in milliseconds (default: {})".format(10.))
    parser.add_argument(
        "--samplingfrequency",
        "-sf",
        type=int,
        default=16000,
        help="Sampling frequency (rate) (default: {})".format(16000))
    parser.add_argument("--numberofchannels",
                        "-noc",
                        type=int,
                        default=8,
                        help="Number of channels (default: {})".format(8))
    parser.add_argument("--validchannels",
                        "-vc",
                        type=str,
                        default="0,1,2,3,4,5",
                        help="Comma-separated list of valid channel indices "
                        "(default: \"{}\")".format("0,1,2,3,4,5"))
    parser.add_argument("--notinterleaved",
                        action="store_true",
                        help="Input is *not* interleaved")
    parser.add_argument("--inputfilepath",
                        "-ifp",
                        type=str,
                        help="Path to file which the valid input is written "
                        "to")
    parser.add_argument(
        "--soundcard",
        "-sc",
        type=str,
        help="(Prefix of) Soundcard name (default: \"{}\"".format(
            "audioinjector"),
        default="audioinjector")
    # TODO
    #parser.add_argument("--format", "-f", choices=["UInt8", "Int8", "Int16",
    #                                               "Int24", "Int32", "Float32"],
    #                    default="Int32")
    parser.add_argument("--format",
                        "-f",
                        choices=["UInt8", "Int8", "Int16", "Int32", "Float32"],
                        default="Int32",
                        help="Format of the input data "
                        "(default: {})".format("Int32"))
    args = parser.parse_args()

    input_pipes = []
    if args.inputs is not None:
        input_pipes = [os.fdopen(fd, 'rb') for fd in args.inputs]
    output_pipes = []
    if args.outputs is not None:
        output_pipes = [os.fdopen(fd, 'wb') for fd in args.outputs]
    outputs = [
        pickle.Pickler(pipe, pickle.HIGHEST_PROTOCOL) for pipe in output_pipes
    ]

    f = Format(args.format)
    valid_channels = np.array(
        [int(chan) for chan in args.validchannels.split(",")])

    frame_length = int((args.framelength * args.samplingfrequency) / 1000.0)
    frameshift = int((args.frameshift * args.samplingfrequency) / 1000.0)
    signal_buffer = SignalBuffer(frame_length, len(valid_channels))

    if len(input_pipes) == 0:
        pa = pyaudio.PyAudio()
        audioinjector_idx = None
        for idx in range(pa.get_device_count()):
            info = pa.get_device_info_by_index(idx)
            if info["name"].lower().startswith(args.soundcard.lower()):
                audioinjector_idx = info["index"]
        if audioinjector_idx is None:
            raise ValueError("Given soundcard name \"{}\" not found".format(
                args.soundcard))
        stream = pa.open(format=f.pyaudioformat,
                         channels=args.numberofchannels,
                         rate=args.samplingfrequency,
                         input=True,
                         frames_per_buffer=frameshift)

    if args.inputfilepath is not None:
        wavfile = wave.open(args.inputfilepath, "wb")
        wavfile.setnchannels(len(valid_channels))
        wavfile.setsampwidth(f.size)
        wavfile.setframerate(args.samplingfrequency)

    while True:
        if len(input_pipes) == 0:
            in_data = np.fromstring(stream.read(frameshift,
                                                exception_on_overflow=False),
                                    dtype=f.type)
        else:
            # XXX: !!! no endianness defined !!!
            in_data = np.fromfile(inp,
                                  dtype=f.type,
                                  count=args.numberofchannels * frameshift)
        if args.notinterleaved:
            innovation = in_data.reshape((args.numberofchannels, frameshift)).T
        else:
            innovation = in_data.reshape((frameshift, args.numberofchannels))
        innovation = f.converttofloat(innovation[:, valid_channels])
        innovation = innovation.flatten('F')
        frame = signal_buffer.process(innovation)
        if args.inputfilepath is not None:
            wavfile.writeframes(f.convertfromfloat(innovation).tobytes())
        for out in output_pipes:
            out.write(frame.tobytes())
            out.flush()
        #for out_idx in range(len(outputs)):
        #    outputs[out_idx].dump(frame)
        #    outputs[out_idx].clear_memo()
        #    output_pipes[out_idx].flush()

    if args.inputfilepath is not None:
        wavfile.close()

    if len(input_pipes) == 0:
        stream.stop_stream()
        stream.close()
        pa.terminate()

    for pipe in input_pipes:
        pipe.close()
    for pipe in output_pipes:
        pipe.close()