Stephen Paterson wrote:
I can't get it to work with libsox. I've made a tiny modification to
example3.c that should do the same but no matter what I try I always
end up with a file that is exactly half the length of the one I get
from sox (or some crazy audio).
example3 is buggy. It doesn't take into account that sox_add_effect()
modifies the "in" signalinfo, which is why it isn't a good idea to
pass it a signalinfo that is still in use elsewhere, or to call
sox_add_effect() with identical in and out signalinfos.
What is happening here is that in->signal.length, after the
sox_open_read(), contains some value like 882000, for a 10-second
stereo 44100 Hz input file. After adding "rate", the value will have
changed to 160000, and after "channels", to 80000. Because it is the
same memory location all the time, the input format handler (from
sox_open_read()) will see this value as well and think that its file
is only 80000 samples long. It will therefore stop reading after 80000
samples (/2 channels, /44100 Hz = 0.907 seconds), and that is all that
is processed by the effects chain.
See the attached diff for how to use a copy of the signalinfo instead.
Ulrich
--- main-pre.c 2013-04-10 17:12:23.000000000 +0200
+++ main.c 2013-04-10 17:20:10.000000000 +0200
@@ -4,6 +4,7 @@
int main(int argc, char * argv[])
{
static sox_format_t * in, * out;
+ sox_signalinfo_t c;
sox_effects_chain_t * chain;
sox_effect_t * e;
char * args[10];
@@ -13,13 +14,14 @@
assert(sox_init() == SOX_SUCCESS);
assert(in = sox_open_read(argv[1], NULL, NULL, NULL));
+ c = in->signal; /* NB: deep copy */
assert(out= sox_open_write("converted.wav", &in->signal, NULL, "wav",
NULL, NULL));
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);
+ assert(sox_add_effect(chain, e, &c, &in->signal) == SOX_SUCCESS);
free(e);
out->signal.precision = 16;
@@ -29,20 +31,20 @@
if (in->signal.rate != out->signal.rate) {
e = sox_create_effect(sox_find_effect("rate"));
assert(sox_effect_options(e, 0, NULL) == SOX_SUCCESS);
- assert(sox_add_effect(chain, e, &in->signal, &out->signal) ==
SOX_SUCCESS);
+ assert(sox_add_effect(chain, e, &c, &out->signal) ==
SOX_SUCCESS);
free(e);
}
if (in->signal.channels != out->signal.channels) {
e = sox_create_effect(sox_find_effect("channels"));
assert(sox_effect_options(e, 0, NULL) == SOX_SUCCESS);
- assert(sox_add_effect(chain, e, &in->signal, &out->signal) ==
SOX_SUCCESS);
+ assert(sox_add_effect(chain, e, &c, &out->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);
+ assert(sox_add_effect(chain, e, &c, &out->signal) == SOX_SUCCESS);
free(e);
sox_flow_effects(chain, NULL, NULL);
------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________
SoX-devel mailing list
SoX-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sox-devel