Page 1 of 1

How to understand the “mixer.xc”?

Posted: Wed Mar 07, 2018 4:25 am
by andy wong
Hi!I want to do an audio processor with multiple inputs and multiple outputs, and when I tried to change "mixer.xc" I realized I could not understand the program at all and there was no website about "mixer.xc" Information or documentation, this is very disturbing to me. The following is my question details
1, I am using the hardware is XVF3100, the firmware is vocalfusion1.1.1rc5
2,2-channel I2S input and 2-channel I2S output, the input for mixing (such as mixing the host music and speaking), the output is separated (just the same I2S signal output through 2 channels)
3, the input and output are real-time synchronization (allowing a little delay) Like conference mode
So how should I understand "mixer.xc" and modify it?
Best wishes ~

Re: How to understand the “mixer.xc”?

Posted: Fri Mar 09, 2018 10:06 am
by infiniteimprobability
mixer.xc is a fully connected matrix mixer with an extensive control path enabling re-mapping, level controls and control of both signal directions (device to host and host to device). It was originally written for pro-audio mixing apps and so is over-engineered for simple applications (as well as being optimised using ASM which makes it less readable).

I would recommend putting some simple mixing code in userbuffermanagement() in beclear_int.xc.

For the I2S build with 2ch in and out (which I think you are using) the array sampsFromAudioToUsb[] has the I2S input in the first two channels and the raw mics in the next 4 (offset by PDM_MIC_INDEX). At the end of this function the I2S outputs are populated with in the first two indicies of sampsFromUsbToAudio[] array.

You can use something like this to attenuate signals before summing them:

Code: Select all

//Attenuation block (no saturation required). (2^31 multiplier is unity)
static inline int attenuator(int input, unsigned multipler){
  int result;
  long long intermediate;
  intermediate = (long long) input * (long long) multipler;
  result = (int)(intermediate >> (31));
  return result;
}
alrady included in the source is a function which can quickly convert dB to a multiplier for the above

Code: Select all

#define DB_N_FRAC_BITS      (0) 
#define MUL_N_FRAC_BITS     (31)
#define ZERO_DB_MUL         (1 << MUL_N_FRAC_BITS)
multiplier= db_to_mult(MIC_ATTEN_DEFAULT_DB, DB_N_FRAC_BITS, MUL_N_FRAC_BITS);

So you could attenuate by 8db using:

Code: Select all

multiplier = db_to_mult(-8, DB_N_FRAC_BITS, MUL_N_FRAC_BITS);
Be careful about overflow. Eg. Make sure when summing signals that they cannot add up to more than INT_MAX. For example:

Code: Select all

mix = (left >>1) + (right >>1);
can never overflow.

Hope that makes sense...