Einzelnen Beitrag anzeigen

Marco Steinebach

Registriert seit: 4. Aug 2006
491 Beiträge
 
Delphi 5 Enterprise
 
#10

Re: Stille aus Wave-Dateien entfernen?

  Alt 13. Aug 2009, 22:29
Hallo,
Ich hab mir den Code heute nochmal zu gemüte geführt und, denke?, er hat einen Fehler.
Delphi-Quellcode:
function Channel_Get_SilenceLength_16Bit(FileName : String; Pinpoint : Boolean; Threshold : QWORD; var StartPoint, EndPoint : DWORD) : Bool; stdcall;
var
  a, b: Integer;
  pos, count, chan: DWORD;
  buf16: array[0..50000] of Smallint; // 100% OK.
  flag : DWORD;
begin
   result:= false;
   count := 0;
   flag:= BASS_STREAM_DECODE; //BASS_STREAM_DECODE or BASS_STREAM_AUTOFREE

     if Pinpoint then
       flag:= flag or BASS_STREAM_PRESCAN;

     Chan:= BASS_StreamCreateFile(FALSE, PChar(FileName), 0, 0, Flag);
  if Chan = 0 then
     Chan:= BASS_MusicLoad(False, PChar(FileName), 0, 0, Flag or BASS_MUSIC_NOSAMPLE, 0);
  if Chan = 0 then
   Exit;

  while Bass_ChannelIsActive(Chan) <> 0 do
   begin
    b := BASS_ChannelGetData(Chan, @buf16, 20000);
    b := b div 2;
    a := 0;
    while (a < b) and (Abs(buf16[a]) <= Threshold) do
      a := a + 1;
      count := count + (a * 2);
    if (a < b) then
     begin
      while (a <> 0) and (Abs(buf16[a]) > (Threshold div 4)) do
       begin
        a := a - 1;
        count := count - 2;
      end;
      Break;
    end;
  end;
   StartPoint := count; // Start-Point ready

   pos := BASS_ChannelGetLength(Chan);
  while (pos > count) do
   begin
    if pos < 100000 then
      pos := 0
    else
      pos := pos - 100000;
    BASS_ChannelSetPosition(chan, pos);
    b := BASS_ChannelGetData(chan, @buf16, 100000);
// ... so, hier geht's los:
    b := b div 2; // b ist also die Anzahl der samples
    a := b;
   while (a > 0) and (Abs(buf16[a - 1]) <= (Threshold div 2)) do
       a := a - 1;
    if a > 0 then
     begin
      count := pos + (a * 4); // warum 4, müßte doch bei smallint, also 2 byte, * 2 heißen, oder? Break;
     end;
    end;
 EndPoint := Count; // End-Point ready
 BASS_MusicFree(Chan);
 BASS_StreamFree(Chan);
 Result:= true;
end;
Das gleiche gilt, natürlich, auch für die 32-Bit-Variante.
Der Code produziert nämlich manchmal Ergebnisse, deren Endposition größer ist, als die tatsächliche Länge.
Hilf mir mal bitte!
Einen freundlichen Gruß
Marco
Marco Steinebach
  Mit Zitat antworten Zitat