AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Zwei Stereo Streams zusammenmischen
Thema durchsuchen
Ansicht
Themen-Optionen

Zwei Stereo Streams zusammenmischen

Ein Thema von Six · begonnen am 30. Jul 2005 · letzter Beitrag vom 31. Jul 2005
Antwort Antwort
Seite 1 von 2  1 2      
Six

Registriert seit: 2. Jun 2005
42 Beiträge
 
#1

Zwei Stereo Streams zusammenmischen

  Alt 30. Jul 2005, 03:38
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
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

Re: Zwei Stereo Streams zusammenmischen

  Alt 30. Jul 2005, 09:27
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?
Volker
  Mit Zitat antworten Zitat
Six

Registriert seit: 2. Jun 2005
42 Beiträge
 
#3

Re: Zwei Stereo Streams zusammenmischen

  Alt 30. Jul 2005, 14:45
Hi Flocke,

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

Size ist eine Globale Variable.

Gruß

Six
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#4

Re: Zwei Stereo Streams zusammenmischen

  Alt 30. Jul 2005, 14:55
Hallo,
Zitat von Flocke:
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
  Mit Zitat antworten Zitat
Six

Registriert seit: 2. Jun 2005
42 Beiträge
 
#5

Re: Zwei Stereo Streams zusammenmischen

  Alt 30. Jul 2005, 15:04
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
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#6

Re: Zwei Stereo Streams zusammenmischen

  Alt 30. Jul 2005, 15:09
Hallo,
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
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

Re: Zwei Stereo Streams zusammenmischen

  Alt 30. Jul 2005, 18:17
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;
Volker
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#8

Re: Zwei Stereo Streams zusammenmischen

  Alt 30. Jul 2005, 18:34
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 . Aber es ist normalerweise immer einfacher, den Wert erst in ein Word umzuwandeln (32768 addieren), dann geht vieles einfacher, z. B. die Faktorberechnung.
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
  Mit Zitat antworten Zitat
Six

Registriert seit: 2. Jun 2005
42 Beiträge
 
#9

Re: Zwei Stereo Streams zusammenmischen

  Alt 30. Jul 2005, 18:40
Danke euch beiden, ich werde das jetzt mal testen!

Gruß

Six
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

Re: Zwei Stereo Streams zusammenmischen

  Alt 31. Jul 2005, 11:15
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 .

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
Volker
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz