DarkDUMB (Dark Dynamic Universal Music Bibliotheque)
----------------------------------------------------
Current release V1.03 (UPDATED: FFT Spectrum code fixed)
Updates:
. FFT spectrum analysis
Because it uses
DUMB and
OpenAL and unlike FMOD, BASS, BASSMOD and other API's, this is license free meaning you can use it for commercial software too...
How to use:
Load a piece of music which gets rendered into a sample of your own specifications. While it's getting rendered it will also perform other calculations to grab individual channel data from the music file.
Play the music and while it's playing you can read the volume levels of either the main stereo output or the individual channels from the music file.
Attached to this post is the latest release with a simple demonstration... Enjoy!
Screenshot: (ignore the FPS, my laptop was busy)
Demo code V1.0:
SET DISPLAY MODE 800, 600, 32
SYNC ON
SYNC RATE 30
AUTOCAM OFF
GLOBAL music AS INTEGER
music = DM_NEW("cream_of_the_earth.mod",8,22050,4)
DM_PLAY music
init_channels()
set_up_spheres()
init_vu_bars()
init_camera()
init_fog()
init_stars()
REPEAT
update_channels()
update_spheres()
update_vu_bars()
update_camera()
update_fog()
update_stars()
draw_track_vus()
SYNC
UNTIL inkey$()=" "
DM_STOP music
DM_DELETE music
END
FUNCTION draw_track_vus()
INK 0xffffff,0xffffff
FOR l=0 TO 3
vu = vus(l) * 3
x1 = l * 200 + 50 : x2 = l * 200 + 150
y1 = 600 - vu: y2 = 600
c = vus(1)
col = RGB( c, c >> 1, 0 )
ink col, col
BOX x1, y1, x2, y2, 0x80008000, 0x80ff0000, 0x80ffff00, 0x800080ff
//BOX x1, y1, x2, y2
NEXT l
ENDFUNCTION
FUNCTION init_camera()
GLOBAL cam_ang AS FLOAT
POSITION CAMERA 0, 10, -90
POINT CAMERA 0, -15, 0
cam_ang = 0
ENDFUNCTION
FUNCTION update_camera()
x# = SIN( cam_ang ) * 90.0
z# = COS( cam_ang ) * 90.0
y# = music_left / 1000.0
POSITION CAMERA x#, y#, z#
POINT CAMERA 0, 0, 0
cam_ang = WRAPVALUE( cam_ang + music_right / 30000.0 )
ENDFUNCTION
FUNCTION init_channels()
GLOBAL DIM vus(4)
GLOBAL music_left AS INTEGER
GLOBAL music_right AS INTEGER
ENDFUNCTION
FUNCTION update_channels()
FOR c=0 TO 3
v = DM_VOLUME_CHANNEL( music, c )
IF v > vus(c)
vus(c) = v
ELSE
IF vus(c) > 0
vus(c) = vus(c) - 6
if vus(c) < 0 then vus(c) = 0
ENDIF
ENDIF
NEXT c
v = DM_VOLUME_LR( music )
music_left = v >> 16
music_right = v AND 0xffff
ENDFUNCTION
FUNCTION set_up_spheres()
GLOBAL sphere_texture AS INTEGER
GLOBAL sphere_object1 AS INTEGER
GLOBAL sphere_object2 AS INTEGER
sphere_texture = 1
sphere_object1 = 1
sphere_object2 = 2
FOR x=0 TO 511 STEP 64
INK 0xff00,0xff00
LINE 0,x,511,x
LINE x,0,x,511
INK 0xff0000,0xff0000
BOX x+30, x+30, x+34, x+34
NEXT x
GET IMAGE sphere_texture, 0, 0, 511, 511
MAKE OBJECT SPHERE sphere_object1, -210
MAKE OBJECT SPHERE sphere_object2, -200
SET OBJECT TRANSPARENCY sphere_object1, 3
SET OBJECT TRANSPARENCY sphere_object2, 3
TEXTURE OBJECT sphere_object1, sphere_texture
TEXTURE OBJECT sphere_object2, sphere_texture
ENDFUNCTION
FUNCTION update_spheres()
rot# = vus(1) / 32.0
xr# = OBJECT ANGLE X( sphere_object1 ) + rot#
yr# = OBJECT ANGLE Y( sphere_object1 ) + rot#
zr# = OBJECT ANGLE Z( sphere_object1 ) + rot#
ROTATE OBJECT sphere_object1, xr#, yr#, zr#
rot# = vus(2) / 32.0
xr# = OBJECT ANGLE X( sphere_object2 ) + rot#
yr# = OBJECT ANGLE Y( sphere_object2 ) + rot#
zr# = OBJECT ANGLE Z( sphere_object2 ) + rot#
ROTATE OBJECT sphere_object2, xr#, yr#, zr#
ENDFUNCTION
FUNCTION init_fog()
GLOBAL fog_obj AS INTEGER
fog_obj = 7
FOG ON
FOG DISTANCE 500
MAKE OBJECT CUBE fog_obj, -1500
ENDFUNCTION
FUNCTION update_fog()
col = music_left >> 10
FOG COLOR RGB( 0, 0, col )
ENDFUNCTION
FUNCTION init_light()
GLOBAL light_ang AS FLOAT
light_ang = 0
MAKE LIGHT 1
SET LIGHT RANGE 1, 500
ENDFUNCTION
FUNCTION update_light()
x# = SIN( light_ang ) * 190.0
y# = 100.0
z# = COS( light_ang ) * 190.0
POSITION LIGHT 1, x#, y#, z#
light_ang = WRAPVALUE( light_ang + 4.0 )
ENDFUNCTION
FUNCTION init_stars()
GLOBAL stars_max AS INTEGER
GLOBAL stars_off AS INTEGER
GLOBAL stars_tex AS INTEGER
LOCAL a AS DWORD
LOCAL col AS DWORD
stars_max = 2000
stars_off = 1000
stars_tex = 2
GLOBAL DIM star_objs(stars_max) AS INTEGER
CLS
FOR c=0 TO 31
a = 255 - ( 31 - c ) << 3
col = 0x00ffff00 or ( a << 24 )
//a2FILLCIRCLE 32, 32, 31 - c, col
INK col, col
CIRCLE 32, 32, 31 - c
NEXT c
GET IMAGE stars_tex, 0, 0, 63, 63
FOR c=0 TO stars_max
x# = RND(1000) - 500
y# = RND(1000) - 500
z# = RND(1000) - 500
star_objs(c) = stars_off + c
MAKE OBJECT PLAIN star_objs(c), 10, 10
POSITION OBJECT star_objs(c), x#, y#, z#
TEXTURE OBJECT star_objs(c), stars_tex
SET OBJECT TRANSPARENCY star_objs(c), 1
NEXT c
ENDFUNCTION
FUNCTION update_stars()
FOR c=0 TO stars_max
x# = OBJECT POSITION X( star_objs(c) )
y# = OBJECT POSITION Y( star_objs(c) )
z# = OBJECT POSITION Z( star_objs(c) )
z# = z# + music_right / 10000.0
IF z# > 500.0 THEN z# = z# - 1000.0
POSITION OBJECT star_objs(c), x#, y#, z#
POINT OBJECT star_objs(c), CAMERA POSITION X(), CAMERA POSITION Y(), CAMERA POSITION Z()
NEXT c
ENDFUNCTION
FUNCTION init_vu_bars()
GLOBAL DIM vubars(4) AS INTEGER
GLOBAL vubars_tex AS INTEGER
vubars_tex = 3
BOX 0, 0, 31, 31, 0xff008000, 0xffff0000, 0xffffff00, 0xff0080ff
GET IMAGE vubars_tex, 0, 0, 31, 31
FOR c=0 TO 3
vubars(c) = 3 + c
MAKE OBJECT CUBE vubars(c), 5
POSITION OBJECT vubars(c), c * 20 - 30, 0, 0
TEXTURE OBJECT vubars(c), vubars_tex
SET OBJECT SPECULAR vubars(c), 0xffffff
SET OBJECT SPECULAR POWER vubars(c), 2
NEXT c
ENDFUNCTION
FUNCTION update_vu_bars()
FOR c=0 TO 3
x# = ( ( vus(c) / 1.1 ) + 1.0 ) + 100
y# = ( ( vus(c) / 0.1 ) + 1.0 ) + 100
z# = ( ( vus(c) / 1.1 ) + 1.0 ) + 100
SCALE OBJECT vubars(c), x#, y#, z#
NEXT c
ENDFUNCTION
README: (Supplied with the download)
To use this plugin:
Copy the ".dll" to the plugins-user in the compiler directory
Copy the ".ini" to the keywords in the editor directory
in your DBP installation folder...
The file "OpenAL32.dll" can either go in the folder where you are
creating your own executable or it can be placed in the system32 folder.
This plugin uses the DUMB library as well as the OpenAL library.
Regards,
WLGfx (CS Norwood 2013)
ps. I've also included the redist for the openAL dll. Hopefully this might just
fix the issues of this plugin not working on some machines...
Function Descriptions:
----------------------
music = DM_NEW( filename$, bitrate, frequency, savetracks )
RETURNS music as the pointer needed for other functions
filename$ = Any compatible MOD, IT, S3M or XM file.
Please note that not all files will work with the DUMB API. It is a
case of trial and error...
bitrate = 8 or 16 bits to which the music will be rendered as.
frequency = 22050 or 44100 to render the sample as.
savetracks = While the music is being rendered as a sample, this function will
also save (at a frequency rate of 1/50th second) the volume levels from
the individual tracks within the module. MOD files usually only have 4
tracks, other file formats may have upto 64. These values can be used
during playback to display the volume of indivdual channels.
----
DM_PLAY music
Plays the music that has been rendered as an internal sample.
----
DM_PAUSE music
Pauses the music.
----
DM_STOP music
Stop the music.
----
volLR = DM_VOLUME_LR( music )
RETURNS the current volumes of both the Left and Right stereo channels in a DWORD.
Bits 0-15 is the Right channel
Bits 16-31 is the Left Channel
eg:
VOL = DM_VOLUME_LR( music )
VOLLEFT = VOL >> 16
VOLRIGHT = VOL AND 0xffff
----
chVol = DM_VOLUME_CHANNEL( music, channel )
RETURNS the current volume of the individual channel.
The individual channel volumes are stored as the music is first rendered.
If you have saved 4 channels (tracks) then channel is from 0 - 3.
----
samples = DM_TOTAL_SAMPLES( music )
RETURNS the total number of samples rendered.
For 8 bit, the memory consumed will be 2 bytes for each sample. 16 bits
takes up 2 times 2 bytes for each sample.
----
position = DM_SAMPLE_POSITION( music )
RETURNS the current sample playing position in the music.
----
flag = DM_FINISHED( music )
RETURNS non-zero if the music has finished playing.
The music will not automaticall loop by itself.
Also note that to get a correct reading from this function you will have
to give at least 1 millisecond before calling it.
This function can be used to re-start the music if finished.
The music does NOT have to be re-rendered.
----
DM_FFT_SPECTRUM music
This will produce the FFT spectrum data from the current playing position.
This data can be read by the program using the next two functions.
The FFT data consists of 128 bytes for each Left and Right channels. The
first 64 bytes are the useful ones for produicing graphs, etc.
----
val = DM_LEFT_SPECTRUM( music, pos )
RETURNS the level of the spectrum data of the Left channel from pos (0-127).
----
val = DM_RIGHT_SPECTRUM( music, pos )
RETURNS the level of the spectrum data of the Right channel from pos (0-127).
----
val = DM_LEFT_SAMPLE( music, sample_pos )
RETURNS the sample value of the sample data for the left channel in 8 or 16 bits.
----
val = DM_RIGHT_SAMPLE( music, sample_pos )
RETURNS the sample value of the right channel in 8 or 16 bits.
Screenshot showing rolling terrain using the FFT Spectrum data and VU bars of 26 individual tracks:
Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!