def __init__(self, dialog, inference_thread):
        super(AudioRecorder, self).__init__()

        self.dialog = dialog
        self.inference_thread = inference_thread

        self.inference_thread.finished.connect(self.on_transcription_finished)

        self.format = QAudioFormat()
        self.format.setSampleRate(16000)
        self.format.setChannelCount(1)
        self.format.setSampleSize(16)
        self.format.setCodec("audio/pcm")
        self.format.setByteOrder(QAudioFormat.LittleEndian)
        self.format.setSampleType(QAudioFormat.SignedInt)
        self.recorder = QAudioInput(self.format, self)

        self.is_recording = False
Esempio n. 2
0
    def initialize_audio(self):
        """Set up parameters for audio recording."""
        self._format = QAudioFormat()
        self._format.setSampleRate(44100)
        self._format.setChannelCount(1)
        self._format.setSampleSize(8)
        self._format.setSampleType(QAudioFormat.UnSignedInt)
        self._format.setByteOrder(QAudioFormat.LittleEndian)
        self._format.setCodec("audio/pcm")

        device_info = QAudioDeviceInfo(self._device)
        if not device_info.isFormatSupported(self._format):
            print("Default format not supported - trying to use nearest.")
            self._format = device_info.nearestFormat(self._format)

        self._audio_data_handler = AudioDataHandler(self._format)

        self._audio_input = QAudioInput(self._device, self._format)
        self._audio_data_handler.data_ready.connect(self.data_ready)
Esempio n. 3
0
    def initializeAudio(self):
        self.m_pullTimer = QTimer(self)
        self.m_pullTimer.timeout.connect(self.pullTimerExpired)
        self.m_pullMode = True

        self.m_format = QAudioFormat()
        self.m_format.setSampleRate(self.DataSampleRateHz)
        self.m_format.setChannelCount(1)
        self.m_format.setSampleSize(16)
        self.m_format.setCodec('audio/pcm')
        self.m_format.setByteOrder(QAudioFormat.LittleEndian)
        self.m_format.setSampleType(QAudioFormat.SignedInt)

        info = QAudioDeviceInfo(QAudioDeviceInfo.defaultOutputDevice())
        if not info.isFormatSupported(self.m_format):
            qWarning("Default format not supported - trying to use nearest")
            self.m_format = info.nearestFormat(self.m_format)

        self.m_generator = Generator(self.m_format,
                self.DurationSeconds * 1000000, self.ToneSampleRateHz, self)

        self.createAudioOutput()
Esempio n. 4
0
    def __init__(self, inputDevice, title, xlim, ylim):
        super(ZeStreamWidget, self).__init__()

        self.inputDevice = inputDevice

        # Creating QChart
        self.series = QtCharts.QLineSeries()
        self.chart = QtCharts.QChart()
        self.chart.addSeries(self.series)

        self.axisX = QtCharts.QValueAxis()
        self.axisX.setRange(0, sampleCount)
        self.axisX.setLabelFormat("%g")
        self.axisX.setTitleText("Samples")
        self.chart.setAxisX(self.axisX, self.series)

        self.axisY = QtCharts.QValueAxis()
        self.axisY.setRange(-1, 1)
        self.chart.setAxisY(self.axisY, self.series)

        self.chart.legend().hide()

        self.chart.setTitle(title)

        formatAudio = QAudioFormat()
        formatAudio.setSampleRate(8000)
        formatAudio.setChannelCount(1)
        formatAudio.setSampleSize(8)
        formatAudio.setCodec("audio/pcm")
        formatAudio.setByteOrder(QAudioFormat.LittleEndian)
        formatAudio.setSampleType(QAudioFormat.UnSignedInt)

        self.audioInput = QAudioInput(self.inputDevice, formatAudio, self)
        self.ioDevice = self.audioInput.start()
        self.ioDevice.readyRead.connect(self._readyRead)

        self.buffer = [QPointF(x, 0) for x in range(sampleCount)]
        self.series.append(self.buffer)
