plɹoM ollǝH

ǝldɯᴉs puɐ llɐɯs ʇᴉ dǝǝʞ

PySide2 + librosa + pyaudio + numpy, play audio repeatedly

import librosa
import numpy as np
import pyaudio
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
import sys

class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self._audio = pyaudio.PyAudio()
        self._wave = librosa.load('test.wav', sr=16000, mono=True)
        self._wave_pos = 0
        self._wave_len = len(self._wave[0])
        self._stream = None
        self._auto_replay()

    def _auto_replay(self):
        if self._stream is None or not self._stream.is_active():
            self._wave_pos = 0
            self._stream = self._audio.open(
            format=pyaudio.paFloat32, channels=1, rate=16000, output=True, stream_callback=self._on_streaming)
        QTimer.singleShot(1000, self._auto_replay)

    def _on_streaming(self, _data, frames, _time, status_flags):
        left = self._wave_pos
        right = min(self._wave_pos + frames, self._wave_len - 1)
        data = np.ndarray.tobytes(self._wave[0][left: right])
        self._wave_pos += frames
        if self._wave_pos >= self._wave_len:
            return data, pyaudio.paComplete
        return data, pyaudio.paContinue

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = Widget()
    main.show()
    sys.exit(app.exec_())