Einzelnen Beitrag anzeigen

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