Dark Bit Factory & Gravity

PROGRAMMING => Freebasic => Topic started by: Rbz on August 06, 2006

Title: uFmod + Freebasic
Post by: Rbz on August 06, 2006
Well, to make things easy, I have updated the uFmod include by MichaelW (freebasic forum (http://www.freebasic.net/forum/viewtopic.php?t=4936&highlight=ufmod))‚  to the latest version. (uFmod 1.18 (http://ufmod.sourceforge.net/)Test.bas
Code: [Select]
'--------------------------------------------------
'   uFmod example for Freebasic
'
'   uFmod.bi:
'       Version 0.1 by MichaelW
'       Version 0.2 by Rbraz - 05 Aug 2006
'
'   FreeBasic + Bin2Bas version by Rbraz - 2006
'
'--------------------------------------------------

ChDir ExePath
Option Explicit

'Includes
#include "windows.bi"
#include "ufmod.bi"

'Include our music
#include "Music.bas"

'Variables
Dim hWave As HWAVEOUT
Dim title_ptr as zstring ptr

'Allocate 50 bytes for music title
title_ptr = allocate(50)


'----------------Main

    'Play our music  (50601 = music length in bytes)
    hWave = uFMOD_PlaySong(@Music(0),50601,XM_MEMORY)
   
    'Get music title
    title_ptr = uFMOD_GetTitle()

    'Set music volume
    uFMOD_SetVolume(60)
   
    Cls
   
    print "Playing ... "; *title_ptr

    While Inkey$() <> Chr$(27)
       
        Locate 3,1
        Print "Time: "; uFMOD_GetTime()/1000
        Sleep 100
       
    Wend
   
    uFMOD_StopSong()

'----------------End
 


uFmod.bi
Code: [Select]
'---------------------------------------------------
' uFmod 1.18 - http://ufmod.sourceforge.net/
'
' uFmod.bi
' Version 0.1 by MichaelW
' Version 0.2 by Rbraz - 05 Aug 2006
'
'----------------------------------------------------

#include "win/mmsystem.bi"

#define XM_RESOURCE 0
#define XM_MEMORY   1
#define XM_FILE     2

' The uFMOD_PlaySong function starts playing an XM song.
'   --------------
'   Parameters:
'     lpXM
'        Specifies the song to play. If this parameter is NULL,
'        any currently playing song is stopped. In such a case, function
'        does not return a meaningful value.
'        fdwSong parameter determines whether this value is interpreted
'        as a filename, as a resource identifier or a pointer to an image
'        of the song in memory.
'     param
'        Handle to the executable file that contains the resource to be
'        loaded or size of the image of the song in memory. This parameter
'        is ignored unless XM_RESOURCE or XM_MEMORY is specified in fdwSong.
'     fdwSong
'        Flags for playing the song. The following values are defined
'        Value        Meaning
'        XM_FILE      lpXM points to filename.
'                     param is ignored.
'        XM_MEMORY    lpXM points to an image of a song in memory.
'                     param is the image size. Once, uFMOD_PlaySong
'                     returns, it's safe to free/discard the memory buffer.
'        XM_RESOURCE  lpXM Specifies the name of the resource.
'                     param identifies the module whose executable file
'                     contains the resource.
'                     The resource type must be RT_RCDATA.
'  Return Values:
'     Returns a pointer to HWAVEOUT on success or NULL otherwise.

declare function uFMOD_PlaySong stdcall alias "uFMOD_PlaySong" (byval as LPVOID , byval as DWORD, byval as DWORD) as HWAVEOUT

' The uFMOD_StopSong function stops the currently playing song, if any.
#define uFMOD_StopSong() uFMOD_PlaySong(0, 0, 0)

' The uFMOD_Pause function pauses the currently playing song, if any.
declare sub uFMOD_Pause stdcall alias "uFMOD_Pause" ()

' The uFMOD_Resume function resumes the currently paused song, if any.
declare sub uFMOD_Resume stdcall alias "uFMOD_Resume" ()

' The uFMOD_GetStats function returns the current RMS volume coefficients
'   in L and R channels.
'   --------------
'   Return Values:
'      low-order word : RMS volume in R channel
'      hi-order  word : RMS volume in L channel
'
declare function uFMOD_GetStats stdcall alias "uFMOD_GetStats" () as UINTEGER

' The uFMOD_GetTime function returns the time in milliseconds since the
'   song was started. This is useful for synchronizing purposes.
'   --------------
'   Return Values:
'      Returns the time in milliseconds since the song was started.
'
declare function uFMOD_GetTime stdcall alias "uFMOD_GetTime" () as UINTEGER

' The uFMOD_GetTitle function returns the current track's title, if any.
'   --------------
'   Return Values:
'      Returns the track's title in ASCIIZ format.
'
declare function uFMOD_GetTitle stdcall alias "uFMOD_GetTitle" () as ZSTRING ptr

' The uFMOD_SetVolume function sets the global volume.
'   --------------
'   0:  muting
'   64: maximum volume
'   NOTE: Any value above 64 maps to maximum volume too.
'   The volume scale is linear. Maximum volume is set by default.
'
declare sub uFMOD_SetVolume stdcall alias "uFMOD_SetVolume" (byval as DWORD)

Compile.bat
..\..\fbc -s console ufmod.o Test.bas

Ps: Don't forget to use the correct path for fbc.  Eg:  C:\FreeBasic\fbc -s console ufmod.o Test.bas


Check out the attach below...


[ Edited: music length  ::) ]
Title: Re: uFmod + Freebasic
Post by: Shockwave on August 06, 2006
Neat!!!
Have lots of good Karma Rbraz, I'll make this topic sticky.
Title: Re: uFmod + Freebasic
Post by: Shockwave on August 06, 2006
I just packed the test exe with upx and got it down to only 32kb. Really nice work Rbraz.
Title: Re: uFmod + Freebasic
Post by: Rbz on August 06, 2006
Yeah, this is really cool   8)  , and I will share the good karma with MichaelW  ;)
Title: Re: uFmod + Freebasic
Post by: Shockwave on August 06, 2006
What I love about this is that it will make synching to music really easy, also the function to give L+R volume is very cool.
Title: Re: uFmod + Freebasic
Post by: Rbz on August 07, 2006
I just packed the test exe with upx and got it down to only 32kb......

