C Pitchshifter с использованием libsamplerate

В первом посте я пытаюсь сделать простую передачу, используя 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;
}

1 ответ

То, как работали самые дешевые преобразователи временного шага (в старых ленточных проигрывателях) при установке звука, было простым дублированием блоков пересэмплированного звука или его частей, чтобы заполнить пробелы. Чуть менее худшие из них сросли блоки вместе при пересечении нуля. Это работало, но было далеко от качественного звучания.

Другие вопросы по тегам