【问题标题】:Combining wav files programmatically - Python以编程方式组合 wav 文件 - Python
【发布时间】:2021-10-20 11:20:06
【问题描述】:

我希望以各种方式组合 10 个音频样本(格式 - 可能是 wav,但这可以更改为任何格式,因为它们将被预先录制)。

from pydub import AudioSegment
sounds = []
sound1 = AudioSegment.from_wav("Dropbox/PIREAD/1.wav")
sound2 = AudioSegment.from_wav("Dropbox/PIREAD/2.wav")
sound3 = AudioSegment.from_wav("Dropbox/PIREAD/3.wav")
sound4 = AudioSegment.from_wav("Dropbox/PIREAD/4.wav")
sound5 = AudioSegment.from_wav("Dropbox/PIREAD/5.wav")
sound6 = AudioSegment.from_wav("Dropbox/PIREAD/6.wav")
sound7 = AudioSegment.from_wav("Dropbox/PIREAD/7.wav")
sound8 = AudioSegment.from_wav("Dropbox/PIREAD/8.wav")
sound9 = AudioSegment.from_wav("Dropbox/PIREAD/9.wav")
sound0 = AudioSegment.from_wav("Dropbox/PIREAD/0.wav")

sounds=[sound1,sound2,sound3,sound4,sound5,sound6,sound7,sound8,sound9,sound0]

combined_sounds = AudioSegment.empty()

for x in range(10):
    for y in range(10):
        combined_sounds += sounds[y]
    
combined_sounds.export("Dropbox/PIREAD/joinedFile.wav", format="wav")

这实际上是我阅读数字 0-9 并将它们组合成一个整体 wav 文件。

它可以工作 - 但是一旦循环扩展 x=100, x=1000 就会很慢。

问:我怎样才能加快速度?

数字的实际顺序将从文本 $ 中读取 - 例如“354224848179261915075”,恰好是第 100 个斐波那契数。

干杯 格伦

【问题讨论】:

  • 你为什么要做双循环?如果您想要 1-10 然后 1-10 一次又一次地总共 10 次,那么最好稍后重新添加 10 元素段,而不是再次遍历所有 10 个文件。 (区别是:走10^2次或走2*10次)
  • 见下文 - 只是测试速度。噢噢噢!!!在我问之前应该虽然 BigO。

标签: python wav pydub


【解决方案1】:

我相信它很慢,因为当您循环 x 时,您会重复操作(循环 y),这可以在循环 x 之前计算,然后组装。

【讨论】:

  • 嵌套的 for 用于测试。我想要实现的是解析一个字符串 - “num = 123456789”并组装它的口头表示。唯一的问题是这个数字将是 1000 个字符长。
  • 那么 - 可以遍历 num 中的字符并从字典中提取这些 wav 文件吗?然后组装它们。将上车并进行测试。
  • 也许您可以解释一下您要做什么:似乎您正在尝试创建 Fibo 序列的声学表示(整洁的项目!)。我相信如果你尝试低数字,比如序列的前 10 个数字,这个程序应该会很快停止。你的程序从哪一步开始感觉慢了?
  • 正是这个...在不同的口音、不同的语言、不同的性别等中我的 for 循环是生成要测试的数字——我要做的就是将其更改为实际的 Fib 数字—— - 然后只有一个循环来迭代数字。
  • 注意你是如何计算 Fib 序列的,这可能是减慢你的程序的步骤 ;)
【解决方案2】:

我查看了AudioSegment 并找到了可能对您有用的方法,即from_mono_audiosegments,但它仅限于单声道,您需要测试它是否比+= 快​​请比较时间方面的这些选项,即

