Qbasicnews.com
February 28, 2020, 02:31:16 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Back to Qbasicnews.com | QB Online Help | FAQ | Chat | All Basic Code | QB Knowledge Base
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: TUTORIAL: In-Game Music with FMOD  (Read 7802 times)
shiftLynx
Wandering Guru
***
Posts: 340



WWW
« on: February 18, 2005, 12:27:32 PM »



Introduction
In this tutorial, I will show you the basics of using FMOD to play music and sound effects in your FreeBASIC programs and games. Smiley Plasma has done a great job in porting the FMOD headers, which are included with the FreeBASIC release, so you don't have to download anything other than FreeBASIC to get started.

Download Accompanying Tutorial Files

FMOD is an amazing sound library. Their web site is at http://www.fmod.org/. If you're writing a shareware or commercial game using the library, you'll have to dish up a lot of money for the licence (and so you should, if you're going to be getting cash from it! there is a very good discount for shareware developers, rather than commercial, by the way). For freeware games though, which you will probably be making, the licence is free to use! More information about the licences is available on the FMOD web page.

FMOD is capable of playing a vast spectrum of different formats. It can currently load and play these 'music' formats: .MID, .MOD, .S3M, .XM, .IT, .RMI, .SGT and .FSB. It can also load and play these 'static sound' file formats: .WAV, .MP2, .MP3, .OGG and .RAW.





Before Starting
Before writing any programs using FMOD, you will find the FMOD documentation EXTREMELY useful. It's really easy to use as well. You can download it in .CHM format from here: http://www.cdsoft.co.uk/fbstuff/fmod.chm





Initialisation
The first thing that we must do is include the relevant header file. To use FMOD's functions, we just need to add this to the top of our program:

[syntax="FreeBASIC"]
'$INCLUDE: 'fmod.bi'
[/syntax]

The next thing that we need is to initialise the library. This is done through the FSOUND_Init function, through which you must specify the sample rate and number of channels that you want. I usually just stick with a sample rate of 48000Hz and 8 channels, which should be plenty. FSOUND_Init also takes one last parameter, through which you can specify some other options. You can look up all of these options in the FSOUND_INIT_FLAGS section of the FMOD reference.

[syntax="FreeBASIC"]
' Initialise FMOD with 48000Hz, 8 channels.
FSOUND_Init(48000, 8, 0)
[/syntax]

Okay, great! Now we're ready to start loading the songs. If you've used FMOD before in C, you will know that to store information about a loaded song, you stored a pointer to an FMUSIC_MODULE structure. Well this isn't needed in FreeBASIC - all we need to do is store the integer, as this effectively acts as the pointer anyway. To save confusion, I will just refer to this pointer as the 'song ID'.

By the way, before exiting, our program should call FSOUND_Close. This will ensure that FMOD has time to clean up all of the memory resources it used and allows it to unload properly.

Our skeleton code is now this:

[syntax="FreeBASIC"]
'$INCLUDE: 'fmod.bi'

FSOUND_Init(48000, 8, 0)

' Main code goes here!

FSOUND_Close
END
[/syntax]





Loading and Playing Songs
In FMOD, 'songs' are considered to be either MIDI files or modular music (S3M, MOD, XM, etc.). For each song we load, we have to keep a reference to it - this is just done by keeping an integer. Using this reference, we can play the song and deallocate it nicely at the end of our program.

The function we'll be using to load the song is the FMUSIC_LoadSong function, which accepts just one argument: the file name of the song, and returns the reference ID. I will stick to loading the MIDI included in the accompanying tutorial zip archive. This MIDI is originally from Ultima Underworld 2.

[syntax="FreeBASIC"]
DIM backgroundMusic AS INTEGER

backgroundMusic = FMUSIC_LoadSong("uw2-07.mid")
[/syntax]

To check for a loading error, you can just see if the return value is 0.

[syntax="FreeBASIC"]
IF backgroundMusic = 0 THEN
    PRINT "Error: Failed to load the MIDI file!"
    FSOUND_Close
    END
END IF
[/syntax]

