Dark Bit Factory & Gravity
PROGRAMMING => Freebasic => Topic started 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
'--------------------------------------------------
' 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
'---------------------------------------------------
' 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 ::) ]
-
Neat!!!
Have lots of good Karma Rbraz, I'll make this topic sticky.
-
I just packed the test exe with upx and got it down to only 32kb. Really nice work Rbraz.
-
Yeah, this is really cool 8) , and I will share the good karma with MichaelW ;)
-
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 just packed the test exe with upx and got it down to only 32kb......
Looking forward to see your first 64Kb ;D
-
Quite useful, great work.
-
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?!?! :)
-
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).
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):
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?
-
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 :)
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()
-
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
-
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
-
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.
-
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:
"<$fbc>" "<$file>" ufmod.o -s gui
-
Thanks for the tip Clyde.
-
:|| yes, it works :) :|| thanks for sharing!
-
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
-
Mmm. I am not sure if this is possible with Ufmod.
-
i know that getting to the left and right audio volums is possible via
' 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.
-
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
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
-
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?
-
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.
-
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.
-
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
-
i can see that keeping track of time would be quite easy but returning a pointer would be handy aslo. anywho cheers jim.
-
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
-
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...
-
slightly off topic . . . has anybody found a modern tracker program that actually works like the octamed or something like that works with vista????
Drew
-
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.
-
Slightly offtopic, sorry.
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..
-
In the new version of Freebasic it comes up with
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
-
Are you sure you included windows.bi before mmsystem.bi?
Jim