Page 1 of 1
Posted: Sat Feb 01, 2003 6:41 pm
by BackupUser
Restored from previous forum. Originally posted by GPI.
I have the "remote controll" code for winamp, but i want to use a winamp-plugin direct.
I have a C-sourcecode for a example-plugin, but i doesn't understand it. It seem, that i must use a in- and a out-plugin, but i don't know how they communicate with winamp.
I want, for example, play a .spc (SNES-sound-file) as background music and play wav for FX-Sounds.
GPI
p.s.: Sorry for my bad english.
Posted: Sat Feb 01, 2003 8:06 pm
by BackupUser
Restored from previous forum. Originally posted by El_Choni.
If you post the C code, maybe someone can help you.
El_Choni
Posted: Sat Feb 01, 2003 9:01 pm
by BackupUser
Restored from previous forum. Originally posted by Manolo.
Hi Choni,
You stay working with "elementals" ASM functions for floats???
Regards,
Manolo
Posted: Sat Feb 01, 2003 9:32 pm
by BackupUser
Restored from previous forum. Originally posted by MrVainSCL.
HI CPI,
you want to play background music (SNES sound) and wav for sound effects? Mhhhh.. listen you want to code something like a game using SNES sound and using wav sound for in game effects?
If you want it for a game i would prefer to use wav with the SoundLib() commdands and if you really want to play SNES tune for background, so you must be sure, that every user running your program have installed any version of WinAmp or other MultiPlayer with SNES support plugin! (i am not sure if WinAmp has SNES support as standart - instead using 3th part plugins)
I think it should be possible to use ExecuteShell command for your SNED tune (if its linked to WinAmp or other) and so it i could load and start WinAmp playing your specfic tune...!?
greetz
MrVainSCL! aka Thorsten
PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX9.0, SB AWE64, Win2000 + all Updates...
Posted: Sat Feb 01, 2003 9:53 pm
by BackupUser
Restored from previous forum. Originally posted by GPI.
Originally posted by MrVainSCL
HI CPI,
GPI!
Mhhhh.. listen you want to code something like a game using SNES sound and using wav sound for in game effects?
That is, what i want.
have installed any version of WinAmp or other MultiPlayer with SNES support plugin! (i am not sure if WinAmp has SNES support as standart - instead using 3th part plugins)
No, that is not what i want. I want to use the winamp-plugin without winamp. I will use the plugin direct.
I know, how to send messages to winamp to play a file. But when winamp play a file, no other programm will start.
the C-files could be found here:
http://ftp.ncnu.edu.tw/Windows/Collecti ... velopment/
In the "in_minisdk.zip" are two example-files and a "out.h". i don't found a "out_minisdk.zip".
(the link on
http://www.winamp.com are dead)
With winamp-plugins you can play almost every soundfile. Voc, SPC (SNES), GYM (Mega Drive/Genesis), NSF (NES), SID (C64),...
EDIT:
what do you mean with "ExecuteShell"-Command. I have no information. (i had only the borland-API-helpfile)
Posted: Sat Feb 01, 2003 11:01 pm
by BackupUser
Restored from previous forum. Originally posted by freak.
Hi,
Winamp Plugins are DLLs. So you can call them from PureBasic. But you'll have to imitate all the Stuff Winamp sends to it's Plugins, and also you'll need to know what to do with the Stuff they return.
In other Words, you would have to write Winamp again

.
I don't think, this can be done easily, as you don't know anything about how Windmp works internally. Your Example Code is an Example for a Plugin, right? But that doesn't tell you anything about the Winamp-side (which is what you need to know for this)
Have you tried to find other DLLs to play such Formats? There may be some that play the sounds directly, without that much work for you.
Timo
Posted: Sat Feb 01, 2003 11:52 pm
by BackupUser
Restored from previous forum. Originally posted by GPI.
Originally posted by freak
In other Words, you would have to write Winamp again

.
only the comunication between the Plugins (in and out plugin).
I have now found out, how to get the header of the files.
But i have two questens:
who do i start the subroutines. I get the adress out of the header.
must i start them with
Code: Select all
start=lpeek(Header) ; Get the adress of the Start-function
file$="test.fil"
CallFunctionFast(*start,@file$)
;or
callfunctionfast(start,@file$)
;or
*start(@file$)
and i doesn't know, what the "DLL instance" is. Is this the return-value of "OpenLibrary"?
here the Code to read the header:
Code: Select all
in= OpenLibrary(0, "in_psf")
out=OpenLibrary(1, "out_wave")
If in
If IsFunction(0, "winampGetInModule2")
Debug "winampGetInModul2 (DLL instance?:"+Hex(in)+")"
head = CallFunction(0, "winampGetInModule2" )
Debug " Headeradr:"+hex(head)
version=PeekL(head):head+4
Debug " version:"+Hex(version) ; module type (IN_VER)
adr=PeekL(head):head+4
discription$=PeekS(adr)
Debug " *description:"+discription$ ; description of module, with version string
hMainWindow=PeekL(head):head+4
Debug " hMainWindow:"+Hex(hMainWindow) ; winamp's main window (filled in by winamp)
hDllInstance=PeekL(head):head+4
Debug " HDllInstance:"+Hex(hDllInstace) ; DLL instance handle (Also filled in by winamp)
adr=PeekL(head):head+4
FileExtension$=PeekS(adr)
Debug " *FileExtensions:"+FileExtension$ ; "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=PeekL(head):head+4
Debug " is_seekable:"+Hex(is_seekable) ; is this stream seekable?
UsesOutputPlug=PeekL(head):head+4
Debug " UsesOutputPlug:"+Hex(UsesOutputPlug) ;does this plug-in use the output plug-ins? (musn't ever change, ever :)
config=PeekL(head):head+4
Debug " *Config:"+Hex(config) ; void (*Config)(HWND hwndParent); // configuration dialog
about=PeekL(head):head+4
Debug " *About:"+Hex(about) ; void (*About)(HWND hwndParent); // about dialog
init=PeekL(head):head+4
Debug " *Init:"+Hex(init) ; void (*Init)(); // called at program init
quit=PeekL(head):head+4
Debug " *quit:"+Hex(quit) ; void (*Quit)(); // called at program quit
GetFileInfo=PeekL(head):head+4
Debug " *GetFileInfo:"+Hex(GetFileInfo) ; void (*GetFileInfo)(char *file, char *title, int *length_in_ms); // if file == NULL, current playing is used
InfoBox=PeekL(head):head+4
Debug " *InfoBox:"+Hex(infobox) ; Int (*InfoBox)(char *file, HWND hwndParent);
IsOurFile=PeekL(Head):head+4
Debug " *IsOurFile:"+Hex(IsOurFile) ; Int (*IsOurFile)(char *fn); // called before extension checks, to allow detection of mms://, etc
Debug " // playback stuff"
play=PeekL(head):head+4
Debug " *Play:"+Hex(play) ; Int (*Play)(char *fn); // return zero on success, -1 on file-not-found, some other value on other (stopping winamp) error
pause=PeekL(head):head+4
Debug " *Pause:"+Hex(pause) ; void (*Pause)(); // pause stream
UnPause=PeekL(head):head+4
Debug " *UnPause:"+Hex(unpause) ; void (*UnPause)(); // unpause stream
IsPaused=PeekL(head):head+4
Debug " *IsPaused:"+Hex(ispaused) ; Int (*IsPaused)(); // ispaused? return 1 if paused, 0 if not
stop=PeekL(head):head+4
Debug " *Stop:"+Hex(stop) ; void (*Stop)(); // stop (unload) stream
Debug " // time stuff"
getlength=PeekL(head):head+4
Debug " *GetLength:"+Hex(getlength) ; Int (*GetLength)(); // get length in ms
; Int (*GetOutputTime)(); // returns current output time in ms. (usually returns outMod->GetOutputTime()
; void (*SetOutputTime)(int time_in_ms); // seeks to point in stream (in ms). Usually you signal yoru thread to seek, which seeks and calls outMod->Flush()..
;
; // volume stuff
; void (*SetVolume)(int volume); // from 0 to 255.. usually just call outMod->SetVolume
; void (*SetPan)(int pan); // from -127 to 127.. usually just call outMod->SetPan
;
; // in-window builtin vis stuff
;
; void (*SAVSAInit)(int maxlatency_in_ms, int srate); // call once in Play(). maxlatency_in_ms should be the value returned from outMod->Open()
; // call after opening audio device with max latency in ms And samplerate
; void (*SAVSADeInit)(); // call in Stop()
;
;
; // simple vis supplying mode
; void (*SAAddPCMData)(void *PCMData, int nch, int bps, int timestamp);
; // 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.
; Int (*SAGetMode)(); // gets csa (the current type (4=ws,2=osc,1=spec))
; // use when calling SAAdd()
; void (*SAAdd)(void *data, int timestamp, int csa); // sets the spec data, filled in by winamp
;
;
; // vis stuff (plug-in)
; // simple vis supplying mode
; void (*VSAAddPCMData)(void *PCMData, int nch, int bps, int timestamp); // 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.
; Int (*VSAGetMode)(int *specNch, int *waveNch); // use to figure out what to give to VSAAdd
; void (*VSAAdd)(void *data, int timestamp); // filled in by winamp, called by plug-in
;
;
; // call this in Play() To tell the vis plug-ins the current output params.
; void (*VSASetInfo)(int nch, int srate);
;
;
; // 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
; Int (*dsp_isactive)();
;
; // returns number of samples To output. This can be as much as twice numsamples.
; // be sure To allocate enough buffer For samples, then.
; Int (*dsp_dosamples)(short int *samples, int numsamples, int bps, int nch, int srate);
;
;
; // eq stuff
; void (*EQSet)(int on, char data[10], int preamp); // 0-64 each, 31 is +0, 0 is +12, 63 is -12. Do nothing to ignore.
;
; // info setting (filled in by winamp)
; void (*SetInfo)(int bitrate, int srate, int stereo, int synched); // if -1, changes ignored? :)
;
; Out_Module *outMod; // filled in by winamp, optionally used :)
EndIf
EndIf
If out
If IsFunction(1, "winampGetOutModule")
Debug "winampGetOutModul"
EndIf
EndIf
here is the out-header:
Code: Select all
typedef struct
{
int version; // module version (OUT_VER)
char *description; // description of module, with version string
int id; // module id. each input module gets its own. non-nullsoft modules should
// be >= 65536.
HWND hMainWindow; // winamp's main window (filled in by winamp)
HINSTANCE hDllInstance; // DLL instance handle (filled in by winamp)
void (*Config)(HWND hwndParent); // configuration dialog
void (*About)(HWND hwndParent); // about dialog
void (*Init)(); // called when loaded
void (*Quit)(); // called when unloaded
int (*Open)(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms);
// returns >=0 on success, <0 on failure
// NOTENOTENOTE: bufferlenms and prebufferms are ignored in most if not all output plug-ins.
// ... so don'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
void (*Close)(); // close the ol' output device.
int (*Write)(char *buf, int len);
// 0 on success. Len == bytes to write (<= 8192 always). buf is straight audio data.
// 1 returns not able to write (yet). Non-blocking, always.
int (*CanWrite)(); // returns number of bytes possible to write at a given time.
// Never will decrease unless you call Write (or Close, heh)
int (*IsPlaying)(); // 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
int (*Pause)(int pause); // returns previous pause state
void (*SetVolume)(int volume); // volume is 0-255
void (*SetPan)(int pan); // pan is -128 to 128
void (*Flush)(int t); // flushes buffers and restarts output at time t (in ms)
// (used for seeking)
int (*GetOutputTime)(); // returns played time in MS
int (*GetWrittenTime)(); // returns time written in MS (used for synching up vis stuff)
} Out_Module;
But that doesn't tell you anything about the Winamp-side (which is what you need to know for this)
it tells me, what the information what the dll get und what information the dll send. I think it is possible to use them without having knowledge of the sourcecode of winamp. It seems, that the "gettheheader"-call is the only call in the DLL.
Have you tried to find other DLLs to play such Formats?
I don't found them. For example the psf-format (playstation) is new. Only a Winamp-Plugin exist.
Posted: Sun Feb 02, 2003 1:43 am
by BackupUser
Restored from previous forum. Originally posted by MrVainSCL.
Hi GPI

Maybe there is any free DLL available on web to play SNES tunes withtout all the work of winamp plugin... Please think about copyrighted stuff (SNES tune, Winamp plugin i.e) ... Mhhhh... i will take a look on web... When finding any interesting DLL, i will tell you
greetz
MrVainSCL! aka Thorsten
PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX9.0, SB AWE64, Win2000 + all Updates...
Posted: Sun Feb 02, 2003 2:06 am
by BackupUser
Restored from previous forum. Originally posted by MrVainSCL.
Hi GPI,
i found a site with some SNES stuff... maybe its interested for you and may help you?
http://zdspc.zophar.net/zdspc.exe <<< including C++/Visual Basic source for DLL
http://www.zophar.net/utilities/spc.html
http://zdspc.zophar.net/
greetz
MrVainSCL! aka Thorsten
PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX9.0, SB AWE64, Win2000 + all Updates...
Posted: Sun Feb 02, 2003 12:03 pm
by BackupUser
Restored from previous forum. Originally posted by GPI.
Hi MrVainSCL
Thanks for that, but i want to use more than only SPC.
So i tested i little bit and i can now start the init, getfile and config, but when i play, it the program crash after a second (i hear a little(!) bit of the music. So i think the dummy routines are not so good. Who can help?
The code:
winampplug.pb
Code: Select all
;Winamp-player
Procedure setinfo(bitrate.l,srate.l,stereo.l,synched.l)
Debug Str(bitrate)+","+Str(srate)+","+Str(stereo)+","+Str(synched)
ProcedureReturn 0
EndProcedure
Procedure.l dummy():ProcedureReturn 0:EndProcedure
Procedure.l dummy1(dumm1.l):ProcedureReturn 0:EndProcedure
Procedure.l dummy2(dumm1.l,dumm2.l):ProcedureReturn 0:EndProcedure
Procedure.l dummy3(dumm1.l,dumm2.l,dumm3.l):ProcedureReturn 0:EndProcedure
Procedure.l dummy4(dumm1.l,dumm2.l,dumm3.l,dumm4.l):ProcedureReturn 0:EndProcedure
Procedure.l dummy5(dumm1.l,dumm2.l,dumm3.l,dumm4.l,dumm5.l):ProcedureReturn 0:EndProcedure
in_dll$="in_psf"
out_dll$="out_wave"
playfile$="dark.psf"+Chr(0)
IncludeFile "modul.pbi"
If OpenWindow(0, 0,0,100,100,#PB_Window_ScreenCentered ,"Winamp-Plugin-Test")
out_DLLinstance=OpenLibrary(1, out_dll$)
If out_DLLinstance
out_head_adr=CallFunction(1,"winampGetOutModule")
If out_head_adr
*out_head.out_module=out_head_adr
;Debug Hex(*out_head\version)
;Debug *out_head\description
*out_head\id=1
*out_head\hMainWindow=WindowID()
*out_head\hDllInstance=out_DLLinstance
CallFunctionFast(*out_head\Init)
CallFunctionFast(*out_head\About,WindowID())
CallFunctionFast(*out_head\Config,WindowID())
Else
MessageRequester("Winamp-Plugin-Test","Can't get out_head", Flags) :End
EndIf
Else
MessageRequester("Winamp-Plugin-Test", "Can't open "+out_dll$, Flags) :End
EndIf
in_DLLinstance= OpenLibrary(0, in_dll$)
If in_DLLinstance
in_head_adr = CallFunction(0, "winampGetInModule2" )
If in_head_adr
*in_head.in_module=in_head_adr
;Debug Hex(*in_head\version)
;Debug *in_head\description
*in_head\hMainWindow=WindowID()
*in_head\hDllInstance=in_DLLinstance
*in_head\SetInfo=@setinfo()
;Dummies for Vis & dspl.
*in_head\SAVSAInit=@dummy2()
*in_head\SAVSADeInit=@dummy()
*in_head\SAAddPCMData=@dummy4()
*in_head\SAGetMode=@dummy()
*in_head\SAAdd=@dummy3()
*in_head\VSAAddPCMData=@dummy4()
*in_head\VSAGetMode=@dummy2()
*in_head\VSAAdd=@dummy2()
*in_head\VSASetInfo=@dummy2()
*in_head\dsp_isactive=@dummy()
*in_head\dsp_dosamples=@dummy5()
*in_head\outMod=out_head_adr
CallFunctionFast(*in_head\Init)
CallFunctionFast(*in_head\About,WindowID())
CallFunctionFast(*in_head\Config,WindowID())
titel$=Space(1000):title_len.l=0
CallFunctionFast(*in_head\GetFileInfo,@playfile$,@titel$,@title_len)
Debug playfile$+" "+titel$+" "+Str(title_len)
;Debug playfile$
ret=CallFunctionFast(*in_head\play,@playfile$)
If ret=0
MessageRequester("Winamp-Plugin-Test", playfile$+Chr(16)+"Ok to stop", Flags)
CallFunctionFast(*in_head\stop)
Else
MessageRequester("Winamp-Plugin-Test", "Can't play:"+Str(ret), Flags)
EndIf
Else
MessageRequester("Winamp-Plugin-Test", "Can't get in_head", Flags) :End
EndIf
Else
MessageRequester("Winamp-Plugin-Test", "Can't open "+in_dll$, Flags) :End
EndIf
EndIf
CallFunctionFast(*out_head\quit)
CallFunctionFast(*in_head\quit)
the "modul.pbi":
Code: Select all
Structure out_module
version.l ;module version (OUT_VER)
*description.s ;description of module, with version string
id.l ;module id. each input module gets its own. non-nullsoft modules should be >= 65536.
hMainWindow.l ;winamp's main window (filled in by winamp)
hDllInstance.l ;DLL instance handle (filled in by winamp)
Config.l ;void (*Config)(HWND hwndParent); // configuration dialog
About.l ;void (*About)(HWND hwndParent); // about dialog
Init.l ;void (*Init)(); // called when loaded
Quit.l ;void (*Quit)(); // called when unloaded
Open.l ; Int (*Open)(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms);
; // returns >=0 on success, GetOutputTime()
SetOutputTime.l ;void (*SetOutputTime)(int time_in_ms); // seeks to point in stream (in ms). Usually you signal yoru thread to seek, which seeks and calls outMod->Flush()..
;volume stuff
SetVolume.l ;void (*SetVolume)(int volume); // from 0 to 255.. usually just call outMod->SetVolume
SetPan.l ;void (*SetPan)(int pan); // from -127 to 127.. usually just call outMod->SetPan
;in-window builtin vis stuff
SAVSAInit.l ;void (*SAVSAInit)(int maxlatency_in_ms, int srate);
; // call once in Play(). maxlatency_in_ms should be the value returned from outMod->Open()
; // call after opening audio device with max latency in ms And samplerate
SAVSADeInit.l ;void (*SAVSADeInit)(); // call in Stop()
;simple vis supplying mode
SAAddPCMData.l ;void (*SAAddPCMData)(void *PCMData, int nch, int bps, int timestamp);
; // 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.l ; Int (*SAGetMode)(); // gets csa (the current type (4=ws,2=osc,1=spec))
; // use when calling SAAdd()
SAAdd.l ;void (*SAAdd)(void *data, int timestamp, int csa);
; // sets the spec data, filled in by winamp
;vis stuff (plug-in)
; simple vis supplying mode
VSAAddPCMData.l ;void (*VSAAddPCMData)(void *PCMData, int nch, int bps, int timestamp)
; // 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.l ;Int (*VSAGetMode)(int *specNch, int *waveNch)
; // use to figure out what to give to VSAAdd
VSAAdd.l ;void (*VSAAdd)(void *data, int timestamp);// filled in by winamp, called by plug-in
;call this in Play() To tell the vis plug-ins the current output params.
VSASetInfo.l ;void (*VSASetInfo)(int nch, int srate);
;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.l ;Int (*dsp_isactive)();
;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.l ;Int (*dsp_dosamples)(short int *samples, int numsamples, int bps, int nch, int srate);
;eq stuff
EQSet.l ;void (*EQSet)(int on, char data[10], int preamp); // 0-64 each, 31 is +0, 0 is +12, 63 is -12. Do nothing to ignore.
;info setting (filled in by winamp)
SetInfo.l ;void (*SetInfo)(int bitrate, int srate, int stereo, int synched); // if -1, changes ignored? :)
outMod.l ;Out_Module *outMod; // filled in by winamp, optionally used :)
EndStructure
Thanks for helping.
Posted: Sun Feb 02, 2003 7:25 pm
by BackupUser
Restored from previous forum. Originally posted by ricardo.
Hi,
There is an Activ eX that does what you want:
Control which will use to winamps input and output plugins without the need for winamp.
http://www.dgpdev.com/waplugxdemo.zip
Iv used sometimes and works fine.
I know that maybe its not usefull to use it from PB, but the point is "its possible to have some generic routine that let you call EVERY winamp in and out plugins".
Could be very interesant to find out how to do it then we dont need to find how to call EVERY plugin and can call any of them.
Best Regards
Ricardo
Dont cry for me Argentina...
Posted: Sun Feb 02, 2003 8:42 pm
by BackupUser
Restored from previous forum. Originally posted by GPI.
Hi ricardo,
two problems: A) demo, b) Active-X
Posted: Sun Feb 02, 2003 8:52 pm
by BackupUser
Restored from previous forum. Originally posted by GPI.
I Havent read this complete, but this sound right:
http://joeblade.com/litestep/tutorials/notch/grdamp.php
But i have now no time to test it.
Posted: Sun Feb 02, 2003 11:31 pm
by BackupUser
Restored from previous forum. Originally posted by ricardo.
Originally posted by GPI
Hi ricardo,
two problems: A) demo, b) Active-X
Hi,
Yes, of course. But this shows that it could be done, using winamp plugins without winamp.
I think that if you see some winamp plugins squeletons, then you may know exactly the structure of the plugin and then you may be able to call this plugin from outside winamp since the plugins of every cathegory has always the same structure.
I hope i explain me in my poor english.
Best Regards
Ricardo
Dont cry for me Argentina...