Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon


5. November 2015

 

In this tutorial we are going to look at playing back music in our SFML game.  We will look at streaming an ogg file from disk.  We will also quickly look at the basics of handling time in SFML as we add fast forward and rewind abilities to our music playback.

 

There is an HD version of this tutorial here.

 

Playing music files is different from playing audio files and we will deal with this in a separate tutorial.  Music files are designed to be streamed from disk, not resident in memory.  SFML supports the following file formats:

  • ogg
  • wav
  • flac
  • aiff
  • au
  • raw
  • paf
  • svx
  • nist
  • voc
  • ircam
  • w64
  • mat4
  • mat5
  • pvf
  • htk
  • sds
  • avr
  • sd2
  • caf
  • wve
  • mpc2k
  • rf64

 

You will notice a very noticeable exception from that list, the mp3 format. That is because the mp3 format is encumbered by a number of patents and should be avoided to protect yourself from potential licensing fees.  Fortunately the ogg format offers similar file sizes and similar audio quality as the mp3 format without the licensing pitfalls.  If you require to covert formats the free software Audacity is an excellent and easy choice.

 

The major difference between sound effect and music is the sound effect stays resident in memory, while a Music file is streamed from disk.  Both classes still possess a great deal of common behaviour.  In fact if you look at the inheritance tree you will see that they have a common base class.

 

image

 

Now lets finally create some code showing how to actually play and control music files.

 

// Demonstrate that the hills are alive with the sound of music
#include "SFML/Graphics.hpp"
#include "SFML/Audio.hpp"
#include <iostream>

int main(int argc, char ** argv){
  sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "Demo Game");

  sf::Event event;
  sf::Music music;
  music.openFromFile("audio/goats_typicalamerican.ogg");
  music.setVolume(50);

  music.play();

  while (renderWindow.isOpen()){
    while (renderWindow.pollEvent(event)){
      if (event.type == sf::Event::EventType::Closed)
        renderWindow.close();


      if (event.type == sf::Event::EventType::KeyPressed){

        // Up and down to control volume
        if (event.key.code == sf::Keyboard::Key::Down)
          music.setVolume(music.getVolume() - 10);
        if (event.key.code == sf::Keyboard::Key::Up)
          music.setVolume(music.getVolume() + 10);
        

        // Left and right to control tracking position
        if (event.key.code == sf::Keyboard::Key::Right){
          auto newPos = music.getPlayingOffset() + sf::seconds(5);
          music.setPlayingOffset(sf::Time(newPos));
        }
          
        if (event.key.code == sf::Keyboard::Key::Left){
          auto newPos = music.getPlayingOffset() - sf::seconds(5);
          if (newPos.asSeconds() <= 0.0f) newPos = sf::seconds(0);
          music.setPlayingOffset(sf::Time(newPos));
        }

        std::cout << "Current volume is :" << music.getVolume() << " position is: " 
          << music.getPlayingOffset().asSeconds() << std::endl;
      }
    }

    renderWindow.clear();
    renderWindow.display();
  }
}

 

You’ll notice that loading a music file is pretty much identical to loading any other asset in SFML.  Keep in mind the Music class actually owns the underlying data of the music that is played so it is not a light weight class so be careful when they are created.  However since the Music file is played from disk instead of from memory, it is safe to allocated multiple concurrent Music files, such as one per song played, without being hugely wasteful.

 

The code itself is fairly self explanitory.  You can set the volume directly on a music file that is being played, you can control music playback using vcr style play/pause/stop() controls.  You can also control the position of the sound using a combination of getPlayingOffset() and setPlayingOffset().  As you can see there are also time operators built into SFML such as sf::seconds() or sf::milliseconds() making time based math extremely simple.

 

There is a great deal more you can do with audio files, but we will cover that in the sound effects tutorial.

 

The Video

 

Programming , ,

blog comments powered by Disqus

Month List

Popular Comments