我在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的任何帮助
发布于 2015-11-22 23:04:30
你的wav文件可能是立体声的。则您的缓冲区大小需要为4096 *2
发布于 2018-12-20 22:15:12
你的代码的问题是,它只适用于单声道输入文件。
根据frames的说法,您需要熟悉框架的概念
对于frames-count函数,frames参数指定帧数。一个帧只是一个采样块,每个通道一个。必须注意确保ptr所指向的数组中有足够的空间来获取(frame*channel)数量的项(短整型、整型、浮点型或双精度型)。
通过使用带有第三个参数4096的函数sf_readf_float,您请求读取4096个帧。一帧是一个采样乘以通道数C。所以当你这样做的时候
sf_readf_float(文件,缓冲区,4096);
您正在请求将4096*C样本存储到您声明为
浮点数*缓冲区=(浮点数*)malloc(4096*sizeof(浮点数));
你的缓冲区溢出了!
要解决此问题,您有两个选择。
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;
}https://stackoverflow.com/questions/33498680
复制相似问题