index 01fd45544a05e7f9590bb10dc6a3abd0e32ecf34..600512b06e9cb05d805cb8d36e527f9b1b570fe4 100644 (file)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
uses e_soundfile, modplug;
type
- // a module loader that uses libxmp-lite
+ // a module loader that uses libmodplug
TModPlugLoader = class (TSoundLoader)
public
- function Load(Data: Pointer; Len: LongWord; SStreaming: Boolean): Boolean; override; overload;
- function Load(FName: string; SStreaming: Boolean): Boolean; override; overload;
- function SetPosition(Pos: LongWord): Boolean; override;
+ function Load(Data: Pointer; Len: LongWord; Loop: Boolean): Boolean; override; overload;
+ function Load(FName: string; Loop: Boolean): Boolean; override; overload;
+ function Finished(): Boolean; override;
+ function Restart(): Boolean; override;
function FillBuffer(Buf: Pointer; Len: LongWord): LongWord; override;
- function GetAll(var OutPtr: Pointer): LongWord; override;
procedure Free(); override;
private
FFile: PModPlugFile;
+ FFinished: Boolean;
+ FLooping: Boolean;
end;
TModPlugLoaderFactory = class (TSoundLoaderFactory)
+ public
function MatchHeader(Data: Pointer; Len: LongWord): Boolean; override;
function MatchExtension(FName: string): Boolean; override;
function GetLoader(): TSoundLoader; override;
function TModPlugLoaderFactory.GetLoader(): TSoundLoader;
begin
- ModPlug_SetSettings(@Settings); // update settings just in case
+ // update interpolation setting
+ if e_MusicLerp then
+ Settings.mResamplingMode := MODPLUG_RESAMPLE_LINEAR
+ else
+ Settings.mResamplingMode := MODPLUG_RESAMPLE_NEAREST;
+ ModPlug_SetSettings(@Settings);
Result := TModPlugLoader.Create();
end;
(* TModPlugLoader *)
-function TModPlugLoader.Load(Data: Pointer; Len: LongWord; SStreaming: Boolean): Boolean;
+function TModPlugLoader.Load(Data: Pointer; Len: LongWord; Loop: Boolean): Boolean;
begin
Result := False;
FFormat.SampleBits := 16;
FFormat.Channels := 2;
FStreaming := True; // modules are always streaming
+ FFinished := False;
+ FLooping := Loop;
Result := True;
end;
-function TModPlugLoader.Load(FName: string; SStreaming: Boolean): Boolean;
+function TModPlugLoader.Load(FName: string; Loop: Boolean): Boolean;
var
S: TStream = nil;
Data: Pointer;
Len := S.Read(Data^, S.Size);
if Len < 0 then
raise Exception.Create('what the fuck');
- Result := Load(Data, Len, SStreaming)
+ Result := Load(Data, Len, Loop);
except
on E: Exception do
e_LogWritefln('ModPlug: ERROR: could not read file `%s`: %s', [FName, E.Message]);
if S <> nil then S.Free();
end;
-function TModPlugLoader.SetPosition(Pos: LongWord): Boolean;
+function TModPlugLoader.Finished(): Boolean;
+begin
+ Result := FFinished;
+end;
+
+function TModPlugLoader.Restart(): Boolean;
begin
Result := False;
if FFile = nil then Exit;
- ModPlug_Seek(FFile, Pos);
+ ModPlug_Seek(FFile, 0);
+ FFinished := False;
Result := True;
end;
Cnt := ModPlug_Read(FFile, Buf, Len);
if Cnt < 0 then Exit;
- if FLooping and (Cnt < Len) then
- begin
- // assume it just ended and restart, because modplug only loops if the
- // module tells it to
- ModPlug_Seek(FFile, 0);
- // this used to be Result := Cnt + Read(FFile, Buf + Cnt, Len - Cnt)
- // but the difference appears to be negligible
- Result := ModPlug_Read(FFile, Buf, Len);
- end
- else
- Result := Len;
-end;
+ Result := Cnt;
-function TModPlugLoader.GetAll(var OutPtr: Pointer): LongWord;
-begin
- Result := 0; // modules are always streaming, so this don't make sense
+ if Cnt < Len then
+ begin
+ if FLooping then
+ begin
+ // assume it just ended and restart, because modplug only loops if the
+ // module tells it to
+ ModPlug_Seek(FFile, 0);
+ // this used to be Result := Cnt + Read(FFile, Buf + Cnt, Len - Cnt)
+ // but the difference appears to be negligible
+ Result := ModPlug_Read(FFile, Buf, Len);
+ end
+ else
+ FFinished := True;
+ end;
end;
procedure TModPlugLoader.Free();
begin
ModPlug_Unload(FFile);
FFile := nil;
+ FFinished := False;
+ FLooping := False;
end;
end;