예제 #1
0
class AudioTest(QMainWindow):

    def __init__(self, filename=None):
        QMainWindow.__init__(self)
        self.pullTimer = QTimer(self)

        # Owned by layout
        self.modeButton = None
        self.suspendResumeButton = None
        self.deviceBox = None

        self.device = QAudioDeviceInfo.defaultOutputDevice()
        self.generator = None
        self.audioOutput = None
        self.output = None
        self.fmt = QAudioFormat()
        self.pullMode = False
        self.buf = QByteArray(BUFFER_SIZE, 0)
        self.dump = filename

        self.initializeWindow()
        self.initializeAudio()

    def initializeWindow(self):
        window = QWidget()
        layout = QVBoxLayout()

        self.deviceBox = QComboBox(self)
        for info in QAudioDeviceInfo.availableDevices(QAudio.AudioOutput):
            self.deviceBox.addItem(info.deviceName(), info)

        self.deviceBox.activated[int].connect(self.deviceChanged)
        layout.addWidget(self.deviceBox)

        self.modeButton = QPushButton(self)
        self.modeButton.setText(PUSH_MODE_LABEL)
        self.modeButton.clicked.connect(self.toggleMode)
        layout.addWidget(self.modeButton)

        self.suspendResumeButton = QPushButton(self)
        self.suspendResumeButton.setText(SUSPEND_LABEL)
        self.suspendResumeButton.clicked.connect(self.toggleSuspendResume)
        layout.addWidget(self.suspendResumeButton)

        window.setLayout(layout)
        self.setCentralWidget(window)
        window.show()

    def initializeAudio(self):
        self.pullTimer.timeout.connect(self.pullTimerExpired)

        self.pullMode = True

        self.fmt.setFrequency(DATA_FREQUENCY_HZ)
        self.fmt.setChannels(1)
        self.fmt.setSampleSize(16)
        self.fmt.setCodec('audio/pcm')
        self.fmt.setByteOrder(QAudioFormat.LittleEndian)
        self.fmt.setSampleType(QAudioFormat.SignedInt)

        info = QAudioDeviceInfo(QAudioDeviceInfo.defaultOutputDevice())
        if not info.isFormatSupported(self.fmt):
            print 'Default format not supported - trying to use nearest'
            self.fmt = info.nearestFormat(self.fmt)

        self.generator = Generator(self.fmt, DURATION_SECONDS * 1000000,
                                   TONE_FREQUENCY_HZ, self, self.dump)

        self.createAudioOutput()

    def createAudioOutput(self):
        self.audioOutput = QAudioOutput(self.device, self.fmt, self)
        self.audioOutput.notify.connect(self.notified)
        self.audioOutput.stateChanged.connect(self.stateChanged)
        self.generator.start()
        self.audioOutput.start(self.generator)

    # Slots
    def notified(self):
        print 'Bytes free %d, elapsed usecs %d, processed usecs %d' % (
                self.audioOutput.bytesFree(),
                self.audioOutput.elapsedUSecs(),
                self.audioOutput.processedUSecs())

    def pullTimerExpired(self):
        if self.audioOutput.state() != QAudio.StoppedState:
            chunks = self.audioOutput.bytesFree() / self.audioOutput.periodSize()
            while chunks:
                data = self.generator.read(self.audioOutput.periodSize())
                self.output.write(data)
                if len(data) != self.audioOutput.periodSize():
                    break
                chunks -= 1

    def toggleMode(self):
        self.pullTimer.stop()
        self.audioOutput.stop()

        if self.pullMode:
            self.modeButton.setText(PULL_MODE_LABEL)
            self.output = self.audioOutput.start()
            self.pullMode = False
            self.pullTimer.start(5)
        else:
            self.modeButton.setText(PUSH_MODE_LABEL)
            self.pullMode = True
            self.audioOutput.start(self.generator)

        self.suspendResumeButton.setText(SUSPEND_LABEL)

    def toggleSuspendResume(self):
        if self.audioOutput.state() == QAudio.SuspendedState:
            print 'Status: Suspended, resuming'
            self.audioOutput.resume()
            self.suspendResumeButton.setText(SUSPEND_LABEL)
        elif self.audioOutput.state() == QAudio.ActiveState:
            print 'Status: Active, suspending'
            self.audioOutput.suspend()
            self.suspendResumeButton.setText(RESUME_LABEL)
        elif self.audioOutput.state() == QAudio.StoppedState:
            print 'Status: Stopped, resuming'
            self.audioOutput.resume()
            self.suspendResumeButton.setText(SUSPEND_LABEL)
        elif self.audioOutput.state() == QAudio.IdleState:
            print 'Status: Idle'

    def stateChanged(self, state):
        print 'State changed: ', state

    def deviceChanged(self, index):
        self.pullTimer.stop()
        self.generator.stop()
        self.audioOutput.stop()
        self.audioOutput.disconnect(self)
        self.device = self.deviceBox.itemData(index)
        self.createAudioOutput()
