AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Audio programmiertechnisch in Lautstärke & Tonhöhe verändern
Thema durchsuchen
Ansicht
Themen-Optionen

Audio programmiertechnisch in Lautstärke & Tonhöhe verändern

Ein Thema von St. Janos · begonnen am 15. Feb 2007 · letzter Beitrag vom 16. Feb 2007
Antwort Antwort
St. Janos

Registriert seit: 25. Dez 2004
Ort: North Germany
12 Beiträge
 
#1

Audio programmiertechnisch in Lautstärke & Tonhöhe verän

  Alt 15. Feb 2007, 15:07
ahoi,
Vorwort:
ich habe vor ein Programm zu schreiben, mit welchem man innerhalb einer Audio-Datei ab einer vorbestimmten Position für eine bestimmte Zeitspanne (sollte möglich sein als minimal wie auch sehr gross definiert zu werden) die Lautstärke zu verringer oder anzuheben (wieder von minimal bis sehr stark) oder die Tonhöhe zu verringer bzw. anzuheben (auch wieder von minimal bis sehr stark). Oder beides. Nach der Veränderung sollte es möglich sein, die veränderte Audio-Datei abzuspeichern. So das die Änderungen in der abgespeicherten Version "hart-kodiert" sind bzw. fest verankert sind. Also nicht via Tag-Information.

Da ich noch ganz am Anfang meines Projektes stehe, stellt sich mir vorerst einmal die Frage: Welche Programmiersprache und auch welches Audioformat sich für mein Vorhaben am besten eignet.
Bzgl. der Audioformate bin ich recht frei in der Wahl. Wer da also eins empfehlen kann, egal welches, immer nur raus damit
In sachen Programmiersprachen würde ich natürlich gerne eine Sprache nutzen, in der ich mich bereits grundlegend auskenne.
Favorisiert wären deshalb: C, Objekt Pascal (Delphi 7) oder Java
Da ich mich jedoch noch nie mit der programmiertechnischen Seite der Audioverarbeitung wie .bearbeitung befasst habe, würde ich bei triftigen Gründen mich auch in eine neue Programmiersprache einfinden wollen

Die Frage:
Worum ich Euch nun bitten würde, mir hier vielleicht einmal Eure Empfehlungen nieder zu schreiben. Gerne auch mit der ein oder anderen Begründung oder Verweisen zu Informationsquellen bzgl. Audioverarbeitung mit jeglicher Programmiersprache.
Wenn jmd. hat, wuerde ich mich auch sehr über Quellcoden zu dem Thema freuen, mit dem ich ein wenig rumexperimentieren kann
Ich freue mich auf Antwort.

Grüße

Janos
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#2

Re: Audio programmiertechnisch in Lautstärke & Tonhöhe v

  Alt 15. Feb 2007, 16:41
So ein Programm muss man ganz klar in Delphi schreiben.
Als Audioformat kommt vorallem das Wav-Format mit 16 Bit in Frage.
Die Daten sollten im Speicher als 16 Bit signed Integer vorliegen, damit du diese mit einem Faktor multiplizieren kannst.
Lautstärkeänderung sind recht einfach zu erreichen (da jeder Samplewert einfach mit einem Faktor multipliziert wird.)
Tonhöhenänderungen sind da schon deutlich anspruchsvoller.
Wenn schon, dann sollten die Lautstärkeänderung über ein Profil oder Verlauf vorgegeben werden.
z.B. über eine Datei: 100%, 80%, 60%, 50%, 20%, 70%
Andreas
  Mit Zitat antworten Zitat
St. Janos

Registriert seit: 25. Dez 2004
Ort: North Germany
12 Beiträge
 
#3

Re: Audio programmiertechnisch in Lautstärke & Tonhöhe v

  Alt 16. Feb 2007, 17:37
ahoi,
nachdem ich nun einige Stunden Beispiel-Quellcode der Bass.dll Doku wie die Doku selber studiert habe, hät ich erstmal 1-2 grundlegende Fragen:
Und zwa geht es um die Procedure DecodeFile aus dem writewav Beispiel.

Hier einmal die Procedure:

