【发布时间】:2016-10-13 08:10:01
【问题描述】:
我决定在音频算法上玩 C++,更习惯于 Matlab 我有点挣扎。
第一步是使用 sndfile 库将 wav 文件记录到数组中。 我使用了库中的示例:
https://github.com/michaelwu/libsndfile/blob/master/examples/sfprocess.c
我想创建一个 wavF 类,其中包含 wav 的一般信息(采样频率、通道...)和 wav 文件的数据以供进一步处理。
我几乎实现了这一点,但是当进入 wavfile.cpp 中的while ((readcount = sf_read_double (infile, data, BUFFER_LEN))) 循环(但并非总是如此)时会出现分段错误。我不知道为什么。
我想将 wav 数据保存在数组 double* m_wavData 中,使用带有缓冲区循环的类构造函数中的函数 process_data。
这是他的代码:
主要:
#include <sndfile.h>
#include <stdio.h>
#include "wavfile.h"
int main (void)
{
SNDFILE *infile ;
const char *infilename = "Piano_mf_Gb2.wav" ;
SndfileHandle file;
file=SndfileHandle(infilename);
int test(initwav(infile, file, infilename));
if(test==1) return 0 ;
wavF wav1(infile, file, infilename);
sf_close (infile) ;
/* Close input and output files. */
return 0 ;
} /* main */
标题:
#ifndef WAVFILE_H_INCLUDED
#define WAVFILE_H_INCLUDED
#define BUFFER_LEN 1024
#include <sndfile.hh>
class wavF
{
public:
wavF(SNDFILE *infile, SndfileHandle file,const char * fName);
wavF(const unsigned int wavsize,const unsigned int channels,const unsigned int samplerate,const char * fileName);
~wavF();
protected:
const unsigned int m_wavsize;
const unsigned int m_channels;
const unsigned int m_samplerate;
const char * m_fileName;
double * m_wavData;
};
static void process_data (double *wavData, double * data, int count, int channels);
int initwav(SNDFILE *infile,SndfileHandle file,const char * fName);
#endif // WAVFILE_H_INCLUDED
和代码 wavfile.cpp
#include "wavfile.h"
wavF::wavF(SNDFILE *infile, SndfileHandle file,const char * fName): m_channels(file.channels()),m_samplerate(file.samplerate()),m_wavsize(file.frames()),m_fileName(fName)
{
/* This is a buffer of double precision floating point values
** which will hold our data while we process it.
*/
static double data [BUFFER_LEN] ;
//initialise class array
double* m_wavData = new double[m_wavsize*m_channels] ;
printf ("Opened file '%s'\n", m_fileName) ;
printf ("Sample rate : %d\n", m_samplerate) ;
printf ("Channels : %d\n", m_channels) ;
printf ("Size : %d\n", m_wavsize) ;
puts ("") ;
//fill array with the wav channel
int readcount(0);
int counter(0);
while ((readcount = sf_read_double (infile, data, BUFFER_LEN)))
{
// printf("%i \n",counter);
// counter++;
process_data (m_wavData,data, readcount, m_channels) ;
} ;
/* RAII takes care of destroying SndfileHandle object. */
} /* read_file */
wavF::wavF(const unsigned int wavsize,const unsigned int channels,const unsigned int samplerate,const char * fileName):
m_channels(channels),m_samplerate(samplerate),m_wavsize(wavsize),m_fileName(fileName)
{
}
static void process_data (double *m_wavData,double *data, int count, int channels)
{
int k;
/* Process the data here.
** If the soundfile contains more then 1 channel you need to take care of
** the data interleaving youself.
*/
for (k = 0 ; k < channels*count ; k ++)
m_wavData [k] = data[k] ;
} /* process_data */
wavF::~wavF()
{
delete m_wavData;
printf("array is detroyed");
}
int initwav(SNDFILE *infile,SndfileHandle file, const char * fName)
{
SF_INFO sfinfo ;
if (! (infile = sf_open (fName, SFM_READ, &sfinfo)))
{ /* Open failed so print an error message. */
printf ("Not able to open input file %s.\n", fName) ;
puts (sf_strerror (NULL)) ;
return 1;
} ;
return 0;
}
我写了什么异端代码?有什么建议吗?
(在 uiowa.edu 数据库中找到的音频 wav) 谢谢。
【问题讨论】:
-
调试器是解决此类问题的正确工具。 在询问 Stack Overflow 之前,您应该逐行逐行检查您的代码。如需更多帮助,请阅读How to debug small programs (by Eric Lippert)。至少,您应该 [编辑] 您的问题,以包含一个重现您的问题的 Minimal, Complete, and Verifiable 示例,以及您在调试器中所做的观察。
-
我正在使用 code::blocks,问题是当我使用调试器时没有错误,只有当我构建和运行时。我会做一个更简单的
-
您可能会将调试器与编译器混淆。调试器可用于在设置断点的情况下运行您的程序,并逐行执行代码。您可以在每一步之后查看当前变量值。
-
仅供参考,
double* m_wavData = ...在您的构造函数主体中隐藏成员变量double* m_wavData,使该成员完全未初始化(它也不会出现在您的成员初始化器列表中)。我真诚地怀疑你是否打算这样做。 -
在
initwav中,您将分配给参数infile。这对您传递其值的变量没有影响。