PDA

View Full Version : How to mix waves



Ñuño Martínez
06-06-2011, 10:27 AM
I've made a "wave reator" to simulate old sound stuff (square, saw, sinus and noise). Now I want to write a function to mix the waves.

I did something similar to:

(* Pseudo Pascal *)
FUNCTION MixWaves (Wave1, Wave2: ARRAY OF BYTE): ARRAY OF BITE
BEGIN
FOR B := 1 TO Length (Wave1) DO
Result[B] := (Wave1[B] + Wave2[B]) DIV 2;
END;
It almost works but the result sounds "softer" (I mean with less volume).

What function should I use?

JSoftware
06-06-2011, 11:22 AM
Just sum them :)

If you fear it might overflow then adjust gain in the inputs before mixing


(* Pseudo Pascal *)
FUNCTION MixWaves (Wave1, Wave2: ARRAY OF BYTE): ARRAY OF BITE
BEGIN
FOR B := 1 TO Length (Wave1) DO
Result[B] := Wave1[B] + Wave2[B];
END;

Dan
06-06-2011, 12:12 PM
Result[B] := Min(Wave1[B] + Wave2[B], 255); that should do it

paul_nicholls
07-06-2011, 07:04 AM
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...)?


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

paul_nicholls
24-07-2011, 09:04 PM
I've made a "wave reator" to simulate old sound stuff (square, saw, sinus and noise). Now I want to write a function to mix the waves.

I did something similar to:

(* Pseudo Pascal *)
FUNCTION MixWaves (Wave1, Wave2: ARRAY OF BYTE): ARRAY OF BITE
BEGIN
FOR B := 1 TO Length (Wave1) DO
Result[B] := (Wave1[B] + Wave2[B]) DIV 2;
END;
It almost works but the result sounds "softer" (I mean with less volume).

What function should I use?

I know it has been a while, but I found this site the other day which might help with the mixing and volume issues:
http://www.vttoth.com/digimix.htm

cheers,
Paul

Ñuño Martínez
26-07-2011, 10:19 AM
Didn't I reply you? IIRC i commented that JSoftware's and Dan's solution would result in distorted sound. BTW I didn't tested it yet so I can't tell you.

paul_nicholls
26-07-2011, 10:29 AM
Didn't I reply you? IIRC i commented that JSoftware's and Dan's solution would result in distorted sound. BTW I didn't tested it yet so I can't tell you.

No, I hadn't seen any reply from you.

Anyway, apparently the link I gave you makes mixing possible without volume changes or distortions :)

cheers,
Paul

JSoftware
26-07-2011, 10:29 AM
This article sums it up pretty nicely. http://kebby.org/articles/fr08snd4.html

Just under the illustration in section 4.2 there's a section about mixing. In short, don't do any tricks to avoid clipping

paul_nicholls
26-07-2011, 11:48 AM
This article sums it up pretty nicely. http://kebby.org/articles/fr08snd4.html

Just under the illustration in section 4.2 there's a section about mixing. In short, don't do any tricks to avoid clipping

hmm...interesting article, thanks for sharing :)

cheers,
Paul