Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi WAV resampling (https://www.delphipraxis.net/144743-wav-resampling.html)

Rer 15. Dez 2009 15:10


WAV resampling
 
Hi @all,
ich wollte die Sample-Rate von WAV-Datein verändern. Hierzu habe ich mir gedacht, dass ich die BASS Komponenten benutzen könnte (bass, bassenc, Bassmix) und komme aber wirklich nicht zurecht. Hier mein Ansatz:
Delphi-Quellcode:
Bass_Init(0, 24000, BASS_UNICODE, Application.Handle, nil);
Source := BASS_StreamCreateFile(false, Pchar('F:\Sound.wav'), 0, 0, BASS_STREAM_DECODE);
BASS_ChannelSetAttribute(Source, BASS_ATTRIB_FREQ, 24000);

BassMix := BASS_Mixer_StreamCreate(24000, 1, BASS_STREAM_DECODE+BASS_MIXER_END);
BASS_Mixer_StreamAddChannel(BassMix, Source, BASS_MIXER_FILTER);

BASS_Encode_Start(BassMix, PAnsiChar(PChar('F:\Sound2.wav')), BASS_ENCODE_PCM or BASS_ENCODE_AUTOFREE, nil, nil);

while (BASS_ChannelIsActive(BassMix) > 0) do begin
 BASS_ChannelGetData(BassMix, @buf, 10000);
 Application.ProcessMessages;
 PercentDone := Trunc(100 * (BASS_ChannelGetPosition(BassMix , BASS_POS_BYTE) / BASS_ChannelGetLength(BassMix , BASS_POS_BYTE)));
 ProgressBar1.Position := PercentDone;
end;
Die Dokumentationen, die beim Download von bass, bassenc und bassmix dabeiwaren, habe ich auch schon um rat bemüht, aber wurde aus diesen leider nicht schlau. Die Funktionsweise dieser Komponenten habe ich definitiv (noch) nicht verstanden. Vielleicht könnt ihr mir ja weiterhelfen :)
mfg RER

Edit:
Wie oben konvertiere ich mit folgendem code auch Mp3 in Wav:
Delphi-Quellcode:
Bass_Init(0, 44100, 0, Application.Handle, nil);
Channel := BASS_StreamCreateFile(false, Pchar(datei_plus_Pfad), 0, 0, BASS_STREAM_DECODE);
try
BASS_Encode_Start(channel, Pchar(AddBackslash(Tempdir)+ChangeFileExt(datei_nur_name, '.wav')), BASS_ENCODE_PCM or BASS_ENCODE_AUTOFREE, nil, nil);
while (BASS_ChannelIsActive(Channel ) > 0) do begin
BASS_ChannelGetData(Channel, @buf, 10000);
Application.ProcessMessages;
PercentDone := Trunc(100 * (BASS_ChannelGetPosition(Channel , BASS_POS_BYTE) / BASS_ChannelGetLength(Channel , BASS_POS_BYTE)));
ProgressBar1.Position := PercentDone; lb_stepprogress.Caption:=Inttostr(PercentDone)+' %';
end;
Nun hab ich in diesem Fall gedacht, dass ich einfach die 44100 bei BASS_INIT in zum Beispiel 24000 ändern kann, was jedoch ebenfalls nich funktioniert :(

markus5766h 20. Dez 2009 18:40

Re: WAV resampling
 
Hallo,

geht auch mit der Lame.dll

SirThornberry 20. Dez 2009 18:47

Re: WAV resampling
 
es geht auch wenn man keine Komponenten nimmt und sich selbst mit dem Format beschäftigt. Aber ich glaube er will nicht wissen mit was es allem noch geht sondern WIE.

igel457 20. Dez 2009 19:06

Re: WAV resampling
 
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/

Rer 21. Dez 2009 09:15

Re: WAV resampling
 
Eigentlich hab ich mich für die Basskomponente entschieden, weil diese so schön einfach ist (auch wenn ich gesagt habe, dass ich die noch nicht so richtig versteh... für mich ist sie aber dennoch nachvollziehbarer). Daher würde ich gerne dabei bleiben...
Gibt es denn keine Möglichkeit eine Lösung mit Bass, Bassenc und Bassmix zu realisieren?
Trotzdem danke für die Antworten :)

Wishmaster 21. Dez 2009 23:24

Re: WAV resampling
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi

in deinem code sind kleine Fehler!

1) die Flags in BASS_Mixer_StreamCreate müssen durch ein or getrennt werden und nicht mit einem +
(BASS_STREAM_DECODE or BASS_MIXER_END)

2) BASS_ChannelSetAttribute(Source, ...) brauchst du nicht.
BASS_Mixer_ macht das ganze resampling


noch en Tipp.

benutze 32-bit floating-point sample data (BASS_SAMPLE_FLOAT) für bessere Qualität.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:44 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