- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的目标是使用 Python 在计算机游戏环境中播放满足以下要求的声音。
获取一些输入 WAV 文件并随机将音高改变为原始值的 +/- 50%。使用 PyDub 更改采样率似乎是一种简单的方法。
播放声音。
能够快速调用该函数,使实际播放时长短声音重叠。
我花了超过 24 个工作时间来寻找满足所有这些要求的方法。我以前在 Visual Basic 中完成过此操作,我对 Python 中的难度感到惊讶。
这是我目前所知道的:
PyGame.Mixer 可以同时播放重叠的声音,但它必须以相同的采样率播放它们。似乎没有办法改变音调。
PyDub 可以通过改变采样率来改变音高,但它无法通过基本播放来播放重叠的声音。而且,我必须将输出声音写入文件,然后立即将其加载回来,这感觉很浪费。
WinSound 可以播放 PyDub 的可变采样率声音,但不能并发播放,甚至不能使用线程。
Playsound 包不适用于 python 3.6。
如果我使用线程,PyAudio 可以通过并发播放来播放 PyDub 的可变采样率声音,但是,超过几次就会导致可怕的内存问题,从而很快导致 Python 崩溃。
我的问题:如何在不引起问题的情况下实现上述 3 个目标?
这是迄今为止我得到的最好结果(这是 PyAudio 版本,如果测试超过一次或两次,它会导致崩溃):
from pydub import AudioSegment
from random import random, seed
from time import sleep
import os
import threading
import pyaudio
import wave
def PlayAsyncWithRandPitch(WavPath):
MyBaseFilename = os.path.basename(WavPath)
sound = AudioSegment.from_file(WavPath, format="wav")
seed()
octaves = ((random()-0.50))
print("random octave factor for this sound is: "+str(octaves))
print("current sound frame rate:"+str(sound.frame_rate))
new_sample_rate = int(sound.frame_rate * (2.0 ** octaves))
print("new sound frame rate:"+str(new_sample_rate))
newpitchsound = sound._spawn(sound.raw_data, overrides={'frame_rate': new_sample_rate})
MyTotalNewPath = os.getcwd()+"\\Soundfiles\\Temp\\Mod_"+MyBaseFilename
newpitchsound.export(MyTotalNewPath, format="wav")
SoundThread = threading.Thread(target=PAPlay, args=(MyTotalNewPath,))
SoundThread.start()
#=======================================================================================
#This function is just code for playing a sound in PyAudio
def PAPlay(filename):
CHUNK = 1024
wf = wave.open(filename, 'rb')
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
data = wf.readframes(CHUNK)
while data != '':
stream.write(data)
data = wf.readframes(CHUNK)
stream.stop_stream()
stream.close()
p.terminate()
return
if __name__ == "__main__":
#Example sounds to test if more than one can play at once
PlayAsyncWithRandPitch(os.getcwd()+'\\Soundfiles\\RifleMiss.WAV')
sleep(0.2)
PlayAsyncWithRandPitch(os.getcwd()+'\\Soundfiles\\splash.wav')
sleep(0.2)
PlayAsyncWithRandPitch(os.getcwd()+'\\Soundfiles\\sparkhit1.WAV')
sleep(5.0)
预先感谢您的热心帮助!
最佳答案
多亏了又一个小时的谷歌搜索,我找到了一个关于 PyDub 的晦涩注释来解决这个问题。有一种方法可以实际更改采样率,但“实际上”不能更改采样率。这就是所谓的花栗鼠方法。
https://github.com/jiaaro/pydub/issues/157#issuecomment-252366466
我真的不想假装理解这里的细微差别,但似乎这个概念是“获取声音,设置采样率到某个修改值,然后转换采样率回到传统的 44,100 HZ 值。”
他们给出了这个非常有效的例子:
from pydub import AudioSegment
sound = AudioSegment.from_file('./test/data/test1.mp3')
# shift the pitch up by half an octave (speed will increase proportionally)
octaves = 0.5
new_sample_rate = int(sound.frame_rate * (2.0 ** octaves))
# keep the same samples but tell the computer they ought to be played at the
# new, higher sample rate. This file sounds like a chipmunk but has a weird sample rate.
chipmunk_sound = sound._spawn(sound.raw_data, overrides={'frame_rate': new_sample_rate})
# now we just convert it to a common sample rate (44.1k - standard audio CD) to
# make sure it works in regular audio players. Other than potentially losing audio quality (if
# you set it too low - 44.1k is plenty) this should now noticeable change how the audio sounds.
chipmunk_ready_to_export = chipmunk_sound.set_frame_rate(44100)
这对我来说没有多大意义,但它确实有效:)希望这对那里的人有帮助。
关于python - 异步并发地播放不同音高的声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44895126/
我正在使用 AudioRecord类通过麦克风录制用户的声音。有没有办法改声音或pitch用户在录制过程中。如果没有这样的方法,我该如何调制输出音频文件并更改其pitch并将文件保存回来。我不需要在播
自从我更新到 iOS7 以来,我总是收到正在开发的应用程序的日志消息“无法在此设备上启用 MKMapView 音高”。该设备是 iPhone4。 有人能告诉我这条消息是什么意思以及我如何摆脱它吗? 最
如何使用 c# 改变波形文件中的频率(音调)和振幅,但在波形文件上不是音调 http://www.youtube.com/watch?v=Tumpkl-xJuA 最佳答案 这answer here提供
因为我是一个音乐迷(但只是一个初级编码员),所以我编写了这个脚本来随机选择一些音调(从 MySQL 表中)(以帮助非正式的串行风格作曲。)它给出 9-12 个不重复的音调音高名称分为 3-4 组,每组
正如标题所说,如果我有一个发出声音的音频节点并将其连接到两个单独的 GainNodes,后者又连接到 Audio Context 目标,则声音以双倍速度/双倍音高播放(好像发送了一半样本一个增益节点,
我找到了 this example使用 ActionScript 3 提高 MP3 的音高。我将如何降低音高而不是提高音高? 最佳答案 您多次将相同的样本写入输出缓冲区。 function downO
我是一名优秀的程序员,十分优秀!