There is also a function called FMUSIC_LoadSongEx which gives you more control over the loading process. You can use this function to load the song from memory instead of from a file, or you can tell it to load the song from a specific offset in the file... if you're really interested in using this (e.g. if your game loads data from a .PAK file), read up on the function in the FMOD documentation - there are a lot of optional arguments, so it's not too hard to change your code to load from an archive or memory instead. Smiley


Now to play the file, it's just a simple case of calling FMUSIC_PlaySong, passing our song ID as the argument. Although there is one more little thing that we need to know. Inside our main loop, we need to call FSOUND_Update, which tells FMOD to update the sound buffers, etc. - i.e. it tells FMOD to keep playing what it's been told to do!

So now take this as an example:

[syntax="FreeBASIC"]
FMUSIC_PlaySong(backgroundMusic)
WHILE INKEY$ = ""
    FSOUND_Update
WEND
[/syntax]

Cool stuff. But what's that? It only plays once? We can fix that using the FMUSIC_SetLooping function. The first argument is the song you want to set looping on and the second is the flag - '0' indicates that the song shouldn't loop and '1' indicates that it should:

[syntax="FreeBASIC"]
FMUSIC_SetLooping(backgroundMusic, 1)
FMUSIC_PlaySong(backgroundMusic)

WHILE INKEY$ = ""
    FSOUND_Update
WEND
[/syntax]

How about stopping songs? You can stop each of the individual songs by using FMUSIC_StopSong, passing the song ID as the argument. Either that, or you can stop -all- of the songs playing by using FMUSIC_StopAllSongs.

Let's try it using a MOD this time (from one of my favourite MOD artists... Nightbeat Smiley).

[syntax="FreeBASIC"]
'$INCLUDE: 'fmod.bi'

DIM niceSong AS INTEGER

' 48kHz sample rate, 8 channels.
FSOUND_Init(48000, 8, 0)

niceSong = FMUSIC_LoadSong("CHILDRMX.S3M")
IF niceSong = 0 THEN
    PRINT "Error: Failed to load 'CHILDRMX.S3M'!"
    FSOUND_Close
    END
END IF

' make it loop.
FMUSIC_SetLooping(niceSong, 1)

' play.
FMUSIC_PlaySong(niceSong)
WHILE INKEY$ = ""
    FSOUND_Update
WEND

' stop the song and quit.
FMUSIC_StopSong(niceSong)
FSOUND_Close

END
[/syntax]

It's so easy to do! Now you have no excuse not to have music in your games (unless you're a terrible musician and have nobody to help work with you, like me Sad)!

Let's review the process...
    1. Initialise FMOD
    2. Load the songs you need
    3. Write the main loop, remembering to call
FSOUND_Update each cycle
4. Unload FMOD
[/list]

You can play or stop the song any time you want to throughout your main loop... so if you need to change the song each time a level changes, all you have to do is add something like this to your level changing routine:

[syntax="FreeBASIC"]
FMUSIC_StopAllSongs
FMUSIC_PlaySong(newSongID)
[/syntax]

