C++ 如何使用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

我想使用“fvad”库来检测音频静音部分,但我有QByteArray而不是SNDFILE。我该怎么做

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 ;