简体   繁体   English

如何在 python sounddevice 中使用 OutputStream 播放声音文件?

[英]How to play a sound file using an OutputStream in python sounddevice?

The goal is to play two sound files simultaneously so the sounddevice.play function is not an option.目标是同时播放两个声音文件,因此sounddevice.play function 不是一个选项。 I believe that I should make an OutputStream for each file.我相信我应该为每个文件制作一个OutputStream Right now I'm stuck in trying to get one OutputStream to work.现在我一直在试图让一个OutputStream工作。 Please help.请帮忙。

My code so far:到目前为止我的代码:

import soundfile as sf
import sounddevice as sd

data, fs = sf.read('sound_file.wav', dtype='float32')

def callback(outdata, frames, time, status):
    outdata[:] = data

with sd.OutputStream(callback=callback):
               pass

Edit: switched to RawOutputStream编辑:切换到RawOutputStream

import soundfile as sf
import sounddevice as sd

wf = sf.SoundFile('sound_file.wav')

def callback(outdata, frames, time, status):
    data = wf.buffer_read(frames, dtype='float32')
    if len(data) <= 0:
        raise sd.CallbackAbort
    if len(outdata) > len(data):
        raise sd.CallbackAbort #wrong obviously
    outdata[:] = data

with sd.RawOutputStream(channels=wf.channels,
                        callback=callback) as stream:
    while stream.active:
        continue

If the sample rates are similar, you could just add your two data arrays together:如果采样率相似,您可以将两个数据 arrays 加在一起:

import numpy as np
import soundfile as sf
import sounddevice as sd

data_1, fs_1 = sf.read('sound_file_1.wav', dtype='float32')
data_2, fs_2 = sf.read('sound_file_2.wav', dtype='float32')

if len(data_1) > len(data_2):
    data = data_1 + np.pad(data_2, (0, len(data_1) - len(data_2)))
else:
    data = np.pad(data_1, (0, len(data_2) - len(data_1))) + data_2

# determine fs from a combination of fs_1 and fs_2 of your choosing, like
fs = min(fs_1, fs_2)

sd.play(data, fs)
import soundfile as sf
import sounddevice as sd
import threading

def _play(sound):
    event =threading.Event()

    def callback(outdata, frames, time, status):
        data = wf.buffer_read(frames, dtype='float32')
        if len(outdata) > len(data):
            outdata[:len(data)] = data
            outdata[len(data):] = b'\x00' * (len(outdata) - len(data))
            raise sd.CallbackStop
        else:
            outdata[:] = data

    with sf.SoundFile(sound) as wf:
        stream = sd.RawOutputStream(samplerate=wf.samplerate,
                                    channels=wf.channels,
                                    callback=callback,
                                    blocksize=1024,
                                    finished_callback=event.set)
        with stream:
            event.wait()

def _playsound(sound):
    new_thread = threading.Thread(target=_play, args=(sound,))
    new_thread.start()

_playsound('sounds_file.wav')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM