PaulStoffregen / Audio

Teensy Audio Library
http://www.pjrc.com/teensy/td_libs_Audio.html
1.07k stars 398 forks source link

Improve mixer performance when gain is 0.0 #466

Open h4yn0nnym0u5e opened 1 year ago

h4yn0nnym0u5e commented 1 year ago

The special case of 1.0 was catered for, but 0.0 can also be treated as a special case by releasing the relevant input block without multiplying and adding its data - it would be all zeroes anyway. Saves about 0.033% CPU per connected zero-gain channel, on a Teensy 4.1. Interestingly, the 1.0 gain optimisation appears to have little effect for the same hardware; those DSP instructions must be really effective!

Here's some test code:



// GUItool: begin automatically generated code
AudioSynthWaveform       wav1;           //xy=139,274
AudioMixer4              mixer1; //xy=351,170
AudioMixer4              mixer2; //xy=367,250
AudioMixer4              mixer3; //xy=395,326
AudioMixer4              mixer4; //xy=408,398
AudioMixer4              mixer5; //xy=563,294
AudioMixer4              mixer6; //xy=705,179
AudioMixer4              mixer7; //xy=729,251
AudioMixer4              mixer8; //xy=746,322
AudioMixer4              mixer9; //xy=762,392
AudioMixer4              mixer;          //xy=954,286
AudioOutputI2S           i2sOut;         //xy=1119,288

AudioConnection          patchCord1(wav1, 0, mixer1, 0);
AudioConnection          patchCord2(wav1, 0, mixer1, 1);
AudioConnection          patchCord3(wav1, 0, mixer1, 2);
AudioConnection          patchCord4(wav1, 0, mixer1, 3);
AudioConnection          patchCord5(wav1, 0, mixer2, 0);
AudioConnection          patchCord6(wav1, 0, mixer2, 1);
AudioConnection          patchCord7(wav1, 0, mixer2, 2);
AudioConnection          patchCord8(wav1, 0, mixer2, 3);
AudioConnection          patchCord9(wav1, 0, mixer3, 0);
AudioConnection          patchCord10(wav1, 0, mixer3, 1);
AudioConnection          patchCord11(wav1, 0, mixer3, 2);
AudioConnection          patchCord12(wav1, 0, mixer3, 3);
AudioConnection          patchCord13(wav1, 0, mixer4, 0);
AudioConnection          patchCord14(wav1, 0, mixer4, 1);
AudioConnection          patchCord15(wav1, 0, mixer4, 2);
AudioConnection          patchCord16(wav1, 0, mixer4, 3);
AudioConnection          patchCord17(mixer1, 0, mixer5, 0);
AudioConnection          patchCord18(mixer2, 0, mixer5, 1);
AudioConnection          patchCord19(mixer3, 0, mixer5, 2);
AudioConnection          patchCord20(mixer4, 0, mixer5, 3);
AudioConnection          patchCord21(mixer5, 0, mixer6, 0);
AudioConnection          patchCord22(mixer5, 0, mixer6, 1);
AudioConnection          patchCord23(mixer5, 0, mixer6, 2);
AudioConnection          patchCord24(mixer5, 0, mixer6, 3);
AudioConnection          patchCord25(mixer5, 0, mixer7, 0);
AudioConnection          patchCord26(mixer5, 0, mixer7, 1);
AudioConnection          patchCord27(mixer5, 0, mixer7, 2);
AudioConnection          patchCord28(mixer5, 0, mixer7, 3);
AudioConnection          patchCord29(mixer5, 0, mixer8, 0);
AudioConnection          patchCord30(mixer5, 0, mixer8, 1);
AudioConnection          patchCord31(mixer5, 0, mixer8, 2);
AudioConnection          patchCord32(mixer5, 0, mixer8, 3);
AudioConnection          patchCord33(mixer5, 0, mixer9, 0);
AudioConnection          patchCord34(mixer5, 0, mixer9, 1);
AudioConnection          patchCord35(mixer5, 0, mixer9, 2);
AudioConnection          patchCord36(mixer5, 0, mixer9, 3);
AudioConnection          patchCord37(mixer6, 0, mixer, 0);
AudioConnection          patchCord38(mixer7, 0, mixer, 1);
AudioConnection          patchCord39(mixer8, 0, mixer, 2);
AudioConnection          patchCord40(mixer9, 0, mixer, 3);
AudioConnection          patchCord41(mixer, 0, i2sOut, 0);
AudioConnection          patchCord42(mixer, 0, i2sOut, 1);

AudioControlSGTL5000     audioShield;    //xy=1106,332
// GUItool: end automatically generated code

AudioMixer4* mixerz[] = {
  &mixer1,  &mixer2,  &mixer3,  &mixer4,  &mixer5,  &mixer6,  &mixer7,  &mixer8,  &mixer9,  &mixer
};

void setGainz(float g)
{
  for (int i=0;i<10;i++)
  {
    mixerz[i]->gain(0,g);
    mixerz[i]->gain(1,g);
    mixerz[i]->gain(2,g);
    mixerz[i]->gain(3,g);
  }
  Serial.printf("Gain set to %.2f (%ld)\n",g,mixer.getMultiplier(0));
}

void setup() 
{
  AudioMemory(10);

  audioShield.enable();
  audioShield.volume(0.07);

  setGainz(0.0f);
  wav1.begin(0.2,220.0f,WAVEFORM_SINE);
}

uint32_t next;
float settings[] = {0.0f, 0.25f, 0.5f, 1.0f};
int setting;

void loop() 
{
  if (millis() > next)
  {
    next = millis() + 500;

    Serial.printf("Memory: %d; CPU %.2f\n\n", AudioMemoryUsageMax(),AudioProcessorUsageMax());
    AudioMemoryUsageMaxReset();
    AudioProcessorUsageMaxReset();

    setting++;
    if (setting > 3)
      setting = 0;
    setGainz(settings[setting]);
  }
}```