Python Forum
playing .wav sound file with sounddevice
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
playing .wav sound file with sounddevice
#1
I have worked out how to play the file and I am using a PyQT5 form i created. Nothing fancy.

So I want to be able to update a status message to state 'Playing' while the .wav file is playing and then when it's finished 'Not Playing'.

The issue I have is that if I remove the actual command to play the file then the label is updated on the form. But as soon as I place the command to play the label is never updated.

my label name is lblstatus

Once the file is selected from a listwidget and i click the play button it will play.

Here is my code, is there something wrong with it?

import sounddevice as sd
import soundfile as sf

    def _buttonplay(self, clicked):
        global filename
        filename = self.lineEditsdir.text() + '/' + self.listWidget.currentItem().text()
        print('Playing:' + filename)
        self.lblstatus.setStyleSheet("QLabel {background-color: rgb(255, 255, 0);color: rgb(0, 170, 0);}")
        self.lblstatus.setText("Playing")
        self.playwav()
        self.lblstatus.setText("Not Playing")
        self.lblstatus.setStyleSheet("QLabel {background-color: rgb(255, 255, 0);color: rgb(255, 0, 0);}")

    def playwav(self):
        data, fs = sf.read(filename,dtype='float32')
        sd.play(data,fs)
        status = sd.wait()
        return
thanks.
SHIFT838
http://shift838.99er.net

Telnet BBS:
fusionbbs.ddns.net:9640
Reply
#2
Check this link on how to play a wav file pyqt5.
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#3
Looked at your link and attempted to implement both method#1 and #3 but I hear no sound whatsoever.

I changed my playwav function below.

def playwav(self):
        filename = self.lineEditsdir.text() + '/' + self.listWidget.currentItem().text()
        sound_file = filename
        sound = PyQt5.QtMultimedia.QSoundEffect()
        sound.setSource(QtCore.QUrl.fromLocalFile(sound_file))
        # sound.setLoopCount(QtMultimedia.QSoundEffect.Infinite)
        sound.setVolume(50)
        sound.play()
SHIFT838
http://shift838.99er.net

Telnet BBS:
fusionbbs.ddns.net:9640
Reply
#4
Parsing through your link again i came up with the below code. The play and stop buttons work as they should.

I want to keep the stop button disabled until I hit play for a file when the file is done playing I want the label to change back to 'not playing' and the stop button to go to disabled state. While the file is playing i want the play button disabled.

If I put the enable to false in the function it immediately stays disabled as it appears that it completely runs through the code.

So in short. I want to be able to play and stop at will but when the buttons are pressed the label changes to playing or not playing while ensuring the stop button stays or moves to the correct state.

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'PC28BITCAS.ui'
#
# Created by: PyQt5 UI code generator 5.15.6
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.

