Exemplo n.º 1
0
class BinauralBeat(Block):
    volume = Input()

    def __init__(self, **config):
        super(BinauralBeat, self).__init__(**config)

        self.server = pyo.Server(buffersize=1024).boot()
        centerFreq = pyo.Sig(256)
        binauralFreq = pyo.Sine(freq=0.05, add=10.5, mul=1.5)

        left = pyo.Sine(freq=centerFreq - binauralFreq / 2)
        right = pyo.Sine(freq=centerFreq + binauralFreq / 2)
        left.out(chnl=0)
        right.out(chnl=1)

        #left = pyo.PinkNoise().mix(2).out()

        import thread
        thread.start_new_thread(self.server.start, ())

        self.left = left
        self.right = right

    def process(self):
        vol = float(self.volume.buffer[-1] / 3500.0)
        vol = min(vol, 1.0)
        self.left.mul = self.right.mul = vol
Exemplo n.º 2
0
class BandPass(Block):
	input = Input()

	order = Range(low=2, high=8, value=5)
	lo = Float
	hi = Float
	nyquist = Float(125)

	def init(self, lo, hi, input):
		self.lo = lo
		self.hi = hi
		self.input = input
		self.output = Signal()

	@on_trait_change("lo,hi,order,nyquist")
	def _range_changed(self):
		b,a = iirfilter(self.order, (self.lo / self.nyquist, self.hi / self.nyquist))

		self._filter_b, self._filter_a = b,a

	def process(self):
		buffer = self.input.buffer[-self.order*3:]
		filt = lfilter(self._filter_b, self._filter_a, buffer)
		self.output.append(filt[-1:])
		self.output.process()


	@property
	def range(self):
		return self.lo, self.hi
Exemplo n.º 3
0
class DominantFrequency(Block):
    input = Input()

    chunk_size = 256

    def init(self, input):
        self.input = input
        self.cnt = 0

        self.window = np.hanning(self.chunk_size)

        self.freq = Signal()

    def process(self):
        self.cnt += 1
        if self.cnt > 20:
            self.cnt = 0
        else:
            return


        C = np.fft.rfft(self.input.buffer[-self.chunk_size:] * self.window)
        C = abs(C)
        Fs = 250.0

        def index_max(values):
            return max(xrange(len(values)),key=values.__getitem__)

        freq = index_max(C)
        freq = freq / Fs

        self.freq.append([freq])
        self.freq.process()
Exemplo n.º 4
0
class Expression(Block):
	args = List(Input)
	input = Input()

	def init(self, func, *args):
		# HACK: should not directly reference lupa here
		import lupa
		if lupa.lua_type(args) == 'table':
			args = args.values()


		print ('Expression: ', func, args)
		self.func = func
		self.args = list(args)
		
		self.output = Signal()

		# Workaround for list event bug 
		self.input = self.args[0]


	def _input_changed(self):
		self.output.copy_traits(self.input, ['label', 'color'])

	def process(self):
		args = [chan.last for chan in self.args]
		self.output.append([self.func(*args)])
		self.output.process()
Exemplo n.º 5
0
class NotchDelay(Block):
	input = Input()

	frequency = Float(50.0)
	samplerate = Int(250)

	def init(self, input):
		self.readjust()
		self.input = input
		self.output = Signal()
		self.delayed = Signal()


	@on_trait_change("frequency,samplerate")
	def readjust(self):
		delay = self.samplerate / self.frequency / 2
		delay = 3
		self.delayline = [0] * int(delay) 

	def process(self):
		for sample in self.input.new:
			self.delayline[1:] = self.delayline[:-1]
			self.delayline[0] = sample
			self.output.append([self.delayline[-1] + sample])
			self.delayed.append([self.delayline[-1] + self.delayline[-2]])

		self.output.process()
		self.delayed.process()
Exemplo n.º 6
0
class DCBlock(Block):
	input = Input()

	def __init__(self, input, **config):
		self.dc = Signal()
		self.ac = Signal()

		super(DCBlock, self).__init__(**config)

		self.input = input

	def _input_changed(self):
		traits = self.input.trait_get(['label', 'color'])
		self.ac.trait_set(**traits)

	def process(self):
		for x in self.input.new:
			new_dc = self.dc.buffer[-1] * 0.95 + x * 0.05
			self.dc.append([new_dc])

		self.dc.process()


		self.ac.append([x - self.dc.buffer[-1] for x in self.input.new])
		self.ac.process()