class AudioRecorder(QObject):
    def __init__(self, dialog, inference_thread):
        super(AudioRecorder, self).__init__()

        self.dialog = dialog
        self.inference_thread = inference_thread

        self.inference_thread.finished.connect(self.on_transcription_finished)

        self.format = QAudioFormat()
        self.format.setSampleRate(16000)
        self.format.setChannelCount(1)
        self.format.setSampleSize(16)
        self.format.setCodec("audio/pcm")
        self.format.setByteOrder(QAudioFormat.LittleEndian)
        self.format.setSampleType(QAudioFormat.SignedInt)
        self.recorder = QAudioInput(self.format, self)

        self.is_recording = False

    @Slot()
    def toggle_record(self):
        if self.is_recording == False:
            logging.info("Capturing sound")
            self.is_recording = True
            self.inference_thread.send_cmd(("start",))
            self.recorded_message = self.recorder.start()
            self.recorded_message.readyRead.connect(self.read_from_IO_devide)
        else:
            logging.info("Finished sound capturing")
            self.is_recording = False
            self.recorder.stop()
            self.inference_thread.send_cmd(("finish",))

    @Slot()
    def read_from_IO_devide(self):
        ''' Forward available audio data to the inference thread. '''
        # self.sender() is the IO device returned by QAudioInput.start()
        self.inference_thread.send_cmd(("data", self.sender().readAll()))

    @Slot(str)
    def on_transcription_finished(self, result):
        logging.info("Transcription: {result}")

        self.dialog.set_user_message(result)
        self.dialog.process_user_message()
        self.dialog.process_machine_message()
