我在 IronPython 中使用 NAudio 来混合多个音频流以创建环境音频。这对于某些曲目来说效果相当好,但对于其他一些曲目(风,雨),它可能会在循环播放时出现不和谐的停止/开始。
因为我最初不是 100% 确定如何在 python 中实现 LoopStream 类示例,所以我开始只是在十分之一秒或更短的时间内进行位置检查。我知道为什么我在那里有差距。从那以后,我能够弄清楚如何在 python 中重新创建 LoopStream,并且它可以工作,但我仍然像以前一样在播放方面存在差距。我现在正试图将轨道的结尾交叉淡入到同一轨道的开头,当我这样做时,音频会完全出现故障。
这是代码:
class LoopStream(WaveStream):
def __init__(self,WaveStream,AudioStream):
self.wavestream = WaveStream
self.audiostream = AudioStream
def get_WaveFormat(self):
return self.wavestream.WaveFormat
def get_Length(self):
return self.wavestream.Length
def get_Position(self):
return self.wavestream.Position
def HasData(count):
return True
def Read(self,buf,offset,count):
read = 0
while(read < count):
required = count - read
#print(str(self.audiostream.get_chan_id()) + " reading @ " + str(self.wavestream.Position) + "/" + str(self.wavestream.Length))
pos = self.wavestream.Position
readthistime = self.wavestream.Read(buf,offset+read,required)
if pos == 0:
self.startbuf = buf
if readthistime < required:
self.wavestream.Position = 0
#print(len(buf))
#buf = buf+self.startbuf
print(len(buf))
buf = FadeOut(self,buf,offset,readthistime) + FadeIn(self,self.startbuf,0,required)
print(len(buf))
readthistime+=required
print(str(self.audiostream.get_chan_id()) + " restarting1")
elif self.wavestream.Position + required > self.wavestream.Length:
#read += readthistime
#readthistime = self.wavestream.Read(buf,self.wavestream.Position,required)
#print(str(self.audiostream.get_chan_id()) + " restarting2")
pass
if self.wavestream.Position >= self.wavestream.Length:
self.wavestream.Position = 0
buf = buf + self.startbuf
print(str(self.audiostream.get_chan_id()) + " restarting3")
read += readthistime
return read
def FadeOut(self,buf,offset,count):
sample = 0
maxfadesamples = int((self.wavestream.WaveFormat.SampleRate * 75) / 1000)
fadesamples = 0
while sample < count:
multiplier = 1.0 - (fadesamples / maxfadesamples)
for i in range(0,self.wavestream.WaveFormat.Channels):
buf[offset+sample] *= multiplier
sample+=1
fadesamples+=1
if fadesamples > maxfadesamples:
for j in range(0,self.wavestream.WaveFormat.Channels):
while sample < count:
buf[offset+sample] = 0
sample+=1
def FadeOut(self,buf,offset,count):
sample = 0
maxfadesamples = int((self.wavestream.WaveFormat.SampleRate * 75) / 1000)
fadesamples = 0
while sample < count:
multiplier = (fadesamples / maxfadesamples)
for i in range(0,self.wavestream.WaveFormat.Channels):
buf[offset+sample] *= multiplier
sample+=1
fadesamples+=1