Looking forward to see your first 64Kb  ;D
Title: Re: uFmod + Freebasic
Post by: zawran on August 08, 2006
Quite useful, great work.
Title: Re: uFmod + Freebasic
Post by: Shockwave on August 08, 2006
I just packed the test exe with upx and got it down to only 32kb......

Looking forward to see your first 64Kb ;D

Now where did I leave Werkzeug?!?! :)
Title: Re: uFmod + Freebasic
Post by: norki on August 09, 2006
Lo guys, first post here. I was a member on the last forum too. Didn't post too much tho  :P

I like this uFMOD thing! Playback isn't perfect, but it's free, and doesn't have any silly license (I think).

Quote
What I love about this is that it will make synching to music really easy, also the function to give L+R volume is very cool.
I had a go on synching a counter to a 60bpm/120bpm module, but failed. I've attached the xm I made to test this. My code went a little something like this (it's rbraz' example, slightly modified):
Code: [Select]
ChDir ExePath
Option Explicit

#include "windows.bi"
#include "ufmod.bi"

Dim hWave As HWAVEOUT
Dim title_ptr as zstring ptr
Dim buffer As Zstring * 512
buffer="kim3.xm"
title_ptr = allocate(50)
dim ctr as double
dim ctr2 as double
dim test1 as double 'this variable is meant to make up for any delay (if any, I think there is) upon loading the module...

hWave = uFMOD_PlaySong(@buffer,0,XM_FILE)
ctr=uFMOD_GetTime()
test1=ctr
title_ptr = uFMOD_GetTitle()