예제 #2
0
class TonePlayer(QObject):

    changed = Signal()

    def getStateLabel(self):
        print "Getting"
        return self._label

    def setStateLabel(self, value):
        print "Setting", value
        self._label = value
        self.changed.emit()

    stateLabel = Property(str, getStateLabel, setStateLabel, notify=changed)

    def __init__(self, devices=None, filename=None, parent=None):
        QObject.__init__(self, parent)

        self.pullTimer = QTimer(self)
        self.buf = QByteArray()
        self.devices = devices
        self.device = QAudioDeviceInfo.defaultOutputDevice()
        self.generator = None
        self.audioOutput = None
        self.output = None
        self.fmt = QAudioFormat()
        self.pullMode = False
        self.dump = filename
        self._label = SUSPEND_LABEL

        self.initializeAudio()

    def initializeAudio(self):
        self.pullTimer.timeout.connect(self.pullTimerExpired)

        self.pullMode = True

        self.fmt.setFrequency(DATA_FREQUENCY_HZ)
        self.fmt.setChannels(1)
        self.fmt.setSampleSize(16)
        self.fmt.setCodec('audio/pcm')
        self.fmt.setByteOrder(QAudioFormat.LittleEndian)
        self.fmt.setSampleType(QAudioFormat.SignedInt)

        info = QAudioDeviceInfo(QAudioDeviceInfo.defaultOutputDevice())
        if not info.isFormatSupported(self.fmt):
            print 'Default format not supported - trying to use nearest'
            self.fmt = info.nearestFormat(self.fmt)

        self.generator = Generator(self.fmt, DURATION_SECONDS * 1000000,
                                   TONE_FREQUENCY_HZ, self, self.dump)

        self.createAudioOutput()

    def createAudioOutput(self):
        self.audioOutput = QAudioOutput(self.device, self.fmt, self)
        self.audioOutput.notify.connect(self.notified)
        self.audioOutput.stateChanged.connect(self.stateChanged)
        self.generator.start()
        self.audioOutput.start(self.generator)

    @Slot()
    def toggleSuspendResume(self):
        if self.audioOutput.state() == QAudio.SuspendedState:
            print 'Status: Suspended, resuming'
            self.audioOutput.resume()
            self.stateLabel = SUSPEND_LABEL
        elif self.audioOutput.state() == QAudio.ActiveState:
            print 'Status: Active, suspending'
            self.audioOutput.suspend()
            self.stateLabel = RESUME_LABEL
        elif self.audioOutput.state() == QAudio.StoppedState:
            print 'Status: Stopped, resuming'
            self.audioOutput.resume()
            self.stateLabel = SUSPEND_LABEL
        elif self.audioOutput.state() == QAudio.IdleState:
            print 'Status: Idle'

    playbackResumed = Signal()

    @Slot()
    def toggleMode(self):
        self.pullTimer.stop()
        self.audioOutput.stop()

        if self.pullMode:
            print "Enabling push mode"
            self.output = self.audioOutput.start()
            self.pullMode = False
            self.pullTimer.start(5)
        else:
            print "Enabling pull mode"
            self.pullMode = True
            self.audioOutput.start(self.generator)
        self.playbackResumed.emit()

    @Slot(int)
    def deviceChanged(self, index):
        print "Device changed: index:", index
        print "Selected device name: ", self.devices[index].deviceName()
        self.pullTimer.stop()
        self.generator.stop()
        self.audioOutput.stop()
        self.audioOutput.disconnect(self)
        self.device = self.devices[index]
        self.createAudioOutput()

    def stateChanged(self, state):
        print 'State changed: ', state

    def notified(self):
        print 'Bytes free %d, elapsed usecs %d, processed usecs %d' % (
            self.audioOutput.bytesFree(), self.audioOutput.elapsedUSecs(),
            self.audioOutput.processedUSecs())

    def pullTimerExpired(self):
        if self.audioOutput.state() != QAudio.StoppedState:
            chunks = self.audioOutput.bytesFree(
            ) / self.audioOutput.periodSize()
            while chunks:
                data = self.generator.read(self.audioOutput.periodSize())
                self.output.write(data)
                if len(data) != self.audioOutput.periodSize():
                    break
                chunks -= 1
