C Pitchshifter 使用 libsamplerate

Posted

技术标签:

【中文标题】C Pitchshifter 使用 libsamplerate【英文标题】:C Pitchshifter using libsamplerate 【发布时间】:2013-04-25 13:47:30 【问题描述】:

第一篇文章, 我正在尝试使用 libsamplerate 和 libsndfile 制作一个简单的音高变换器。 我通过制作一个简单的采样率转换器然后破解它以最基本的形式实现了这一点,我通过改变比率浮点值来改变音高。 pitchshifter 移位 - 在正弦音上听起来非常好 - 如果您将它用于音频,您可以听到声音块之间的间隙 - 特别是如果您将文件调高。 我想知道是否有一种方法可以使代码更有效地应对这种情况或某种插值函数或库,我可以毫不费力地实现它们。 我对 C 非常陌生 - 以前只通过 PD 处理声音,这是我的第一个项目 - 据我所知,libsamplerate 并不是真正为实现音高转换而设计的,所以我知道到达那里有点困难。

谢谢

这是我的代码

    #include <stdio.h>
    #include </usr/local/include/sndfile.h>
#include </usr/local/include/samplerate.h>

#define BUFFER_LEN 44100 //defines buffer length

#define MAX_CHANNELS 2 //defines max channels 

int main ()

    static float datain [BUFFER_LEN]; //static defines as a global variable

    static float dataout [BUFFER_LEN]; //static defines as a global variable

    SNDFILE *infile, *outfile; //determines file open function + pointers

    /*descriptor*/SF_INFO /*sf_open*/ sfinfo, sfinfo2; 

    int readcount;//used to store data in while ((readcount = sf...

    const char *infilename/*pointer*/ = "/tmp/input.wav"; //const means that it is a value that cannot change 
                                               //after initialisation

    const char *outfilename/*pointer*/ = "/tmp/soundchanged.wav"; //const means that it is a value that cannot change 
                                                       //after initialisation

    SRC_DATA src_data; //struct from libsamplerate library
    //http://www.mega-nerd.com/SRC/api_misc.html#SRC_DATA

    infile = sf_open (infilename/*pointer*/, SFM_READ, &sfinfo); //infile declares a file variable, SFM_READ-reads file
                                                     //sfinfo -function of sfopen

    outfile = sf_open (outfilename/*pointer*/, SFM_WRITE, &sfinfo); //outfile declares a file variable, SFM_WRITE-writes file
                                                        //sfinfo -function of sfopen

    src_data.data_in = datain; //used to pass audio data into the converter

    src_data.input_frames = BUFFER_LEN; //supply the converter with the lengths of the arrays 
                                       //(in frames) pointed to by the data_in  

    src_data.data_out = dataout; //supplies the converter with an array to hold the converter's output

    src_data.output_frames = BUFFER_LEN; //supply the converter with the lengths of the arrays 
                                        //(in frames) pointed to by the data_out 

    /*------->*/src_data.src_ratio = 0.2 /*changing this number changes the pitch of the output file*/; 
    //specifies the conversion ratio defined as the input sample rate 
                           //divided by the output sample rate

    src_simple (&src_data/*reference address of src_data*/, SRC_SINC_BEST_QUALITY, 1);//

    while ((readcount = sf_read_float (infile, datain, BUFFER_LEN)))//while readcount is equal to
        //sf_read_float - function call: infile,datain and BUFFER_LEN 
        //this data is then fed into the converter argument below 


    
        src_simple (&src_data, SRC_SINC_BEST_QUALITY, 1); //selects converter
        //http://www.mega-nerd.com/SRC/api_misc.html#SRC_DATA

        sf_write_float (outfile, dataout, readcount); 
        //write the data in the array pointed to by ptr to the file
    ;


    sf_close (infile);
    sf_close (outfile); // closes infile,outfile
    //The close function closes the file, deallocates 
    //its internal buffers and returns 0 on success or an error value otherwise.

    sf_open ("/tmp/soundchanged.wav", SFM_READ, &sfinfo2/*reference address of sfinfo2*/);

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

    return 0;

【问题讨论】:

更改采样率(如果库正在这样做)不是正确的方法。改变音高并不是一件容易的事,而且成本低廉且质量上乘。 感谢您的浏览。您能否详细说明我如何采用正确的方法?就质量而言,我的目标不是任何出色的东西 - 只是在处理后不会丢失音频块的东西。 我不会告诉你比你在网上找到的更多。研究pitch shift的话题。这只是一个起点。有论文和算法,我敢肯定,还有示例实现。 您所做的并不是真正的音高变换,而是更准确地称为变速,改变播放速度从而改变音高。您可能想要的是与速度无关的音高变换;即播放速度保持不变,音高发生变化。为此,请查看 librubberband。 【参考方案1】:

过去最便宜的时间音高转换器(在旧的磁带播放器中)在调高时的工作方式是简单地复制重新采样的声音块或其中的一部分,以填补空白。稍差一点的那些在零交叉处将块拼接在一起。这种方法有效,但远非高质量的声音。

【讨论】:

以上是关于C Pitchshifter 使用 libsamplerate的主要内容,如果未能解决你的问题,请参考以下文章

我们如何使用WPF / C#可执行文件调试DLL(使用本机C / C ++的bulit)源?

在 C/C++ 中使用 swift 库?

在 linux 上,使用 C/C++ 编程时,我应该使用啥函数来输入密码? [复制]

在 C++ 中使用 C 函数 使用 extern "C"

Flutter 使用 C/C++ 代码构建 - 示例?

使用Notepad++编译运行C/C++/Python程序