A couple of other useful functions:
    FMUSIC_IsPlaying - Pass the song ID and it will return 1 if the song is playing, 0 if not.
    FMUSIC_IsFinished - Pass the song ID and it will return 1 if the song has finished, 0 if not.
    [/list]



    Loading and Playing Samples
    Samples are considered to be 'static sound' in FMOD... this includes .WAV, .MP2, .MP3, .OGG and .RAW files. The process is very similar to loading and playing songs - there is one advantage though, we don't have to explicitly deallocate the samples ourselves at the end of the program. The FMOD developers realised that this can be a bit of a pain if you're using hundreds of samples in a large game, so they decided to add this automanager for you. There is a way to tell FMOD not to manage the samples for you if you really want - have a look in the reference manual at the FSOUND_Sample_Load function.

    Speaking of which, the next function we'll be using is FSOUND_Sample_Load. As you can guess, it loads a sample from a file. This function returns a sample ID, just like the FMUSIC_LoadSong function did. We can use this ID to refer to the sample when playing it.

    The FSOUND_Sample_Load function takes a few more arguments than the FMUSIC_LoadSong function though:
      index The first argument is the 'index'. If you want, you can tell FMOD to use a specific index in its internal list of samples... but that doesn't sound too flexible to me, so we'll tell it to use the next free sample slot. We do this by passing FSOUND_FREE as the 'index' argument.

      name_or_data - The file name to load from (or if you're loading from memory, the offset in memory to load from).

      inputmode - Allows you to specify some optional modes. Leave this as 0 if you're loading from a file for FMOD to figure everything out automatically. If you're loading from memory, pass FSOUND_LOADMEMORY as the value for this argument. If you want to know more about what this argument can be, look up FSOUND_MODES in the FMOD manual.

      offset - If you're loading the sample from a normal file, just leave this as 0. If you're loading it from an archived file, like a .PAK file, set this as the offset within in file you specified as 'name_or_data' where the sample is located.

      length - If loading from a file, leave this as 0. If loading from memory, specify the length of the buffer pointed to by 'name_or_data'.
      [/list]

      Okay, so it's not really that bad! Here is the code for loading an MP3.

      [syntax="FreeBASIC"]
      DIM mySample AS INTEGER

      mySample = FSOUND_Sample_Load(FSOUND_FREE, "HC-MainTitle.mp3", 0, 0, 0)
      IF mySample = 0 THEN
          PRINT "Error: Failed to load the sample!"
          FSOUND_Close
          END
      END IF
      [/syntax]

      Playing is extremely simple. All we have to use is the FSOUND_PlaySound function, which accepts two arguments: the channel to play the sample in and the sample ID. If, like me, you couldn't really care about which channel the sample plays in, just set the first argument to FSOUND_FREE. FMOD will pick a free one for you. If you find that in your game, some of the sounds aren't playing, try increasing the number of channels you specify in the FMOD initialisation code.

      [syntax="FreeBASIC"]
      FSOUND_PlaySound(FSOUND_FREE, mySample)
      WHILE INKEY$ = ""
          FSOUND_Update
      WEND
      [/syntax]

      Remember to call FSOUND_Update as usual.

      To stop a sound playing, use FSOUND_StopSound, passing the sample ID as the argument.

      If you want the sample to loop, you must set the appropriate sample mode. Do this with the FSOUND_Sample_SetMode function, which requires the sample ID and the mode to set. We'll be setting the FSOUND_LOOP_NORMAL mode (for more modes, look up FSOUND_Sample_SetMode in the FMOD documentation).

      [syntax="FreeBASIC"]
      FSOUND_Sample_SetMode(mySample, FSOUND_LOOP_NORMAL)
      FSOUND_PlaySound(FSOUND_FREE, mySample)

      WHILE INKEY$ = ""
          FSOUND_Update
      WEND
      [/syntax]

      So now, the full code for loading and playing a sample:

      [syntax="FreeBASIC"]
      '$INCLUDE: 'fmod.bi'

      DIM mySample AS INTEGER

      ' 48kHz sample rate, 8 channels.
      FSOUND_Init(48000, 8, 0)

      mySample = FSOUND_Sample_Load(FSOUND_FREE, "HC-MainTitle.mp3", 0, 0, 0)
      IF mySample = 0 THEN
          PRINT "Error: Failed to load the sample!"
          FSOUND_Close
          END
      END IF

      FSOUND_Sample_SetMode(mySample, FSOUND_LOOP_NORMAL)
      FSOUND_PlaySound(FSOUND_FREE, mySample)

      WHILE INKEY$ = ""
          FSOUND_Update
      WEND

      FSOUND_Close

      END
      [/syntax]

      Beautiful.





      Conclusion
      As you can see, using FMOD is extremely simple. It is also a good idea to learn to use FMOD in your games if you're planning on trying  to make commercial games in the future; you can distribute freeware while you're learning, then buy a fairly cheap shareware licence. If that takes off, then you could even go for a commercial licence. The licencing has been well designed so that you can hop up to each stage like that.

      If anything, you should use FMOD because it's free, it's well-written and it's really, really easy to use. Smiley

      I hope this inspired at least some people to use FMOD through FreeBASIC. Feedback on the tutorial would be warmly welcomed.

      If you'd like to contact me, you can e-mail: c.g.davies@gmail.com
      Or visit my site: http://www.cdsoft.co.uk/


      -shiftLynx
      Logged

      img]http://www.cdsoft.co.uk/misc/shiftlynx.png[/img]
      relsoft
      */-\*
      *****
      Posts: 3927



      WWW
      « Reply #1 on: February 19, 2005, 05:28:20 AM »

      Somebody should collect all these snippets that you, bastet, etc write and upload em somewhere.

      kool!!!
      Logged

      y smiley is 24 bit.


      Genso's Junkyard:
      http://rel.betterwebber.com/
      BastetFurry
      Forum Regular
      **
      Posts: 136



      WWW
      « Reply #2 on: February 19, 2005, 06:31:40 AM »

      @relsoft: I will get my own server next month, wait till then. Wink

      @shiftlynx: Great Tut ^.^
      Logged

      color=red]Look at you, Hacker. A pathetic creature of meat and bone, panting and sweating as you run through my corridors. How can you challenge a perfect, immortal machine?" - Shodan, AI at Citadel Station orbiting Earth[/color]
      shiftLynx
      Wandering Guru
      ***
      Posts: 340



      WWW
      « Reply #3 on: February 19, 2005, 09:08:16 AM »

      I include the code to the posts that I make in the "accompanying files" archives. Smiley Zap added my OpenAL one to FreeBASIC.tk -- it was easy to do with the post code. Wink

      Looking forward to see your site, Bastet. Smiley

      -shiftLynx
      Logged

      img]http://www.cdsoft.co.uk/misc/shiftlynx.png[/img]
      na_th_an
      */-\*
      *****
      Posts: 8244



      WWW
      « Reply #4 on: February 19, 2005, 09:10:57 AM »

      Very nice tut, I'm sure that many people will take advantage of it Smiley Keep up the good work.

      These are the kind of things that this community needs Smiley
      Logged

      SCUMM (the band) on Myspace!
      ComputerEmuzone Games Studio
      underBASIC, homegrown musicians
      [img]http://www.ojodepez-fanzine.net/almacen/yoghourtslover.png[/i
      aetherfox
      Been there, done that
      *****
      Posts: 1071



      WWW
      « Reply #5 on: February 19, 2005, 03:23:08 PM »

      Damn Straight.

      Excellent job.  I like the presentation, the language, the delivery etc.

      How about some HTML formats?  I can host em temporarily for you if you need...email me.
      Logged

      ~''i|~thrFx~|i''~-  
      avinash.vora - http://www.avinashv.net
      dumbledore
      Ancient Guru
      ****
      Posts: 520



      WWW
      « Reply #6 on: February 20, 2005, 02:01:28 AM »

      Quote
      FreeBASIC:

      FSOUND_PlaySound(FSOUND_FREE, mySample)
      WHILE INKEY$ = ""
          FSOUND_Update
      WEND



      Remember to call FSOUND_Update as usual.

      strange, when i wrote my music player prog, i didn't use fsound_update, but it still works... :Huh:  maybe it's because i used streams and not samples? :Huh:  :Huh:
      Logged

      ttp://m0n573r.afraid.org/
      Quote from: "HexDude"
      quote: "<+whtiger> you... you don't know which way the earth spins?" ... see... stupidity leads to reverence, reverence to shakiness, shakiness to... the dark side
      ...phear
      E.K.Virtanen
      Senior Member
      **
      Posts: 166



      WWW
      « Reply #7 on: April 11, 2005, 06:07:33 AM »

      Ok, im total linux rookie so is there any tut how to use FMOD in linux?
      Read realrealreal linux rookie  :lol:  :oops:
      Logged

      url=http://www.ascii-world.com]ASCII-World.com[/url]
      Yeah, nick changed from lurah, but bullshit's are the same.
      KiZ
      __/--\__
      *****
      Posts: 2879


      WWW
      « Reply #8 on: May 16, 2005, 04:42:40 PM »

      Sorry to dig this up, I wanted to say good job on the excellent tutorial!


      Also, I think it might be good to point out that earlier versions of some music format files such as mod and xm fail to load with the latest versions of fmod.
      This can be corrected by opening with a tracker and resaving the file as the same format. Saving as a different format usually destroys the integrity of the track.
      Logged
      Pages: [1]
        Print  
       
      Jump to:  

      Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!