Exemplo n.º 7
0
class ClockAnalyzer(Block):
    input = Input()
    alpha = 0.5

    def init(self, input):
        self.input = input
        self.last_time = monotonic()

        self.time_diff = Signal()
        self.sample_rate = Signal()
        self.jitter = Signal()

    def process(self):
        #self.input.buffer_size = 1024

        #if len(self.input.buffer) < 1024: return

        new_time = monotonic()
        diff = new_time - self.last_time
        self.last_time = new_time

        self.time_diff.append([diff])
        self.time_diff.process()

        sample_rate = 1.0 / moving_average_exp(self.alpha,
                                               self.time_diff.buffer)

        self.sample_rate.append([sample_rate])
        self.sample_rate.process()

        period = 1.0 / sample_rate
        jitter = abs(diff - period) * 1000
        self.jitter.append([jitter])
        self.jitter.process()
Exemplo n.º 8
0
class JitterBuffer(Block):
    input = Input()

    buffer_size = 5

    def init(self, input, sample_rate):
        self.input = input
        self.output = Signal()
        self.period = 1.0 / sample_rate

        self.buffer = []

        self.started = False

    def process(self):
        newbuf = self.input.new
        newbuf.extend(self.buffer)
        self.buffer = newbuf

        if not self.started and len(self.buffer) > self.buffer_size:
            self.started = True

            import threading
            threading.Thread(target=self.run).start()

    def clock_sample(self):
        if len(self.buffer):
            self.output.append([self.buffer.pop()])
            self.output.process()
        else:
            print('Warning: JitterBuffer ran empty')

    def run(self):
        nperiod = int(self.period * 1000000000)
        ncomputation = nperiod // 10
        nconstraint = ncomputation * 2

        print(self.period, nperiod, ncomputation, nconstraint)

        set_realtime(nperiod, ncomputation, nconstraint)

        start = monotonic()
        while (True):
            loop_begin = monotonic()
            #print ('diff time %f' % (loop_begin - start))

            wait_time = start + self.period - monotonic()

            if wait_time <= 0.000001:
                start += self.period
                self.clock_sample()

                loop_end = monotonic()
                #print ('clock process took %f seconds' % (loop_end - loop_begin))
            elif wait_time > self.period / 2:
                #print ('%f seconds left, sleeping' % wait_time)
                thread_yield()

            else:
                pass
Exemplo n.º 9
0
class Spectrograph(Block):
    CHUNKSZ = Int(256)
    input = Input()
        
    def __init__(self, name, **config):
        self.img = pg.ImageItem()
        self.plot_widget = pg.PlotWidget(title=name)
        self.plot_widget.block = self

        self.plot_widget.addItem(self.img)

        #self.img_array = np.zeros((1000, self.CHUNKSZ/2+1))
        self.img_array = np.zeros((1000, 48))

        # bipolar colormap
        pos = np.array([0., 1., 0.5, 0.25, 0.75])
        color = np.array([[0,255,255,255], [255,255,0,255], [0,0,0,255], (0, 0, 255, 255), (255, 0, 0, 255)], dtype=np.ubyte)
        cmap = pg.ColorMap(pos, color)
        lut = cmap.getLookupTable(0.0, 1.0, 256)

        self.img.setLookupTable(lut)
        self.img.setLevels([-2,7])

        FS = 48 * 2

        freq = np.arange((self.CHUNKSZ/2)+1)/(float(self.CHUNKSZ)/FS)
        yscale = 1.0/(self.img_array.shape[1]/freq[-1])
        self.img.scale((1./FS)*self.CHUNKSZ, yscale)

        self.plot_widget.setLabel('left', 'Frequency', units='Hz')

        self.win = np.hanning(self.CHUNKSZ)
        #self.show()
        super(Spectrograph, self).__init__(**config)
        
    def process(self):
        # normalized, windowed frequencies in data chunk
        spec = np.fft.rfft(self.input.buffer*self.win) / self.CHUNKSZ

        spec = spec[0:48]
        # get magnitude 
        psd = abs(spec)
        # convert to dB scale
        psd = np.log10(psd)
        
        #self.img.setLevels([min(psd), max(psd)])
        
        #print (psd)

        # roll down one and replace leading edge with new data
        self.img_array = np.roll(self.img_array, -1, 0)
        self.img_array[-1:] = psd

        self.img.setImage(self.img_array, autoLevels=False)

    def widget(self):
        return self.plot_widget
        
    def updateGUI(self):
        pass