uFMOD_SetVolume(64)
print test1
print "Playing ... "; *title_ptr
   
ctr2=1
While Inkey$() <> Chr$(27)
       
   if uFMOD_GetTime >= ctr + (500-test1) then
      ctr=uFMOD_GetTime
      ctr2=ctr2+1
      if ctr2>4 then ctr2=1       
   endif
   locate 5,2
   print ctr2; " " ; ctr ; " " ; uFMOD_GetTime()
Wend
   
uFMOD_StopSong()

Any ideas?
Title: Re: uFmod + Freebasic
Post by: Rbz on August 12, 2006
Hello dude, you will need to convert the result of uFMOD_GetTime() (millisecs) into seconds, just use  -->  uFMOD_GetTime() / 1000
Check out the example below, hope this is what you looking for :)

Code: [Select]
ChDir ExePath
Option Explicit

#include "windows.bi"
#include "ufmod.bi"

Dim hWave As HWAVEOUT
Dim title_ptr as zstring ptr
Dim buffer As Zstring * 512
buffer="kim3.xm"
title_ptr = allocate(50)

'Kim3.xm lenght = 8 seconds
dim as double music_time = 8

'Test when time reach to 3 seconds
dim as double music_time_test = 3

'Music elapsed time in seconds
dim as double elapsed_time


hWave = uFMOD_PlaySong(@buffer,0,XM_FILE)
title_ptr = uFMOD_GetTitle()

cls

uFMOD_SetVolume(64)
Locate 1,1

if *title_ptr <> "" then
    print "Playing ... "; *title_ptr
else
    print "Playing ... No Title!"
end if

While Inkey$() <> Chr$(27)
   
    'Elapsed time in seconds
    elapsed_time = uFMOD_GetTime() / 1000
   
    Locate 3,2
    Print "Elapsed Time: ";elapsed_time
   
    if (elapsed_time >= music_time) then
        uFMOD_StopSong()
        Sleep(2000)
        hWave = uFMOD_PlaySong(@buffer,0,XM_FILE)
    end if
       
    if (elapsed_time >= music_time_test) then
        Locate 5,2
        Print "Song Time >= 3 seconds"
    else
        Locate 5,2
        Print "                      "
    end if
   
Wend
   
uFMOD_StopSong()
Title: Re: uFmod + Freebasic
Post by: DrewPee on August 12, 2006
Not sure if im doing something wrong, i keep on getting compilation errors . . .

Command executed:
"C:\Program Files\FreeBASIC\fbc.exe" "C:\Documents and Settings\DrewPee\Desktop\FreeBasic\FreeBasic+ufmod\Test.bas"

