Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用numpy和scipy生成波形文件后波形之间的间隙_Python_Numpy_Audio_Scipy_Wave - Fatal编程技术网

Python 使用numpy和scipy生成波形文件后波形之间的间隙

Python 使用numpy和scipy生成波形文件后波形之间的间隙,python,numpy,audio,scipy,wave,Python,Numpy,Audio,Scipy,Wave,我使用Python3.7、numpy和scipy编写了一个程序,该程序使用pi的数字生成波形,并将它们缝合在一起生成一首“歌曲”。我唯一的问题是每个音符之间都有间隙 我曾尝试使用数学函数,使每个音符的波浪淡出,我尝试让音符重叠一点(几乎没有运气弄清楚),还有一些更疯狂的事情,没有做任何事情 将numpy导入为np 从scipy.io.wavfile导入写入 pi=“3.1415926535897932384626433832795202884197169399375105820974944592

我使用Python3.7、numpy和scipy编写了一个程序,该程序使用pi的数字生成波形,并将它们缝合在一起生成一首“歌曲”。我唯一的问题是每个音符之间都有间隙

我曾尝试使用数学函数,使每个音符的波浪淡出,我尝试让音符重叠一点(几乎没有运气弄清楚),还有一些更疯狂的事情,没有做任何事情

将numpy导入为np
从scipy.io.wavfile导入写入
pi=“3.14159265358979323846264338327952028841971693993751058209749445923078164062862089280348253421170679828148086513282306647093844609550582317253594081288”
piarray=列表(pi)
piarray.移除(“.”)
印刷品(露天)
#每秒采样数
sps=44100
#正弦波的频率/节距
频率=440.0
#持续时间
持续时间=0.2
每个样本编号=np.arange(持续时间*sps)
对于范围内的i(len(piarray)):
如果(piarray[i]=“0”):
频率=277.18
埃利夫(皮亚雷[i]=“1”):
频率=311.13
埃利夫(皮亚雷[i]=“2”):
频率=369.99
埃利夫(皮亚雷[i]=“3”):
频率=415.30
埃利夫(皮亚雷[i]=“4”):
频率=466.16
埃利夫(皮亚雷[i]=“5”):
频率=554.37
埃利夫(皮亚雷[i]=“6”):
频率=622.25
埃利夫(皮亚雷[i]=“7”):
频率=739.99
埃利夫(皮亚雷[i]=“8”):
频率=830.61
其他:
频率=932.33
波形=np.sin(2*np.pi*每个样本数*频率*赫兹/秒)*0.3
#这一行上下各有一个音符。
波形_整数=np.int16(波形*32767)
如果(i==0):
waveformc=波形_整数
打印(waveformc)
其他:
waveormc=np.append(waveormc,波形_整数,轴=None)
编写('song.wav',sps,waveormc)
打印(“完成”)

我试着寻找这个特定问题的解决方案,但我没有找到任何相关的地方。我只希望wave文件在每个音符之间没有间隙,但存在间隙。谢谢你能给我的任何帮助

波形之间没有任何间隙。您可以从“收割者”的结果视图中看到,您拥有连续的声音:

每次你开始一个新的音符时,你的波形中都有一个不连续的部分。每次音符更改时,都会听到咔嗒声或砰砰声。由于每个音符的波形都是根据底层数据结构计算的,因此它们在0时都有一个过零,然后很快从0开始彼此产生相位

要解决这个问题,您可以尝试对每个声音进行适当的逐渐淡入/淡出,或者确保跟踪波形的相位,并在音符变化时保持一致

对于衰减函数,您需要沿
(帧-每个样本数)/帧)**n的行添加一些内容,以便在结束时达到零。您可以使用此函数查看它如何影响声音的持续时间和音符之间的感知剪辑

import numpy as np
from scipy.io.wavfile import write

pi = "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848"
piarray = list(pi)
piarray.remove(".")

print(piarray)

# Samples per second
sps = 44100

# Frequency / pitch of the sine wave
freq_hz = 440.0

# Duration
duration_s = 0.2
frames = duration_s * sps # counting how many frames for a note
each_sample_number = np.arange(duration_s * sps)



for i in range(len(piarray)):
    if(piarray[i] == "0"):
        freq_hz = 277.18
    elif(piarray[i] == "1"):
        freq_hz = 311.13
    elif(piarray[i] == "2"):
        freq_hz = 369.99
    elif(piarray[i] == "3"):
        freq_hz = 415.30
    elif(piarray[i] == "4"):
        freq_hz = 466.16
    elif(piarray[i] == "5"):
        freq_hz = 554.37
    elif(piarray[i] == "6"):
        freq_hz = 622.25
    elif(piarray[i] == "7"):
        freq_hz = 739.99
    elif(piarray[i] == "8"):
        freq_hz = 830.61
    else:
        freq_hz = 932.33

    # added fall off feature
    waveform = (((frames - each_sample_number) / frames)**0.5) * np.sin(
                        np.pi+ 2 * np.pi * each_sample_number * freq_hz / sps)*0.3

    #The line above and below this one make an individual note.
    waveform_integers = np.int16(waveform * 32767)

    if(i == 0):
        waveformc = waveform_integers
        print(waveformc)
    else:
        waveformc = np.append(waveformc, waveform_integers, axis=None)