Exemplo n.º 10
0
class Normalizer(Block):
    input = Input()
    time_factor = Float(0.9999)

    def __init__(self, input, **config):
        self.output = Signal()

        super(Normalizer, self).__init__(**config)

        self.min = 0.0
        self.max = 1.0

        self.input = input

    def process(self):

        min = np.min(self.input.buffer) / 2
        self.min = self.min * self.time_factor + min * (1.0 - self.time_factor)

        max = np.max(self.input.buffer) * 2
        self.max = self.max * self.time_factor + max * (1.0 - self.time_factor)

        out = (np.array(self.input.new) - self.min) / (self.max - self.min) * 2
        self.output.append(out)
        self.output.process()
Exemplo n.º 11
0
class NotchFilter(Block):
	input = Input()

	frequency = Float(50.0)

	# Find out what module_pole is and rename it
	module_pole = Float(0.9)

	nyquist = Float(125.0)

	@on_trait_change("frequency,module_pole")
	def compute_filter(self):
		theta = 2 * np.pi * self.frequency / self.nyquist * 2
		zero = np.exp(np.array([1j, -1j]) * theta)
		pole = self.module_pole * zero

		self._filter_b = np.poly(zero)
		self._filter_a = np.poly(pole)


	def init(self, input):
		self.compute_filter()
		self.input = input

		self.output = Signal()



	def process(self):
		buffer = self.input.buffer
		assert self.input.new_samples == 1

		filt = lfilter(self._filter_b, self._filter_a, buffer)
		self.output.append(filt[-1:])
		self.output.process()
Exemplo n.º 12
0
class MIDIDrum(Block):
    pitch = Input(default=440)
    velocity = Input(default=1.0)
    trigger = Input()

    def init(self, channel=0, port_name='drum'):
        from rtmidi2 import MidiOut
        self.channel = channel
        self.midi = MidiOut().open_virtual_port(port_name)

    def process(self):
        if self.trigger.posedge:
            pitch = self.pitch
            vel = self.velocity
            if not pitch:
                pitch = 100
            if not vel:
                vel = 1.0
            self.midi.send_noteon(self.channel, pitch, vel)
Exemplo n.º 13
0
class Oscilloscope(Block):

    autoscale = Bool(True)
    #yrange = List(Float, [0.0, 1.0], minlen=2, maxlen=2)
    yrange = Tuple(Float, Float)
    channels = List(Input())
    name = Str()

    def __init__(self, name, channels, **config):
        self._plot_widget = pg.PlotWidget(title=name)
        self._plot_widget.block = self

        self.plots = {}
        self.name = name
        self.scale_changed()

        # Workaround for lua tables
        if hasattr(channels, 'values'):
            channels = channels.values()
        channels = list(channels)

        super(Oscilloscope, self).__init__(channels=channels, **config)

    @on_trait_change('channels[]')
    def channels_changed(self, object, name, old, new):
        for channel in old:
            del self.plots[channel]
        for channel in new:
            plot = self._plot_widget.plot()
            
            
            plot.setPen(QtGui.QColor(channel.color))
            self.plots[channel] = plot

    @on_trait_change('autoscale,yrange')
    def scale_changed(self):
        self._plot_widget.setYRange(*self.yrange)

        self._plot_widget.enableAutoRange('y', 0.95 if self.autoscale else False)


    def widget(self):
        return self._plot_widget

    def updateGUI(self):
        for channel in self.plots:
            plot = self.plots[channel]
            plot.setData(channel.buffer)

    def process(self):
        pass
Exemplo n.º 14
0
class Averager(Block):
	input = Input()

	def __init__(self, input):
		self.output = Signal()
		self.average = 0.0
		self.factor = 0.99
		super(Averager, self).__init__(input=input)

	def process(self):
		for x in self.input.new:
			self.average = self.average * self.factor + x * (1.0 - self.factor)
			self.output.append([self.average])

		self.output.process()
