Thema: Delphi WAV resampling

Einzelnen Beitrag anzeigen

Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#4

Re: WAV resampling

  Alt 20. Dez 2009, 20:06
Wenn du keinen großen Wert auf nahezu perfekte Qualität nimmst (für Studioanwendungen etc.) dann sollte folgender Ansatz völlig genügen:

Schnapp dir diese Unit und interpoliere damit über die Audiodaten drüber.
http://audorra.svn.sourceforge.net/v...16&view=markup

Hier ist eine Beispielanwendung dafür:
Delphi-Quellcode:
program audiospline;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes,
  AcSysUtils,
  AuAudioSpline,
  AuProtocolClasses,
  AuDecoderClasses,
  AuWAV;

var
  spline: TAuSplineData;
  proc: PAuSplineProcessor;
  dec: TAuDecoder;
  prot: TAuProtocol;
  fs: TFileStream;
  fs2: TMemoryStream;
  pck: TAuPacket;
  p, v: Double;
  si: SmallInt;
  c, i, j, smpl: integer;
  pb: PByte;

function ReadSample(var AData: PByte): Single;
begin
  result := PSmallInt(AData)^ / High(SmallInt);
  inc(AData, 2);
end;

begin
  proc := nil;
  fs2 := TMemoryStream.Create;
  fs := TFileStream.Create(ParamStr(1), fmOpenRead);
  prot := TAuStreamProtocol.Create(fs);
  dec := TAuWAVDecoder.Create(prot);

  if dec.OpenDecoder then
  begin
    p := 0;
    while dec.Decode = audsHasFrame do
    begin
      dec.GetPacket(pck);

      pb := pck.Buffer;
      c := pck.BufferSize div 2;

      //Start the spline if this hasn't been done now
      if proc = nil then
      begin
        proc := AuSplineStart(ReadSample(pb), ReadSample(pb));
        c := c - 2;
      end;

      while c > 0 do
      begin
        AuSplineFeed(proc, ReadSample(pb), @spline);
        while p < 1 do
        begin
          v := AuSplineCalcValue(Frac(p), @spline);
          si := round(v * High(SmallInt));
          fs2.Write(si, SizeOf(si));
          p := p + 0.8; //Anstatt "0.8" sollte hier das Verhältnis zwischen den beiden Abtastraten stehen
        end;

        //Skip all overread samples
        for i := 1 to Trunc(p) - 1 do
        begin
          if c > 0 then
            AuSplineFeed(proc, ReadSample(pb), @spline);
          c := c - 1;
        end;

        p := Frac(p);

        c := c - 1;
      end;
    end;
  end;

  if proc <> nil then
    AuSplineStop(proc);

  dec.Free;
  prot.Free;
  fs.Free;
  fs2.SaveToFile('C:\test.raw');
  fs2.Free;
end.
Edit: Hier steht näheres dazu: http://audorra.sourceforge.net/index.php?p=news/
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein
  Mit Zitat antworten Zitat