write('song.wav', sps, waveformc)
print("DONE")
您可以在波形上看到当前设置的结果:

我在频率中添加了一个“校正因子”,以确保每个波的振幅为零,并且没有间断。它会稍微改变频率,但不会超过1%。我就是这样做的:

cor_fac = round(each_sample_number[-1] * freq_hz / sps)/(each_sample_number[-1] * freq_hz / sps)
cor_factors.append(cor_fac)
waveform = np.sin(2 * np.pi * each_sample_number * freq_hz / sps * cor_fac)*0.3
我认为它解决了问题

如果频率变化不可接受,您可以尝试更改采样阵列的开始,使其以与上一个完成的波形相同的振幅开始

我会尽量做到这一点,并张贴在这里

让我知道这对你有用

编辑: 不改变声音频率的代码:

import numpy as np
from scipy.io.wavfile import write
import matplotlib.pyplot as plt
import wave
import sys


pi = "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848"
piarray = list(pi)
piarray.remove(".")

print(piarray)

# Samples per second
sps = 44100

# Frequency / pitch of the sine wave
freq_hz = 440.0

# Duration
duration_s = 0.2

last_amp = 0
cor_factors = []
direction_down = False

for i in range(len(piarray)):
    if(piarray[i] == "0"):
        freq_hz = 277.18
    elif(piarray[i] == "1"):
        freq_hz = 311.13
    elif(piarray[i] == "2"):
        freq_hz = 369.99
    elif(piarray[i] == "3"):
        freq_hz = 415.30
    elif(piarray[i] == "4"):
        freq_hz = 466.16
    elif(piarray[i] == "5"):
        freq_hz = 554.37
    elif(piarray[i] == "6"):
        freq_hz = 622.25
    elif(piarray[i] == "7"):
        freq_hz = 739.99
    elif(piarray[i] == "8"):
        freq_hz = 830.61
    else:
        freq_hz = 932.33

    # cor_fac = round(each_sample_number[-1] * freq_hz / sps)/(each_sample_number[-1] * freq_hz / sps)
    # cor_factors.append(cor_fac)

    start = np.arcsin(last_amp/0.3)    
    if direction_down:
        start = np.pi - start   
    start = start/(2 * np.pi * freq_hz / sps)

    each_sample_number = np.arange(start, start + duration_s * sps)
    waveform = np.sin(2 * np.pi * each_sample_number * freq_hz / sps)*0.3
    print(waveform[0]-last_amp)
    last_amp = waveform[-1]
    direction_down = waveform[-1]<waveform[-2]
    #The line above and below this one make an individual note.
    waveform_integers = np.int16(waveform * 32767)

    if(i == 0):
        waveformc = waveform_integers
        print(waveformc)
    else:
        waveformc = np.append(waveformc, waveform_integers, axis=None)

write('song_2.wav', sps, waveformc)
print("DONE")
将numpy导入为np
从scipy.io.wavfile导入写入
将matplotlib.pyplot作为plt导入
输入波
导入系统
pi=“3.14159265358979323846264338327952028841971693993751058209749445923078164062862089280348253421170679828148086513282306647093844609550582317253594081288”
piarray=列表(pi)
piarray.移除(“.”)
印刷品(露天)
#每秒采样数
sps=44100
#正弦波的频率/节距
频率=440.0
#持续时间
持续时间=0.2
最后_amp=0
相关系数=[]
方向向下=错误
对于范围内的i(len(piarray)):
如果(piarray[i]=“0”):
频率=277.18
埃利夫(皮亚雷[i]=“1”):
频率=311.13
埃利夫(皮亚雷[i]=“2”):
频率=369.99
埃利夫(皮亚雷[i]=“3”):
频率=415.30
埃利夫(皮亚雷[i]=“4”):
频率=466.16
埃利夫(皮亚雷[i]=“5”):
频率=554.37
埃利夫(皮亚雷[i]=“6”):
频率=622.25
埃利夫(皮亚雷[i]=“7”):
频率=739.99
埃利夫(皮亚雷[i]=“8”):
频率=830.61
其他:
频率=932.33
#cor_fac=四舍五入(每个样本编号[-1]*频率/sps)/(每个样本编号[-1]*频率/sps)
#相关因素附加(相关因素)
开始=np.Arcin(最后一次放大/0.3)
如果方向向下:
开始=np.pi-开始
开始=开始/(2*np.pi*freq_hz/sps)
每个样本编号=np.arange(开始,开始+持续时间*sps)
波形=np.sin(2*np.pi*每个样本数*频率*赫兹/秒)*0.3
打印(波形[0]-最后一个放大器)
最后一次_amp=波形[-1]

方向向下=波形[-1]如我所说,我已经尝试使其淡入/淡出。我试图使用数学函数sin(x)/x使其淡出,但它没有解决问题。你知道更好的方法吗?我寻找方法来模拟衰减的正弦函数,但是sin(x)/x是我发现的唯一真正有用的方法。我还尝试了sin(x)/(x^1/2),但它也不起作用。我为您添加了一个淡出方法,这将为您尝试其他函数提供一个良好的起点。@Spencer1O1我使用淡出方法进行了更新。关键的是,当每个音符到达它的末端时,它实际上应该达到零,否则它将无法解决