Правильный способ связать несколько эффектов с помощью libSox и прочитать выходные данные

Я пытаюсь программно применить несколько эффектов с помощью libSox, и в настоящее время я не могу понять, правильно ли я это делаю. Например, мне нужно применить эффекты темпа и усиления и прочитать полученное аудио в буфере для дальнейшей обработки. Документация действительно скудная, и поиск в Google не удался.
Вот мой код:

sox_format_t* input = sox_open_read("<file.wav>", NULL, NULL, NULL);
//sox_format_t* out;

sox_format_t* output = sox_open_memstream_write(&buffer, &buffer_size,
&input->signal, &input->encoding, "raw", NULL);
//assert(output = sox_open_write("/home/egor/hello_processed.wav", &input->signal, NULL, NULL, NULL, NULL));
sox_effects_chain_t* chain = sox_create_effects_chain(&input->encoding, &output->encoding);

char* sox_args[10];
//input effect

sox_effect_t* e = sox_create_effect(sox_find_effect("input"));
sox_args[0] = (char*)input;
assert(sox_effect_options(e, 1, sox_args) == SOX_SUCCESS);
assert(sox_add_effect(chain, e, &input->signal, &input->signal) ==
SOX_SUCCESS);
free(e);

e = sox_create_effect(sox_find_effect("tempo"));
std::string tempo_str = "1.01";
sox_args[0] = (char*)tempo_str.c_str();
assert(sox_effect_options(e, 1, sox_args) == SOX_SUCCESS);
assert(sox_add_effect(chain, e, &input->signal,&input->signal) ==
SOX_SUCCESS);
free(e);e = sox_create_effect(sox_find_effect("output"));
sox_args[0] = (char*)output;
assert(sox_effect_options(e, 1, sox_args) == SOX_SUCCESS);
assert(sox_add_effect(chain, e, &input->signal, &input->signal) ==
SOX_SUCCESS);
free(e);
sox_flow_effects(chain, NULL, NULL);static const size_t maxSamples=4096;
sox_sample_t samples[maxSamples];

std::vector<sox_sample_t> audio_buffer;
for (size_t r; 0 != (r=sox_read(output,samples,maxSamples));)
for(int i=0;i<r ;i++)
audio_buffer.push_back(samples[i]);

std::cout << audio_buffer.size() << std::endl;

Мои вопросы:

  1. Правильно ли я настроил цепочку эффектов?

  2. Как прочитать в памяти полученные аудио образцы?

    Если я использую значения темпа < 1 Я получаю правильное количество сэмплов (в audio_buffer) из выходных данных, но если я изменяю его, например, на 1,2, я неожиданно получаю очень небольшое количество сэмплов и 0, если я использую значение 1,0. Мне интересно, есть ли ошибка в конфигурации моей цепочки или чтение данных с выхода? Это мой первый опыт работы с libsox, и я пытался следовать примерам, но я застрял здесь.

Заранее спасибо за помощь!

Спасибо!

3

Решение

  1. Ваша цепочка эффектов в порядке, и вы можете проверить, что она дает правильный выходной буфер, записав его в файл — просто замените эту строку в вашем коде:

sox_format_t* output = sox_open_memstream_write(&buffer, &buffer_size, &input->signal, &input->encoding, "raw", NULL);

к этому:

sox_format_t* output = sox_open_write("2.wav", &input->signal, &input->encoding, "raw", NULL, NULL);

  1. Что касается проблемы с буфером вывода памяти — я изучал libsox код, кажется, есть ошибка в его обработке буфера памяти. В качестве обходного пути я бы предложил вам добавить output->olength = 0; Перед чтением output буфер, то, кажется, работает правильно.

Итак, ваш код будет выглядеть так:

...
if (std::stof(tempo_str) >= 1.0) { // use workaround only if tempo >= 1.0
output->olength = 0;
}

std::vector<sox_sample_t> audio_buffer;
for (size_t r; 0 != (r=sox_read(output,samples,maxSamples));)
for(int i=0;i<r ;i++)
audio_buffer.push_back(samples[i]);
...

UPD: использовать обходной путь только тогда, когда tempo >= 1.0

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]