簡體   English   中英

解釋WAV數據

[英]Interpreting WAV Data

我正在嘗試編寫一個程序來顯示PCM數據。 我一直很沮喪地試圖找到具有正確抽象級別的庫,但是我已經找到了python wave庫並一直在使用它。 但是,我不確定如何解釋數據。

wave.getparams函數返回(2個通道,2個字節,44100 Hz,96333幀,無壓縮,無壓縮)。 這一切看起來都很愉快,但是后來我嘗試打印一個幀:'\\ xc0 \\ xff \\ xd0 \\ xff',這是4個字節。 我想一幀可能是2個樣本,但是歧義並沒有到此為止。

96333幀* 2個樣本/幀*(1 / 44.1k秒/樣本)= 4.3688秒

但是,iTunes報告的時間接近2秒,並且基於文件大小和比特率的計算約為2.7秒。 這里發生了什么?

另外,我如何知道字節是帶符號的還是無符號的?

非常感謝!

謝謝您的幫助! 我開始使用它,並將解決方案發布在這里,以供其他可憐的人需要時使用:

import wave
import struct

def pcm_channels(wave_file):
    """Given a file-like object or file path representing a wave file,
    decompose it into its constituent PCM data streams.

    Input: A file like object or file path
    Output: A list of lists of integers representing the PCM coded data stream channels
        and the sample rate of the channels (mixed rate channels not supported)
    """
    stream = wave.open(wave_file,"rb")

    num_channels = stream.getnchannels()
    sample_rate = stream.getframerate()
    sample_width = stream.getsampwidth()
    num_frames = stream.getnframes()

    raw_data = stream.readframes( num_frames ) # Returns byte data
    stream.close()

    total_samples = num_frames * num_channels

    if sample_width == 1: 
        fmt = "%iB" % total_samples # read unsigned chars
    elif sample_width == 2:
        fmt = "%ih" % total_samples # read signed 2 byte shorts
    else:
        raise ValueError("Only supports 8 and 16 bit audio formats.")

    integer_data = struct.unpack(fmt, raw_data)
    del raw_data # Keep memory tidy (who knows how big it might be)

    channels = [ [] for time in range(num_channels) ]

    for index, value in enumerate(integer_data):
        bucket = index % num_channels
        channels[bucket].append(value)

    return channels, sample_rate

“兩個通道”表示立體聲,因此,將每個通道的持續時間相加是沒有意義的,因此您的距離減少了兩倍(2.18秒,而不是4.37秒)。 至於符號性,例如解釋在這里 ,我引用:

8位樣本存儲為0到255之間的無符號字節。16位樣本存儲為2的補碼有符號整數,范圍從-32768到32767。

這是WAV格式(實際上是其超集RIFF)規范的一部分,因此不依賴於您用於處理WAV文件的庫。

我知道答案已經被接受,但是前一陣子我在音頻方面做了一些事情,您必須像這樣做一些事情。

pcmdata = wave.struct.unpack("%dh"%(wavedatalength),wavedata)

另外,我使用的一個軟件包稱為PyAudio,盡管我仍然必須使用wave軟件包。

每個樣本為16位,有2個通道,因此幀占用4個字節

持續時間就是幀數除以每秒的幀數。 根據您的數據,這是: 96333 / 44100 = 2.18 seconds

基於此答案 ,可以通過使用numpy.fromstringnumpy.fromfile獲得良好的性能提升。 另請參閱此答案

這是我所做的:

def interpret_wav(raw_bytes, n_frames, n_channels, sample_width, interleaved = True):

    if sample_width == 1:
        dtype = np.uint8 # unsigned char
    elif sample_width == 2:
        dtype = np.int16 # signed 2-byte short
    else:
        raise ValueError("Only supports 8 and 16 bit audio formats.")

    channels = np.fromstring(raw_bytes, dtype=dtype)

    if interleaved:
        # channels are interleaved, i.e. sample N of channel M follows sample N of channel M-1 in raw data
        channels.shape = (n_frames, n_channels)
        channels = channels.T
    else:
        # channels are not interleaved. All samples from channel M occur before all samples from channel M-1
        channels.shape = (n_channels, n_frames)

    return channels

如果需要將形狀復制到形狀中,則為形狀賦一個新值將引發錯誤。 這是一件好事,因為您想就地使用數據(總體上使用更少的時間和內存)。 如果可能,ndarray.T函數也不會復制(即返回視圖),但是我不確定如何確保它不會復制。

使用np.fromfile直接讀取文件會更好,但是您必須使用自定義dtype跳過標頭。 我還沒有嘗試過。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM