Exemple #1
0
    def __init__(self, logger):
        QMainWindow.__init__(self)

        # exception hook that logs to console, file, and display a message box
        self.errorDialogOpened = False
        sys.excepthook = self.excepthook

        # logger
        self.logger = logger

        # Setup the user interface
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # Initialize the audio data ring buffer
        self.audiobuffer = AudioBuffer(self.logger)

        # Initialize the audio backend
        self.audiobackend = AudioBackend(self.logger)

        # signal containing new data from the audio callback thread, processed as numpy array
        self.audiobackend.new_data_available.connect(self.audiobuffer.handle_new_data)

        # this timer is used to update widgets that just need to display as fast as they can
        self.display_timer = QtCore.QTimer()
        self.display_timer.setInterval(SMOOTH_DISPLAY_TIMER_PERIOD_MS)  # constant timing

        # slow timer
        self.slow_timer = QtCore.QTimer()
        self.slow_timer.setInterval(SLOW_TIMER_PERIOD_MS)  # constant timing

        self.about_dialog = About_Dialog(self, self.logger, self.audiobackend, self.slow_timer)
        self.settings_dialog = Settings_Dialog(self, self.logger, self.audiobackend)

        self.centralwidget = CentralWidget(self.ui.centralwidget, self.logger, "central_widget", 0)
        self.centralLayout = QVBoxLayout(self.ui.centralwidget)
        self.centralLayout.setContentsMargins(0, 0, 0, 0)
        self.centralLayout.addWidget(self.centralwidget)

        self.dockmanager = DockManager(self, self.logger)

        # timer ticks
        self.display_timer.timeout.connect(self.centralwidget.canvasUpdate)
        self.display_timer.timeout.connect(self.dockmanager.canvasUpdate)

        # toolbar clicks
        self.ui.actionStart.triggered.connect(self.timer_toggle)
        self.ui.actionSettings.triggered.connect(self.settings_called)
        self.ui.actionAbout.triggered.connect(self.about_called)
        self.ui.actionNew_dock.triggered.connect(self.dockmanager.new_dock)

        # restore the settings and widgets geometries
        self.restoreAppState()

        # start timers
        self.timer_toggle()
        self.slow_timer.start()

        self.logger.push("Init finished, entering the main loop")
Exemple #2
0
	def __init__(self, logger):
		QMainWindow.__init__(self)

		# logger
		self.logger = logger

		# Setup the user interface
		self.ui = Ui_MainWindow()
		self.ui.setupUi(self)

		# sharedGLWidget is a hidden GL widget that will be used as a parent
		# to all QGLWidgets so that they have the same GL context, and can
		# share display lists, etc.
		self.sharedGLWidget = QtOpenGL.QGLWidget(self)
		self.sharedGLWidget.hide()

		# Initialize the audio data ring buffer
		self.audiobuffer = AudioBuffer(self.logger)

		# Initialize the audio backend
		self.audiobackend = AudioBackend(self.logger)

		# this timer is used to update widgets that just need to display as fast as they can
		self.display_timer = QtCore.QTimer()
		self.display_timer.setInterval(SMOOTH_DISPLAY_TIMER_PERIOD_MS) # constant timing

		# slow timer
		self.slow_timer = QtCore.QTimer()
		self.slow_timer.setInterval(SLOW_TIMER_PERIOD_MS) # constant timing

		self.about_dialog = About_Dialog(self, self.logger, self.audiobackend, self.slow_timer)
		self.settings_dialog = Settings_Dialog(self, self.logger, self.audiobackend)

		self.centralwidget = CentralWidget(self.ui.centralwidget, self.sharedGLWidget, self.logger, "central_widget", 0)
		self.centralLayout = QVBoxLayout(self.ui.centralwidget)
		self.centralLayout.setContentsMargins(0, 0, 0, 0)
		self.centralLayout.addWidget(self.centralwidget)

		self.dockmanager = DockManager(self, self.sharedGLWidget, self.logger)

		# timer ticks
		self.connect(self.display_timer, QtCore.SIGNAL('timeout()'), self.update_buffer)
		self.connect(self.display_timer, QtCore.SIGNAL('timeout()'), self.centralwidget.update)
		self.connect(self.display_timer, QtCore.SIGNAL('timeout()'), self.dockmanager.update)

		# toolbar clicks
		self.connect(self.ui.actionStart, QtCore.SIGNAL('triggered()'), self.timer_toggle)
		self.connect(self.ui.actionSettings, QtCore.SIGNAL('triggered()'), self.settings_called)
		self.connect(self.ui.actionAbout, QtCore.SIGNAL('triggered()'), self.about_called)
		self.connect(self.ui.actionNew_dock, QtCore.SIGNAL('triggered()'), self.dockmanager.new_dock)

		# restore the settings and widgets geometries
		self.restoreAppState()

		# start timers
		self.timer_toggle()
		self.slow_timer.start()
		
		self.logger.push("Init finished, entering the main loop")
