Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Zwei Stereo Streams zusammenmischen (https://www.delphipraxis.net/50718-zwei-stereo-streams-zusammenmischen.html)

Six 30. Jul 2005 02:38


Zwei Stereo Streams zusammenmischen
 
Hallo,

wie kann ich zwei Stereostreams zusammenmischen?

So geht es mit zwei Monostreams (Ergebnis ein Stereo Stream):

Delphi-Quellcode:
function TForm1.SoundStreamsMischenMono(Stream1, Stream2: PSmallInt): PSmallInt;
var
  i: integer;
  Data2, Data3, Data4, Ziel, Ziel2: PSmallInt;
begin
  Ziel := 0;
  Ziel2 := 0;
  Data2 := 0;
  Data4 := 0;
  GetMem(Ziel, Size * 2);
  Ziel2 := Ziel;
  Data2 := Stream1;
  Data4 := Stream2;
  for i := (Size div 2) - 1 downto 0 do
  begin
    ziel2^ := Data2^;
    Inc(Ziel2);
    Inc(Data2);
    ziel2^ := Data4^;
    Inc(Ziel2);
    Inc(Data4);
  end;
  Result := Ziel;
end; //  SoundStreamsMischen (TForm1)
Was muss ich ändern, um zwei Stereostreams Mischen zu können?

Dankeschön!

Six

Flocke 30. Jul 2005 08:27

Re: Zwei Stereo Streams zusammenmischen
 
Also in deinem Beispiel mixt du zwei Mono-Streams zu einem Stereo-Stream zusammen.

Mono-Stream: jeweils ein 16-Bit-Wert je Sample
Stereo-Stream: jeweils zwei 16-Bit-Werte je Sample, abwechselnd links und rechts.

Das Zusammenmischen von Audiodaten ist normalerweise eine einfache Addition, wobei du aber auf Überlauf prüfen oder ggf. eine Anpassung der Lautstärke machen musst.

Delphi-Quellcode:
function TForm1.SoundStreamsMischenStereo(Stream1, Stream2: PSmallInt): PSmallInt;
var
  i: integer;
  Data2, Data3, Data4, Ziel, Ziel2: PSmallInt;
begin
  GetMem(Ziel, Size);
  Ziel2 := Ziel;
  Data2 := Stream1;
  Data4 := Stream2;
  for i := Size - 1 downto 0 do
  begin
    ziel2^ := (Data2^ + Data4^) div 2; // Halbe Lautstärke -> kein Überlauf möglich
    Inc(Ziel2);
    Inc(Data2);
    Inc(Data4);
  end;
  Result := Ziel;
end;
Frage: woher kommt die Variable Size?

Six 30. Jul 2005 13:45

Re: Zwei Stereo Streams zusammenmischen
 
Hi Flocke,

Danke für deine Hilfe, ich werde es gleich mal testen.

Size ist eine Globale Variable.

Gruß

Six

xaromz 30. Jul 2005 13:55

Re: Zwei Stereo Streams zusammenmischen
 
Hallo,
Zitat:

Zitat von Flocke
Delphi-Quellcode:
ziel2^ := (Data2^ + Data4^) div 2; // Halbe Lautstärke -> kein Überlauf möglich

Das würde ich so nicht machen. Besser ist wohl mit Automatic Gain Control (AGC). Funktioniert eigentlich ganz einfach:

Werte Zusammenzählen.
Wenn die Werte zu groß sind, den Wert mittels eines Faktors zurechtstutzen (z.B. mit 0.5 malnehmen).
Nun bei jeder weiteren Addition den Faktor erhöhen, bis der Faktor wieder Eins ist oder eben gegebenenfalls den Faktor wieder anpassen, wenn das Ergebnis zu groß ist.

Damit wird dein Stream nicht zu leise, und plötzliche Lautstärkewechsel werden vermieden. Den Anstieg des Faktors am besten ausprobieren oder per Eingabe abfragen. Je kleiner die Erhöhung, desto weniger "unruhig" ist der Lautstärkeverlauf, aber die Lautstärke bzw. die Dynamik geht etwas flöten.

Gruß
xaromz

Six 30. Jul 2005 14:04

Re: Zwei Stereo Streams zusammenmischen
 
Hi xaromz,

Zitat:

Wenn die Werte zu groß sind
danke für den Tipp, aber wann sind denn die Werte zu groß, bzw. wie kann ich das abfragen?

Gruß

Six

xaromz 30. Jul 2005 14:09

Re: Zwei Stereo Streams zusammenmischen
 
Hallo,
Zitat:

Zitat von Six
danke für den Tipp, aber wann sind denn die Werte zu groß, bzw. wie kann ich das abfragen?

Ganz einfach: Du zählst die Werte zusammen und speicherst das Ergebnis in einem Integer. Wenn der Wert größer als 65535 ist, dann ist der Wert zu groß und Du musst ist stutzen, so dass er kleiner oder gleich 65535 ist.

Gruß
xaromz

Flocke 30. Jul 2005 17:17

Re: Zwei Stereo Streams zusammenmischen
 
Zitat:

Zitat von xaromz
Wenn der Wert größer als 65535 ist, dann ist der Wert zu groß und Du musst ist stutzen, so dass er kleiner oder gleich 65535 ist.

16-Bit Audiosamples werden vorzeichenbehaftet gespeichert, der Wert muss also zwischen -32768 und +32767 liegen.

Außerdem ist eine dynamische Signalanpassung ein etwas kompliziertes Unterfangen für jemanden, der zu Beginn der Fragestellung nicht wusste, wie man zwei Audiosignale mischt.

@Six:

Wenn du die kompletten Audiostreams auf einen Schlag verarbeitest, dann kannst du zunächst den maximalen absoluten Sample-Wert berechnen, der bei der Addition der beiden Streams herauskommt. Danach kannst du dann einen Faktor <= 1 berechnen, so dass dieser Wert 32767 nicht übersteigt. Dafür bräuchtest du dann zwei Durchläufe.

Beispiel (ungetestet):
Delphi-Quellcode:
function TForm1.SoundStreamsMischenStereo2(Stream1, Stream2: PSmallInt): PSmallInt;
var
  i, n, d, v: integer;
  Data2, Data3, Data4, Ziel, Ziel2: PSmallInt;
begin
  n := 32767;
  d := 32767;

  // Erster Durchlauf: d (Divisor) anpassen
  Data2 := Stream1;
  Data4 := Stream2;
  for i := Size - 1 downto 0 do
  begin
    v := Data2^ + Data4^;
    if v > d then
      d := v
    else if -v > d then
      d := -v;
    Inc(Data2);
    Inc(Data4);
  end;

  // Zweiter Durchlauf: Ziel berechnen, mit Pegelanpassung
  GetMem(Ziel, Size);
  Ziel2 := Ziel;
  Data2 := Stream1;
  Data4 := Stream2;
  for i := Size - 1 downto 0 do
  begin
    ziel2^ := (Data2^ + Data4^) * n div d;
    Inc(Ziel2);
    Inc(Data2);
    Inc(Data4);
  end;
  Result := Ziel;
end;

xaromz 30. Jul 2005 17:34

Re: Zwei Stereo Streams zusammenmischen
 
Zitat:

Zitat von Flocke
16-Bit Audiosamples werden vorzeichenbehaftet gespeichert, der Wert muss also zwischen -32768 und +32767 liegen.

Das mit dem Vorzeichen weiß ich auch, hatte ich nur vergessen :oops: . Aber es ist normalerweise immer einfacher, den Wert erst in ein Word umzuwandeln (32768 addieren), dann geht vieles einfacher, z. B. die Faktorberechnung.
Zitat:

Zitat von Flocke
Außerdem ist eine dynamische Signalanpassung ein etwas kompliziertes Unterfangen für jemanden, der zu Beginn der Fragestellung nicht wusste, wie man zwei Audiosignale mischt.

Eine dynamische Signalanpassung ist auch nicht viel schwieriger als das, was Du angeboten hast, man muss eben nur die Berechnung des Faktors in die Schleife ziehen. Aber so, wie Du das vorgeschlagen hast, reichts für den Hausgebrauch sicher auch (mit dynamischer Anpassung hat man ja auch einen gewissen Qualitätsverlust).

Gruß
xaromz

Six 30. Jul 2005 17:40

Re: Zwei Stereo Streams zusammenmischen
 
Danke euch beiden, ich werde das jetzt mal testen!

Gruß

Six

Flocke 31. Jul 2005 10:15

Re: Zwei Stereo Streams zusammenmischen
 
Zitat:

Zitat von xaromz
Aber es ist normalerweise immer einfacher, den Wert erst in ein Word umzuwandeln (32768 addieren), dann geht vieles einfacher, z. B. die Faktorberechnung.

Hui, das ist aber nicht ungefährlich, weil du dann bei jeder Skalierung den 0-Punkt verschiebst :roll:.

Beispiel: du willst N Samples auf die halbe Lautstärke reduzieren, die sind aber alle 0 (also Stille). Dann kriegst du danach N Samples mit dem Wert -16384.
Code:
Y := ((X + 32768) / 2) - 32768;

     ((0 + 32768) / 2) - 32768 =
        32768    /  2  - 32768 =
            16483      - 32768 = -16384


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:44 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz