我正在尝试以编程方式对libSox施加一些效果,但目前无法理解我是否做得正确。例如,我需要应用速度和增益效果,并在缓冲区中读取生成的音频以进行进一步处理。该文档确实很稀缺,并且无法搜索。 这是我的代码:
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,我会从输出中获得正确数量的样本(在audio_buffer中),但是如果将其更改为例如1.2,我突然会得到非常少的样本数,如果使用该值,则为0的1.0。我想知道链配置或从输出读取数据时是否存在错误?这是我对libsox的第一次体验,我尝试遵循示例,但是我被困在这里。
预先感谢您的帮助!
谢谢!
答案 0 :(得分:0)
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);
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