C++ 如何使用QByteArray代替SNDFILE
我想使用“fvad”库来检测音频静音部分,但我有QByteArray而不是SNDFILE。我该怎么做C++ 如何使用QByteArray代替SNDFILE,c++,qt,type-conversion,C++,Qt,Type Conversion,我想使用“fvad”库来检测音频静音部分,但我有QByteArray而不是SNDFILE。我该怎么做 sf_read_double(infile, buf0, framelen) [ 这是我的代码: /* *版权所有(c)2016丹尼尔·皮尔奇 * *此源代码的使用受BSD样式许可证的约束 *可以在源的根目录中的许可证文件中找到 *树。可以找到额外的知识产权授权 *所有参与项目的作者都可以 *可以在源树根目录下的AUTHORS文件中找到。 */ #定义POSIX_C_SOURCE200809L
sf_read_double(infile, buf0, framelen)
[
这是我的代码:
/*
*版权所有(c)2016丹尼尔·皮尔奇
*
*此源代码的使用受BSD样式许可证的约束
*可以在源的根目录中的许可证文件中找到
*树。可以找到额外的知识产权授权
*所有参与项目的作者都可以
*可以在源树根目录下的AUTHORS文件中找到。
*/
#定义POSIX_C_SOURCE200809L
#包括
#包括
#包括
#包括
#包括
#包括
#包括
静态bool过程(SNDFILE*infile、Fvad*vad、,
大小\u t framelen,SNDFILE*输出文件[2],文件*列表文件)
{
布尔成功=假;
double*buf0=NULL;
int16_t*buf1=NULL;
int-vadres,prev=-1;
长帧[2]={0,0};
长段[2]={0,0};
if(framelen>SIZE_MAX/sizeof(双精度)
||!(buf0=malloc(framelen*sizeof*buf0))
||!(buf1=malloc(framelen*sizeof*buf1))){
fprintf(stderr,“分配缓冲区失败\n”);
转到终点;
}
而(sf_读取双精度(填充、buf0、帧长度)==(sf_计数)帧长度){
//将读取的样本转换为int16
对于(大小i=0;i=min&&val=argc){
fprintf(stderr,“需要输入文件”);
GotoArgfail;
}
in_fname=argv[optind++];
如果(选项D
您应该使用而不是sf\u open
来创建SNDFILE
实例。
因此,根据文档,您应该将SF\u VIRTUAL\u IO*
传递给
必须实现该结构的每个成员的定义以反映QBuffer。因此,您需要创建一个helper类,该类接受对QBuffer的引用,并实现具有相同封装外形的方法,如下所示
typedef sf_count_t (*sf_vio_get_filelen) (void *user_data) ;
typedef sf_count_t (*sf_vio_seek) (sf_count_t offset, int whence, void *user_data) ;
typedef sf_count_t (*sf_vio_read) (void *ptr, sf_count_t count, void *user_data) ;
typedef sf_count_t (*sf_vio_write) (const void *ptr, sf_count_t count, void *user_data) ;
typedef sf_count_t (*sf_vio_tell) (void *user_data) ;
以下是需要传递给结构的函数的实现:
static sf_count_t
qbuffer_get_filelen (void *user_data)
{ QBuffer *buff = (QBuffer *) user_data ;
return buff->size();
}
static sf_count_t
qbuffer_seek (sf_count_t offset, int whence, void *user_data)
{
QBuffer *buff = (QBuffer *) user_data ;
switch (whence)
{ case SEEK_SET :
buff->seek(offset);
break ;
case SEEK_CUR :
buff->seek(buff->pos()+offset);
break ;
case SEEK_END :
buff->seek(buff->size()+offset);
break ;
default :
break ;
} ;
return buff->pos();
}
static sf_count_t
qbuffer_read (void *ptr, sf_count_t count, void *user_data)
{
QBuffer *buff = (QBuffer *) user_data ;
return buff->read((char*)ptr,count);
}
static sf_count_t
qbuffer_write (const void *ptr, sf_count_t count, void *user_data)
{
QBuffer *buff = (QBuffer *) user_data ;
return buff->write((const char*)ptr,count);
}
static sf_count_t
qbuffer_tell (void *user_data)
{
QBuffer *buff = (QBuffer *) user_data ;
return buff->pos() ;
}
您可以创建如下结构:
SF_VIRTUAL_IO qbuffer_virtualio ;
qbuffer_virtualio.get_filelen = qbuffer_get_filelen ;
qbuffer_virtualio.seek = qbuffer_seek ;
qbuffer_virtualio.read = qbuffer_read ;
qbuffer_virtualio.write = qbuffer_write ;
qbuffer_virtualio.tell = qbuffer_tell ;
然后,当您呼叫sf\u open\u virtual
QBuffer buffer(&yourArray);
buffer.open(QIODevice::ReadWrite);
sf_open_virtual (&qbuffer_virtualio , mode, sfinfo, (void *)(&buffer));
// doing whatever
// you may want to close the buffer
buffer.close();
您还可以将这些接口函数设置为一个名为QBuffer\u SFVIRTUAL\u interface
的类,并引用它们,如下所示:
qbuffer_virtualio.get_filelen = QBuffer_SFVIRTUAL_Interface::qbuffer_get_filelen ;
qbuffer_virtualio.seek = QBuffer_SFVIRTUAL_Interface::qbuffer_seek ;
qbuffer_virtualio.read = QBuffer_SFVIRTUAL_Interface::qbuffer_read ;
qbuffer_virtualio.write = QBuffer_SFVIRTUAL_Interface::qbuffer_write ;
qbuffer_virtualio.tell = QBuffer_SFVIRTUAL_Interface::qbuffer_tell ;
你能给我一个简单的例子吗?因为我不知道什么应该是sf_open_虚拟输入。@MohammadrezaKashi,我用代码更新了我的答案。我没有测试它,但它应该可以工作。khosh Begzareh我可以用.SFM_读取模式吗?当然可以。在这种模式下,
sf_vio_write
是g
qbuffer_virtualio.get_filelen = QBuffer_SFVIRTUAL_Interface::qbuffer_get_filelen ;
qbuffer_virtualio.seek = QBuffer_SFVIRTUAL_Interface::qbuffer_seek ;
qbuffer_virtualio.read = QBuffer_SFVIRTUAL_Interface::qbuffer_read ;
qbuffer_virtualio.write = QBuffer_SFVIRTUAL_Interface::qbuffer_write ;
qbuffer_virtualio.tell = QBuffer_SFVIRTUAL_Interface::qbuffer_tell ;