我的程序将音乐速度降低了50%,但仅限于一个频道

Ant*_*son 5 python wave

我在python中使用wave库试图将音频速度降低50%.我成功了,但只有在正确的渠道.在左声道中,它是一大堆静态的.

import wave,os,math
r=wave.open(r"C:\Users\A\My Documents\LiClipse Workspace\Audio 
compression\Audio compression\aha.wav","r")
w=wave.open(r"C:\Users\A\My Documents\LiClipse Workspace\Audio 
compression\Audio compression\ahaout.wav","w")
frames=r.readframes(r.getnframes())
newframes=bytearray()
w.setparams(r.getparams())
for i in range(0,len(frames)-1):
    newframes.append(frames[i])
    newframes.append(frames[i])
w.writeframesraw(newframes)
Run Code Online (Sandbox Code Playgroud)

为什么是这样?既然我只是复制和粘贴原始数据,我肯定无法生成静态?编辑:我一直在寻找年龄,我终于找到了一个有用的波形格式资源:http://soundfile.sapp.org/doc/WaveFormat/ 如果我想保留立体声,看起来我需要复制实际样本宽度为4倍.这是因为有两个通道,它们占用4个字节而不是2个.

`import wave
r=wave.open(r"C:\Users\A\My Documents\LiClipse Workspace\Audio 
compression\Audio compression\aha.wav","r")
w=wave.open(r"C:\Users\A\My Documents\LiClipse Workspace\Audio 
compression\Audio compression\ahaout.wav","w")
frames=r.readframes(r.getnframes())
newframes=bytearray()
w.setparams(r.getparams())
w.setframerate(r.getframerate())
print(r.getsampwidth())
for i in range(0,len(frames)-4,4):
    newframes.append(frames[i])
    newframes.append(frames[i+1])
    newframes.append(frames[i+2])
    newframes.append(frames[i+3])
    newframes.append(frames[i])
    newframes.append(frames[i+1])
    newframes.append(frames[i+2])
    newframes.append(frames[i+3])
w.writeframesraw(newframes)`
Run Code Online (Sandbox Code Playgroud)

编辑2:好吧我不知道是什么驱使我这样做但我已经享受它给我的自由了.我选择将wav文件复制到内存中,直接编辑副本,然后将其写入输出文件.我对结果非常满意.我可以导入一个wav,重复一次音频,并将其写入输出文件,仅需0.2秒.使用wav插件,使用我的旧代码将速度降低一半现在只需要9秒而不是30秒以上这里是代码,仍然有点未优化我想但它比它更好.

import struct
import time as t
t.clock()
r=open(r"C:/Users/apier/Documents/LiClipse Workspace/audio editing 
software/main/aha.wav","rb")
w=open(r"C:/Users/apier/Documents/LiClipse Workspace/audio editing 
software/main/output.wav","wb")
rbuff=bytearray(r.read())
def replacebytes(array,bites,stop):
    length=len(bites)
    start=stop-length
    for i in range(start,stop):
        array[i]=bites[i-start]
def write(audio):
    w.write(audio)
def repeat(audio,repeats):
    if(repeats==1):
        return(audio)
    if(repeats==0):
        return(audio[:44])
    replacebytes(audio, struct.pack('<I', struct.unpack('<I',audio[40:44])
[0]*repeats), 44)
    return(audio+(audio[44:len(audio)-58]*(repeats-1)))
def slowhalf(audio):
    buff=bytearray()
    replacebytes(audio, struct.pack('<I', struct.unpack('<I',audio[40:44])
[0]*2), 44)
    for i in range(44,len(audio)-62,4):
        buff.append(audio[i])
        buff.append(audio[i+1])
        buff.append(audio[i+2])
        buff.append(audio[i+3])
        buff.append(audio[i])
        buff.append(audio[i+1])
        buff.append(audio[i+2])
        buff.append(audio[i+3])
    return(audio[:44]+buff)
rbuff=slowhalf(rbuff)
write(rbuff)
print(t.clock())
Run Code Online (Sandbox Code Playgroud)

我很惊讶代码有多小.

Mar*_*som 4

返回的每个元素readframes都是一个字节,即使类型是int。音频样本通常为 2 个字节。通过将每个字节而不是每个整个样本加倍,您会得到噪声。

我不知道为什么一个通道会起作用,根据问题中显示的代码,它应该是所有噪音。

这是部分修复。它仍然混合左右声道,但它会让您了解什么是有效的。

for i in range(0,len(frames)-1,2):
    newframes.append(frames[i])
    newframes.append(frames[i+1])
    newframes.append(frames[i])
    newframes.append(frames[i+1])
Run Code Online (Sandbox Code Playgroud)

编辑:这是应该在立体声下工作的代码。它一次复制 4 个字节,2 个用于左通道,2 个用于右通道,然后再次复制以将它们加倍。这将防止通道数据交错。

for i in range(0, len(frames), 4):
    for _ in range(2):
        for j in range(4):
            newframes.append(frames[i+j])
Run Code Online (Sandbox Code Playgroud)