Esempio n. 6
0
class AudioTest(QMainWindow):

    PUSH_MODE_LABEL = "Enable push mode"
    PULL_MODE_LABEL = "Enable pull mode"
    SUSPEND_LABEL = "Suspend playback"
    RESUME_LABEL = "Resume playback"

    DurationSeconds = 1
    ToneSampleRateHz = 600
    DataSampleRateHz = 44100

    def __init__(self):
        super(AudioTest, self).__init__()

        self.m_device = QAudioDeviceInfo.defaultOutputDevice()
        self.m_output = None

        self.initializeWindow()
        self.initializeAudio()

    def initializeWindow(self):
        layout = QVBoxLayout()

        self.m_deviceBox = QComboBox()
        self.m_deviceBox.activated[int].connect(self.deviceChanged)
        for deviceInfo in QAudioDeviceInfo.availableDevices(
                QAudio.AudioOutput):
            self.m_deviceBox.addItem(deviceInfo.deviceName(), deviceInfo)

        layout.addWidget(self.m_deviceBox)

        self.m_modeButton = QPushButton()
        self.m_modeButton.clicked.connect(self.toggleMode)
        self.m_modeButton.setText(self.PUSH_MODE_LABEL)

        layout.addWidget(self.m_modeButton)

        self.m_suspendResumeButton = QPushButton(
            clicked=self.toggleSuspendResume)
        self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)

        layout.addWidget(self.m_suspendResumeButton)

        volumeBox = QHBoxLayout()
        volumeLabel = QLabel("Volume:")
        self.m_volumeSlider = QSlider(Qt.Horizontal,
                                      minimum=0,
                                      maximum=100,
                                      singleStep=10)
        self.m_volumeSlider.valueChanged.connect(self.volumeChanged)

        volumeBox.addWidget(volumeLabel)
        volumeBox.addWidget(self.m_volumeSlider)

        layout.addLayout(volumeBox)

        window = QWidget()
        window.setLayout(layout)

        self.setCentralWidget(window)

    def initializeAudio(self):
        self.m_pullTimer = QTimer(self)
        self.m_pullTimer.timeout.connect(self.pullTimerExpired)
        self.m_pullMode = True

        self.m_format = QAudioFormat()
        self.m_format.setSampleRate(self.DataSampleRateHz)
        self.m_format.setChannelCount(1)
        self.m_format.setSampleSize(16)
        self.m_format.setCodec('audio/pcm')
        self.m_format.setByteOrder(QAudioFormat.LittleEndian)
        self.m_format.setSampleType(QAudioFormat.SignedInt)

        info = QAudioDeviceInfo(QAudioDeviceInfo.defaultOutputDevice())
        if not info.isFormatSupported(self.m_format):
            qWarning("Default format not supported - trying to use nearest")
            self.m_format = info.nearestFormat(self.m_format)

        self.m_generator = Generator(self.m_format,
                                     self.DurationSeconds * 1000000,
                                     self.ToneSampleRateHz, self)

        self.createAudioOutput()

    def createAudioOutput(self):
        self.m_audioOutput = QAudioOutput(self.m_device, self.m_format)
        self.m_audioOutput.notify.connect(self.notified)
        self.m_audioOutput.stateChanged.connect(self.handleStateChanged)

        self.m_generator.start()
        self.m_audioOutput.start(self.m_generator)
        self.m_volumeSlider.setValue(self.m_audioOutput.volume() * 100)

    def deviceChanged(self, index):
        self.m_pullTimer.stop()
        self.m_generator.stop()
        self.m_audioOutput.stop()
        self.m_device = self.m_deviceBox.itemData(index)

        self.createAudioOutput()

    def volumeChanged(self, value):
        if self.m_audioOutput is not None:
            self.m_audioOutput.setVolume(value / 100.0)

    def notified(self):
        qWarning(
            "bytesFree = %d, elapsedUSecs = %d, processedUSecs = %d" %
            (self.m_audioOutput.bytesFree(), self.m_audioOutput.elapsedUSecs(),
             self.m_audioOutput.processedUSecs()))

    def pullTimerExpired(self):
        if self.m_audioOutput is not None and self.m_audioOutput.state(
        ) != QAudio.StoppedState:
            chunks = self.m_audioOutput.bytesFree(
            ) // self.m_audioOutput.periodSize()
            for _ in range(chunks):
                data = self.m_generator.read(self.m_audioOutput.periodSize())
                if data is None or len(
                        data) != self.m_audioOutput.periodSize():
                    break

                self.m_output.write(data)

    def toggleMode(self):
        self.m_pullTimer.stop()
        self.m_audioOutput.stop()

        if self.m_pullMode:
            self.m_modeButton.setText(self.PULL_MODE_LABEL)
            self.m_output = self.m_audioOutput.start()
            self.m_pullMode = False
            self.m_pullTimer.start(20)
        else:
            self.m_modeButton.setText(self.PUSH_MODE_LABEL)
            self.m_pullMode = True
            self.m_audioOutput.start(self.m_generator)

        self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)

    def toggleSuspendResume(self):
        if self.m_audioOutput.state() == QAudio.SuspendedState:
            qWarning("status: Suspended, resume()")
            self.m_audioOutput.resume()
            self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)
        elif self.m_audioOutput.state() == QAudio.ActiveState:
            qWarning("status: Active, suspend()")
            self.m_audioOutput.suspend()
            self.m_suspendResumeButton.setText(self.RESUME_LABEL)
        elif self.m_audioOutput.state() == QAudio.StoppedState:
            qWarning("status: Stopped, resume()")
            self.m_audioOutput.resume()
            self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)
        elif self.m_audioOutput.state() == QAudio.IdleState:
            qWarning("status: IdleState")

    stateMap = {
        QAudio.ActiveState: "ActiveState",
        QAudio.SuspendedState: "SuspendedState",
        QAudio.StoppedState: "StoppedState",
        QAudio.IdleState: "IdleState"
    }

    def handleStateChanged(self, state):
        qWarning("state = " + self.stateMap.get(state, "Unknown"))