Exemple #3
0
class Friture(QMainWindow, ):

    def __init__(self, logger):
        QMainWindow.__init__(self)

        # logger
        self.logger = logger

        # Setup the user interface
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # Initialize the audio data ring buffer
        self.audiobuffer = AudioBuffer(self.logger)

        # Initialize the audio backend
        self.audiobackend = AudioBackend(self.logger)

        # signal containing new data from the audio callback thread, processed as numpy array
        self.audiobackend.new_data_available.connect(self.audiobuffer.handle_new_data)

        # this timer is used to update widgets that just need to display as fast as they can
        self.display_timer = QtCore.QTimer()
        self.display_timer.setInterval(SMOOTH_DISPLAY_TIMER_PERIOD_MS)  # constant timing

        # slow timer
        self.slow_timer = QtCore.QTimer()
        self.slow_timer.setInterval(SLOW_TIMER_PERIOD_MS)  # constant timing

        self.about_dialog = About_Dialog(self, self.logger, self.audiobackend, self.slow_timer)
        self.settings_dialog = Settings_Dialog(self, self.logger, self.audiobackend)

        self.centralwidget = CentralWidget(self.ui.centralwidget, self.logger, "central_widget", 0)
        self.centralLayout = QVBoxLayout(self.ui.centralwidget)
        self.centralLayout.setContentsMargins(0, 0, 0, 0)
        self.centralLayout.addWidget(self.centralwidget)

        self.dockmanager = DockManager(self, self.logger)

        # timer ticks
        self.display_timer.timeout.connect(self.centralwidget.canvasUpdate)
        self.display_timer.timeout.connect(self.dockmanager.canvasUpdate)

        # toolbar clicks
        self.ui.actionStart.triggered.connect(self.timer_toggle)
        self.ui.actionSettings.triggered.connect(self.settings_called)
        self.ui.actionAbout.triggered.connect(self.about_called)
        self.ui.actionNew_dock.triggered.connect(self.dockmanager.new_dock)

        # restore the settings and widgets geometries
        self.restoreAppState()

        # start timers
        self.timer_toggle()
        self.slow_timer.start()

        self.logger.push("Init finished, entering the main loop")

    # slot
    def settings_called(self):
        self.settings_dialog.show()

    # slot
    def about_called(self):
        self.about_dialog.show()

    # event handler
    def closeEvent(self, event):
        self.audiobackend.close()
        self.saveAppState()
        event.accept()

    # method
    def saveAppState(self):
        settings = QtCore.QSettings("Friture", "Friture")

        settings.beginGroup("Docks")
        self.dockmanager.saveState(settings)
        settings.endGroup()

        settings.beginGroup("CentralWidget")
        self.centralwidget.saveState(settings)
        settings.endGroup()

        settings.beginGroup("MainWindow")
        windowGeometry = self.saveGeometry()
        settings.setValue("windowGeometry", windowGeometry)
        windowState = self.saveState()
        settings.setValue("windowState", windowState)
        settings.endGroup()

        settings.beginGroup("AudioBackend")
        self.settings_dialog.saveState(settings)
        settings.endGroup()

    # method
    def restoreAppState(self):
        settings = QtCore.QSettings("Friture", "Friture")

        settings.beginGroup("Docks")
        self.dockmanager.restoreState(settings)
        settings.endGroup()

        settings.beginGroup("CentralWidget")
        self.centralwidget.restoreState(settings)
        settings.endGroup()

        settings.beginGroup("MainWindow")
        self.restoreGeometry(settings.value("windowGeometry", type=QtCore.QByteArray))
        self.restoreState(settings.value("windowState", type=QtCore.QByteArray))
        settings.endGroup()

        settings.beginGroup("AudioBackend")
        self.settings_dialog.restoreState(settings)
        settings.endGroup()

    # slot
    def timer_toggle(self):
        if self.display_timer.isActive():
            self.logger.push("Timer stop")
            self.display_timer.stop()
            self.ui.actionStart.setText("Start")
            self.audiobackend.pause()
            self.centralwidget.pause()
            self.dockmanager.pause()
        else:
            self.logger.push("Timer start")
            self.display_timer.start()
            self.ui.actionStart.setText("Stop")
            self.audiobackend.restart()
            self.centralwidget.restart()
            self.dockmanager.restart()
