1

Mixing audio files is simple with SoX from the command line with "sox -m ..." but I'm trying to find to the exact same thing with the C library and I can't find out how to do it anywhere. Is it even possible?

Jonas
  • 121,568
  • 97
  • 310
  • 388
Johnzo
  • 112
  • 10
  • What are you *exactly* trying to achieve? Read *n* files, mix them and then…? SoX seems like a poor choice for a library; very unfriendly API. – Michał Górny Aug 24 '12 at 10:54
  • Read n files and mix them into an output file. Are there any other libraries you would suggest? – Johnzo Aug 24 '12 at 11:10
  • I still need to know more. Since you're practically performing the operation command-line `sox` does, why are you embedding it in C? – Michał Górny Aug 24 '12 at 11:57
  • SoX has a C library (http://sox.sourceforge.net/libsox.html) which we are testing out as an alternative to the command-line. There is an example code (example4.c, available in the SoX source distribution) which concatenates two files but I can't see a way to alter this to make them mix. – Johnzo Aug 24 '12 at 12:13
  • Yes, that I understand. But I'm thinking of the bigger picture. Are you creating some bigger application where the audio mixing will be one of the features? – Michał Górny Aug 24 '12 at 12:33
  • Yes, there would be one or more files, each having gone through an effect chain, and they need to be mixed together to an output file. – Johnzo Aug 24 '12 at 14:32

1 Answers1

1

Well, it is possible but the library won't help you with that.

Looking through the sox.c code, you can notice that the actual mixing code is in a static function:

for (ws = 0; ws < olen; ++ws) { /* wide samples */
  if (combine_method == sox_mix || combine_method == sox_mix_power) {
    for (s = 0; s < effp->in_signal.channels; ++s, ++p) { /* sum samples */
      *p = 0;
      for (i = 0; i < input_count; ++i)
        if (ws < z->ilen[i] && s < files[i]->ft->signal.channels) {
          /* Cast to double prevents integer overflow */
          double sample = *p + (double)z->ibuf[i][ws * files[i]->ft->signal.channels + s];
          *p = SOX_ROUND_CLIP_COUNT(sample, mixing_clips);
        }
    }
/* [...] */

So, if you really want to use sox, you can use it for file input/output, but the mixing you will need to do yourself.

Michał Górny
  • 18,713
  • 5
  • 53
  • 76
  • And by do it myself, you mean try implement those functions in my own C code? Sounds fun! – Johnzo Aug 24 '12 at 14:35
  • Or find some other library to do the mixing. But I think it should straightforward enough to be done by hand, unless you're looking for some more refined methods. – Michał Górny Aug 24 '12 at 14:47
  • Ok well I'm not a very experienced programmer but I'll see how I go. Thanks for your help! – Johnzo Aug 24 '12 at 14:54
  • Unless I'm missing something, the algorithm used here is pretty simple: for each sample `i`, `output[i] = mean(input1[i], input2[i], …)` (in pseudo-code). I'm not a sound specialist however, so there may be better methods. – Michał Górny Aug 24 '12 at 15:10