我在家用猫拨号,粘附件很慢的,大家凑合着看吧!!
文件ioplug.pas如下:
////////////////////////////////////////////////////////////////////////////////
//
//
//
// Winamp i/o plugin header adaption for Delphi/Pascal by Snake
//
//
//
////////////////////////////////////////////////////////////////////////////////
//
// (Based on the mini-SDK from Justin Frankel/Nullsoft Inc.)
//
// This ioplug.pas unit contains the follwing converted C-headers:
// in2.h, out.h
//
//do
wnload:
// E-Mail: <snakers@gmx.net>
//
//
// This unit has 4 managment-functions:
//
// function InitInputDLL(dll:string) : Boolean;
// Loads the proc-address for getInModule from <dll> at runtime.
//
// function InitOutputDLL(dll:string) : Boolean;
// Loads the proc-address for getOutModule from <dll> at runtime.
//
// procedure CloseInputDLL;
// Releases the runtime-link to the input DLL and sets all proc-addresses to nil.
// Youdo
n't have to call this procedure, because the Finalization sectiondo
it for you.
//
// procedure CloseOutputDLL;
// Releases the runtime-link to the Output DLL and sets all proc-addresses to nil.
// Youdo
n't have to call this procedure, because the Finalization sectiondo
it for you.
//
// Modyfied: 8. Dec. 1999
//
//
////////////////////////////////////////////////////////////////////////////////
unit ioplug;
{$MINENUMSIZE 4}
{$ALIGN ON}
interface
uses
Windows,
SysUtils;
(*
** -----------------------------------------------------------------------
** MODULE PROTOTYPES
** -----------------------------------------------------------------------
*)
type TData=array[1..10] of byte;
type TIn_Module=record
version:integer; // module type (IN_VER)
description
Char; // description of module, with version string
hMainWindow:integer; // winamp's main window (filled in by winamp)
hDllInstance:LongWord; // DLL instance handle (Also filled in by winamp)
FileExtensions
Char; // "mp3/0Layer 3 MPEG/0mp2/0Layer 2 MPEG/0mpg/0Layer 1 MPEG/0"
// May be altered from Config, so the user can select what they want
is_seekable:integer; // is this stream seekable?
UsesOutputPlug:integer; //do
es this plug-in use the output plug-ins? (musn't ever change, ever
config
rocedure(hwndParent:HWND);cdecl;
// configuration dialog
About
rocedure(hwndParent:HWND);cdecl;
// about dialog
Init
rocedure;cdecl;
// called at program init
Quit
rocedure;cdecl; // called at program quit
GetFileInfo
rocedure(var _file
Char;
var title
Char;var length_in_ms:integer);cdecl;
// if file == NULL, current playing is used
InfoBox:function(_file
Char;
hwndParent:HWND ):integer;cdecl;
IsOurFile:function(fn
Char):integer;cdecl; // called before extension checks, to allow detection of mms://, etc
// playback stuff
Play:function(fn
Char):integer;cdecl; // return zero on success, -1 on file-not-found, some other value on other (stopping winamp) error
Pause
rocedure;cdecl; // pause stream
UnPause
rocedure;cdecl; // unpause stream
IsPaused:function:integer;cdecl; // ispaused? return 1 if paused, 0 if not
Stop
rocedure;cdecl; // stop (unload) stream
// time stuff
GetLength:function:integer;cdecl; // get length in ms
GetOutputTime:function:integer;cdecl; // returns current output time in ms. (usually returns outMod->GetOutputTime()
SetOutputTime
rocedure(time_in_ms:integer);cdecl; // seeks to point in stream (in ms). Usually you signal yoru thread to seek, which seeks and calls outMod->Flush()..
// volume stuff
SetVolume
rocedure(volume:integer);cdecl; // from 0 to 255.. usually just call outMod->SetVolume
SetPan
rocedure(pan:integer);cdecl; // from -127 to 127.. usually just call outMod->SetPan
// in-window builtin vis stuff
SAVSAInit
rocedure(maxlatency_in_ms:integer;srate:integer);cdecl; // call once in Play(). maxlatency_in_ms should be the value returned from outMod->Open()
SAVSADeInit
rocedure;cdecl; // call in Stop()
// simple vis supplying mode
SAAddPCMData
rocedure(PCMData
ointer;nch:integer;bps:integer;timestamp:integer);cdecl;
// sets the spec data directly from PCM data
// quick and easy way to get vis working
// needs at least 576 samples
// advanced vis supplying mode, only use if you're cool. Use SAAddPCMData for most stuff.
SAGetMode:function:integer;cdecl; // gets csa (the current type (4=ws,2=osc,1=spec))
// use when calling SAAdd()
SAAdd
rocedure(data
ointer;
timestamp:integer;csa:integer);cdecl;
// sets the spec data, filled in by winamp
// vis stuff (plug-in)
// simple vis supplying mode
VSAAddPCMData
rocedure(PCMData
ointer;nch: integer
bps:integer;timestamp:integer);cdecl;
// sets the vis data directly from PCM data
// quick and easy way to get vis working
// needs at least 576 samples
// advanced vis supplying mode, only use if you're cool. Use VSAAddPCMData for most stuff.
VSAGetMode:function(var specNch:integer;
var waveNch:integer):integer;cdecl;
// use to figure out what to give to VSAAdd
VSAAdd
rocedure(data
ointer;
timestamp:integer);cdecl;
// filled in by winamp, called by plug-in
// call this in Play() to tell the vis plug-ins the current output params.
VSASetInfo
rocedure(nch:integer;srate:integer);cdecl;
// dsp plug-in processing:
// (filled in by winamp, called by input plug)
// returns 1 if active (which means that the number of samples returned by dsp_dosamples
// could be greater than went in.. Use it to estimate if you'll have enough room in the
// output buffer
dsp_isactive:function:integer;cdecl;
// returns number of samples to output. This can be as much as twice numsamples.
// be sure to allocate enough buffer for samples, then
.
dsp_dosamples:function(samples
ointer;
numsamples, bps, nch, srate:integer):integer;cdecl;
// eq stuff
EQSet
rocedure(on:integer;data:TData;preamp:integer);cdecl;
// 0-64 each, 31 is +0, 0 is +12, 63 is -12.do
nothing to ignore.
// info setting (filled in by winamp)
SetInfo
rocedure(bitrate,srate,stereo,synched:integer);cdecl;
// if -1, changes ignored?
outMod
ointer;
// filled in by winamp, optionally used
end;
type TOut_Module=record
version:integer; // module version (OUT_VER)
description
Char; // description of module, with version string
id:integer; // module id. each input module gets its own. non-nullsoft modules should
// be >= 65536.
hMainWindow:integer; // winamp's main window (filled in by winamp)
hDllInstance:longword; // DLL instance handle (filled in by winamp)
Config
rocedure(hwndParent:hwnd);cdecl;
// configuration dialog
About
rocedure(hwndParent:hwnd);cdecl;
// about dialog
Init
rocedure;cdecl; // called when loaded
Quit
rocedure;cdecl; // called when unloaded
Open:function(samplerate,numchannels,bitspersamp,bufferlenms,prebufferms:integer):integer;cdecl;
// returns >=0 on success, <0 on failure
// NOTENOTENOTE: bufferlenms and prebufferms are ignored in most if not all output plug-ins.
// ... sodo
n't expect the max latency returned to be what you asked for.
// returns max latency in ms (0 for diskwriters, etc)
// bufferlenms and prebufferms must be in ms. 0 to use defaults.
// prebufferms must be <= bufferlenms
Close
rocedure;cdecl; // close the ol' output device.
Write:function(buf
ointer;len:integer):integer;cdecl;
// 0 on success. Len == bytes to write (<= 8192 always). buf is straight audio data.
// 1 returns not able to write (yet). Non-blocking, always.
CanWrite:function:integer;cdecl; // returns number of bytes possible to write at a given time.
// Never will decrease unless you call Write (or Close, heh)
IsPlaying:function:integer;cdecl;
// non0 if output is still going or if data in buffers waiting to be
// written (i.e. closing while IsPlaying() returns 1 would truncate the song
Pause:function(pause:integer):integer;cdecl;
// returns previous pause state
SetVolume
rocedure(volume:integer);cdecl;
// volume is 0-255
SetPan
rocedure(pan:integer);cdecl;
// pan is -128 to 128
Flush
rocedure(t:integer);cdecl; // flushes buffers and restarts output at time t (in ms)
// (used for seeking)
GetOutputTime:function:integer;cdecl;
// returns played time in MS
GetWrittenTime:function:integer;cdecl;
// returns time written in MS (used for synching up vis stuff)
end;
//---------------------------------------------------------------------------------------------------------
var
getInModule : function : pointer;
stdcall;
getOutModule : function : pointer;
stdcall;
const
InputDLLHandle : THandle = 0;
OutputDLLHandle : THandle = 0;
function InitInputDLL(DLL: string): Boolean;
function InitOutputDLL(DLL: string): Boolean;
procedure CloseInputDLL;
procedure CloseOutputDLL;
//---------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------
implementation
function InitInputDLL(DLL: string): Boolean;
begin
Result := False;
getinmodule:=nil;
if InputDLLHandle <> 0 then
CloseInputDLL;
InputDLLHandle := LoadLibrary(PChar(DLL));
if (InputDLLHandle = 0) then
exit;
getInModule := GetProcAddress (InputDLLHandle, 'winampGetInModule2');
if @getInModule<>nil then
Result := true;
end;
function InitOutputDLL(DLL: string): Boolean;
begin
Result := False;
getOutmodule:=nil;
if OutputDLLHandle <> 0 then
CloseOutputDLL;
OutputDLLHandle := LoadLibrary(PChar(DLL));
if (OutputDLLHandle = 0) then
exit;
getOutModule := GetProcAddress (OutputDLLHandle, 'winampGetOutModule');
if @getOutModule<>nil then
Result := true;
end;
procedure CloseInputDLL;
begin
getinmodule:=nil;
if inputDLLHandle <> 0 then
begin
FreeLibrary(InputDLLHandle);
InputDLLHandle := 0;
end;
end;
procedure CloseOutputDLL;
begin
getoutmodule:=nil;
if outputDLLHandle <> 0 then
begin
FreeLibrary(outputDLLHandle);
outputDLLHandle := 0;
end;
end;
initialization
begin
getinmodule:=nil;
getOutmodule:=nil;
// InitDLL;
end
finalization
begin
CloseInputDLL;
CloseOutputDLL;
end
end.
//====================================================
例子:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ioplug,
StdCtrls, ExtCtrls, ComCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
TrackBar1: TTrackBar;
Button6: TButton;
Button7: TButton;
Memo1: TMemo;
Button8: TButton;
OpenDialog1: TOpenDialog;
OpenDialog2: TOpenDialog;
procedure Button1Click(Sender: TObject);
procedure Button8Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
var imod:^TIn_module;
omod:^TOut_module;
procedure SetInfo1(bitrate,srate,stereo,synched:integer);cdecl;
// if -1, changes ignored?
begin
end;
function dsp_isactive1:integer;cdecl;
begin
result:=0;
end;
function dsp_dosamples1(samples
ointer;
numsamples, bps, nch, srate:integer):integer;cdecl;
begin
result:=numsamples;
end;
procedure SAVSAInit1(maxlatency_in_ms:integer;srate:integer);cdecl;
begin
end;
procedure SAVSADeInit1;cdecl; // call in Stop()
begin
end;
procedure SAAddPCMData1(PCMData
ointer;nch:integer;bps:integer;timestamp:integer);cdecl;
begin
end;
function SAGetMode1:integer;cdecl; // gets csa (the current type (4=ws,2=osc,1=spec))
begin
end;
procedure SAAdd1(data
ointer;
timestamp:integer;csa:integer);cdecl;
// sets the spec data, filled in by winamp
begin
end;
procedure VSAAddPCMData1(PCMData
ointer;nch: integer
bps:integer;timestamp:integer);cdecl;
// sets the vis data directly from PCM data
begin
end;
function VSAGetMode1(var specNch:integer;
var waveNch:integer):integer;cdecl;
// use to figure out what to give to VSAAdd
begin
end;
procedure VSAAdd1(data
ointer;
timestamp:integer);cdecl;
// filled in by winamp, called by plug-in
begin
end;
procedure VSASetInfo1(nch:integer;srate:integer);cdecl;
begin
end;
var s:string;
procedure TForm1.Button1Click(Sender: TObject);
begin
S:= InputBox('', 'Enter File:', '');
if s='' then
begin
opendialog2.execute;s:=opendialog2.filename;
end;
end;
procedure TForm1.Button8Click(Sender: TObject);
begin
halt;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
if not opendialog1.Execute then
exit;
if not initInputDll(opendialog1.FileName) then
begin
memo1.Lines.Add('Failed to load input plugin !');
exit;
end;
memo1.Lines.Add('Input plugin loaded !');
imod:=getinmodule;
imod.hMainWindow:=application.Handle;
imod.hDllInstance:=InputDllHandle;
imod.outMod:=omod;
imod.init;
imod.SetInfo:=SetInfo1;
imod.dsp_IsActive:=dsp_isactive1;
imod.dsp_dosamples:=dsp_dosamples1;
imod.SAVSAInit:=SAVSAInit1;
imod.SAVSADeInit:=SAVSADeinit1;
imod.SAAddPCMData:=SAAddPCMData1;
imod.SAGetMode:=SAGetMode1;
imod.SAAdd:=SAADD1;
imod.VSASetInfo:=VSASetInfo1;
imod.VSAAddPCMData:=VSAAddPCMData1;
imod.VSAGetMode:=VSAGetMode1;
imod.VSAAdd:=VSAAdd1;
imod.About(0);
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
if imod=nil then
begin
memo1.Lines.add('Load input plugin first !');
exit;
end;
if not opendialog1.Execute then
exit;
if not initOutputDll(opendialog1.FileName) then
begin
memo1.Lines.Add('Failed to load output plugin !');
exit;
end;
memo1.Lines.Add('Output plugin loaded !');
omod:=getoutmodule;
omod.hMainWindow:=application.Handle;
omod.hDllInstance:=OutputDllHandle;
omod.init;
omod.about(0);
omod.setvolume(128);
imod.outMod:=omod;
button1.enabled:=true;
button2.enabled:=true;
button3.enabled:=true;
button6.enabled:=true;
button7.enabled:=true;
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
imod.config(application.handle);
end;
procedure TForm1.Button7Click(Sender: TObject);
begin
omod.config(application.handle);
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
omod.setvolume(trackbar1.position);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if imod.Play(Pchar(s))=0 then
memo1.lines.add('Playing '+s) else
memo1.lines.add('Can not playing '+s);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
imod.Stop;
end;
end.