Esempio n. 7
0
class AudioDevice(QObject):
    """Class for storing computer's audio system information."""
    data_ready = Signal(np.ndarray)
    audio_inputs = Signal(object)

    def __init__(self, default_device_name):
        super().__init__()
        self.default_device_name = default_device_name
        self._pull_timer = QTimer()
        self._pull_timer.setInterval(3000)
        self._pull_timer.timeout.connect(self.write_to_buffer)

        self._audio_input = None
        self._input = None
        self._audio_data_handler = None

        devices = QAudioDeviceInfo.availableDevices(QAudio.AudioInput)
        self._device = None
        self.monitors = []

        for item in devices:
            dev_name = item.deviceName()
            if dev_name.endswith(".monitor"):
                self.monitors.append(item)
            if self.default_device_name and self.default_device_name == item.deviceName(
            ):
                self._device = item
        if not self._device:
            try:
                self._device = self.monitors[0]
            except IndexError:
                self._device = QAudioDeviceInfo.defaultInputDevice()

        self.initialize_audio()

        self.start_audio()

    def initialize_audio(self):
        """Set up parameters for audio recording."""
        self._format = QAudioFormat()
        self._format.setSampleRate(44100)
        self._format.setChannelCount(1)
        self._format.setSampleSize(8)
        self._format.setSampleType(QAudioFormat.UnSignedInt)
        self._format.setByteOrder(QAudioFormat.LittleEndian)
        self._format.setCodec("audio/pcm")

        device_info = QAudioDeviceInfo(self._device)
        if not device_info.isFormatSupported(self._format):
            print("Default format not supported - trying to use nearest.")
            self._format = device_info.nearestFormat(self._format)

        self._audio_data_handler = AudioDataHandler(self._format)

        self._audio_input = QAudioInput(self._device, self._format)
        self._audio_data_handler.data_ready.connect(self.data_ready)

    def start_audio(self):
        """Start running all audio objects."""
        self._audio_data_handler.start()
        self._audio_input.start(self._audio_data_handler)
        self._input = self._audio_input.start()
        self._pull_timer.start()

    def get_input_devices(self):
        devices = []
        if self._device:
            devices.append(self._device)
        for item in self.monitors:
            if item.deviceName() not in [x.deviceName() for x in devices]:
                devices.append(item)
        system_default = QAudioDeviceInfo.defaultInputDevice()
        if system_default not in [x.deviceName() for x in devices]:
            devices.append(system_default)
        return devices

    def get_input_device_names(self):
        devices = self.get_input_devices()
        names = [x.deviceName() for x in devices]
        return names

    @Slot(str)
    def change_audio_input(self, input_name):
        input_devices = self.monitors
        input_devices.append(QAudioDeviceInfo.defaultInputDevice())
        for i in range(len(input_devices)):
            if input_devices[i].deviceName() == input_name:
                self._device = input_devices[i]
                self.initialize_audio()
                self.start_audio()
                break

    @Slot()
    def write_to_buffer(self):
        """Write data to buffer for later analysis."""
        len_ = self._audio_input.bytesReady()
        if len_ > 0:
            self._audio_data_handler.writeData(self._input.readAll(), len_)
Esempio n. 8
0
    def __init__(self, device):
        super(MainWindow, self).__init__()

        self.series = QtCharts.QLineSeries()
        self.chart = QtCharts.QChart()
        self.chart.addSeries(self.series)
        self.axisX = QtCharts.QValueAxis()
        self.axisX.setRange(0, sampleCount)
        self.axisX.setLabelFormat("%g")
        self.axisX.setTitleText("Samples")
        self.axisY = QtCharts.QValueAxis()
        self.axisY.setRange(-1, 1)
        self.axisY.setTitleText("Audio level")
        self.chart.setAxisX(self.axisX, self.series)
        self.chart.setAxisY(self.axisY, self.series)
        self.chart.legend().hide()
        self.chart.setTitle("Data from the microphone ({})".format(
            device.deviceName()))

        formatAudio = QAudioFormat()
        formatAudio.setSampleRate(8000)
        formatAudio.setChannelCount(1)
        formatAudio.setSampleSize(8)
        formatAudio.setCodec("audio/pcm")
        formatAudio.setByteOrder(QAudioFormat.LittleEndian)
        formatAudio.setSampleType(QAudioFormat.UnSignedInt)

        self.audioInput = QAudioInput(device, formatAudio, self)
        self.ioDevice = self.audioInput.start()
        self.ioDevice.readyRead.connect(self._readyRead)

        self.chartView = QtCharts.QChartView(self.chart)
        self.setCentralWidget(self.chartView)

        self.buffer = [QPointF(x, 0) for x in range(sampleCount)]
        self.series.append(self.buffer)
