Entwickler-Ecke

Multimedia / Grafik - TMemoryStream, WAV mischen


der organist - Di 22.10.13 10:50
Titel: TMemoryStream, WAV mischen
Hallo Forum,

ich möchte gerne zwei Töne (Klavier, in wav vorhanden) mischen, so dass ich nachher beide Töne im Ausgabe Stream übereinander habe.

Dazu mache ich folgendes:
Lade beide ein einzelne Streams,
Mischen, momentan mit dem Mittelwert
Speichern

Das klappt auch soweit ganz gut. Meine Frage ist: Ist der "Mischalgorithmus" falsch? Das Ergebnis ist nicht das, was ich hören will...

Der Code dazu, die Ein/Ausgabetöne hab ich mal angehangen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure TIntervalForm.Button1Click(Sender: TObject);
var
  Stream1,Stream2,Ziel:TMemoryStream;
  k,DataCount: Integer;
  SoundValue1,SoundValue2,SoundValue:Byte;

begin

  DataCount:=trunc(900*44100/1000);      //Länge/ms*Bitrate/1000

  Stream1:=TMemoryStream.Create;
  Stream2:=TMemoryStream.Create;
  Ziel:=TMemoryStream.Create;

  Stream1.LoadFromFile(ExtractFilePath(ParamStr(0))+'\Töne\01c1.wav');
  Stream2.LoadFromFile(ExtractFilePath(ParamStr(0))+'\Töne\08g1.wav');

  for k := 0 to DataCount-1 do begin
    Stream2.Read(SoundValue1,SizeOf(Byte));
    Stream1.Read(SoundValue2,SizeOf(Byte));
    SoundValue:=(SoundValue1+SoundValue2)div 2;
    Ziel.Write(SoundValue,SizeOf(Byte));
  end;

  Stream1.Seek(0, soFromBeginning);
  Stream2.Seek(0, soFromBeginning);
  Ziel.Seek(0, soFromBeginning);
  Ziel.SaveToFile(ExtractFilePath(ParamStr(0))+'Ziel.wav');

  Stream1.Free;
  Stream2.Free;
  Ziel.Free;
end;


Gruss und besten Dank für eure Antworten,
Lukas


Sinspin - Di 22.10.13 12:57

Prinzipiell ist dein vorgehen richtig. Ich habe mit dieser Methode immer gute Ergebnisse erziehlt. Aber du musst beachten wieviel Byte du pro Sample hast und ob in der Datei RAW Daten oder eine Wav Datei enthalten ist. Heutzutage wird meißt mit 16 Bit pro Sample gearbeitet. Du musst also integer lesen und schreiben. Hast du Wav Dateien geladen musst du zusätzlich noch über den Header der Datei hinweg. Dazu am besten mal die Suche im Netz bemühen um dich mit dem Format vertraut zu machen.

Ansonsten, wenn du eher das Ergebnis haben willst und dich eigentlich nicht für den Weg dahin interessierst, schau dir mal Trackerprogramme an. Ich verwenden schon seit Jahren MPT (Modplug Tracker), jetzt als Open MPT in SF zu finden.


der organist - Di 22.10.13 20:33

Hei Sinspin,

die Idee mit Modplug Tracker ist sehr gut, allerdings soll es ein Programm zum Üben von Intervallen werden; d.h. ich will zwei zufällig Töne nehmen. Es wäre zu viel Datenkrams, wenn ich alle Kombinationen mitgebe. Daher das Mischverfahren..

Kennst du denn gute Tutorials? Ich will nicht tief in die Materie hinein und mich dort auch nicht lange aufhalten ;)

Gruss,
Lukas


Sinspin - Di 22.10.13 21:34

Schreib es doch selber. Deine Methode zum Mischen ist doch gut. Nur am aufbereiten der Daten musst du noch arbeiten.
Als erstes, schreib erstmal ein Programm mit dem du eine .wav Datei, also deren Schwingung, als Grafik darstellen kannst. Wenn du das hast ist alles da um auch zu mischen. Zudem kannst du dann das Ergebnis visualisieren, was bei einfachen Sinusschwingungen recht interessant aussieht.


Martok - Di 22.10.13 22:58

Müssen es denn Wave-Dateien sein oder geht es dir nur um die Töne an sich?

Zum Thema Hüllkurvensynthese kann ich das Synthie-Tutorial von DGL [http://wiki.delphigl.com/index.php/Tutorial_Software-Synthesizer] immer empfehlen. Selbst wenn man nicht den Code direkt benutzt, ist es eine sehr schöne Einführung dazu, wie man KrachTöne machen kann.


GuaAck - Mi 23.10.13 19:44

Hallo,

ich habe vor einigen Jahren mal ein besonders Entknackser-Programm machen wollen, es lief, der Erfolg war nicht so toll. Aber die Reste kannst Du evtl verwerten. Da lese ich die Werte aus einem Stream, löse die Struktur (die Chunks) auf und habe die Infos zu Bytes per Sample, Anzahl Kanäle (Stereo?) usw. verfügbar. Der Code (lausig kommentiert, ich weiß..) anbei, in der HTML-datei ist das WAV-Format schön knapp beschrieben.

Zum Algorithmus: Mehr als addieren macht ein Mikrofon ja auch nicht. Mit einer nicht-linearen Funktion bekäme man erhebliche Verzerrungen. Man könnte lediglich eine Gewichtung machen nach dem Muster (a*x1+b*x2)/(a+b).

Beste Grüße
GuaAck


der organist - Sa 26.10.13 13:46

Danke ihr drei,
eure Antworten scheinen auf den ersten Blick sehr hilfreich, allen voran das Projekt zum Download. Ich werde nur momentan leider nicht weiter dran arbeiten können, aber es sobald wie möglich versuchen.

Einzigen Haken: Die glib-Unit, ist die Freeware oder woher hast du die?

Gruss,
Lukas


GuaAck - So 27.10.13 00:26

Hallo Organist,

der Code sollte Dir eigentlich nur Schnipsel liefern für Dein Problem. Das Programm selbst lieferte ja schlechte Ergebnisse, deshalb habe ich die Idee nicht weiter verfolgt. Aber lauffähig ist das Programm. Glib2 ist ein Grafik-Paket zum Plotten von x-y-Diagrammen. Ich habe es vor langer Zeit selbst angefangen und immer wieder um neue Funktionen ergänzt. In dem WAV-Projekt wird damit eine statistische Analyse der WAV-Datei geplottet. Hat aber kaum Nährwert.

Trotzdem, falls Du den Code gerne laufen lassen möchtest, anbei die ZIP-Datei mit der glib2-unit.

Gruß
GuaAck