const Tube122 = ({ input, output, pre, dist, q, post }) => {
  const filter = useBiQuadFilter();
  for (let i = 0; i < input.length; i ++) {
    const x = input[i] * pre[i];
    if (q[i] === 0) {
      if (x === 0) {
        output[i] = 1/dist[i];
      } else {
        output[i] = x / (1 - Math.exp(-dist[i] * x));
      }
    } else {
      if (x === q[i]) {
        output[i] = 1 / dist[i] + q / (1 - Math.exp(dist[i] * q[i]));
      } else {
        output[i] = (x - q[i]) / (1 - Math.exp((-dist[i] * (x - q[i])))) + q[i] / (1 - Math.exp(dist[i] * q[i]));
      }
    }
  }
  const filtered = filter(output, BiQuadFilterMode.HighPass, useConstantBuffer(20), useConstantBuffer(1), useConstantBuffer(0));
  for (let i = 0; i < output.length; i ++) {
    output[i] = filtered[i] * post[i];
  }
}

this.constructDevice = () => constructPerChannelDevice({
  implementation: Tube122,
  inputs: {
    input: stereo('In'),
    pre: dbSetting('Pre-Gain', { defaultValue: 16, min: -24, max: 24 }),
    dist: numberSetting('Dist', { defaultValue: 1, min: 1, max: 10 }),
    q: numberSetting('Q', { defaultValue: -.1, min: -2, max: 2 }),
    post: dbSetting('Post-Gain', { defaultValue: -12, min: -24, max: 24 }),
  },
  outputs: {
    output: stereo('Out'),
  }
});