Compiler output:
C:\Documents and Settings\DrewPee\Desktop\FreeBasic\FreeBasic+ufmod\Test.o:fake:(.text+0x55): undefined reference to `uFMOD_PlaySong@12'
C:\Documents and Settings\DrewPee\Desktop\FreeBasic\FreeBasic+ufmod\Test.o:fake:(.text+0x5d): undefined reference to `uFMOD_GetTitle@0'
C:\Documents and Settings\DrewPee\Desktop\FreeBasic\FreeBasic+ufmod\Test.o:fake:(.text+0x67): undefined reference to `uFMOD_SetVolume@4'
C:\Documents and Settings\DrewPee\Desktop\FreeBasic\FreeBasic+ufmod\Test.o:fake:(.text+0xd0): undefined reference to `uFMOD_GetTime@0'
C:\Documents and Settings\DrewPee\Desktop\FreeBasic\FreeBasic+ufmod\Test.o:fake:(.text+0xef): undefined reference to `uFMOD_PlaySong@12'

Results:
Compilation failed

System:
FBIde: 0.4.6
fbc:   FreeBASIC Compiler - Version 0.16 for win32 (target:win32)
OS:    Windows XP (build 2600, Service Pack 2)

Any ideas?

DrewPee
Title: Re: uFmod + Freebasic
Post by: Rbz on August 12, 2006
You must compile your prog. with ufmod.o (library),  so ,use "Compile.bat" to make it (download my first example)

Check the correct path for fbc (inside of Compile.bat file). 
Example: 
C:\FreeBasic\fbc -s console ufmod.o Test.bas
Title: Re: uFmod + Freebasic
Post by: Shockwave on August 13, 2006
That caught me out too Drew, I kludged my way around it to be honest with you. Rbraz has the most elegant solution there but I will post a step by step guide to getting your programs to compile and create an example zip later today for everyone who's stuck.
Title: Re: uFmod + Freebasic
Post by: Clyde on August 21, 2006
Alternatively If your using FBIDE.

Go into View -> Settings which will bring up the FBide Settings then choose the Freebasic tab.
And under Compiler Command type in:

Code: [Select]
"<$fbc>" "<$file>" ufmod.o  -s gui
Title: Re: uFmod + Freebasic
Post by: Shockwave on August 22, 2006
Thanks for the tip Clyde.
Title: Re: uFmod + Freebasic
Post by: .:] Druid [:. on November 12, 2006
 :||  yes, it works :)  :||  thanks for sharing!
Title: Re: uFmod + Freebasic
Post by: ninogenio on May 05, 2007
hey guys how exactly would i go about retriving left and right audio vol do i have to shl and shr to get the values?

also is there a way of getting to the audio data at whatever position the audio bufferis at?

cheers
Title: Re: uFmod + Freebasic
Post by: Shockwave on May 05, 2007
Mmm. I am not sure if this is possible with Ufmod.
Title: Re: uFmod + Freebasic
Post by: ninogenio on May 05, 2007
i know that getting to the left and right audio volums is possible via

Code: [Select]
' The uFMOD_GetStats function returns the current RMS volume coefficients
'   in L and R channels.
'   --------------
'   Return Values:
'      low-order word : RMS volume in R channel
'      hi-order  word : RMS volume in L channel
'
declare function uFMOD_GetStats stdcall alias "uFMOD_GetStats" () as UINTEGER

but im not sure exactly how to get to the high and low words ( l/r channels )

and as for the getting to the audio data i dont think it is possible but thought id ask.
Title: Re: uFmod + Freebasic
Post by: Jim on May 06, 2007
The high word and low word are just the top and bottom 16bits of the result - it's a shortcut to return two values in one parameter.
Something like this will split them up again
Code: [Select]
dim high, low as uinteger
dim value as uinteger

value=&H12345678
high=value shr 16
low=value and &H0000ffff

print hex$(high),hex$(low)

It's important to use uinteger, not integer.

Jim

Title: Re: uFmod + Freebasic
Post by: ninogenio on May 06, 2007
ahh cheers jim i thought it might be something along those lines.

any idea if ufmod can return the audio data at whatever position the buffer is at? if not would it be a possibility to add such a feature?
Title: Re: uFmod + Freebasic
Post by: Shockwave on May 06, 2007
This calls for some Karma for Nino and Jim, that's a feature I didn't realise was there!

If the frequency of a channel can be returned, a spectrum analyzer could be made.
Title: Re: uFmod + Freebasic
Post by: ninogenio on May 06, 2007
cheers shockwave yeah stuff like media player effects can be acheived through pitches and drops in the l/r channel volums.

it works pretty much the same as the bass.dll.
Title: Re: uFmod + Freebasic
Post by: Jim on May 06, 2007
To get the frequency graph, you need to keep a track of the amplitude (volume) against time and use what's called an FFT (or DFT) to get the instantaneous frequency.  Frequency is defined as rate of change of amplitude vs. time.

Either you want to poll that call to get the volumes really fast (simple, but cpu intensive), or you need to get a pointer to the audio buffer (a few ms worth) when it gets delivered by the driver to the sound card (needs a change to ufmod I think - need to research that).

Jim
Title: Re: uFmod + Freebasic
Post by: ninogenio on May 07, 2007
i can see that keeping track of time would be quite easy but returning a pointer would be handy aslo. anywho cheers jim.
Title: Re: uFmod + Freebasic
Post by: DrewPee on December 03, 2007
Hello guys . . .
Im using FMod at the mo but it won't play protracker mods . . . and I have loads of tunes (other peoples!) i want to use!!!! Does UFMod play other types of mods?
I love FMod cos I have now written an equaliser around it . . . I don't really want to have to start again with new code for UFMod do i? has anybody found a way around getting an equaliser to work?

Drew
Title: Re: uFmod + Freebasic
Post by: Shockwave on December 03, 2007
You could load your protracker song into a modern tracker and then save it as an XM to make it work.

I like Ufmod because it's so tiny, I haven't made an equaliser with it yet though, I don't know about anyone else...
Title: Re: uFmod + Freebasic
Post by: DrewPee on December 03, 2007
slightly off topic . . . has anybody found a modern tracker program that actually works like the octamed or something like that works with vista????

Drew
Title: Re: uFmod + Freebasic
Post by: Rbz on December 04, 2007
slightly off topic . . . has anybody found a modern tracker program that actually works like the octamed or something like that works with vista????

Drew
I don't have Vista here, but you can try Milkytracker (http://www.milkytracker.net/) or Madtracker (http://www.madtracker.org/), you can use both to load a .mod file and save to .xm file.
Title: Re: uFmod + Freebasic
Post by: zawran on December 04, 2007
Slightly offtopic, sorry.

Quote
Im using FMod at the mo but it won't play protracker mods

I am fairly certain that the BASS library plays those mod files. But unfortunately I do not know how to use that with FreeBasic, perhaps someone else does..
Title: Re: uFmod + Freebasic
Post by: Clyde on September 21, 2010
In the new version of Freebasic it comes up with

Quote
Compiler output:
C:\Program Files\FreeBasic\inc\win\mmsystem.bi(901) error 66: Incomplete type, before ','
type YIELDPROC as function (byval as MCIDEVICEID, byval as DWORD) as UINT
                                                ^
C:\Program Files\FreeBasic\inc\win\mmsystem.bi(901) error 56: Illegal specification, at parameter 2
type YIELDPROC as function (byval as MCIDEVICEID, byval as DWORD) as UINT
                                                           ^
C:\Program Files\FreeBasic\inc\win\mmsystem.bi(916) error 14: Expected identifier, found 'DWORD'
   songptrpos as DWORD
                 ^
C:\Program Files\FreeBasic\inc\win\mmsystem.bi(920) error 14: Expected identifier, found 'UINT'
   wType as UINT
            ^
C:\Program Files\FreeBasic\inc\win\mmsystem.bi(922) error 14: Expected identifier, found 'DWORD'
      ms as DWORD
            ^
C:\Program Files\FreeBasic\inc\win\mmsystem.bi(923) error 14: Expected identifier, found 'DWORD'
      sample as DWORD
                ^
C:\Program Files\FreeBasic\inc\win\mmsystem.bi(924) error 14: Expected identifier, found 'DWORD'
      cb as DWORD
            ^
C:\Program Files\FreeBasic\inc\win\mmsystem.bi(925) error 14: Expected identifier, found 'DWORD'
      ticks as DWORD
               ^
C:\Program Files\FreeBasic\inc\win\mmsystem.bi(941) error 14: Expected identifier, found 'DWORD'
   dwDCISize as DWORD
                ^
C:\Program Files\FreeBasic\inc\win\mmsystem.bi(942) error 14: Expected identifier, found 'LPCWSTR'
   lpszDCISectionName as LPCWSTR
                         ^
C:\Program Files\FreeBasic\inc\win\mmsystem.bi(942) error 123: Too many errors, exiting
Title: Re: uFmod + Freebasic
Post by: Jim on September 21, 2010
Are you sure you included windows.bi before mmsystem.bi?
Jim