How to understand the “mixer.xc”?

New to XMOS and XCore? Get started here.
Post Reply
andy wong
Member
Posts: 12
Joined: Tue Jan 02, 2018 12:04 pm

How to understand the “mixer.xc”?

Post 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 ~


User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post 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...
Post Reply