![]() |
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:
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 :)
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; mfg RER Edit: Wie oben konvertiere ich mit folgendem code auch Mp3 in Wav:
Delphi-Quellcode:
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 :(
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; |
Re: WAV resampling
Hallo,
geht auch mit der Lame.dll |
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.
|
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. ![]() Hier ist eine Beispielanwendung dafür:
Delphi-Quellcode:
Edit: Hier steht näheres dazu:
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. ![]() |
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 :) |
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:07 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz