使用libsox将音频转换为FLAC

时间:2016-09-27 10:40:37

标签: c++ audio sox flac libsox

我正在尝试使用libSoX API以编程方式转换内存缓冲区中的音频。例如,它可以很好地改变采样率,但是在PCM和FLAC之间进行转换时我遇到了一些麻烦。

QByteArray inData = [...];
sox_effect_t *e;
char *args[10];

sox_globals.output_message_handler = output_message;
sox_globals.verbosity = 4;

assert(sox_init() == SOX_SUCCESS);

sox_signalinfo_t in_signal_info;
in_signal_info.channels = numChannels;
in_signal_info.length = numSamples * numChannels;
in_signal_info.precision = precision;
in_signal_info.rate = sampleRate;
in_signal_info.mult = NULL;

sox_encodinginfo_t in_encoding_info;
in_encoding_info.bits_per_sample = bitsPerSample;
in_encoding_info.encoding = SOX_ENCODING_SIGN2;

in_encoding_info.reverse_bytes = sox_option_no;
in_encoding_info.reverse_bits = sox_option_no;
in_encoding_info.opposite_endian = sox_false;
in_encoding_info.reverse_nibbles = sox_option_no;

sox_format_t *in =
    sox_open_mem_read(inData, inData.size(),
                      &in_signal_info, &in_encoding_info, "raw");

sox_format_t *out_format = (sox_format_t *)malloc(sizeof(sox_format_t));
memcpy(out_format, in, sizeof(sox_format_t));
out_format->encoding.encoding = SOX_ENCODING_FLAC;

char *outbuffer;
size_t outbuffer_size;
sox_format_t *out = sox_open_memstream_write(&outbuffer, &outbuffer_size,
                                             &out_format->signal,
                                             &out_format->encoding, "flac", NULL);

sox_effects_chain_t *chain =
sox_create_effects_chain(&in->encoding, &out->encoding);

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

e = sox_create_effect(sox_find_effect("output"));
args[0] = (char *)out;
assert(sox_effect_options(e, 1, args) == SOX_SUCCESS);
assert(sox_add_effect(chain, e, &in->signal, &out->signal) == SOX_SUCCESS);
free(e);

sox_flow_effects(chain, NULL, NULL);
sox_delete_effects_chain(chain);
sox_close(out);
free(out_format);
free(outbuffer);
sox_close(in);

我得到的输出:

DBUG formats: opening format plugin `lsx_flac_format_fn': library 0x1075ee0, entry point 0x7f3258eee5c0
FAIL formats: can't open output file `': FLAC compression level must be a whole number from 0 to 8
demo_sox: main.cpp:120: int main(int, char **): Assertion `sox_effect_options(e, 1, args) == SOX_SUCCESS' failed.

失败了:

e = sox_create_effect(sox_find_effect("output"));
args[0] = (char *)out;
assert(sox_effect_options(e, 1, args) == SOX_SUCCESS);

LibSoX的使用几乎没有文档,我这样做是否正确?

1 个答案:

答案 0 :(得分:2)

答案是为输出格式指定FLAC压缩级别:

out_format->encoding.encoding = SOX_ENCODING_FLAC;
out_format->encoding.compression = 8;