首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用libSox链接多个效果并读取输出数据的正确方法

用libSox链接多个效果并读取输出数据的正确方法
EN

Stack Overflow用户
提问于 2018-08-18 12:17:48
回答 1查看 727关注 0票数 3

我正在尝试以编程的方式使用libSox应用很少的效果,目前我无法理解我是否做得对。例如,我需要应用速度并获得效果,并在缓冲区中读取产生的音频以供进一步处理。这些文档非常稀少,谷歌搜索也没有结果。这是我的代码:

代码语言:javascript
复制
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. 如何读取内存中产生的音频示例? 如果我使用tempo值<1,我从输出中得到正确的样本数(在audio_buffer中),但是如果我将它更改为1.2,我突然得到了非常少的样本数,如果我使用1.0的值,则得到0。我想知道我的链式配置中是否有错误,还是从输出中读取数据?这是我第一次接触libsox,我试着学习一些例子,但是我被困在这里了。

提前感谢您的帮助!

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-28 23:02:15

  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,然后它似乎正确工作。

所以,您的代码将如下所示:

代码语言:javascript
复制
...
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51908577

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档