import sys
import os
import time
import glob
import wave
import contextlib
from datetime import timedelta
from os import path
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5 import QtMultimedia as M
from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QFileDialog, QLineEdit

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(10, 10, 781, 551))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(10)
        self.tabWidget.setFont(font)
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.butplay = QtWidgets.QPushButton(self.tab)
        self.butplay.setEnabled(False)
        self.butplay.setGeometry(QtCore.QRect(90, 500, 75, 23))
        self.butplay.setAutoDefault(False)
        self.butplay.setDefault(False)
        self.butplay.setFlat(False)
        self.butplay.setObjectName("butplay")
        self.butstop = QtWidgets.QPushButton(self.tab)
        self.butstop.setEnabled(False)
        self.butstop.setGeometry(QtCore.QRect(260, 500, 75, 23))
        self.butstop.setObjectName("butstop")
        self.butrecord = QtWidgets.QPushButton(self.tab)
        self.butrecord.setGeometry(QtCore.QRect(410, 500, 75, 23))
        self.butrecord.setObjectName("butrecord")
        self.listWidget = QtWidgets.QListWidget(self.tab)
        self.listWidget.setGeometry(QtCore.QRect(10, 110, 411, 361))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(10)
        self.listWidget.setFont(font)
        self.listWidget.setAlternatingRowColors(True)
        self.listWidget.setModelColumn(0)
        self.listWidget.setSelectionRectVisible(True)
        self.listWidget.setObjectName("listWidget")
        self.lineEditsdir = QtWidgets.QLineEdit(self.tab)
        self.lineEditsdir.setEnabled(False)
        self.lineEditsdir.setGeometry(QtCore.QRect(10, 30, 671, 31))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(10)
        self.lineEditsdir.setFont(font)
        self.lineEditsdir.setText("")
        self.lineEditsdir.setObjectName("lineEditsdir")
        self.butbrowse = QtWidgets.QPushButton(self.tab)
        self.butbrowse.setGeometry(QtCore.QRect(690, 30, 75, 31))
        self.butbrowse.setObjectName("butbrowse")
        self.lblcurrentpath = QtWidgets.QLabel(self.tab)
        self.lblcurrentpath.setGeometry(QtCore.QRect(10, 10, 151, 16))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(12)
        self.lblcurrentpath.setFont(font)
        self.lblcurrentpath.setObjectName("lblcurrentpath")
        self.lblcurrentpath_2 = QtWidgets.QLabel(self.tab)
        self.lblcurrentpath_2.setGeometry(QtCore.QRect(460, 120, 41, 16))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(12)
        self.lblcurrentpath_2.setFont(font)
        self.lblcurrentpath_2.setObjectName("lblcurrentpath_2")
        self.lblcurrentpath_3 = QtWidgets.QLabel(self.tab)
        self.lblcurrentpath_3.setGeometry(QtCore.QRect(430, 210, 81, 16))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(12)
        self.lblcurrentpath_3.setFont(font)
        self.lblcurrentpath_3.setObjectName("lblcurrentpath_3")
        self.lineEditselected = QtWidgets.QLineEdit(self.tab)
        self.lineEditselected.setEnabled(False)
        self.lineEditselected.setGeometry(QtCore.QRect(500, 110, 271, 31))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(12)
        self.lineEditselected.setFont(font)
        self.lineEditselected.setObjectName("lineEditselected")
        self.lineEditduration = QtWidgets.QLineEdit(self.tab)
        self.lineEditduration.setEnabled(False)
        self.lineEditduration.setGeometry(QtCore.QRect(500, 200, 271, 31))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(12)
        self.lineEditduration.setFont(font)
        self.lineEditduration.setObjectName("lineEditduration")
        self.lblcurrentpath_4 = QtWidgets.QLabel(self.tab)
        self.lblcurrentpath_4.setGeometry(QtCore.QRect(10, 80, 201, 16))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(12)
        self.lblcurrentpath_4.setFont(font)
        self.lblcurrentpath_4.setObjectName("lblcurrentpath_4")
        self.lblstatus = QtWidgets.QLabel(self.tab)
        self.lblstatus.setGeometry(QtCore.QRect(490, 310, 201, 20))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(16)
        self.lblstatus.setFont(font)
        self.lblstatus.setStyleSheet("")
        self.lblstatus.setFrameShadow(QtWidgets.QFrame.Raised)
        self.lblstatus.setLineWidth(4)
        self.lblstatus.setAlignment(QtCore.Qt.AlignCenter)
        self.lblstatus.setObjectName("lblstatus")
        self.tabWidget.addTab(self.tab, "")
        self.tab_3 = QtWidgets.QWidget()
        self.tab_3.setObjectName("tab_3")
        self.lblsdir = QtWidgets.QLabel(self.tab_3)
        self.lblsdir.setGeometry(QtCore.QRect(30, 30, 231, 16))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(12)
        self.lblsdir.setFont(font)
        self.lblsdir.setObjectName("lblsdir")
        self.qlesourcedir = QtWidgets.QLineEdit(self.tab_3)
        self.qlesourcedir.setGeometry(QtCore.QRect(280, 30, 431, 20))
        font = QtGui.QFont()
        font.setFamily("DAGGERSQUARE")
        font.setPointSize(10)
        self.qlesourcedir.setFont(font)
        self.qlesourcedir.setObjectName("qlesourcedir")
        self.butsdir = QtWidgets.QPushButton(self.tab_3)
        self.butsdir.setGeometry(QtCore.QRect(720, 20, 31, 31))
        self.butsdir.setText("")
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("images/browse-2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.butsdir.setIcon(icon)
        self.butsdir.setIconSize(QtCore.QSize(24, 24))
        self.butsdir.setObjectName("butsdir")
        self.butsavecfg = QtWidgets.QPushButton(self.tab_3)
        self.butsavecfg.setGeometry(QtCore.QRect(650, 412, 91, 91))
        self.butsavecfg.setText("")
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap("images/save-icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.butsavecfg.setIcon(icon1)
        self.butsavecfg.setIconSize(QtCore.QSize(90, 90))
        self.butsavecfg.setObjectName("butsavecfg")
        self.tabWidget.addTab(self.tab_3, "")
        self.tab_4 = QtWidgets.QWidget()
        self.tab_4.setObjectName("tab_4")
        self.label = QtWidgets.QLabel(self.tab_4)
        self.label.setGeometry(QtCore.QRect(80, 40, 611, 401))
        self.label.setText("")
        self.label.setPixmap(QtGui.QPixmap("images/logocassette-medium.png"))
        self.label.setObjectName("label")
        self.tabWidget.addTab(self.tab_4, "")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.butplay.setText(_translate("MainWindow", "Play"))
        self.butstop.setText(_translate("MainWindow", "Stop"))
        self.butrecord.setText(_translate("MainWindow", "Record"))
        self.listWidget.setSortingEnabled(True)
        self.butbrowse.setText(_translate("MainWindow", "Browse"))
        self.lblcurrentpath.setText(_translate("MainWindow", "Current Folder: "))
        self.lblcurrentpath_2.setText(_translate("MainWindow", "File:"))
        self.lblcurrentpath_3.setText(_translate("MainWindow", "Duration:"))
        self.lblcurrentpath_4.setText(_translate("MainWindow", "Select file to load below:"))
        self.lblstatus.setText(_translate("MainWindow", "Not Playing"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Cassete #1"))
        self.lblsdir.setText(_translate("MainWindow", "RAW Wave Source Directory"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Configuration"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("MainWindow", "About"))
        self.butplay.clicked.connect(self.play)
        self.butstop.clicked.connect(self.stop)
        self.butbrowse.clicked.connect(self._buttonbrowse)
        self.listWidget.currentItemChanged.connect(self._fileselected)


    def play(self):

        self.url = QtCore.QUrl.fromLocalFile(self.lineEditsdir.text() + '/' + self.listWidget.currentItem().text())
        self.content = M.QMediaContent(self.url)
        self.player = M.QMediaPlayer()
        self.player.setMedia(self.content)
        self.lblstatus.setStyleSheet("QLabel {background-color: rgb(255, 255, 0);color: rgb(0, 170, 0);}")
        self.lblstatus.setText("Playing")
        self.butstop.setEnabled(True)
        self.player.play()
        self.butstop.setEnabled(False)


    def stop(self):
        self.player.stop()
        self.lblstatus.setText("Not Playing")
        self.lblstatus.setStyleSheet("QLabel {background-color: rgb(255, 255, 0);color: rgb(255, 0, 0);}")

    def playreset(self):
        self.lblstatus.setText("Not Playing")
        self.lblstatus.setStyleSheet("QLabel {background-color: rgb(255, 255, 0);color: rgb(255, 0, 0);}")

    def _buttonbrowse(self, clicked):
        a = 0
        folder = str(QFileDialog.getExistingDirectory(None, "Select Directory"))
        self.lineEditsdir.setText(folder)
        os.chdir(folder)
        self.listWidget.clear()

        for file in glob.glob("*.wav"):
            self.listWidget.insertItem(a, file)

    def _fileselected(self,clicked):
        self.lineEditselected.setText(self.listWidget.currentItem().text())
        self.getwavduration()
        self.butplay.setEnabled(True)


    def getwavduration(self):
        fname = self.listWidget.currentItem().text()
        print(fname)
        with contextlib.closing(wave.open(fname, 'r')) as f:
            frames = f.getnframes()
            rate = f.getframerate()
            duration = frames / float(rate)
            # rounded = int(duration(round))
            duration = round(duration)
            td = timedelta(seconds=duration)
            self.lineEditduration.setText(str(td))

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    ui.lblstatus.setStyleSheet("QLabel {background-color: rgb(255, 255, 0);color: rgb(255, 0, 0);}")
    MainWindow.show()
    sys.exit(app.exec_())
SHIFT838
http://shift838.99er.net

Telnet BBS:
fusionbbs.ddns.net:9640
Reply
#5
These are not physical buttons. Why is there a stop button at all? When you press the play button the play button becomes the top button. And when you press the stop button it reverts back to play. That only leaves reaching the end of the media and switching from Stop to Play automatically.

The media player probably has a signal to notify the program when the media state changed. Maybe position changed? You could update a display to show playout status, and when you reach the end of the media you stop.
Reply
#6
Here is a simple example. replace the old_car.wav file
#! /usr/bin/env python3
import sys
from PyQt5.QtWidgets import (QApplication, QLabel, QVBoxLayout, QWidget, QPushButton)
from PyQt5 import QtCore
from PyQt5.QtMultimedia import(QMediaPlayer, QMediaContent)

def _play():
    player.play()

def state_changed(state):
    if state == QMediaPlayer.PlayingState:
        text = 'Playing'
        color = 'green'
    else:
        text = 'Stopped'
        color = 'red'
    label.setText(f'{text}')
    label.setStyleSheet(f'color:{color}')



if __name__ == '__main__':

    app = QApplication([])
    layout = QVBoxLayout()

    file = 'old_car.wav'
    player = QMediaPlayer()
    sound = QtCore.QUrl.fromLocalFile(file)
    player.setMedia(QMediaContent(sound))

    label = QLabel('Stopped')
    label.setStyleSheet('color:red;')
    btn = QPushButton('Play')
    btn.pressed.connect(_play)

    player.stateChanged.connect(state_changed)

    layout.addWidget(label)
    layout.addWidget(btn)

    widget = QWidget()
    widget.setLayout(layout)

    widget.show()

    sys.exit(app.exec())
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  sounddevice errors ALSA audio marcomac01 0 537 Dec-08-2023, 06:16 PM
Last Post: marcomac01
  .wav file not playing in python .exe program ose 0 2,267 Jun-24-2020, 07:17 PM
Last Post: ose
  Playing mp3 file to specific device treii28 3 3,525 Mar-26-2019, 04:02 PM
Last Post: Larz60+
  SoX Sound Exchange sample code to Rec & Play audio file Fran_3 3 6,570 Sep-11-2017, 09:13 AM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020