Delphi-Quellcode:
procedure TForm1.DecodeFile(OutPath, SourceFileName : String);
 var chan, frq, vl : DWORD; Tmp: Integer;
     buf : array [0..10000] of BYTE;
   BytesRead : integer;
   temp : string;
   i : longint;
   RecStream : TFileStream;
   nChannels : Word; // number of channels (i.e. mono, stereo, etc.)
   nSamplesPerSec : DWORD; // sample rate
   nAvgBytesPerSec : DWORD;
   nBlockAlign : Word;
   wBitsPerSample : Word; // number of bits per sample of mono data
   FileName : String;
   chaninfo: BASS_CHANNELINFO;
begin

    chan := BASS_StreamCreateFile(FALSE, PChar(SourceFileName), 0, 0, BASS_STREAM_DECODE);

    CancelOp := False;
    LabelOp.Caption := 'Opening file ...';

  BASS_ChannelGetInfo(chan, chaninfo);
   nChannels := chaninfo.chans;
        if (chaninfo.flags and BASS_SAMPLE_8BITS > 0) then wBitsPerSample := 8 else wBitsPerSample := 16;
   nBlockAlign := nChannels * wBitsPerSample div 8;
   BASS_ChannelGetAttributes(chan, frq, vl, Tmp);
        nSamplesPerSec := frq;
   nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;

    FileName := ExtractFileName(SourceFileName);
    FileName := Copy(FileName, 1, Length(FileName) - Length(ExtractFileExt(FileName)));
    RecStream := TFileStream.Create(OutPath + FileName + '.wav', fmCreate);

 // Write header portion of wave file
    temp := 'RIFF'; RecStream.write(temp[1], length(temp));
    temp := #0#0#0#0; RecStream.write(temp[1], length(temp)); // File size: to be updated
    temp := 'WAVE'; RecStream.write(temp[1], length(temp));
    temp := 'fmt '; RecStream.write(temp[1], length(temp));
    temp := #$10#0#0#0; RecStream.write(temp[1], length(temp)); // Fixed
    temp := #1#0; RecStream.write(temp[1], length(temp)); // PCM format
    if nChannels = 1 then
       temp := #1#0
    else
       temp := #2#0;
    RecStream.write(temp[1], length(temp));
    RecStream.write(nSamplesPerSec, 2);
    temp := #0#0; RecStream.write(temp[1], length(temp)); // SampleRate is given as dWord
    RecStream.write(nAvgBytesPerSec, 4);
    RecStream.write(nBlockAlign, 2);
    RecStream.write(wBitsPerSample, 2);
    temp := 'data'; RecStream.write(temp[1],length(temp));
    temp := #0#0#0#0; RecStream.write(temp[1],length(temp)); // Data size: to be updated
   while (BASS_ChannelIsActive(chan) > 0) do
         begin
                BytesRead := BASS_ChannelGetData(chan, @buf, 10000);
                RecStream.Write(buf, BytesRead);
                Application.ProcessMessages;
                if CancelOp then Break;
                PercentDone := Trunc(100 * (BASS_ChannelGetPosition(Chan) / BASS_ChannelGetLength(chan)));
                ProgressBar.Position := PercentDone;
                LabelOp.Caption := 'Done ' + IntToStr(PercentDone) + '%';
   end;
   BASS_StreamFree(chan); // free the stream

   LabelOp.Caption := 'Closing file ...';
// complete WAV header
// Rewrite some fields of header
   i := RecStream.Size - 8; // size of file
   RecStream.Position := 4;
   RecStream.write(i, 4);
   i := i - $24; // size of data
   RecStream.Position := 40;
   RecStream.write(i, 4);
   RecStream.Free;
   LabelOp.Caption := 'Done';
end;
Wie die Procedure funktioniert und was Sie macht, is mir glaub ich klar. Nachdem ich nun auch ausführlich den Wav-Header studiert habe, stellen sich mir jedoch 2 grundlegende Fragen, die wohl mehr mit dem Delphi Syntax zu tun haben. Wessen Schreibweise ich mich nicht wirklich erinnern kann, so schon mal gesehen zu haben. Bis auf glaube ich bei RGB-Farb-Code Zuweisungen. Naja, ich schweife ab
Es geht um die Zeilen:

Delphi-Quellcode:
    temp := #$10#0#0#0; RecStream.write(temp[1], length(temp)); // Fixed
    temp := #1#0; RecStream.write(temp[1], length(temp)); // PCM format
wie um
i := i - $24; // size of data Mir ist klar, dass im oberen Teil nur Platzhalter eingetragen werden. Jedoch verstehe ich nicht welche Bedeutung in Delphi diese Zeichenkombinationen haben, wenn Sie ohne Hochkommatas zugewiesen werden.
Also was bewirkt zb. #1#0 oder #$10#0#0#0 oder auch x - $24 wenn x jetzt mal 100 sei?
Leider hab ich es net hinbekommen nach solchen Zeichenkombinationen gescheit zu suchen und hoffe deshalb auf Eure Hilfe.
Eine 2. Sache dich mich stutzig macht ist, dass in der letzteren von mir erwähnten Zeile die Stream/Dateigrösse mit 24 subtrahiert wird. Laut Wikipedia werden bis einschließlich der fmt-Header Länge erst 20 Bytes verbraucht. Was auch immer $24 zu bedeuten hat, müsste es nicht $20 heißen? Meine Vermutung wird mit aller Wahrscheinlichkeit falsch sein, aber warum $24 und nicht $20? Mir würde sehr geholfen werden, wenn Ihr mir auch diese Frage beantworten könntet

Außerdem frag ich mich, wie du des meinst mit dem multiplizieren der Daten? Was genau multiplizieren? Und mit was und was für eine Verstärkung der Lautstärke bewirkt die Mulitplikation mit dem Faktor x bzw. mit welchem Faktor erreich ich die minimalste Verstärkung/Verringerung der Lautstärke? Und was wäre die minimalste Verstärkung/Verringerung in dB oder auch %? Ich weiss, viele Frage auf einmal. Aber in Sachen Veränderung seh ich noch kein Licht am Ende des Tunnels

Grüße Janos

Ps.: Anbei habe ich mich inzwischen entschieden, dass Projekt mit Delphi und Wave-Dateien oder Mp3-Dateien oder OGG-Dateien fortzuführen
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#4

Re: Audio programmiertechnisch in Lautstärke & Tonhöhe v

  Alt 16. Feb 2007, 18:08
Zitat von St. Janos:
Delphi-Quellcode:
    temp := #$10#0#0#0; RecStream.write(temp[1], length(temp)); // Fixed
    temp := #1#0; RecStream.write(temp[1], length(temp)); // PCM format
wie um
i := i - $24; // size of data Mir ist klar, dass im oberen Teil nur Platzhalter eingetragen werden. Jedoch verstehe ich nicht welche Bedeutung in Delphi diese Zeichenkombinationen haben, wenn Sie ohne Hochkommatas zugewiesen werden.
Das Dollarzeichen ($) vor einer Zahl bedeutet, dass diese hexadezimal zu interpretieren ist.
Der Gartenzaum (#) bedeutet, das die folgende Zahl der Wert des Zeichens ist:
Delphi-Quellcode:
temp := #$10#0#0#0;
temp := chr(16)+chr(0)+chr(0)+chr(0); // das ist das Gleiche wie oben, nur viel umständlicher
Zitat von St. Janos:
Außerdem frag ich mich, wie du des meinst mit dem multiplizieren der Daten? Was genau multiplizieren? Und mit was und was für eine Verstärkung der Lautstärke bewirkt die Mulitplikation mit dem Faktor x bzw. mit welchem Faktor erreich ich die minimalste Verstärkung/Verringerung der Lautstärke?
Erst mal musst du verstehen, wie Signale digital dargestellt werden.
http://de.wikipedia.org/wiki/BildAM-Prinzip.png
Jeder blaue Strich in dem Bild stellt einen digitalisierten Wert im Bereich von -128 bis +127 (bei 8-Bit Auflösung) dar.
Wenn du jetzt jeden einzelnen Wert mit 0.5 multiplizierst, dann ist das Signal halb so laut.
Wenn du mit Werten grösser 1.0 multiplizierst, wird das Signal lauter.
Aber Vorsicht: zu viel, und der gültige Wertebereich wird verlassen, was ganz grausame Verzerrungen verursacht.
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort


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 22:20 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