Exemplo n.º 15
0
class PulseAnalyzer(Block):
    input = Input()

    def init(self, input):
        self.input = input

        self.output = Signal()
        self.bpm = Signal()
        self.gradient = Signal()
        self.pulse = Signal()

        self.last_beat = -1
        self.timestamp = 0

    def _input_changed(self):
        self.output.copy_traits(self.input, ['label', 'color'])

    def process(self):
        avg = np.average(self.output.buffer)
        max = np.max(self.output.buffer)

        self.timestamp += 1

        self.gradient.append([self.input.buffer[-1] - self.input.buffer[-2]])

        buf = np.power(self.gradient.buffer[-50:], 2)
        s = np.sum(np.hanning(50)[:50] * buf)

        self.output.append([s])

        for i, sample in enumerate(self.output.new):
            new = 1.0 if sample > max * 0.7 else 0.0
            self.pulse.append([new])

            if new > self.pulse.buffer[-2]:
                diff = self.timestamp - self.last_beat
                bpm = 1.0 / (diff / 250.) * 60

                self.bpm.append([bpm])
                self.bpm.process()

                print('beat event', diff, bpm, self.timestamp, self.last_beat)

                self.last_beat = self.timestamp

        self.output.process()
        self.gradient.process()
Exemplo n.º 16
0
class NumberBox(Block):
    input = Input()

    def init(self, name, input):
        self.name = name
        self.input = input
        self.label = QtGui.QLabel()
        self.label.setStyleSheet("QLabel { background-color : black; color : white; }")

    def widget(self):
        return self.label

    def updateGUI(self):
        self.label.setText('%.2f' % self.input.buffer[-1])
        pass

    def process(self):
        pass
Exemplo n.º 17
0
class HeartAnalyzer(Block):
    input = Input()

    def init(self):
        self.beat = Signal('Beat Event')
        self.bpm = Signal("Beats per Minute")

    def process(self):
        square = np.array(self.input.buffer)**2

        threshold = np.percentile(square, 98)

        if np.max(self.input.buffer[:self.input.new_samples]) > threshold:
            self.beat.append([1.0])
            print 'beat event'
        else:
            self.beat.append([0.0])

        self.beat.process()
Exemplo n.º 18
0
class RMS(Block):
	input = Input()
	avg_size = Int(42)

	def init(self, input):
		self.output = Signal()
		self.input = input

	def _input_changed(self):
		self.output.copy_traits(self.input, ['label', 'color'])


	def process(self):
		buf = np.array(self.input.buffer[-self.avg_size:])
		rms = sum(buf ** 2) / len(buf)
		avg = np.sqrt(rms)

		self.output.append([avg])
		self.output.process()
Exemplo n.º 19
0
class MPlayerControl(Block):
    from mplayer import Player

    enable = Input()

    def init(self, path):
        self.player = self.Player('-input default-bindings')
        self.player.loadfile(path)
        self.player.pause()
        self.player.frame_drop(2)
        self.playing = False

    def process(self):
        enable = self.enable.last

        if self.playing and not enable:
            self.playing = False
            self.player.pause()

        if not self.playing and enable:
            self.playing = True
            self.player.pause()
Exemplo n.º 20
0
class Trendline(Block):
	input = Input()
	interval = Int(25)

	def __init__(self, input):
		self.output = Signal(buffer_size=1000)
		self.cnt = 0

		super(Trendline, self).__init__(input=input)

	def _input_changed(self):
		traits = self.input.trait_get(['label', 'color'])
		self.ac.trait_set(**traits)

	def process(self):
		self.cnt += self.input.new_samples
		if self.cnt >= self.interval:
			self.cnt = 0

			avg = sum(self.input.buffer[-self.interval:]) / self.interval

			self.output.append([avg])
			self.output.process()
