Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.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 为什么我的输出会忽略其他样本,为什么频率是预期值的一半?_Python_Python 3.x_Wav_Waveform - Fatal编程技术网

Python 为什么我的输出会忽略其他样本,为什么频率是预期值的一半?

Python 为什么我的输出会忽略其他样本,为什么频率是预期值的一半?,python,python-3.x,wav,waveform,Python,Python 3.x,Wav,Waveform,我在玩弄,我遇到了两个我无法解决的问题 每隔一个样本的振幅为0。理想的行为是有一个连续的正弦波 产生的频率似乎是期望频率的一半。从数学上看,我不明白为什么。我知道如何修理它。我就是搞不懂原因。在我看来,将频率乘以2π,而不是4π,对我来说是有意义的 from functools import partial, wraps from math import pi, sin import struct import wave class Wave: def __init__(self, f

我在玩弄,我遇到了两个我无法解决的问题

  • 每隔一个样本的振幅为0。理想的行为是有一个连续的正弦波

  • 产生的频率似乎是期望频率的一半。从数学上看,我不明白为什么。我知道如何修理它。我就是搞不懂原因。在我看来,将频率乘以2π,而不是4π,对我来说是有意义的

    from functools import partial, wraps
    from math import pi, sin
    import struct
    import wave
    
    class Wave:
        def __init__(self, frequency, amplitude=1.0, phase_shift=0.0, vertical_translation=0.0):
            self.frequency = frequency
            self.amplitude = amplitude
            self.phase_shift = phase_shift
            self.vertical_translation = vertical_translation
    
        def __call__(self, time):
            try:
                amplitude = self.amplitude(time)
            except TypeError:
                amplitude = self.amplitude
    
            try:
                frequency = self.frequency(time)
            except TypeError:
                frequency = self.frequency
    
            try:
                phase_shift = self.phase_shift(time)
            except TypeError:
                phase_shift = self.phase_shift
    
            try:
                vertical_translation = self.vertical_translation(time)
            except TypeError:
                vertical_translation = self.vertical_translation
    
            return amplitude * sin(2 * pi * frequency * time + phase_shift) + vertical_translation
    
    if __name__ == '__main__':
        SAMPLE_RATE = 96000
        NUMBER_OF_CHANNELS = 1
        SAMPLE_WIDTH = 4
        MAX_AMPLITUDE = 2 ** (8 * SAMPLE_WIDTH - 1)
    
        with wave.open('output.wav', 'w') as output:
            output.setsampwidth(SAMPLE_WIDTH)
            output.setnchannels(NUMBER_OF_CHANNELS)
            output.setframerate(SAMPLE_RATE)
            output.setcomptype('NONE', 'Uncompressed')
    
            a440 = Wave(440)
    
            for time in range(SAMPLE_RATE // a440.frequency):
                sample = MAX_AMPLITUDE * a440(time / SAMPLE_RATE)
                output.writeframes(struct.pack('l', round(sample)))
    

  • 如果您有任何见解,我将不胜感激。

    我无法复制您的问题。运行代码后,我得到了一个理想的正弦波,其长度为预期长度(1/440Hz)≈ 0.0023s)在Audacity中检查.wav时:


    我有一点要告诉你,你不能简单地把从
    sin*MAX_振幅
    中得到的东西取整。你必须向负无穷大方向截断。这是因为(比如)8位样本从-128到127,而不是从-128到128。

    有趣。当我将格式从
    'l'
    更改为
    'd'
    时,我将获得您的输出。显然,我的机器上的长整数是8字节,而您的机器必须使用4字节宽的长整数。好吧,开枪。平台无关代码就这么多了。@TylerCrompton没有意义,
    d
    是双重格式。*耸耸肩*我可能在尝试
    'I'
    时看到了结果。无论如何,我通过将表单更改为
    '{}s'.format(SAMPLE\u WIDTH)
    并将要打包的值更改为
    SAMPLE.to\u bytes(SAMPLE\u WIDTH,'little',signed=True)
    来修复它。此外,我不能仅使用
    地板
    进行取整,因为样本可能完全等于
    最大振幅
    。这是因为当使用二的补码时,可能有奇数个负值和偶数个正值。因此,我使用了
    floor
    并将所有值剪切到允许范围之外。谢谢