Hello, everyone.
I’ve been reading through the mixer code and there’s one part which leaves me somewhat doubtful:
/* mix N PCM source streams to one sink stream */ static void mix_n(struct comp_dev *dev, struct comp_buffer *sink, struct comp_buffer **sources, uint32_t num_sources, uint32_t frames) { int32_t *src; int32_t *dest = sink->w_ptr; int32_t count; int64_t val[2]; int i; int j;
count = frames * dev->params.channels;
for (i = 0; i < count; i += 2) { val[0] = 0; val[1] = 0; for (j = 0; j < num_sources; j++) { src = sources[j]->r_ptr;
/* TODO: clamp */ val[0] += src[i]; val[1] += src[i + 1]; }
/* TODO: best place for attenuation ? */ dest[i] = (val[0] >> (num_sources >> 1)); dest[i + 1] = (val[1] >> (num_sources >> 1)); } }
More specifically: dest[i] = (val[0] >> (num_sources >> 1)); dest[i + 1] = (val[1] >> (num_sources >> 1));
Going back in the history of the file I found it was supposed to be an average. However, it will only be an average if num_sources is power of 2, because otherwise such bitwise operations will yield different results from what I take should be an optimized way for division.
For example, suppose we have 2 cases: • We have 2 sources, thus num_sources >> 1 will equal 1, valid right bitshift, same as division by the number of sources, which is 2 • We have 3 sources, thus num_sources >> 1 will equal 1 once again, no longer valid, because it will yield the same result as division by 2, instead of 3.
There’s one more “problem”, by averaging the samples like that we will end up with quieter output for when we have 1 source completely silent. Is that intentional?
Whether it’s all deliberate or not, or simply whether I misunderstood the code, I hope you can help me clear this up.
Thank you, Sławomir Błauciak