两种计算WAV文件总块数的方法为何结果不同?
问题分析与解决
你的核心问题是混淆了wave模块中「帧数」和「字节数」的概念,导致计算和实际读取的基准完全不匹配:
错误根源
wave.getnframes()返回的是WAV文件的总帧数,每个帧的字节数由声道数和采样位深决定:每帧字节数 = 声道数 × 采样位深字节数(比如立体声+16位采样,每帧是2×2=4字节)。wave.readframes(n)的参数n是要读取的帧数,不是字节数。你传入的CHUNK=4096是字节数,导致每次读取了4096帧,返回的字节数据量远大于预期,因此实际读取的块数远少于错误计算的数值。calc_total_chunks函数直接用总帧数除以字节数(CHUNK),单位完全不匹配,计算结果自然错误。
修正后的代码
from custom_logging import CustomLogger import logging import wave import math import os testing_logger = CustomLogger(log_files=["testing.log"]) CHUNK_SIZE_BYTES = 4096 # 明确标注为字节数,避免概念混淆 def calc_total_chunks(song_dir, song_name, chunk_size_bytes): song_path = os.path.join(song_dir, song_name) with wave.open(song_path) as mywav: nframes = mywav.getnframes() nchannels = mywav.getnchannels() sampwidth = mywav.getsampwidth() bytes_per_frame = nchannels * sampwidth # 计算每次可读取的帧数:块字节数 ÷ 每帧字节数 frames_per_chunk = chunk_size_bytes // bytes_per_frame if frames_per_chunk == 0: frames_per_chunk = 1 # 容错:避免块字节数小于单帧字节数的极端情况 total_chunks = math.ceil(nframes / frames_per_chunk) return total_chunks def count_chunks_in_song(song_dir, song_name, chunk_size_bytes): song_path = os.path.join(song_dir, song_name) chunk_count = 0 with wave.open(song_path) as mywav: nchannels = mywav.getnchannels() sampwidth = mywav.getsampwidth() bytes_per_frame = nchannels * sampwidth frames_per_chunk = chunk_size_bytes // bytes_per_frame if frames_per_chunk == 0: frames_per_chunk = 1 while True: # 按计算好的帧数读取,保证每次读取的字节数接近设定的块大小 song_data_chunk = mywav.readframes(frames_per_chunk) if not song_data_chunk: break chunk_count += 1 return chunk_count songs = ["american.wav", "beats.wav", "No_38.wav"] for song in songs: calc = calc_total_chunks('songs', song, CHUNK_SIZE_BYTES) actual = count_chunks_in_song('songs', song, CHUNK_SIZE_BYTES) logging.info(f"total chunks calc for {song}: {calc}") logging.info(f"total chunks read for {song}: {actual}")
说明
- 将原
CHUNK重命名为CHUNK_SIZE_BYTES,明确标注含义,避免概念混淆。 - 两个函数统一先计算每帧字节数,再推导每次应读取的帧数,保证计算和实际读取的基准一致。
- 增加了容错处理,防止块字节数小于单帧字节数时出现异常。
修正后,计算的块数和实际读取的块数会完全匹配。
内容的提问来源于stack exchange,提问作者for i in range
相关产品推荐
相关产品推荐