Exemplo n.º 21
0
class BEServer(Block):

    channels = List(Input())

    def init(self, channels):
        global main_socket
        if not main_socket:
            main_socket = socket.socket()
            main_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

            # Disable Nagle's algorithm
            main_socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
            main_socket.bind(('', 2666))
            main_socket.listen(1)

        self.channels = list(channels.values())

        threading.Thread(target=self.socket_thread).start()

    # Add header and send to clients
    def _send_packet(self, packet):
        global client_socket
        if not client_socket: return

        header = b'\xce\xfa\xce\xfe'
        header += struct.pack('<i', 8 + len(packet))
        packet = header + packet

        packet += b'\n'

        client_socket.send(packet)

    def _send_data(self, index, data):

        #print ('send_data to', index, data)

        packet = bytes()
        packet += struct.pack('<i', CMD_CHANNEL_DATA)
        packet += struct.pack('<i', index)
        packet += struct.pack('<i', len(data))

        for sample in data:
            packet += struct.pack('<d', sample)

        self._send_packet(packet)

    def _start(self):
        packet = struct.pack('<i', CMD_START)
        self._send_packet(packet)

    def _stop(self):
        packet = struct.pack('<i', CMD_STOP)
        self._send_packet(packet)

    def _add_channel(self, channel, index):
        packet = bytes()
        packet += struct.pack('<i', CMD_ADD_CHANNEL)
        packet += struct.pack('<i', index)
        packet += struct.pack('<d', channel.sample_rate)

        name = 'Channel %d' % (index + 1)

        if hasattr(channel, 'name'):
            name = channel.name

        name = name.encode('utf-8') + b'\0'

        packet += struct.pack('<i', len(name))
        packet += name

        self._send_packet(packet)

        print('add channel', name, index)

    def _remove_channel(self, index):
        packet = bytes()
        packet += struct.pack('<i', CMD_REMOVE_CHANNEL)
        packet += struct.pack('<i', index)

        self._send_packet(packet)

    def socket_thread(self):
        try:
            global client_socket
            if not client_socket:
                client_socket = main_socket.accept()[0]

            self._stop()

            #for i in range(32):
            #    self._remove_channel(i)

            for idx, ch in enumerate(self.channels):
                self._add_channel(ch, idx)

            self._start()

            sent_timestamp = self.channels[0].timestamp

            while True:
                ts = self.channels[0].timestamp
                if sent_timestamp < ts:
                    l = ts - sent_timestamp
                    sent_timestamp += l
                    #l = min(l, 2)

                    ## Assume same clocking on all signals

                    for idx, ch in enumerate(self.channels):
                        newdata = ch.buffer[-l:]
                        self._send_data(idx, newdata)

                time.sleep(0)
                #rt_thread.thread_yield()
        except BrokenPipeError:
            client_socket = None
            self.socket_thread()

    def __del__(self):
        print('BEServer closing socket...')

        global main_socket, client_socket

        if main_socket: main_socket.close()
        if client_socket: client_socket.close()

    def process(self):
        pass
