【问题标题】:Libsndfile on OSX corrupts dataOSX 上的 Libsndfile 损坏数据
【发布时间】:2015-11-03 12:04:01
【问题描述】:

我在 OSX 上制作基于 Libsndfile 的音频应用时遇到了奇怪的问题。读取和写入缓冲区中的数据以奇怪且不可预测的方式损坏。

这是一个为我重现问题的简短程序:

#include <iostream>
#include "sndfile.h"

int main(int argc, const char * argv[])
{
float* buffer = (float*)malloc(4096*sizeof(float));
SNDFILE* file;
SF_INFO infos;
infos.format = 0;
file = sf_open("ABCD.WAV",SFM_READ,&infos);
if (file==NULL)
{
    std::cout << "LIBSNDFILE ERROR: " << sf_strerror(file) << "\n";   
}

int samplesread=1;
while (samplesread!=0)
    {
        samplesread = sf_readf_float(file,buffer,4096);
        std::cout << " " << samplesread;
    }
std::cout << "";
sf_close(file);
free(buffer);
return 0;
}

程序编译并运行良好,但用 Valgrind 运行它会发现这种错误:

==933== Invalid write of size 8 
==933==    at 0x56EF4B: _platform_bzero$VARIANT$Merom (in    /usr/lib/system/libsystem_platform.dylib)
==933==    by 0x2FDBB: psf_memset (in /opt/local/lib/libsndfile.1.dylib)
==933==    by 0x11E0B: sf_readf_float (in /opt/local/lib/libsndfile.1.dylib)
==933==    by 0x100001323: main (in ./sndfiletest)
==933==  Address 0x873270 is 0 bytes after a block of size 16,384 alloc'd
==933==    at 0x4711: malloc (vg_replace_malloc.c:296)
==933==    by 0x100001287: main (in ./sndfiletest

提前感谢您的帮助 -T

【问题讨论】:

    标签: macos valgrind libsndfile


    【解决方案1】:

    您的 wav 文件可能是立体声的。那么你的缓冲区大小需要为 4096 * 2

    【讨论】:

      【解决方案2】:

      您的代码的问题在于它仅适用于单声道输入文件。

      你需要熟悉框架的概念,根据frames

      对于帧数函数,frames 参数指定帧数。一帧只是一个样本块,每个通道一个。必须注意确保 ptr 指向的数组中有足够的空间来获取 (frames * channels) 数量的项目(shorts、int、float 或 doubles)。

      通过使用带有第三个参数4096 的函数sf_readf_float,您要求读取4096 个。一帧是一个样本乘以通道数C。所以当你这样做时

      sf_readf_float(file,buffer,4096);
      

      您要求将4096*C 样本存储到您声明为的缓冲区中

      float* buffer = (float*)malloc(4096*sizeof(float));
      

      你溢出了缓冲区!

      要解决此问题,您有两个选择。

      1。继续使用sf_readf_float并修复buffer的分配

      #include <stdlib.h>
      #include <iostream>
      #include "sndfile.h"
      
      int main(int argc, const char * argv[])
      {
        float* buffer;
        SNDFILE* file;
        SF_INFO infos;
        file = sf_open("inFile.wav",SFM_READ,&infos);
      
        buffer = (float*)malloc(infos.channels*4096*sizeof(float));
      
        if (file==NULL)
        {
          std::cout << "LIBSNDFILE ERROR: " << sf_strerror(file) << "\n";
        }
      
        int samplesread=1;
        while (samplesread!=0)
        {
          samplesread = sf_readf_float(file,buffer,4096);
          std::cout << " " << samplesread;
        }
        std::cout << "";
      
        sf_close(file);
        free(buffer);
        return 0;
      }
      

      2。保留您的缓冲区分配并使用sf_read_float

      我不推荐这种方式,因为您仍然需要检查4096 是否是C 的倍数。在立体声输入的情况下,您可以:

      #include <stdlib.h>
      #include <iostream>
      #include "sndfile.h"
      
      int main(int argc, const char * argv[])
      {
        float* buffer = (float*)malloc(4096*sizeof(float));
        SNDFILE* file;
        SF_INFO infos;
        file = sf_open("inFile.wav",SFM_READ,&infos);
      
        if (file==NULL)
        {
          std::cout << "LIBSNDFILE ERROR: " << sf_strerror(file) << "\n";
        }
      
        int samplesread=1;
        while (samplesread!=0)
        {
          samplesread = sf_read_float(file,buffer,4096);
          std::cout << " " << samplesread;
        }
        std::cout << "";
      
        sf_close(file);
        free(buffer);
        return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-15
        • 2015-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-27
        • 2012-09-18
        相关资源
        最近更新 更多