Winamp 2.x Visual plugin example

Share your advanced PureBasic knowledge/code with the community.
Doobrey
Enthusiast
Enthusiast
Posts: 218
Joined: Sat Apr 26, 2003 4:47 am
Location: Dullsville..population: me
Contact:

Winamp 2.x Visual plugin example

Post by Doobrey »

Code updated for 5.20+

Here ya go... just a simple small example of how to write a visual plugin for Winamp 2.x <--- Note...NOT V3 !! that might come later

It should be pretty straightforward, I commented all the important bits
Just compile this to a DLL, and put the DLL in \Winamp\plugins and fire up Winamp.
Next up for me is to try and see what I can do with the OGRE 3D lib in a plugin

Code: Select all

;## Winamp 2.x Vis Plugin example by Doobrey.
;## No asm was harmed in the making of this program.

#VIS_HDRVER =$101
Structure winampVisModule
  description.l   ;## Pointer to plugin description string
  
  hwndParent.l    ;## This lot is filled by Winamp .
  hDllInstance.l
  sRate.l
  nCh.l
  
  latencyMs.l    ;## Set these 2 to time the calls to render()
  delayMs.l
  
  spectrumNch.l   ;## Set these to what your render() needs
  waveformNch.l   ;## either 0,1 or 2 ..but I get wierd results on 1 :(
  
  ;## Winamp fills these 2 every render(), depending on what was set above ^^^^
  spectrumData.b[1152] ;(2*576)   
  waveformData.b[1152] ;## 8 bit samples
  
  Config.l   ;## These 4 are the pointers to your routines.
  Init.l
  Render.l
  Quit.l
  
  UserData.l  ;## pfffff??
  
EndStructure

Structure winampVisHeader
  version.l      ;## **MUST** always be #VIS_HDRVER
  description.l  ;## Addr of module title string
  getmodule.l    ;## Addr of your getmodule() proc
EndStructure


Structure tmpspec
  specdata.b[106]
EndStructure




Global hdr.winampVisHeader,mod0.winampVisModule,mod1.winampVisModule,imgnumber.l,rendercount.l,oldtitle.s,winamphwnd.l
Global Mem1.l,Mem2.l,Mem3.l,count.l,oldspec.tmpspec

