Simultaneous playback of several sounds in python

I was looking for a way to play sounds from a list of samples, and I found several modules that can do this.

I use the AudioLazy module to play sound using the following script:

from audiolazy import AudioIO

sound = Somelist
with AudioIO(True) as player:
  player.play(sound, rate=44100)

The problem with this code is that it stops the entire application until the sound stops playing, and I cannot play several sounds at the same time.

My program is interactive, so I want to be able to play several sounds at once. Therefore, for example, I can run this script, which will play a sound in 5 seconds, and then in the second 2 I can play a 5 second sound.

And I don’t want the whole program to stop until the sound has finished.

+4
source share
3 answers

I suggest using Pyaudio to do this.

import pyaudio 
import wave
sound1 = wave.open("/path/to/sound1", 'rb')
sound2 = wave.open("/path/to/sound2", 'rb')

def callback(in_data, frame_count, time_info, status):
    data1 = sound1.readframes(frame_count)
    data2 = sound2.readframes(frame_count)
    decodeddata1 = numpy.fromstring(data1, numpy.int16)
    decodeddata2 = numpy.fromstring(data2, numpy.int16)
    newdata = (decodeddata1 * 0.5 + decodeddata2* 0.5).astype(numpy.int16)
    return (result.tostring(), pyaudio.paContinue)
+2
source

Here is a simpler solution using pydub .

Using overlaythe module function AudioSegment, you can easily superimposeadd multiple audio to each other.

Here is the working code for combining the three audio files. Using the same concept, you can combine multiple audio with each other.

Read more about the overlayfunction here.

pydub also supports multiple audio formats.

from pydub import AudioSegment
from pydub.playback import play

audio1 = AudioSegment.from_file("chunk1.wav") #your first audio file
audio2 = AudioSegment.from_file("chunk2.wav") #your second audio file
audio3 = AudioSegment.from_file("chunk3.wav") #your third audio file

mixed = audio1.overlay(audio2)          #combine , superimpose audio files
mixed1  = mixed.overlay(audio3)          #Further combine , superimpose audio files
#If you need to save mixed file
mixed1.export("mixed.wav", format='wav') #export mixed  audio file
play(mixed1)                             #play mixed audio file

.
44 sound.wav

.
dtype int16
/, . wav test.txt

import numpy as np
from scipy.io.wavfile import read
from pydub import AudioSegment
from pydub.playback import play
import wave, struct, math


#Create 44KHz signal and save to 'sound.wav'
sampleRate = 44100.0 # hertz
duration = 1.0       # seconds
frequency = 440.0    # hertz

wavef = wave.open('sound.wav','w')
wavef.setnchannels(1) # mono
wavef.setsampwidth(2) 
wavef.setframerate(sampleRate)

for i in range(int(duration * sampleRate)):
    value = int(32767.0*math.cos(frequency*math.pi*float(i)/float(sampleRate)))
    data = struct.pack('<h', value)
    wavef.writeframesraw( data )

wavef.writeframes('')
wavef.close()

#Read wave file and save signal to text file
rate, signal = read("sound.wav")

np.savetxt('test.txt', signal, delimiter=',')   # X is an array


#load wav data from text file
wavedata1 = np.loadtxt("test.txt", comments="#", delimiter=",", unpack=False, dtype=np.int16)

#Create variation of signal
wavedata2 = np.loadtxt("test.txt", comments="#", delimiter=",", unpack=False, dtype=np.int32)

#Create variation of signal
wavedata3 = np.loadtxt("test.txt", comments="#", delimiter=",", unpack=False, dtype=np.float16)

#create first audio segment
audio_segment1 = AudioSegment( 
    wavedata1.tobytes(), 
    frame_rate=rate,
    sample_width=2, 
    channels=1
)

#create second audio segment
audio_segment2 = AudioSegment( 
    wavedata2.tobytes(), 
    frame_rate=rate,
    sample_width=2, 
    channels=1
)

#create third audio segment
audio_segment3 = AudioSegment( 
    wavedata3.tobytes(), 
    frame_rate=rate,
    sample_width=2, 
    channels=1
)

# Play audio (requires ffplay, or pyaudio):
play(audio_segment1)
play(audio_segment2)
play(audio_segment3)

#Mix three audio segments
mixed1 = audio_segment1.overlay(audio_segment2)          #combine , superimpose audio files
mixed2  = mixed1.overlay(audio_segment3)          #Further combine , superimpose audio files
#If you need to save mixed file
mixed2.export("mixed.wav", format='wav') #export mixed  audio file
play(mixed2)                             #play mixed audio file
+2

Using multiple threads will solve your problem:

import threading
from audiolazy import AudioIO

sound = Somelist
with AudioIO(True) as player:
  t = threading.Thread(target=player.play, args=(sound,), kwargs={'rate':44100})
  t.start()
+1
source

Source: https://habr.com/ru/post/1653480/


All Articles