使用 libsndfile 和 libsamplerate 的音频采样率转换器。不确定是不是正确使用函数 src_simple

Posted

技术标签:

【中文标题】使用 libsndfile 和 libsamplerate 的音频采样率转换器。不确定是不是正确使用函数 src_simple【英文标题】:Audio samplerate converter using libsndfile and libsamplerate. Not sure if using function src_simple correctly使用 libsndfile 和 libsamplerate 的音频采样率转换器。不确定是否正确使用函数 src_simple 【发布时间】:2012-05-20 11:00:10 【问题描述】:

我一直在使用 libsndfile 和 libsamplerate 在 c 中构建一个简单的采样率转换器。无论我尝试什么,我似乎都无法让 libsamplerate 的 src_simple 函数工作。我已将我的代码简化为尽可能简单,现在它只输出一个相同采样率的无声音频文件:

#include <stdio.h>
#include <sndfile.h>
#include <samplerate.h>

#define BUFFER_LEN 1024
#define MAX_CHANNELS 6

int main ()

    static double datain [BUFFER_LEN];
    static double dataout [BUFFER_LEN];
    SNDFILE *infile, *outfile;
    SF_INFO     sfinfo, sfinfo2 ;
    int         readcount ;
    const char  *infilename = "C:/Users/Oli/Desktop/MARTYTHM.wav" ;
    const char  *outfilename = "C:/Users/Oli/Desktop/Done.wav" ;
    SRC_DATA    src_data;

    infile = sf_open (infilename, SFM_READ, &sfinfo);
    outfile = sf_open (outfilename, SFM_WRITE, &sfinfo);

    src_data.data_in = datain
    src_data.input_frames = BUFFER_LEN;
    src_data.data_out = dataout;
    src_data.output_frames = BUFFER_LEN;
    src_data.src_ratio = 0.5;

    src_simple (&src_data, SRC_SINC_BEST_QUALITY, 1);

    while ((readcount = sf_read_double (infile, datain, BUFFER_LEN)))
    
        src_simple (&src_data, SRC_SINC_BEST_QUALITY, 1);
        sf_write_double (outfile, dataout, readcount) ;
    ;

    sf_close (infile);
    sf_close (outfile);

    sf_open ("C:/Users/Oli/Desktop/Done.wav", SFM_READ, &sfinfo2);

    printf("%d", sfinfo2.samplerate);

    return 0;

这真的开始让我感到压力了。该计划是一个单人项目,很快就要到期了,这让我非常焦虑,因为无论我尝试什么似乎都会导致失败。谁能帮帮我?

【问题讨论】:

你为什么删除旧问题并重新发布?现在答案和 cmets 已经丢失了。 对不起,我想,因为它本质上是一个不同的程序,我应该创建一个新线程。 好吧,如果您有一个真正的新问题,请随时发布它,但不要删除旧问题,因为这些答案将来可能对其他人有用。如果您只是想向原始问题添加更多信息,那么只需对其进行编辑。 好的,抱歉,我会记住的。 嗨,你能提供上面代码的工作(固定)版本吗?这对我真的很有帮助。谢谢 【参考方案1】:

我不是这个特定库的专家,但仅通过查看 online documentation 我发现您的代码存在一些问题:

src_simple 显然适用于浮点数,但您的缓冲区是双倍的 - 我认为您需要将缓冲区更改为浮点数并使用 sf_read_float/sf_write_float 进行 I/O。

李>

src_simple 是“简单”接口,旨在通过一次调用应用于整个波形,而不是像您所做的那样以块的形式应用 - 请参阅http://www.mega-nerd.com/SRC/faq.html#Q004 - 您应该首先获取输入文件大小,然后分配足够的内存,读入整个文件,一次性转换,然后将转换后的输出数据写入到你的输出文件中。

更改采样率时,输出文件中的样本数量与输出文件中的样本数量不同(在这种情况下约为一半),但您写入的样本数量与您读取的相同(readcount)。您可能应该使用src_data.output_frames_gen 作为要写入的帧数,而不是readcount

【讨论】:

谢谢。我在一分钟前意识到了双/浮动错误并修复了它,但是谢谢。我将如何在一次通话中应用“src_simple”?我不确定我是否有必要分块进行。我需要改变'src_data.output_frames = BUFFER_LEN;' ?我将如何计算样本数量?谢谢你的帮助。 Re-read mega-nerd.com/SRC/api_simple.html carefully - 在src_data.output_frames_gen 中返回生成的样本数 - 将其用作要写入输出文件的样本数(即将此作为调用中的第三个参数传递给sf_write_float)。 好的,我已经尝试过了,但我不确定我是否做对了。我现在有 sf_write_float (outfile, dataout, src_data.output_frames_gen) ;这会导致输出的文件播放速度非常快,大约 10 秒长(原来是 1:47)。 已解决:原来我需要为 outfile 设置一个单独的 sf_info 结构,并使用所需的采样率对其进行初始化,以便它以正确的速度播放。为您的帮助干杯。 我是 libsndfile 和 libsamplerate 的主要作者。我重申@PaulR 所说的内容,重新阅读src_simple 上的文档。它不应该按照您在上面示例中的使用方式使用。 src_simple 用于一次性转换整个文件。当像您正在做的那样在文件的离散块上多次调用时,它确实 not 会产生良好的结果。如果你想像这样将文件转换成块,你应该使用src_process API。另请注意,libsamplerate 源代码压缩包包含一个名为 sndfile-convert 的程序的源代码,该程序可以执行您想要的操作。

以上是关于使用 libsndfile 和 libsamplerate 的音频采样率转换器。不确定是不是正确使用函数 src_simple的主要内容,如果未能解决你的问题,请参考以下文章

C++ libsndfile 和 mac osx

将 libsamplerate 与 libsndfile 一起使用

MacPorts 2.1.2 git 和 libsndfile 安装

iOS 上的 libsndfile

使用 VS2010 的 libsndfile 奇怪行为

使用 libsndfile 和 libsamplerate 的音频采样率转换器。不确定是不是正确使用函数 src_simple