Exemple #4
0
class Friture(QMainWindow, ):
	def __init__(self, logger):
		QMainWindow.__init__(self)

		# logger
		self.logger = logger

		# Setup the user interface
		self.ui = Ui_MainWindow()
		self.ui.setupUi(self)

		# sharedGLWidget is a hidden GL widget that will be used as a parent
		# to all QGLWidgets so that they have the same GL context, and can
		# share display lists, etc.
		self.sharedGLWidget = QtOpenGL.QGLWidget(self)
		self.sharedGLWidget.hide()

		# Initialize the audio data ring buffer
		self.audiobuffer = AudioBuffer(self.logger)

		# Initialize the audio backend
		self.audiobackend = AudioBackend(self.logger)

		# this timer is used to update widgets that just need to display as fast as they can
		self.display_timer = QtCore.QTimer()
		self.display_timer.setInterval(SMOOTH_DISPLAY_TIMER_PERIOD_MS) # constant timing

		# slow timer
		self.slow_timer = QtCore.QTimer()
		self.slow_timer.setInterval(SLOW_TIMER_PERIOD_MS) # constant timing

		self.about_dialog = About_Dialog(self, self.logger, self.audiobackend, self.slow_timer)
		self.settings_dialog = Settings_Dialog(self, self.logger, self.audiobackend)

		self.centralwidget = CentralWidget(self.ui.centralwidget, self.sharedGLWidget, self.logger, "central_widget", 0)
		self.centralLayout = QVBoxLayout(self.ui.centralwidget)
		self.centralLayout.setContentsMargins(0, 0, 0, 0)
		self.centralLayout.addWidget(self.centralwidget)

		self.dockmanager = DockManager(self, self.sharedGLWidget, self.logger)

		# timer ticks
		self.connect(self.display_timer, QtCore.SIGNAL('timeout()'), self.update_buffer)
		self.connect(self.display_timer, QtCore.SIGNAL('timeout()'), self.centralwidget.update)
		self.connect(self.display_timer, QtCore.SIGNAL('timeout()'), self.dockmanager.update)

		# toolbar clicks
		self.connect(self.ui.actionStart, QtCore.SIGNAL('triggered()'), self.timer_toggle)
		self.connect(self.ui.actionSettings, QtCore.SIGNAL('triggered()'), self.settings_called)
		self.connect(self.ui.actionAbout, QtCore.SIGNAL('triggered()'), self.about_called)
		self.connect(self.ui.actionNew_dock, QtCore.SIGNAL('triggered()'), self.dockmanager.new_dock)

		# restore the settings and widgets geometries
		self.restoreAppState()

		# start timers
		self.timer_toggle()
		self.slow_timer.start()
		
		self.logger.push("Init finished, entering the main loop")
	
	# slot
	def settings_called(self):
		self.settings_dialog.show()
	
	# slot
	def about_called(self):
		self.about_dialog.show()
	
	# event handler
	def closeEvent(self, event):
		self.saveAppState()
		event.accept()
	
	# method
	def saveAppState(self):
		settings = QtCore.QSettings("Friture", "Friture")
		
		settings.beginGroup("Docks")
		self.dockmanager.saveState(settings)
		settings.endGroup()
		
		settings.beginGroup("CentralWidget")
		self.centralwidget.saveState(settings)
		settings.endGroup()
		
		settings.beginGroup("MainWindow")
		windowGeometry = self.saveGeometry()
		settings.setValue("windowGeometry", windowGeometry)
		windowState = self.saveState()
		settings.setValue("windowState", windowState)
		settings.endGroup()

		settings.beginGroup("AudioBackend")
		self.settings_dialog.saveState(settings)
		settings.endGroup()
	
	# method
	def restoreAppState(self):
		settings = QtCore.QSettings("Friture", "Friture")

		settings.beginGroup("Docks")
		self.dockmanager.restoreState(settings)
		settings.endGroup()

		settings.beginGroup("CentralWidget")
		self.centralwidget.restoreState(settings)
		settings.endGroup()

		settings.beginGroup("MainWindow")
		self.restoreGeometry(settings.value("windowGeometry").toByteArray())
		self.restoreState(settings.value("windowState").toByteArray())
		settings.endGroup()
  
  		settings.beginGroup("AudioBackend")
		self.settings_dialog.restoreState(settings)
		settings.endGroup()

	# slot
	def timer_toggle(self):
		if self.display_timer.isActive():
			self.logger.push("Timer stop")
			self.display_timer.stop()
			self.ui.actionStart.setText("Start")
			self.centralwidget.pause()
			self.dockmanager.pause()
		else:
			self.logger.push("Timer start")
			self.display_timer.start()
			self.ui.actionStart.setText("Stop")
			self.centralwidget.restart()
			self.dockmanager.restart()

	# slot
	def update_buffer(self):
     		newpoints = self.audiobackend.update(self.audiobuffer.ringbuffer)
     		self.audiobuffer.set_newdata(newpoints)