Esempio n. 9
0
    def __init__(self, device):
        super(MainWindow, self).__init__()

        self.series = QtCharts.QLineSeries()
        self.chart = QtCharts.QChart()
        self.chart.addSeries(self.series)
        self.axisX = QtCharts.QValueAxis()
        self.axisX.setRange(0, sampleCount)
        self.axisX.setLabelFormat("%g")
        self.axisX.setTitleText("Samples")
        self.axisY = QtCharts.QValueAxis()
        self.axisY.setRange(-1, 1)
        self.axisY.setTitleText("Audio level")
        self.chart.setAxisX(self.axisX, self.series)
        self.chart.setAxisY(self.axisY, self.series)
        self.chart.legend().hide()
        self.chart.setTitle("Data from the microphone ({})".format(device.deviceName()))

        formatAudio = QAudioFormat()
        formatAudio.setSampleRate(8000)
        formatAudio.setChannelCount(1)
        formatAudio.setSampleSize(8)
        formatAudio.setCodec("audio/pcm")
        formatAudio.setByteOrder(QAudioFormat.LittleEndian)
        formatAudio.setSampleType(QAudioFormat.UnSignedInt)

        self.audioInput = QAudioInput(device, formatAudio, self)
        self.ioDevice = self.audioInput.start()
        self.ioDevice.readyRead.connect(self._readyRead)

        self.chartView = QtCharts.QChartView(self.chart)
        self.setCentralWidget(self.chartView)

        self.buffer = [QPointF(x, 0) for x in range(sampleCount)]
        self.series.append(self.buffer)