예제 #3
0
class TonePlayer(QObject):

    changed = Signal()

    def getStateLabel(self):
        print "Getting"
        return self._label

    def setStateLabel(self, value):
        print "Setting", value
        self._label = value
        self.changed.emit()

    stateLabel = Property(str, getStateLabel, setStateLabel, notify=changed)

    def __init__(self, devices=None, filename=None, parent=None):
        QObject.__init__(self, parent)

        self.pullTimer = QTimer(self)
        self.buf = QByteArray()
        self.devices = devices
        self.device = QAudioDeviceInfo.defaultOutputDevice()
        self.generator = None
        self.audioOutput = None
        self.output = None
        self.fmt = QAudioFormat()
        self.pullMode = False
        self.dump = filename
        self._label = SUSPEND_LABEL

        self.initializeAudio()

    def initializeAudio(self):
        self.pullTimer.timeout.connect(self.pullTimerExpired)

        self.pullMode = True

        self.fmt.setFrequency(DATA_FREQUENCY_HZ)
        self.fmt.setChannels(1)
        self.fmt.setSampleSize(16)
        self.fmt.setCodec("audio/pcm")
        self.fmt.setByteOrder(QAudioFormat.LittleEndian)
        self.fmt.setSampleType(QAudioFormat.SignedInt)

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

        self.generator = Generator(self.fmt, DURATION_SECONDS * 1000000, TONE_FREQUENCY_HZ, self, self.dump)

        self.createAudioOutput()

    def createAudioOutput(self):
        self.audioOutput = QAudioOutput(self.device, self.fmt, self)
        self.audioOutput.notify.connect(self.notified)
        self.audioOutput.stateChanged.connect(self.stateChanged)
        self.generator.start()
        self.audioOutput.start(self.generator)

    @Slot()
    def toggleSuspendResume(self):
        if self.audioOutput.state() == QAudio.SuspendedState:
            print "Status: Suspended, resuming"
            self.audioOutput.resume()
            self.stateLabel = SUSPEND_LABEL
        elif self.audioOutput.state() == QAudio.ActiveState:
            print "Status: Active, suspending"
            self.audioOutput.suspend()
            self.stateLabel = RESUME_LABEL
        elif self.audioOutput.state() == QAudio.StoppedState:
            print "Status: Stopped, resuming"
            self.audioOutput.resume()
            self.stateLabel = SUSPEND_LABEL
        elif self.audioOutput.state() == QAudio.IdleState:
            print "Status: Idle"

    playbackResumed = Signal()

    @Slot()
    def toggleMode(self):
        self.pullTimer.stop()
        self.audioOutput.stop()

        if self.pullMode:
            print "Enabling push mode"
            self.output = self.audioOutput.start()
            self.pullMode = False
            self.pullTimer.start(5)
        else:
            print "Enabling pull mode"
            self.pullMode = True
            self.audioOutput.start(self.generator)
        self.playbackResumed.emit()

    @Slot(int)
    def deviceChanged(self, index):
        print "Device changed: index:", index
        print "Selected device name: ", self.devices[index].deviceName()
        self.pullTimer.stop()
        self.generator.stop()
        self.audioOutput.stop()
        self.audioOutput.disconnect(self)
        self.device = self.devices[index]
        self.createAudioOutput()

    def stateChanged(self, state):
        print "State changed: ", state

    def notified(self):
        print "Bytes free %d, elapsed usecs %d, processed usecs %d" % (
            self.audioOutput.bytesFree(),
            self.audioOutput.elapsedUSecs(),
            self.audioOutput.processedUSecs(),
        )

    def pullTimerExpired(self):
        if self.audioOutput.state() != QAudio.StoppedState:
            chunks = self.audioOutput.bytesFree() / self.audioOutput.periodSize()
            while chunks:
                data = self.generator.read(self.audioOutput.periodSize())
                self.output.write(data)
                if len(data) != self.audioOutput.periodSize():
                    break
                chunks -= 1