Exemple #5
0
	def __init__(self, logger):
		QMainWindow.__init__(self)

		# logger
		self.logger = logger

		# Setup the user interface
		self.ui = Ui_MainWindow()
		self.ui.setupUi(self)
		
		self.settings_dialog = Settings_Dialog(self)
		self.about_dialog = About_Dialog(self)
		
		self.chunk_number = 0
		
		self.buffer_timer_time = 0.
		
		self.cpu_percent = 0.

		# Initialize the audio data ring buffer
		self.audiobuffer = AudioBuffer()

		# Initialize the audio backend
		self.audiobackend = AudioBackend(self.logger)
   
		devices = self.audiobackend.get_readable_devices_list()
		for device in devices:
			self.settings_dialog.comboBox_inputDevice.addItem(device)

		channels = self.audiobackend.get_readable_current_channels()
		for channel in channels:
			self.settings_dialog.comboBox_firstChannel.addItem(channel)
			self.settings_dialog.comboBox_secondChannel.addItem(channel)

		current_device = self.audiobackend.get_readable_current_device()
		self.settings_dialog.comboBox_inputDevice.setCurrentIndex(current_device)

		first_channel = self.audiobackend.get_current_first_channel()
		self.settings_dialog.comboBox_firstChannel.setCurrentIndex(first_channel)
		second_channel = self.audiobackend.get_current_second_channel()
		self.settings_dialog.comboBox_secondChannel.setCurrentIndex(second_channel)

		# this timer is used to update widgets that just need to display as fast as they can
		self.display_timer = QtCore.QTimer()
		self.display_timer.setInterval(SMOOTH_DISPLAY_TIMER_PERIOD_MS) # constant timing

		# slow timer
		self.slow_timer = QtCore.QTimer()
		self.slow_timer.setInterval(1000) # constant timing

		self.centralwidget = CentralWidget(self.ui.centralwidget, self.logger, "central_widget", 0)
		self.centralLayout = QVBoxLayout(self.ui.centralwidget)
		self.centralLayout.setContentsMargins(0, 0, 0, 0)
		self.centralLayout.addWidget(self.centralwidget)

		# timer ticks
		self.connect(self.display_timer, QtCore.SIGNAL('timeout()'), self.update_buffer)
		self.connect(self.display_timer, QtCore.SIGNAL('timeout()'), self.statistics)

		# timer ticks
		self.connect(self.slow_timer, QtCore.SIGNAL('timeout()'), self.get_cpu_percent)
		
		# toolbar clicks
		self.connect(self.ui.actionStart, QtCore.SIGNAL('triggered()'), self.timer_toggle)
		self.connect(self.ui.actionSettings, QtCore.SIGNAL('triggered()'), self.settings_called)
		self.connect(self.ui.actionAbout, QtCore.SIGNAL('triggered()'), self.about_called)
		self.connect(self.ui.actionNew_dock, QtCore.SIGNAL('triggered()'), self.new_dock_called)
		
		# settings signals
		self.connect(self.settings_dialog.comboBox_inputDevice, QtCore.SIGNAL('currentIndexChanged(int)'), self.input_device_changed)
  		self.connect(self.settings_dialog.comboBox_firstChannel, QtCore.SIGNAL('currentIndexChanged(int)'), self.first_channel_changed)
		self.connect(self.settings_dialog.comboBox_secondChannel, QtCore.SIGNAL('currentIndexChanged(int)'), self.second_channel_changed)
		self.connect(self.settings_dialog.radioButton_single, QtCore.SIGNAL('toggled(bool)'), self.single_input_type_selected)
		self.connect(self.settings_dialog.radioButton_duo, QtCore.SIGNAL('toggled(bool)'), self.duo_input_type_selected)
		self.connect(self.settings_dialog.doubleSpinBox_delay, QtCore.SIGNAL('valueChanged(double)'), self.delay_changed)

		# log change
		self.connect(self.logger, QtCore.SIGNAL('logChanged'), self.log_changed)
		self.connect(self.about_dialog.log_scrollarea.verticalScrollBar(), QtCore.SIGNAL('rangeChanged(int,int)'), self.log_scroll_range_changed)

		# restore the settings and widgets geometries
		self.restoreAppState()

		# start timers
		self.timer_toggle()
		self.slow_timer.start()
		
		self.logger.push("Init finished, entering the main loop")