Exemplo n.º 22
0
class Waterfall(Block):
    input = Input()

    history_size = 100

    window_size = Int(512)
    lo, hi = CFloat(1), CFloat(30)
    #align = Trait('bottom', Enum('left', 'right', 'top', 'bottom'))

    logarithm = Bool(False)
    sampling_rate = Float(250)

    update_rate = 20

    def init(self, name):
        self.name = name

        self.autoscale_button = QtGui.QCheckBox('Autoscale')
        self.autoscale_button.setCheckState(True)

        self.welch_button = QtGui.QCheckBox('Use Welch')
        self.welch_button.setCheckState(False)

        self.plot_widget = pg.PlotWidget(title=name)
        self.plot_widget.block = self

        self.plot_widget.setLabel('bottom', 'Frequency', units='Hz')
        self.plot_widget.setLabel("left", "Time", units='s')

        #TODO: listener for this
        #self.plot_widget.setYRange(-self.history_size / self.sampling_rate, 0)

        #self.plot_widget.setLimits(xMin=0, yMax=0)
        #self.plot_widget.showButtons()
        #self.waterfallPlotWidget.setAspectLocked(True)
        #self.waterfallPlotWidget.setDownsampling(mode="peak")
        #self.waterfallPlotWidget.setClipToView(True)
        
        # Setup histogram widget (for controlling waterfall plot levels and gradients)
        self.histogram = pg.PlotWidget(title='Histogram')
        self.waterfallHistogram = pg.HistogramLUTItem()
        self.histogram.addItem(self.waterfallHistogram)
        self.waterfallHistogram.gradient.loadPreset("flame")
        #self.waterfallHistogram.setHistogramRange(-50, 0)
        #self.waterfallHistogram.setLevels(-50, 0)

        self.waterfallImg = pg.ImageItem()
        self.plot_widget.clear()
        self.plot_widget.addItem(self.waterfallImg)      
        self.waterfallHistogram.setImageItem(self.waterfallImg)

        self.setup_range()

        self.update_counter = 0

    @on_trait_change('window_size,input')
    def size_input(self):
        if self.input.buffer_size < self.window_size:
            self.input.buffer_size = self.window_size
        
    @on_trait_change('window_size,lo,hi,history_size,sampling_rate,update_rate')
    def setup_range(self):

        self.window = np.hanning(self.window_size)

        nyquist = self.sampling_rate / 2

        bins = self.window_size / 2 + 1

        freqs = np.linspace(0, nyquist, bins)

        freq_step = nyquist / bins

        # Calculate bin indices
        self.lo_index = int(np.floor(self.lo / freq_step))
        self.hi_index = int(np.ceil(self.hi / freq_step))

        # Snap values to actual bin frequencies
        self.lo = freq_step * self.lo_index
        self.hi = freq_step * self.hi_index

        display_bins = self.hi_index - self.lo_index

        self.waterfallImgArray = np.zeros((self.history_size, display_bins))

        history_time = self.history_size / self.sampling_rate * self.update_rate
        self.waterfallImg.resetTransform()
        self.waterfallImg.setPos(self.lo, -history_time)
        self.waterfallImg.scale((self.hi - self.lo) / display_bins, history_time / self.history_size)
        #self.plot_widget.setYRange(-self.history_size / self.sampling_rate, 0)


    def process(self):
        self.update_counter += 1
        if self.update_counter == self.update_rate:
            self.update_counter = 0
        else:
            return


        if self.welch_button.checkState():
            f, C = welch(self.input.buffer, fs=250, nperseg=self.window_size, scaling='spectrum')
        else:
            C = np.fft.rfft(self.input.buffer[-self.window_size:] * self.window)
            C = abs(C)
            #C = C*C
        C = C[self.lo_index: self.hi_index]

        if self.logarithm:
            C = np.log(C)

        # Roll down one and replace leading edge with new data
        self.waterfallImgArray = np.roll(self.waterfallImgArray, -1, axis=0)
        self.waterfallImgArray[-1] = C

    def updateGUI(self):
        self.waterfallImg.setImage(self.waterfallImgArray.T,
                                   autoLevels=self.autoscale_button.checkState(),
                                   #autoRange=False
                                   )


    # TODO: This is overwritten by widget member
    def widget(self):
        config_widget = QtGui.QWidget()

        layout = QtGui.QHBoxLayout()
        layout.addWidget(self.autoscale_button)
        layout.addWidget(self.welch_button)
#        layout.addWidget(self.histogram)

        config_widget.setLayout(layout)

        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.plot_widget)
        layout.addWidget(config_widget)

        main_widget = QtGui.QWidget()
        main_widget.setLayout(layout)
        main_widget.block = self

        return main_widget
Exemplo n.º 23
0
class BarSpectrogram(Block):
    input = Input()

    bins = Int(256)
    lo, hi = CFloat(1), CFloat(30)
    align = Trait('bottom', Enum('left', 'right', 'top', 'bottom'))

    yrange = Int(65000)

    ratio = Bool(False)
    sampling_rate = Float(250)

    def init(self, name, input):
        self.plot = pg.PlotWidget(title=name)
        self.plot.block = self

        self.plot.setLabel('bottom', 'Frequency', units='Hz')

        self.bars = pg.BarGraphItem()

        self.setup_range()

        # TODO: Better autoranging features
        #self.plot.enableAutoRange('xy', False)
        
        self.plot.setYRange(0, self.yrange)

        self.input = input
        self.name = name

    @on_trait_change('bins,lo,hi')
    def setup_range(self):
        self.win = np.hanning(self.bins)
        
        FS = self.sampling_rate

        #num_bars = int(round((self.bins - 1) * (self.hi - self.lo) / FS))
        num_bars = len(np.zeros(self.bins)[self.lo: self.hi])

        #print 'num_bars', num_bars, self.bins * (self.hi - self.lo) / FS

        x = np.linspace(self.lo, self.hi, num_bars)

        self.bars = pg.BarGraphItem(x=x, height=range(num_bars), width=1.0)
        
        self.bars.setOpts(brushes=[pg.hsvColor(float(x) / num_bars) for x in range(num_bars)])
        self.plot.addItem(self.bars)

    def process(self):
        pass

    def updateGUI(self):

        C = np.fft.rfft(self.input.buffer[-self.bins:] * self.win)
        C = abs(C)

        lo, hi = self.lo, self.hi
        data = C[lo : hi]

        if self.ratio:
            data = data / sum(C)

        self.bars.setOpts(height=data)
        

    def widget(self):
        return self.plot
