Glusoft

Play music and sound with ALmixer

In this tutorial the goal is to play music and sound with ALmixer.

Setting up

Before starting to play music and sound with ALmixer you will need to :

Playing music

When everything is configure, you will need a ogg music to play, I will use this one in the tutorial: music.ogg
The first thing to do is load the audio data. The music file can be big so we don’t want to load everything in memory, for that we use the function.

ALmixer_LoadStream(const char* file_name, 
				   ALuint buffer_size,
				   ALuint max_queue_buffers,
				   ALuint num_startup_buffers,
				   ALuint suggested_number_of_buffers_to_queue_per_update_pass,
				   ALuint access_data)

We can simply take the default parameters:

ALmixer_Data *music_data = ALmixer_LoadStream("music.ogg",
											  ALMIXER_DEFAULT_BUFFERSIZE,
											  ALMIXER_DEFAULT_QUEUE_BUFFERS,
											  ALMIXER_DEFAULT_STARTUP_BUFFERS,
											  ALMIXER_DEFAULT_BUFFERS_TO_QUEUE_PER_UPDATE_PASS,
											  AL_FALSE);

To play the music we will need to use a channel, to find a free channel you can use:

ALint channel_music = ALmixer_FindFreeChannel(0);

The first paramater is the starting channel, Almixer will find the first available channel starting from this channel.

Good we can play the song!

ALmixer_PlayChannel(channel_music, music_data, 0);

The third paramameter is the number of loop you want to play the song. If you set the number of loop to -1, the song loop forever.

You can set the volume for the channel with:

ALmixer_SetVolumeChannel(channel_music, 80);

In this example I want to be able to pause the music when pressing the ‘P’ key, and resume the channel when pressing the ‘R’ key:

In the event loop you will need to call ALmixer_PauseChannel and ALmixer_ResumeChannel

if (e.key.keysym.sym == SDLK_p) {
	ALmixer_PauseChannel(channel_music);
}
else if (e.key.keysym.sym == SDLK_r) {
	ALmixer_ResumeChannel(channel_music);
}

If you want to know when the song is finished you can set a callback function with:

ALmixer_SetPlaybackFinishedCallback(Internal_SoundFinished_CallbackIntercept, NULL);

In this case, Internal_SoundFinished_CallbackIntercept is the callback function.

void Internal_SoundFinished_CallbackIntercept(ALint which_channel, 
											  ALuint al_source,
											  ALmixer_Data* almixer_data,
											  ALboolean finished_naturally,
											  void* user_data) {
	std::cout << "sound finished : " << which_channel << "\n";
}

Playing sound

A sound is simply a really short noise or music, so we can load the small file in memory.

In this example we will use the sound: kick.ogg

ALmixer_Data* sound_data = ALmixer_LoadAll("kick.ogg", AL_FALSE);

The rest of the code is similar to the previous example.

ALint channel_sound = ALmixer_FindFreeChannel(0);
ALmixer_PlayChannel(channel_sound, sound_data, 0);

Full source code

void Internal_SoundFinished_CallbackIntercept(ALint which_channel, ALuint al_source, ALmixer_Data* almixer_data, ALboolean finished_naturally, void* user_data) {
	std::cout << "sound finished : " << which_channel << "\n";
}

int main(int argc, char* argv[]) {
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
	ALmixer_Init(ALMIXER_DEFAULT_FREQUENCY, ALMIXER_DEFAULT_NUM_SOURCES, ALMIXER_DEFAULT_REFRESH);

	SDL_Window* window = SDL_CreateWindow("Playing music and sound with ALmixer", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);
	SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

	ALmixer_Data *music_data = ALmixer_LoadStream("music.ogg", ALMIXER_DEFAULT_BUFFERSIZE, ALMIXER_DEFAULT_QUEUE_BUFFERS, ALMIXER_DEFAULT_STARTUP_BUFFERS, ALMIXER_DEFAULT_BUFFERS_TO_QUEUE_PER_UPDATE_PASS, AL_FALSE);

	ALint channel_music = ALmixer_FindFreeChannel(0);
	ALmixer_PlayChannel(channel_music, music_data, 0);
	ALmixer_SetVolumeChannel(channel_music, 80);

	ALmixer_SetPlaybackFinishedCallback(Internal_SoundFinished_CallbackIntercept, NULL);
	ALmixer_Data* sound_data = ALmixer_LoadAll("kick.ogg", AL_FALSE);
	ALint channel_sound = ALmixer_FindFreeChannel(0);

	while (true) {
		SDL_Event e;
		if (SDL_PollEvent(&e)) {
			if (e.type == SDL_QUIT) {
				break;
			}
			if (e.type == SDL_KEYDOWN) {
				if (e.key.keysym.sym == SDLK_p) {
					ALmixer_PauseChannel(channel_music);
				}
				else if (e.key.keysym.sym == SDLK_r) {
					ALmixer_ResumeChannel(channel_music);
				}
				else if (e.key.keysym.sym == SDLK_k) {
					ALmixer_PlayChannel(channel_sound, sound_data, 0);
				}
			}
		}

		SDL_RenderClear(renderer);
		SDL_RenderPresent(renderer);
	}

	ALmixer_Quit();
	SDL_Quit();

	return 0;
}

You can download the project : PlayingMusic.7z