Skip to content

Commit

Permalink
Mixer: Switch back to f32 to get better saturation behavior
Browse files Browse the repository at this point in the history
But use arm CMSIS functions this time to keep it fast!
  • Loading branch information
qiemem committed Dec 30, 2024
1 parent b760100 commit 8e11fca
Showing 1 changed file with 21 additions and 31 deletions.
52 changes: 21 additions & 31 deletions software/src/Audio/AudioMixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,54 +12,44 @@ class AudioMixer : public AudioStream {

void gain(size_t channel, float gain) {
if (channel >= NumChannels) return;
int8_t shift = 0;
while (gain < -1.0f || gain > 0.999969f) {
gain /= 2.0f;
shift++;
}
scale_fracts[channel] = float_to_q15(gain);
shifts[channel] = shift;
gains[channel] = gain;
}

virtual void update(void) {
audio_block_t* out = NULL;
q15_t aux[AUDIO_BLOCK_SAMPLES];
float aux[AUDIO_BLOCK_SAMPLES];
float out[AUDIO_BLOCK_SAMPLES];
bool out_filled = false;

// Originally I had this scaling and mixing all with q15 but that has much
// less desirable saturation behavior with phase correlated material.
for (size_t channel = 0; channel < NumChannels; channel++) {
q15_t scalar = scale_fracts[channel];
int8_t shift = shifts[channel];
auto* in = receiveReadOnly(channel);
if (in) {
if (!out) {
out = allocate();
if (!out) {
release(in);
return;
}
arm_fill_q15(0, out->data, AUDIO_BLOCK_SAMPLES);
float gain = gains[channel];
if (!out_filled) {
arm_fill_f32(0.0f, out, AUDIO_BLOCK_SAMPLES);
out_filled = true;
}
if (scalar != 0) {
// Don't scale for unity gain; that's represented by 0.5 in q15 with a
// shift of 1
if (scalar != 16384 || shift != 1) {
arm_scale_q15(in->data, scalar, shift, aux, AUDIO_BLOCK_SAMPLES);
arm_add_q15(aux, out->data, out->data, AUDIO_BLOCK_SAMPLES);
} else {
arm_add_q15(in->data, out->data, out->data, AUDIO_BLOCK_SAMPLES);
if (gain != 0.0f) {
arm_q15_to_float(in->data, aux, AUDIO_BLOCK_SAMPLES);
if (gain != 1.0f) {
arm_scale_f32(aux, gain, aux, AUDIO_BLOCK_SAMPLES);
}
arm_add_f32(aux, out, out, AUDIO_BLOCK_SAMPLES);
}
release(in);
}
}

if (out != NULL) {
transmit(out);
release(out);
if (out_filled) {
audio_block_t* out_block = allocate();
arm_float_to_q15(out, out_block->data, AUDIO_BLOCK_SAMPLES);
transmit(out_block);
release(out_block);
}
}

private:
audio_block_t* inputQueueArray[NumChannels];
std::array<q15_t, NumChannels> scale_fracts;
std::array<int8_t, NumChannels> shifts;
std::array<float, NumChannels> gains = {0.0f};
};

0 comments on commit 8e11fca

Please sign in to comment.