Exemplo n.º 24
0
class Threshold(Block):
    input = Input()

    average_period = Float(0.35)
    epoch = Float(3.0)

    auto_mode = Bool(True)
    mode = Enum('increase', 'decrease', 'range')

    auto_target = Float(0.90)

    low_target = Float(0.90)
    high_target = Float(0.90)

    def init(self, name, input):
        self.FS = 250
        self.name = name

        epoch_samples = int(self.FS * self.epoch)

        self.signal = Signal(buffer_size=epoch_samples)
        self.passfail = Signal()
        self.ratio = Signal()

        self.threshold = 1.0
        self.high_threshold = 0.0

        self.calc_cnt = 0

        self.bar = QtGui.QProgressBar(orientation=QtCore.Qt.Vertical)
        self.slider = QtGui.QSlider()

        self.slider.setRange(0, 17)
        self.bar.setRange(0, 17)

        self.pass_palette = self.bar.palette()

        self.input = input

        if isinstance(self.input.color, QtGui.QColor):
            self.color = self.input.color
        else:
            self.color = QtGui.QColor(self.input.color)

        self.bar.setStyleSheet("""
			QProgressBar::chunk { background: red; }
			QProgressBar::chunk[pass='******'] { background: %s ; }
			""" % self.color.name())

        self.button = QtGui.QPushButton("config")
        self.button.clicked.connect(self.configure_traits)

        self._widget = ThresholdWidget(self)

    def widget(self):
        return self._widget

        w = QtGui.QGroupBox()
        w.setTitle(self.name)

        l = QtGui.QGridLayout()
        l.addWidget(self.bar, 0, 0)
        l.addWidget(self.slider, 0, 1)

        l.addWidget(self.button, 1, 0, 1, 2)

        w.setLayout(l)
        w.block = self

        return w

    def updateGUI(self):
        self._widget.update()
        return
        self.bar.setValue(self.signal.last)

        self.bar.setProperty('pass', self.passfail.last)
        self.bar.style().polish(self.bar)

        if self.auto_mode:
            self.slider.setValue(self.threshold)

            #print type(self.threshold), self.threshold, self.nameano

    def process(self):
        assert self.input.new_samples == 1

        avg_period_samples = int(self.average_period * self.FS)

        avg = sum(self.input.buffer[-avg_period_samples:]) / avg_period_samples
        self.signal.append([avg])
        self.signal.process()

        self.calc_cnt += 1
        if self.auto_mode and self.calc_cnt >= avg_period_samples:
            self.calc_cnt = 0

            if self.mode == 'decrease':
                self.threshold = np.percentile(self.signal.buffer,
                                               100 * self.auto_target)
            elif self.mode == 'increase':
                self.threshold = np.percentile(self.signal.buffer,
                                               100 - 100 * self.auto_target)
            else:
                self.high_threshold = np.percentile(self.signal.buffer,
                                                    self.high_target)
                self.threshold = np.percentile(self.signal.buffer,
                                               100 - 100 * self.low_target)

        success = False

        self.ratio.append([avg / self.threshold])
        self.ratio.process()

        if self.mode == 'decrease':
            if avg < self.threshold:
                success = True
        elif self.mode == 'increase':
            if avg > self.threshold:
                success = True
        else:
            if avg > self.threshold and avg < self.high_threshold:
                success = True

        self.passfail.append([float(success)])
        self.passfail.process()