X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fengine%2Fe_soundfile_modplug.pas;h=600512b06e9cb05d805cb8d36e527f9b1b570fe4;hb=ca23794a6f2dc5eb454f65fc53efc265f16de612;hp=01fd45544a05e7f9590bb10dc6a3abd0e32ecf34;hpb=41373861bfc2c613356bcba4f57e854592888ee5;p=d2df-sdl.git diff --git a/src/engine/e_soundfile_modplug.pas b/src/engine/e_soundfile_modplug.pas index 01fd455..600512b 100644 --- a/src/engine/e_soundfile_modplug.pas +++ b/src/engine/e_soundfile_modplug.pas @@ -2,8 +2,7 @@ * * 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 @@ -21,21 +20,24 @@ interface 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; @@ -89,13 +91,18 @@ end; 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; @@ -110,11 +117,13 @@ begin 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; @@ -131,7 +140,7 @@ begin 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]); @@ -141,11 +150,17 @@ begin 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; @@ -159,22 +174,22 @@ begin 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(); @@ -183,6 +198,8 @@ begin begin ModPlug_Unload(FFile); FFile := nil; + FFinished := False; + FLooping := False; end; end;