gpt4 book ai didi

python - 似乎无法在原始 Python 中编写两个 channel Wave 文件(无 Wave 模块)

转载 作者:行者123 更新时间:2023-12-03 00:12:45 25 4
gpt4 key购买 nike

我正在尝试学习一些有关音频编程的知识,因此我决定看看是否可以弄清楚如何生成正弦波并将其写入 .wav 文件。来自引用 here ,我认为每个 channel 只是在文件末尾的数据 block 中交错。但是,我生成的 wav 文件似乎只在左声道中播放。我还将我的输出与真正的 440hz A 进行了比较,发现它比预期的低一个 Octave 。

我想象正在发生的是,我用来收听文件的程序将数据解释为单个 channel ,并且由于每个样本都被复制一次,因此以预期频率的 1/2 播放波形。

我知道有一个 Python 模块可以帮助编写 wav 文件,但这是一个教育项目,我正在尝试学习编写二进制文件和 wav 文件格式。

为什么我似乎无法让这个文件在两个 channel 中播放?任何帮助将不胜感激。

我为困惑的代码道歉,一旦我解决了最后一个错误,我打算重构一下。

import struct
import math

# Frequency Table
A4 = 440.0



#Misc inputs
waveDuration = 3
amp_16 = 32760

# Wave Header

# Chunk Descriptor
chunkID = b'\x52\x49\x46\x46' #RIFF

hFormat = b'\x57\x41\x56\x45' #WAVE

# fmtSubChunk
fChunkID = b'\x66\x6d\x74\x20' #'fmt '
fChunkSize = 16 # 16 for PCM
audioFormat = 1 # 1 for PCM
numChannels = 2
sampleRate = 48000
bitsPerSample = 16
byteRate = int(sampleRate * numChannels * bitsPerSample / 8)

blockAlign = int(numChannels * bitsPerSample / 8)

# dataSubChunk
numSamples = waveDuration * sampleRate * numChannels
dChunkID = b'\x64\x61\x74\x61' #DATA
dChunkSize = int(numSamples * bitsPerSample / 8)

chunkSize = dChunkSize + 36 + 8

# Generate Sin Wave
def generateSin(sampleRate, bitDepth, frequency, amplitude, duration):
data = [0] * sampleRate * duration

angle = frequency * 2 * math.pi

cur_sample = 0
for sample in data:
data[cur_sample] = amplitude * (math.sin(angle * cur_sample/ sampleRate))
cur_sample += 1

return data

# Write .wav file
waveFile = open('test.wav', 'wb')

# Header
waveFile.write(chunkID)
waveFile.write(struct.pack('<i', chunkSize))
waveFile.write(hFormat)

# Format Subchunk
waveFile.write(fChunkID)
waveFile.write(struct.pack('<i', fChunkSize))
waveFile.write(struct.pack('<h', audioFormat))
waveFile.write(struct.pack('<h', numChannels))
waveFile.write(struct.pack('<i', sampleRate))
waveFile.write(struct.pack('<i', byteRate))
waveFile.write(struct.pack('<h', blockAlign))
waveFile.write(struct.pack('<h', bitsPerSample))

# Data Subchunk
waveFile.write(dChunkID)
waveFile.write(struct.pack('<i', dChunkSize))



for samp in generateSin(sampleRate, bitsPerSample, A4, amp_16, 1):

waveFile.write(struct.pack('<i', int(round(samp))))
waveFile.write(struct.pack('<i', int(round(samp))))

waveFile.close()

最佳答案

了解 wav 的好方法文件。
16 位的样本大小意味着 每个 channel 是 16 位。您获取正弦波的样本值,将其打包成 4 个字节(32 位),这样您就会得到类似 XX00 的内容,其中 XX 是第一个 channel 的正确 16 位值,然后是第二个 channel 的 00,所以第二个 channel 只有零。之后 - 您再次写入相同的值,因此您复制了前一个样本的数据,这就是您的频率错误的原因:
enter image description here
更改您的 for从循环

for samp in generateSin(sampleRate, bitsPerSample, A4, amp_16, 1):
waveFile.write(struct.pack('<i', int(round(samp))))
waveFile.write(struct.pack('<i', int(round(samp))))

到 -
for samp in generateSin(sampleRate, bitsPerSample, A4, amp_16, 1):
waveFile.write(struct.pack('<h', int(round(samp))))
waveFile.write(struct.pack('<h', int(round(samp))))

现在您将一次只写入 2 个字节,即一个 channel ,然后您将再次为第二个 channel 写入相同的值。
频率不是 440Hz 而是 500Hz - 我相信这是由于对数字进行了四舍五入。

关于python - 似乎无法在原始 Python 中编写两个 channel Wave 文件(无 Wave 模块),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54896173/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com