import time
from pydub import AudioSegment
sounds = []
sound1 = AudioSegment.from_wav("Dropbox/PIREAD/1.wav")
sound2 = AudioSegment.from_wav("Dropbox/PIREAD/2.wav")
sound3 = AudioSegment.from_wav("Dropbox/PIREAD/3.wav")
sound4 = AudioSegment.from_wav("Dropbox/PIREAD/4.wav")
sound5 = AudioSegment.from_wav("Dropbox/PIREAD/5.wav")
sound6 = AudioSegment.from_wav("Dropbox/PIREAD/6.wav")
sound7 = AudioSegment.from_wav("Dropbox/PIREAD/7.wav")
sound8 = AudioSegment.from_wav("Dropbox/PIREAD/8.wav")
sound9 = AudioSegment.from_wav("Dropbox/PIREAD/9.wav")
sound0 = AudioSegment.from_wav("Dropbox/PIREAD/0.wav")

sounds=[sound1,sound2,sound3,sound4,sound5,sound6,sound7,sound8,sound9,sound0]
# option1 using +=
t1 = time.time()
combined_sounds1 = AudioSegment.empty()
for s in sounds
    combined_sounds1 += s
t2 = time.time()
# end of option1
# option2 using from_mono_audiosegments
t3 = time.time()
combined_sounds2 = AudioSegment.from_mono_audiosegments(*sounds)
t4 = time.time()
# end of option2
print('option1 (seconds):',t2-t1)
print('option2 (seconds):',t4-t3)

【讨论】:

  • 很好 - 每一点帮助(我的意思是速度 - 非常感谢帮助) - 会随着进度更新。 TY
【解决方案3】:

感谢以上建议和意见。这是我使用的最终代码并链接到生成的视频(使用 ffmpeg 可视化):

# Program to display the Fibonacci sequence up to n-th term
from pydub import AudioSegment
    
combined_sounds = ""
sound1 = AudioSegment.from_wav("1_2.wav")
sound2 = AudioSegment.from_wav("2_2.wav")
sound3 = AudioSegment.from_wav("3_2.wav")
sound4 = AudioSegment.from_wav("4_2.wav")
sound5 = AudioSegment.from_wav("5_2.wav")
sound6 = AudioSegment.from_wav("6_2.wav")
sound7 = AudioSegment.from_wav("7_2.wav")
sound8 = AudioSegment.from_wav("8_2.wav")
sound9 = AudioSegment.from_wav("9_2.wav")
sound0 = AudioSegment.from_wav("0_2.wav")



nterms=1000
# first two terms
n1, n2 = 0, 1
count = 0
fib = ""

# check if the number of terms is valid
if nterms <= 0:
    print("Please enter a positive integer")
# if there is only one term, return n1
elif nterms == 1:
    print("Fibonacci sequence upto",nterms,":")
    print(n1)
# generate fibonacci sequence
else:
    print("Fibonacci sequence:")
    while count < nterms:
        #print(n1)
        fib += str(n1)
        nth = n1 + n2
       # update values
        n1 = n2
        n2 = nth
        count += 1
        
i=-36
j=0

fibs = [fib[i:i+1000] for i in range(0, len(fib), 1000)]

seg = 0
for a in fibs:
    if seg == 2:
        break
        
    combined_sounds = AudioSegment.empty()
    seg +=1
    for x in a:
        i,j = -36,0
        s = eval("sound"+str(x))    
        s = s.apply_gain_stereo(i,j)
        combined_sounds += s
        i,j = j,i
        

    combined_sounds.export("joinedFile"+str(seg)+".wav", format="wav")

这会将输出拆分为 1000 位 wav 文件。前 1000 个斐波那契项产生近 15Gb 的 wav!

已上传到 YouTube:https://www.youtube.com/watch?v=U7Z_HOGqjlE

谢谢大家。

【讨论】:

  • 我可以自己回复接受的答案吗 - 为我缺乏 SO-fu 道歉
  • 绝对。鼓励自我回答,自我接纳也是如此。
猜你喜欢
  • 1970-01-01
  • 2020-03-05
  • 2014-08-16
  • 1970-01-01
  • 2015-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
相关资源
最近更新 更多