Lecture 15 | How to load background music and sound effects?

Good music always accompanies games and is always remembered by players. Playing music and sound effects in the game is not difficult, but when to play what sound effects and how to implement them may require some skills. For example, what I am going to talk about today can be implemented by bundling it with certain functions.

Pygame supports the playback of mp3, ogg, wav audio and sound effects. The music modules are all in pygame.mixer, which includes music and sound effects.

When we use the audio module, we need to initialize it first.

pygame.mixer.init()

This initialization should be done after the initialization of pygame.init().

Let’s take a look at the specific functions. These functions exist under the pygame.mixer.Sound module.

Let’s take a look at the Pygame.mixer.music music module. We can try to load the audio and play it.

pygame.mixer.music.load('bgm.mp3')
pygame.mixer.music.set_volume(0.5)
pygame.mixer.music.play()
s1 = pygame.mixer.Sound('a.wav')
s1.set_volume(0.5)
s2 = pygame.mixer.Sound('b.wav')
s2.set_volume(0.5)

Explain this code.

At the beginning, we loaded an mp3 file named bgm, told the program that it needed to load this file, and then adjusted the volume to 0.5, followed by play, that is, playback. Playback is played in the background of the program, and then the program will continue to run. to the line of code below.

Then, we use the Sound module. The Sound module initializes and loads a.wav, then returns an object that sets the volume to 0.5. It then initializes it again, loads b.wav, and sets the volume to 0.5.

So far, we have done all the initialization and settings outside the game loop.

Then, we need to combine the content of the previous sections and perform sound operations on the collision of the aircraft in the loop. For example, when an explosion occurs, what sound is played; when the collision ends, another sound is played.

if True == collide(pln, (100,300 + y1), enm, (100,20 + y2)):
s1.play()
else:
  s2.play()
for event in pygame.event.get():
   if event.type == QUIT:
     pygame.quit()
   if event.type == KEYDOWN:
     if event.key == K_p:
       pygame.mixer.music.pause()
     if event.key == K_r:
       pygame.mixer.music.unpause()

First, we use the collide function . This has been explained in detail in previous chapters.

This is a piece of code that detects aircraft collision. If the aircraft collides, it will return True. If True is returned, we will play the s1 audio, otherwise we will play the s2 audio. Of course, this s2 audio may keep playing (since there are no collisions).

Then there is Event monitoring. If K_p is detected, press p on the keyboard to stop the music and use the pause function; if the r key is pressed, playback will resume.

Our work on Pygame is basically over, but the audio and sound effects content is not over.

In game programming, we need to embed audio and sound effects, especially when there is no Pygame. If some game engines do not provide audio libraries, we need to use third-party audio libraries ourselves. Although you can use the familiar ffmpeg, it feels a bit overkill, so we need a dedicated audio library.

Here, I recommend the BASS Audio Library. You can go to http://www.un4seen.com to download the development library. This audio library is not open source. If you just develop your own games and play them for non-commercial purposes, you can use it. If it is for commercial use, you need to purchase a certificate.

On this page, we click the download button to download the latest version of the development library. After unzipping, development directories corresponding to several languages will appear.

The bass.dll file is a dynamic link library. If you want to use it, you can use the lib library and bass.h in the c folder to include the header file for programming.

Let’s take a look at how to add the Bass engine code using C/C++ language.

BASS_Init(-1, 44100, 0, hwnd, NULL);
HSTREAM s = BASS_StreamCreateFile(false, "a.mp3", 0, 0, 0);
BASS_ChannelPlay(s, false);
BASS_StreamFree(s)

First, we initialize the BASS library. The initialization parameters are: device, output ratio, flag bit (such as 8-bit sound quality, stereo, 3D, etc.), Windows handle. You can also enter 0. The last one is clsid, which is the ID of the class used to initialize DirectSound. NULL is generally used.

Subsequently, to create a stream from the file, the BASS_StreamCreateFile function returns an HSTREAM. HSTREAM is actually a DWORD type.

The parameters in this function are also explained.

The first parameter is memory. If true is passed in, the stream will be saved in memory; otherwise, it will not be saved in memory.

The second parameter is the audio file name. This parameter will be linked to the first parameter. When the first parameter is stored in memory, fill in the memory address, otherwise fill in the file name.

The third parameter is the offset, which is where the file starts playing. Of course, this parameter only works when the first parameter is false and is not saved in memory.

The fourth parameter is the length. If 0 is filled in, it will be all lengths.

The last one is the flag bit, which is filled in with the creation mode, such as loop playback mode, software decoding mode, etc.

The next step is to start playback. The first parameter is the handle of the stream just returned, and the second parameter is whether to restart playback. The last one is to recycle resources and delete the handle after playing.

float v; DWORD r;
BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, 100);
v = BASS_GetVolume();
v = 200;
BASS_SetVolume(v);
r = BASS_ChannelIsActive(s);
if(r == BASS_ACTIVE_PAUSED)
...
else if(r == BASS_ACTIVE_PLAYING)
...
else if(r == BASS_ACTIVE_STOPPED)
...
else if (r == BASS_ACTIVE_STALLED)
  ..

The next step is to adjust the volume and get the playback status function.

Among them, in BASS_SetConfig, the first parameter is the option, and the second parameter is the value to adjust the volume. The meaning of BASS_CONFIG_GVOL_STREAM is the global stream volume.

Then we started to get the volume. BASS_GetVolume is to get the system volume, not the stream volume. The fifth line of code is to set the system volume.

Next, we need to get the playback status. Fill in the handle of the stream in the function of BASS_ChannelIsActive, then get the return value, and then use the return value for comparison. BASS_ACTIVE_PAUSED means that the playback state is paused, BASS_ACTIVE_PLAYING means that it is playing or recording, and BASS_ACTIVE_STOPPED means that it is stopped, or the stream handle is not Effectively, BASS_ACTIVE_STALLED is the stalled state.

The general reason is that the playback state lacks sample data and the stream playback is stalled. If the data is enough for playback, it will automatically resume.

The BASS library also has many functions and functions, so I won’t elaborate on them here.

Summary

Today we explained the playback of audio and sound effects in Pygame. These things should be remembered.

In Pygame, playing music does not require multi-thread control. It will play itself in the background.

All music and sound effects are in the pygame.mixer module. If music is loaded, the music module is used; if sound effects are loaded, the Sound module is used.

We then introduced the BASS audio library. This is almost the most professional audio library. Since it is a C interface, it can be used in multiple languages. You can use languages such as .NET or VB to apply it. Of course, if you want to perform functions such as background playback and multiple channel playback, you need to write multi-threaded code, which is not as easy as Pygame. There are many things you need to do yourself.