I just thought of something possibly cool...

Have a mixing function as already mentioned that sums the waves, but also return a variable that shows if, and by how much that the output has overflowed/underflowed.

Then using this value adjust the combined output slightly to stop the clipping

Maybe something like this (not tested...)?

Code:
function MixWaveValues(const aValues: array of Integer; var aHasClipped: Boolean; 
// aHasClipped returns true if input has clipped ( < -128 or > +127)
// aClippedAmount returns the integer amount under/over the minimum/maximum values.
var aClippedAmount: Integer): Integer; 
var
  i: Integer;
  Value: Integer;
begin
  aHasClipped := False;
  aClippedAmount := 0;

  Value:= 0;
  for i := 0 to High(aValues) do
  begin
    Value:= Value+ aValues[i];
    if Value < -128 then
    begin
      aHasClipped := True;
      if (Value + 128) < aClippedAmount then aClippedAmount := Value + 128;
    end
    else
    if Value > +127 then
    begin
      aHasClipped := True;
      if (Value - 127) > aClippedAmount then aClippedAmount := Value - 127;
    end
  end;
  Result := Value;
end;
cheers,
Paul