| 142 | } |
| 143 | |
| 144 | void process(const ProcessArgs &args) override { |
| 145 | |
| 146 | int maxChannels = 1; |
| 147 | float_4 mix[4] = {}; |
| 148 | float_4 channelCrossFades[4] = {}; |
| 149 | const float masterCrossfadeValue = computeMasterCrossfade(args.sampleTime); |
| 150 | |
| 151 | for (int i = 0; i < NUM_MIXER_CHANNELS; i++) { |
| 152 | |
| 153 | const int channels = std::max(std::max(inputs[A_INPUT + i].getChannels(), inputs[B_INPUT + i].getChannels()), 1); |
| 154 | // keep track of the max number of channels for the mix output, noting that if channels are taken out of the mix |
| 155 | // (i.e. they're connected) they shouldn't contribute to the mix polyphony calculation |
| 156 | if (!outputs[OUT + i].isConnected()) { |
| 157 | maxChannels = std::max(maxChannels, channels); |
| 158 | } |
| 159 | |
| 160 | float_4 out[4] = {}; |
| 161 | for (int c = 0; c < channels; c += 4) { |
| 162 | float_4 inA = inputs[A_INPUT + i].getNormalVoltageSimd(normal10VSimd, c) * params[A_LEVEL + i].getValue(); |
| 163 | float_4 inB = inputs[B_INPUT + i].getNormalVoltageSimd(normal10VSimd, c) * params[B_LEVEL + i].getValue(); |
| 164 | channelCrossFades[c / 4] = computeChannelCrossfadePoly(i, c, masterCrossfadeValue); |
| 165 | |
| 166 | switch (static_cast<CrossfadeMode>(params[MODE + i].getValue())) { |
| 167 | case CV_MODE: { |
| 168 | out[c / 4] = equalSumCrossfade(inA, inB, channelCrossFades[c / 4]); |
| 169 | break; |
| 170 | } |
| 171 | case AUDIO_MODE: { |
| 172 | // in audio mode, close to the centre point it is possible to get large voltages |
| 173 | // (e.g. if A and B are both 10V const). however according to the standard, it is |
| 174 | // better not to clip this https://vcvrack.com/manual/VoltageStandards#Output-Saturation |
| 175 | out[c / 4] = equalPowerCrossfade(inA, inB, channelCrossFades[c / 4]); |
| 176 | break; |
| 177 | } |
| 178 | default: { |
| 179 | out[c / 4] = 0.f; |
| 180 | } |
| 181 | } |
| 182 | } |
| 183 | |
| 184 | // if output is patched, the channel is taken out of the mix |
| 185 | if (outputs[OUT + i].isConnected() && i != NUM_MIXER_CHANNELS - 1) { |
| 186 | outputs[OUT + i].setChannels(channels); |
| 187 | for (int c = 0; c < channels; c += 4) { |
| 188 | outputs[OUT + i].setVoltageSimd(out[c / 4], c); |
| 189 | } |
| 190 | } else { |
| 191 | for (int c = 0; c < channels; c += 4) { |
| 192 | mix[c / 4] += out[c / 4]; |
| 193 | } |
| 194 | } |
| 195 | |
| 196 | if (i == NUM_MIXER_CHANNELS - 1) { |
| 197 | outputs[OUT + i].setChannels(maxChannels); |
| 198 | |
| 199 | for (int c = 0; c < maxChannels; c += 4) { |
| 200 | outputs[OUT + i].setVoltageSimd(mix[c / 4], c); |
| 201 | } |
no test coverage detected