Mixing is how two sounds become one - you add them sample by sample. Like gain, the sum can exceed the range, so today reuses the clamp to keep a loud mix from wrapping into noise.
Add two signals sample by sample, clamping the sum to the 16-bit range.
Mixing combines two signals into one by adding their samples position by position - the mathematical truth that sound pressures superimpose. Two voices, a tone plus a drum, a signal plus its echo: all of them are a sample-wise sum. Where both signals are loud and in phase, the sum can easily exceed the range, so mixing has the same overflow hazard as gain and the same answer.
Reuse clampInt16: add the two samples, then clamp. 20000 + 20000 is 40000,
which clamps to 32767 - crucially not the value a naive 16-bit add would give,
where 40000 wraps around to -25536 and a loud passage turns to a click. The
negative edge mirrors it: -20000 + -20000 clamps to -32768. Assume the two
signals are the same length here; padding a shorter one is a detail you can add
later. Mixing plus gain are the two building blocks the capstone leans on hardest.
func mix(a, b []int) []int {out := make([]int, len(a))for i := range a {out[i] = clampInt16(a[i] + b[i]) // sum, then clamp - never wrap}return out}