Exemple #6
0
class Friture(QMainWindow, ):
	def __init__(self, logger):
		QMainWindow.__init__(self)

		# logger
		self.logger = logger

		# Setup the user interface
		self.ui = Ui_MainWindow()
		self.ui.setupUi(self)
		
		self.settings_dialog = Settings_Dialog(self)
		self.about_dialog = About_Dialog(self)
		
		self.chunk_number = 0
		
		self.buffer_timer_time = 0.
		
		self.cpu_percent = 0.

		# Initialize the audio data ring buffer
		self.audiobuffer = AudioBuffer()

		# Initialize the audio backend
		self.audiobackend = AudioBackend(self.logger)
   
		devices = self.audiobackend.get_readable_devices_list()
		for device in devices:
			self.settings_dialog.comboBox_inputDevice.addItem(device)

		channels = self.audiobackend.get_readable_current_channels()
		for channel in channels:
			self.settings_dialog.comboBox_firstChannel.addItem(channel)
			self.settings_dialog.comboBox_secondChannel.addItem(channel)

		current_device = self.audiobackend.get_readable_current_device()
		self.settings_dialog.comboBox_inputDevice.setCurrentIndex(current_device)

		first_channel = self.audiobackend.get_current_first_channel()
		self.settings_dialog.comboBox_firstChannel.setCurrentIndex(first_channel)
		second_channel = self.audiobackend.get_current_second_channel()
		self.settings_dialog.comboBox_secondChannel.setCurrentIndex(second_channel)

		# this timer is used to update widgets that just need to display as fast as they can
		self.display_timer = QtCore.QTimer()
		self.display_timer.setInterval(SMOOTH_DISPLAY_TIMER_PERIOD_MS) # constant timing

		# slow timer
		self.slow_timer = QtCore.QTimer()
		self.slow_timer.setInterval(1000) # constant timing

		self.centralwidget = CentralWidget(self.ui.centralwidget, self.logger, "central_widget", 0)
		self.centralLayout = QVBoxLayout(self.ui.centralwidget)
		self.centralLayout.setContentsMargins(0, 0, 0, 0)
		self.centralLayout.addWidget(self.centralwidget)

		# timer ticks
		self.connect(self.display_timer, QtCore.SIGNAL('timeout()'), self.update_buffer)
		self.connect(self.display_timer, QtCore.SIGNAL('timeout()'), self.statistics)

		# timer ticks
		self.connect(self.slow_timer, QtCore.SIGNAL('timeout()'), self.get_cpu_percent)
		
		# toolbar clicks
		self.connect(self.ui.actionStart, QtCore.SIGNAL('triggered()'), self.timer_toggle)
		self.connect(self.ui.actionSettings, QtCore.SIGNAL('triggered()'), self.settings_called)
		self.connect(self.ui.actionAbout, QtCore.SIGNAL('triggered()'), self.about_called)
		self.connect(self.ui.actionNew_dock, QtCore.SIGNAL('triggered()'), self.new_dock_called)
		
		# settings signals
		self.connect(self.settings_dialog.comboBox_inputDevice, QtCore.SIGNAL('currentIndexChanged(int)'), self.input_device_changed)
  		self.connect(self.settings_dialog.comboBox_firstChannel, QtCore.SIGNAL('currentIndexChanged(int)'), self.first_channel_changed)
		self.connect(self.settings_dialog.comboBox_secondChannel, QtCore.SIGNAL('currentIndexChanged(int)'), self.second_channel_changed)
		self.connect(self.settings_dialog.radioButton_single, QtCore.SIGNAL('toggled(bool)'), self.single_input_type_selected)
		self.connect(self.settings_dialog.radioButton_duo, QtCore.SIGNAL('toggled(bool)'), self.duo_input_type_selected)
		self.connect(self.settings_dialog.doubleSpinBox_delay, QtCore.SIGNAL('valueChanged(double)'), self.delay_changed)

		# log change
		self.connect(self.logger, QtCore.SIGNAL('logChanged'), self.log_changed)
		self.connect(self.about_dialog.log_scrollarea.verticalScrollBar(), QtCore.SIGNAL('rangeChanged(int,int)'), self.log_scroll_range_changed)

		# restore the settings and widgets geometries
		self.restoreAppState()

		# start timers
		self.timer_toggle()
		self.slow_timer.start()
		
		self.logger.push("Init finished, entering the main loop")
	
	# slot
	# update the log widget with the new log content
	def log_changed(self):
		self.about_dialog.LabelLog.setText(self.logger.text())
	
	# slot
	# scroll the log widget so that the last line is visible
	def log_scroll_range_changed(self, min, max):
		scrollbar = self.about_dialog.log_scrollarea.verticalScrollBar()
		scrollbar.setValue(max)
	
	# slot
	def settings_called(self):
		self.settings_dialog.show()
	
	# slot
	def about_called(self):
		self.about_dialog.show()
	
	# slot
	def new_dock_called(self):
		# the dock objectName is unique
		docknames = [dock.objectName() for dock in self.docks]
		dockindexes = [int(str(name).partition(' ')[-1]) for name in docknames]
		if len(dockindexes) == 0:
			index = 1
		else:
			index = max(dockindexes)+1
		name = "Dock %d" %index
		new_dock = Dock(self, self.logger, name)
		self.addDockWidget(QtCore.Qt.TopDockWidgetArea, new_dock)
		
		self.docks += [new_dock]
	
	#slot
	def dock_closed(self, dock):
		self.docks.remove(dock)
	
	# event handler
	def closeEvent(self, event):
		self.saveAppState()
		event.accept()
	
	# method
	def saveAppState(self):
		settings = QtCore.QSettings("Friture", "Friture")
		
		settings.beginGroup("Docks")
		docknames = [dock.objectName() for dock in self.docks]
		settings.setValue("dockNames", docknames)
		for dock in self.docks:
			settings.beginGroup(dock.objectName())
			dock.saveState(settings)
			settings.endGroup()
		settings.endGroup()
		
		settings.beginGroup("CentralWidget")
		self.centralwidget.saveState(settings)
		settings.endGroup()
		
		settings.beginGroup("MainWindow")
		windowGeometry = self.saveGeometry()
		settings.setValue("windowGeometry", windowGeometry)
		windowState = self.saveState()
		settings.setValue("windowState", windowState)
		settings.endGroup()

		settings.beginGroup("AudioBackend")
		self.settings_dialog.saveState(settings)
		settings.endGroup()
	
	# method
	def restoreAppState(self):
		settings = QtCore.QSettings("Friture", "Friture")

		settings.beginGroup("Docks")
		if settings.contains("dockNames"):
			docknames = settings.value("dockNames", []).toList()
			docknames = [dockname.toString() for dockname in docknames]
			# list of docks
			self.docks = [Dock(self, self.logger, name) for name in docknames]
			for dock in self.docks:
				settings.beginGroup(dock.objectName())
				dock.restoreState(settings)
				settings.endGroup()
		else:
			self.logger.push("First launch, display a default set of docks")
			self.docks = []
			self.docks += [Dock(self, self.logger, "Dock 0", type = 3)] #spectrogram
			self.docks += [Dock(self, self.logger, "Dock 1", type = 4)] #octave spectrum
			#self.docks += [Dock(self, self.logger, "Dock 2", type = 1)] #scope
			#self.docks += [Dock(self, self.logger, "Dock 3", type = 0)] #level
			for dock in self.docks:
				self.addDockWidget(QtCore.Qt.TopDockWidgetArea, dock)

		settings.endGroup()

		settings.beginGroup("CentralWidget")
		self.centralwidget.restoreState(settings)
		settings.endGroup()

		settings.beginGroup("MainWindow")
		self.restoreGeometry(settings.value("windowGeometry").toByteArray())
		self.restoreState(settings.value("windowState").toByteArray())
		settings.endGroup()
  
  		settings.beginGroup("AudioBackend")
		self.settings_dialog.restoreState(settings)
		settings.endGroup()

	# slot
	def timer_toggle(self):
		if self.display_timer.isActive():
			self.logger.push("Timer stop")
			self.display_timer.stop()
			self.ui.actionStart.setText("Start")
			for dock in self.docks:
				dock.custom_timer_stop()
			self.centralwidget.custom_timer_stop()
		else:
			self.logger.push("Timer start")
			self.display_timer.start()
			self.ui.actionStart.setText("Stop")
			for dock in self.docks:
				dock.custom_timer_start()
			self.centralwidget.custom_timer_start()

	# slot
	def update_buffer(self):
     		(chunks, t, newpoints) = self.audiobackend.update(self.audiobuffer.ringbuffer)
     		self.audiobuffer.set_newdata(newpoints)
		self.chunk_number += chunks
		self.buffer_timer_time = (95.*self.buffer_timer_time + 5.*t)/100.

	def get_cpu_percent(self):
		self.cpu_percent = psutil.cpu_percent()

	# method
	def statistics(self):
		if not self.about_dialog.LabelStats.isVisible():
		    return
		    
		label = "Chunk #%d\n"\
		"Audio buffer retrieval: %.02f ms\n"\
		"Global CPU usage: %d %%"\
		% (self.chunk_number, self.buffer_timer_time, self.cpu_percent)
		
		self.about_dialog.LabelStats.setText(label)

	# slot
	def input_device_changed(self, index):
		self.ui.actionStart.setChecked(False)
		
		success, index = self.audiobackend.select_input_device(index)
		
		self.settings_dialog.comboBox_inputDevice.setCurrentIndex(index)
		
		if not success:
			# Note: the error message is a child of the settings dialog, so that
			# that dialog remains on top when the error message is closed
			error_message = QErrorMessage(self.settings_dialog)
			error_message.setWindowTitle("Input device error")
			error_message.showMessage("Impossible to use the selected input device, reverting to the previous one")
		
		# reset the channels
		first_channel = self.audiobackend.get_current_first_channel()
		self.settings_dialog.comboBox_firstChannel.setCurrentIndex(first_channel)
		second_channel = self.audiobackend.get_current_second_channel()
		self.settings_dialog.comboBox_secondChannel.setCurrentIndex(second_channel)  
  
		self.ui.actionStart.setChecked(True)

	# slot
	def first_channel_changed(self, index):
		self.ui.actionStart.setChecked(False)
		
		success, index = self.audiobackend.select_first_channel(index)
		
		self.settings_dialog.comboBox_firstChannel.setCurrentIndex(index)
		
		if not success:
			# Note: the error message is a child of the settings dialog, so that
			# that dialog remains on top when the error message is closed
			error_message = QErrorMessage(self.settings_dialog)
			error_message.setWindowTitle("Input device error")
			error_message.showMessage("Impossible to use the selected channel as the first channel, reverting to the previous one")
		
		self.ui.actionStart.setChecked(True)

	# slot
	def second_channel_changed(self, index):
		self.ui.actionStart.setChecked(False)
		
		success, index = self.audiobackend.select_second_channel(index)
		
		self.settings_dialog.comboBox_secondChannel.setCurrentIndex(index)
		
		if not success:
			# Note: the error message is a child of the settings dialog, so that
			# that dialog remains on top when the error message is closed
			error_message = QErrorMessage(self.settings_dialog)
			error_message.setWindowTitle("Input device error")
			error_message.showMessage("Impossible to use the selected channel as the second channel, reverting to the previous one")
		
		self.ui.actionStart.setChecked(True)

	# slot
	def single_input_type_selected(self, checked):
                if checked:
                    self.settings_dialog.groupBox_second.setEnabled(False)
                    self.settings_dialog.label_delay.setEnabled(False)
                    self.settings_dialog.doubleSpinBox_delay.setEnabled(False)
                    self.audiobackend.set_single_input()
                    self.logger.push("Switching to single input")

	# slot
	def duo_input_type_selected(self, checked):
                if checked:
                    self.settings_dialog.groupBox_second.setEnabled(True)
                    self.settings_dialog.label_delay.setEnabled(True)
                    self.settings_dialog.doubleSpinBox_delay.setEnabled(True)
                    self.audiobackend.set_duo_input()
                    self.logger.push("Switching to difference between two inputs")

	# slot
	def delay_changed(self, delay_ms):
                    self.delay_ms = delay_ms
                    self.logger.push("Delay changed to %f" %delay_ms)
                    self.audiobuffer.set_delay_ms(delay_ms)