Esempio n. 10
0
class AudioTest(QMainWindow):

    PUSH_MODE_LABEL = "Enable push mode"
    PULL_MODE_LABEL = "Enable pull mode"
    SUSPEND_LABEL = "Suspend playback"
    RESUME_LABEL = "Resume playback"

    DurationSeconds = 1
    ToneSampleRateHz = 600
    DataSampleRateHz = 44100

    def __init__(self):
        super(AudioTest, self).__init__()

        self.m_device = QAudioDeviceInfo.defaultOutputDevice()
        self.m_output = None

        self.initializeWindow()
        self.initializeAudio()

    def initializeWindow(self):
        layout = QVBoxLayout()

        self.m_deviceBox = QComboBox()
        self.m_deviceBox.activated[int].connect(self.deviceChanged)
        for deviceInfo in QAudioDeviceInfo.availableDevices(QAudio.AudioOutput):
            self.m_deviceBox.addItem(deviceInfo.deviceName(), deviceInfo)

        layout.addWidget(self.m_deviceBox)

        self.m_modeButton = QPushButton()
        self.m_modeButton.clicked.connect(self.toggleMode)
        self.m_modeButton.setText(self.PUSH_MODE_LABEL)

        layout.addWidget(self.m_modeButton)

        self.m_suspendResumeButton = QPushButton(
                clicked=self.toggleSuspendResume)
        self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)

        layout.addWidget(self.m_suspendResumeButton)

        volumeBox = QHBoxLayout()
        volumeLabel = QLabel("Volume:")
        self.m_volumeSlider = QSlider(Qt.Horizontal, minimum=0, maximum=100,
                singleStep=10)
        self.m_volumeSlider.valueChanged.connect(self.volumeChanged)

        volumeBox.addWidget(volumeLabel)
        volumeBox.addWidget(self.m_volumeSlider)

        layout.addLayout(volumeBox)

        window = QWidget()
        window.setLayout(layout)

        self.setCentralWidget(window)

    def initializeAudio(self):
        self.m_pullTimer = QTimer(self)
        self.m_pullTimer.timeout.connect(self.pullTimerExpired)
        self.m_pullMode = True

        self.m_format = QAudioFormat()
        self.m_format.setSampleRate(self.DataSampleRateHz)
        self.m_format.setChannelCount(1)
        self.m_format.setSampleSize(16)
        self.m_format.setCodec('audio/pcm')
        self.m_format.setByteOrder(QAudioFormat.LittleEndian)
        self.m_format.setSampleType(QAudioFormat.SignedInt)

        info = QAudioDeviceInfo(QAudioDeviceInfo.defaultOutputDevice())
        if not info.isFormatSupported(self.m_format):
            qWarning("Default format not supported - trying to use nearest")
            self.m_format = info.nearestFormat(self.m_format)

        self.m_generator = Generator(self.m_format,
                self.DurationSeconds * 1000000, self.ToneSampleRateHz, self)

        self.createAudioOutput()

    def createAudioOutput(self):
        self.m_audioOutput = QAudioOutput(self.m_device, self.m_format)
        self.m_audioOutput.notify.connect(self.notified)
        self.m_audioOutput.stateChanged.connect(self.handleStateChanged)

        self.m_generator.start()
        self.m_audioOutput.start(self.m_generator)
        self.m_volumeSlider.setValue(self.m_audioOutput.volume() * 100)

    def deviceChanged(self, index):
        self.m_pullTimer.stop()
        self.m_generator.stop()
        self.m_audioOutput.stop()
        self.m_device = self.m_deviceBox.itemData(index)

        self.createAudioOutput()

    def volumeChanged(self, value):
        if self.m_audioOutput is not None:
            self.m_audioOutput.setVolume(value / 100.0)

    def notified(self):
        qWarning("bytesFree = %d, elapsedUSecs = %d, processedUSecs = %d" % (
                self.m_audioOutput.bytesFree(),
                self.m_audioOutput.elapsedUSecs(),
                self.m_audioOutput.processedUSecs()))

    def pullTimerExpired(self):
        if self.m_audioOutput is not None and self.m_audioOutput.state() != QAudio.StoppedState:
            chunks = self.m_audioOutput.bytesFree() // self.m_audioOutput.periodSize()
            for _ in range(chunks):
                data = self.m_generator.read(self.m_audioOutput.periodSize())
                if data is None or len(data) != self.m_audioOutput.periodSize():
                    break

                self.m_output.write(data)

    def toggleMode(self):
        self.m_pullTimer.stop()
        self.m_audioOutput.stop()

        if self.m_pullMode:
            self.m_modeButton.setText(self.PULL_MODE_LABEL)
            self.m_output = self.m_audioOutput.start()
            self.m_pullMode = False
            self.m_pullTimer.start(20)
        else:
            self.m_modeButton.setText(self.PUSH_MODE_LABEL)
            self.m_pullMode = True
            self.m_audioOutput.start(self.m_generator)

        self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)

    def toggleSuspendResume(self):
        if self.m_audioOutput.state() == QAudio.SuspendedState:
            qWarning("status: Suspended, resume()")
            self.m_audioOutput.resume()
            self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)
        elif self.m_audioOutput.state() == QAudio.ActiveState:
            qWarning("status: Active, suspend()")
            self.m_audioOutput.suspend()
            self.m_suspendResumeButton.setText(self.RESUME_LABEL)
        elif self.m_audioOutput.state() == QAudio.StoppedState:
            qWarning("status: Stopped, resume()")
            self.m_audioOutput.resume()
            self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)
        elif self.m_audioOutput.state() == QAudio.IdleState:
            qWarning("status: IdleState")

    stateMap = {
        QAudio.ActiveState: "ActiveState",
        QAudio.SuspendedState: "SuspendedState",
        QAudio.StoppedState: "StoppedState",
        QAudio.IdleState: "IdleState"}

    def handleStateChanged(self, state):
        qWarning("state = " + self.stateMap.get(state, "Unknown"))
Esempio n. 11
0
    def __init__(self, inference_thread):
        super(Dialog, self).__init__()
        self._btn = QPushButton('Record', self)
        self._label = QLabel('', self)

        layout = QVBoxLayout()
        layout.addWidget(self._btn)
        layout.addWidget(self._label)
        self.setLayout(layout)

        self._btn.clicked.connect(self._btn_clicked)
        self._is_recording = False

        self._inference_thread = inference_thread
        self._inference_thread.finished.connect(
            self._on_transcription_finished)

        audio_format = QAudioFormat()
        audio_format.setCodec('audio/pcm')
        audio_format.setChannelCount(1)
        audio_format.setSampleSize(16)
        audio_format.setSampleRate(16000)
        audio_format.setByteOrder(QAudioFormat.LittleEndian)
        audio_format.setSampleType(QAudioFormat.SignedInt)

        input_device_info = QAudioDeviceInfo.defaultInputDevice()
        if not input_device_info.isFormatSupported(audio_format):
            print('Can\'t record audio in 16kHz 16-bit signed PCM format.')
            exit(1)

        self._audio_input = QAudioInput(audio_format)