Procedure.s GetSongTitle() ;## RETURNS NULL IF SAME TITLE, OTHERWISE NEW TITLE
  ;## Full list of the usercodes on the Winamp2 dev forums.
  If winamphwnd
    songindex.l=SendMessage_(winamphwnd,#WM_USER,0,125)
    titlepointer.l=SendMessage_(winamphwnd,#WM_USER,songindex,212)
    If titlepointer
      title.s=PeekS(titlepointer)
      If title<>oldtitle
        ProcedureReturn title
      EndIf
    EndIf
  EndIf
  
EndProcedure

;## This little proc gets asked by winamp for the address of the winampVisModule struct
;## for every module you write. Return 0 to tell it there`s no more!

ProcedureCDLL .l  getModule(modnum.l)
  pr.l=0
  Select modnum  ;## ONCE CASE PER MODULE
    Case 0
      pr= @mod0
    Case 1
      pr= @mod1
      ;Case 2         
      ;pr= @anothermod  -- just an example
      
  EndSelect
  ProcedureReturn pr
EndProcedure

;## Put any user config  stuff in this routine.
Procedure Config(*this_mod.winampVisModule)
  MessageBox_(*this_mod\hwndParent,"Powered by PureBasic !","Config",#MB_OK)
EndProcedure

;## Init for the windowed mode.. I know it`s yucky..
;## But double buffering using 2 images seemed the easiest way for a window test !
;## Return 0 for InitOK, or 1 for error.
Procedure Init1(*this_mod.winampVisModule)
  wintitle.s=Str(*this_mod\hwndParent)
  winamphwnd=*this_mod\hwndParent
  If OpenWindow(0,0,0,288,128,"PB Winamp Test",0,winamphwnd) ;## REALLY NEED TO ADD WINAMP PARENT WINDOW !
    CreateImage(0,288,128)
    CreateImage(1,288,128)
    StartDrawing(ImageOutput(0))
    Box(0,0,288,128,0)
    StopDrawing()
    ImageGadget(0,0,0,288,128,ImageID(0),0)
    imagenumber=1
    rendercount=0
    ProcedureReturn 0
  Else
    ;## Should really add an error msg here
    ProcedureReturn 1
  EndIf
EndProcedure

;## The render routines must return 0 for OK, or 1=Error
;## Beware, spectrumdata is in a linear scale..2*576 bytes
;## **MUST be CDLL ** or welcome to crashville!
ProcedureCDLL.l Render1(*this_mod.winampVisModule)
  pr.l=1
  StartDrawing(ImageOutput(imagenumber))
  Box(0,0,288,128,0)
  For a.l=0 To 71 ;## Same as 0 to 287 step ..average out the bands.
    w.l=0
    For b=0 To 3
      v.l=(*this_mod\spectrumdata[(a*4)+b]&$FF)
      w+v ;## I got wierd results doing w=w+(*this_mod\spectrumdata[(a*4)+b]&$FF)
    Next
    w=w>>4
    w=(Sqr(w)*16)
    ;## Simple /2 average with old data
    tmp.l=((w+oldspec\specdata[a])>>1)
    oldspec\specdata[a]=tmp
    ;## Get a funky colour
    col.l=RGB(111+(a*2),255-(a*2),tmp)
    
    Box(a*4,128,4,-tmp,col)
  Next
  StopDrawing()
  SetGadgetState(0,ImageID(imagenumber))
  imagenumber=1-imagenumber
  rendercount+1
  
  If rendercount>7
    title.s=GetSongTitle()
    If title
      SetWindowText_(WindowID(0),@title)
      oldtitle=title
    EndIf
    rendercount=0
  EndIf
  pr=0
  ProcedureReturn pr
EndProcedure

;## Must cleanup any resources that Init created...no return val.
Procedure Quit1(*this_mod.winampVisModule)
  CloseWindow(0)
  FreeImage(0)
  FreeImage(1)
EndProcedure

;##-- Now for another module --##

;## Init for fullscreen-o-rama
Procedure.l Init0(*this_mod.winampVisModule)
  pr.l=1
  If InitSprite() And InitKeyboard()
    If OpenScreen(640,480,32,"PB Winamp test")
      
      ;## CLEAR OLD SPECTRUM DATA ARRAY
      For a=0 To 105
        oldspec\specdata[a]=0
      Next
      pr=0
    EndIf
  EndIf
  
  ProcedureReturn pr
EndProcedure

;## The full screen render routine..
ProcedureCDLL.l Render0(*this_mod.winampVisModule)
  pr.l=0
  
  If IsScreenActive()
    FlipBuffers()
    ClearScreen(RGB(0,0,0))
    
    StartDrawing(ScreenOutput())
    addr.w=0
    For a.l=0 To 105
      w.f=0
      For b=0 To 3
        v.l=(*this_mod\spectrumdata[addr]&$FF) ;#left channel
        w+v
        addr+1
      Next
      
      ;## Just an attempt to boost the high end spectrum
      w=(Sqr(w/4)*8)
      v=w*((a/25)+1)
      
      ;## AVERAGE IT OUT WITH OLD DATA
      tmp.l=((v+oldspec\specdata[a])/2)&$FFFF
      oldspec\specdata[a]=tmp
      
      Box(a*6,480,6,-4*tmp,RGB(2*a,255-(2*a),tmp))
      
    Next
    
    ;## Now to piddle about with the waveform
    lx.l=0:ly=128:nx.l=0
    For a.l=0 To 105
      ny.l=128-*this_mod\waveformdata[a*4]
      nx+6
      LineXY(lx,ly,nx,ny,RGB(ny,255-ny,180))
      ly=ny:lx=nx
    Next
    
    StopDrawing()
    
    ;## Better just check to see if escape has been pressed !
    ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Escape)
      pr=1
    EndIf
    
  EndIf
  
  ProcedureReturn pr
EndProcedure

;## Cleanup after Init0
Procedure Quit0(*this_mod.winampVisModule)
  CloseScreen()
EndProcedure



;## This is called by winamp to examine all available plugin modes
;## Don`t init anything here, just return the address of the header structure!
ProcedureDLL.l winampVisGetHeader()
  ;## GENERAL HEADER STUFF
  hdr\version=#VIS_HDRVER
  hdr\description=?desc_label
  hdr\getmodule=@getModule()
  
  ;## MODULE STUFF ..fill out one of these for each module in the plugin.
  ;## MODULE 0..FULL SCREEN
  mod0\description=?mod0_label
  mod0\latencyMs=25
  mod0\delayMs=25
  mod0\spectrumNch=2 ;# Gimme one of each
  mod0\waveformNch=2 ;# Wierd results when using 1 !
  mod0\Config=@Config()
  mod0\Init=@Init0()
  mod0\Render=@Render0()
  mod0\Quit=@Quit0()
  
  ;## MODULE 1..WINDOW MODE
  mod1\description=?mod1_label
  mod1\latencyMs=25
  mod1\delayMs=25
  mod1\spectrumNch=1 ;# Just one spectrum in window
  mod1\waveformNch=0
  mod1\Config=@Config()
  mod1\Init=@Init1()
  mod1\Render=@Render1()
  mod1\Quit=@Quit1()
  
  ProcedureReturn @hdr
EndProcedure


;## Quick and easy static strings
DataSection
  desc_label:
  Data.s "Doobreys PB Plugathlon"
  mod0_label:
  Data.s "Full Screen ( escape to stop)"
  mod1_label:
  Data.s "Windowed mode"
EndDataSection
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

Post by Num3 »

Excellent work :P
dige
Addict
Addict
Posts: 1412
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Post by dige »

Amazing, great work!
... PB rulez :D
User avatar
kenmo
Addict
Addict
Posts: 2047
Joined: Tue Dec 23, 2003 3:54 am

Post by kenmo »

Sorry to bring back a topic over a year old, but I just recently found this on purearea.net and have been fooling around with it lately. Has anyone who tried noticed that if you run the plugin and exit, then try to run it again it will not work? I can only get it to work if I close winamp and open it again. I replaced the init function with

Code: Select all

Procedure.l Init0(*this_mod.winampVisModule) 
pr.l=1 
If initted=0
   If InitSprite() And InitKeyboard() : initted=1 : EndIf
EndIf
If initted=1
   If OpenScreen(640,480,32,"Winamp Visuals") 
   ;## CLEAR OLD SPECTRUM DATA ARRAY 
     For a=0 To 105 
      oldspec\specdata[a]=0 
     Next 
     dangle=0.0
     pr=0
   Else
      MessageRequester("","no screen")
   EndIf
Else
   MessageRequester("","not initted")
EndIf 
ProcedureReturn pr 
EndProcedure 
to find out why it wouldnt re-run, and I get the "not initted" error even though initted is a global variable and is never reset to 0.

By the way I know initted is not a word, I didnt feel like typing out "initialized", hehe.
Last edited by kenmo on Fri Apr 17, 2015 4:42 pm, edited 1 time in total.
PolyVector
Enthusiast
Enthusiast
Posts: 499
Joined: Wed Sep 17, 2003 9:17 pm
Location: Southern California
Contact:

Post by PolyVector »

I played with that code last year... I had the same problem and couldn't solve it :?
Doobrey
Enthusiast
Enthusiast
Posts: 218
Joined: Sat Apr 26, 2003 4:47 am
Location: Dullsville..population: me
Contact:

Post by Doobrey »

kenmo wrote:Has anyone who tried noticed that if you run the plugin and exit, then try to run it again it will not work?
Now that is wierd.. I never had anything like that when I was testing it.
I could happily switch from full screen to windowed, stop and start with no problems.

Mind you, I did it a year ago, PB has changed a lot since then, so it could be an issue with old code and the newer PB.
User avatar
kenmo
Addict
Addict
Posts: 2047
Joined: Tue Dec 23, 2003 3:54 am

Post by kenmo »

Awww. This isnt good. I was planning on making a small collection of cheesy visualizations, but this problem seems to pretty much screw up the whole thing.
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Post by KarLKoX »

Doobrey wrote: Now that is wierd.. I never had anything like that when I was testing it.
I could happily switch from full screen to windowed, stop and start with no problems.
Me too :) (winamp 2.95)
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Thats ok, im bringing it up again to see if there is a V5 version since v3 is long and gone.
Doobrey
Enthusiast
Enthusiast
Posts: 218
Joined: Sat Apr 26, 2003 4:47 am
Location: Dullsville..population: me
Contact:

Post by Doobrey »

Doesn`t Winamp V5 use the same plugin API as V2 for visual plugins?
..I know that the 'general' type plugins from v2 work under v5.
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

Post by Num3 »

Arghhhhhh...

Why in hell does one need a huge media player like winamp 5 ???

I'm quite happy with 2.91 ... It does the job!

BTW: I had the same problem here...
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Not a need, its just that 2.x and 3.x series are not available for download on the site.
Beach
Enthusiast
Enthusiast
Posts: 677
Joined: Mon Feb 02, 2004 3:16 am
Location: Beyond the sun...

Post by Beach »

Not a need, its just that 2.x and 3.x series are not available for download on the site.
I started using XMPlay since WinAmp keeps getting bigger and bigger. The XMPlay download is only 312k (354k expanded) and has visualization and skin support. XMplay visualisations are compatible with Sonique plugins, which are really nice.

One thing that XMPlay needs is a media library like Winamp has, then it would be the best player out there (IMHO).

XMPlay site: http://www.un4seen.com/
-Beach
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

Post by Num3 »

Shannara wrote:Not a need, its just that 2.x and 3.x series are not available for download on the site.
Use the Google Luke ...

http://www.google.pt/search?q=winamp+2.95+download
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Post by ricardo »

Whats the difference to write a DSP plugin? Can anyboy showm me an skeleton for DSP winamp plugin?
Post Reply