【问题标题】:Python librosa error "Audio buffer is not Fortran-contiguous"Python librosa 错误“音频缓冲区不是 Fortran 连续的”
【发布时间】:2021-09-14 05:03:34
【问题描述】:

我正在使用librosa

只是loadstft,我遇到了错误Audio buffer is not Fortran-contiguous

我google了一下,发现需要添加np.asfortranarray,所以我添加了这些句子,但徒劳无功。

a, sr = librosa.load("mywave.wav",sr=self.sr,mono=False)

print(a.shape) #(2, 151199)

a[0] = np.asfortranarray(a[0])# try to avoide Fortran-contiguous
a[1] = np.asfortranarray(a[1])

# but this returns error
#Audio buffer is not Fortran-contiguous. Use numpy.asfortranarray to ensure Fortran contiguity.    

stft_L = librosa.stft(a[0], n_fft=self.stft_frame,hop_length= self.hop_frame, window='hann') 

我第一次编写此代码时(可能是半年前),它成功了。

有什么办法吗??

【问题讨论】:

    标签: python numpy audio librosa


    【解决方案1】:

    您误解了 C 与 Fortran 连续内存布局是什么,以及这意味着您可以做什么和不能做什么。比如改变数组中一行的内存布局

    a[0] = np.asfortranarray(a[0])
    

    没有意义,因为内存布局决定了一行是什么

    为了说明这一点,让我们看一些 Fortran 连续数据

    x = np.asfortranarray(np.arange(12).reshape(3, 4))
    x.flags.f_contiguous
    # True
    
    x
    # array([[ 0,  1,  2,  3],
    #        [ 4,  5,  6,  7],
    #        [ 8,  9, 10, 11]])
    

    在内部,二维数组当然是线性保存的,C-/Fortran-contigouity 决定了行还是列在前:

    x.flatten('A')
    # array([ 0,  4,  8,  1,  5,  9,  2,  6, 10,  3,  7, 11])
    
    np.asfortranarray(x).flatten('A')
    # array([ 0,  4,  8,  1,  5,  9,  2,  6, 10,  3,  7, 11])
    
    np.ascontiguousarray(x).flatten('A')
    # array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
    

    Fortran 内存布局是列优先的,即列在内存中保持在一起。 C 内存是行优先的,即行在内存中保持在一起。

    真正令人困惑的是,该数组中的视图可以是连续的,也可以不是:

    x.flags.f_contiguous, x[0].flags.f_contiguous
    # (True, False)
    

    x 显然是连续的,但 x[0] 不是。那是因为[0, 1, 2, 3] 在内存中并不相邻。

    你想做什么

    a = x.copy('A')
    
    a.flags.f_contiguous, a[0].flags.f_contiguous
    # (True, False)
    
    a[0] = np.asfortranarray(a[0])
    a[1] = np.asfortranarray(a[1])
    
    a.flags.f_contiguous, a[0].flags.f_contiguous
    # (True, False)
    

    不起作用,因为更改单行的布局没有意义。

    现在出现令人困惑的部分:如果您有一个 Fortran 连续数组,并且希望第一行是 Fortran 连续的,则不能将数组更改为 Fortran 连续:

    a = x.copy('A')
    
    a = np.asfortranarray(a)
    a.flags.f_contiguous, a[0].flags.f_contiguous
    # (True, False)
    

    因为列是连续的,而不是行。

    如果改为将数组更改为 C-contigous

    a = x.copy('A')
    
    a = np.ascontiguousarray(a)
    a.flags.f_contiguous, a[0].flags.f_contiguous
    # (False, True)
    

    这意味着行现在是连续的。

    另一种解决方案是简单地复制数据

    a = x.copy('A')
    
    a[0].copy().flags.f_contiguous
    # True
    

    因为复制会将数据写入一个新的、线性的、连续的数组中。

    那么最终的解决方案呢?

    a, sr = librosa.load("mywave.wav")
    stft_L = librosa.stft(a[0].copy())
    

    不过librosa也有removed the need for contiguity recently,所以这个问题以后应该会慢慢消失的。

    【讨论】:

      猜你喜欢
      • 2016-06-07
      • 2016-01-10
      • 2015-07-31
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多