Search…

Play Audio trong SDL

27/09/20205 min read
Hướng dẫn cách play Sound Effects và Music sử dụng thư viện mở rộng của SDL (Simple DirectMedia Layer) bằng SDL_mixer.

Âm thanh là 1 trong những thành phần quan trọng và không thể thiếu trong game, làm cho game sinh động và hấp dẫn hơn.

Cài đặt thư viện SDL_mixer

Để download thư viện tại đây, tại mục Development Libraries, download file SDL2_mixer-devel-2.0.0-VC.zip (cho môi trường Windows).

ss_1

Sau khi download về và giải nén ra, được 2 thư mục là includelib:

ss_2

Tiếp tục sử dụng Project ở bài viết Khởi Tạo Môi Trường Lập Trình Game Sử Dụng Thư Viện SDL (Simple DirectMedia Layer), tích hợp thư viện SDL_mixer vào project tượng tự như tích hợp thư viện SDL. Tạo thư mục SDL_Mix trong thư mục Lib và copy 2 thư mục là includelib vừa giải nén ở trên vào thư mục vừa tạo.

Copy tất cả các file .dll trong thư mục SDL_Mix/lib/x86 vào thư mục chứa file thực thi (.exe) là thư mục Output.

Mở project với Visual Studio, nhấn chuột phải (Right click) vào project để mở hộp thoại Properties. Chọn C/C++ > General và mở hộp thoại Additional Include Directories để thêm đường dẫn tới thư mục chứa file header của bộ thư viện SDL_mixer.

ss_3

Tương tự, chọn Linker/General mở hộp thoại Additional Library Directories để thêm đường dẫn tới các file thư viện (.lib, .dll) của SDL_mixer nằm trong thư mục lib:

ss_4

Ở mục Linker, chọn Input và mở hộp thoại Additional Dependencies thêm vào SDL2_mixer.lib:

ss_5

Play Music và Sound Effects

Cần thêm chỉ thị #include "SDL_mixer.h" vào đầu những file muốn sử dụng thư viện này:

#include "SDL_mixer.h"

Trước khi sử dụng các function mà SDL_mixer cung cấp thì phải khởi tạo:

if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) == -1)
{
	printf("%s", Mix_GetError());
}

SDL_mixer có hỗ trợ cho 2 cấu trúc để quản lý Music và Sound Effect là Mix_MusicMix_Chunk:

Mix_Chunk* chunk = NULL;
Mix_Music* music = NULL;

Load Music và Sound Effects

Với 2 cấu trúc trên thì có những hàm load tương ứng là Mix_LoadWAV và Mix_LoadMUS:

//Load Sound Effect
chunk = Mix_LoadWAV("sound_effects.wav");
if (chunk == NULL)
{
	printf("%s", Mix_GetError());
	return -1;
}

//Load Music
music = Mix_LoadMUS("background_music.mp3");
if (music == NULL)
{
	printf("%s", Mix_GetError());
}

Play, Pause, Resume, Stop

Với Music và Sound Effects thì SDL_mixer có cung cấp các hàm để play, pause, resume, stop cũng như các hàm kiểm tra trạng thái.

Music

Các hàm hỗ trợ play Music:

int Mix_PlayMusic(Mix_Music *music, int loops): Phát music được load bởi hàm Mix_LoadMUS, vói tham số truyền vào là con trỏ tới đối tượng Mix_Music, và số lần lặp, nếu truyền vào -1 sẽ lặp vô tận.

  • void Mix_PauseMusic(): Tạm dừng phát music.
  • void Mix_ResumeMusic(): Tiếp tục phát lại music sau khi pause.
  • int Mix_HaltMusic(): Dừng phát music.

Và các hàm kiểu tra trạng thái:

  • int Mix_PlayingMusic(): Trả về 1 nếu music đang phát, ngược lại trả về 0.
  • int Mix_PausedMusic(): Trả về 1 nếu music tạm dừng, ngược lại trả về 0.

Sound Effects

Các hàm hỗ trợ play Sound Effect:

  • int Mix_PlayChannel (int channel, Mix_Chunk *chunk, int loops): Play Sound Effect với tham số thứ nhất là channel muốn phát, thông thường là -1, tham số thứ 2 là con trỏ tới đối tượng Mix_Chunk, và cuối cùng là số lần lặp, nếu truyền vào -1 sẽ lặp vô tận.
  • void Mix_Pause(int channel): Tạm dừng Sound Effects, đối số channel thông thường là -1.
  • void Mix_Resume(int channel): Tiếp tục phát Sound Effects sau khi Pause, đối số channel thông thường truyền vào -1.
  • int Mix_HaltChannel(int channel): Dừng phát Sound Effects, đối số channel thông thường truyền vào -1.

Các hàm kiểm tra trạng thái cũng tương tự như đối với Music là các hàm Mix_Play, Mix_Paused.

Ví dụ demo

#include <stdio.h>
#include <SDL.h>

#include "SDL_mixer.h"
#undef main
int main()
{
	SDL_Window* window = NULL;
	SDL_Renderer* renderer = NULL;
	SDL_Surface* tempSurface = NULL;
	SDL_Texture* texture = NULL;
	SDL_Event mainEvent;
	bool isRunning = true;

	//Sound Effect
	Mix_Chunk* chunk = NULL;
	//Background Music
	Mix_Music* music = NULL;

	//initializes  the subsystems
	if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
	{
		printf("Unable to initialize SDL %s\n", SDL_GetError());
		return -1;
	}

	//Create window
	window = SDL_CreateWindow("Stdio.vn - SDL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 640, SDL_WINDOW_SHOWN);
	if (window == NULL)
	{
		printf("Could not create window %s", SDL_GetError());
		return -1;
	}

	//create a renderer
	renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
	if (renderer == NULL)
	{
		printf("Could not create render %s", SDL_GetError());
		return -1;
	}

	//create a tempSurface
	tempSurface = SDL_LoadBMP("background_stdio.bmp");
	//create a texutre from surface
	texture = SDL_CreateTextureFromSurface(renderer, tempSurface);
	//free surface
	SDL_FreeSurface(tempSurface);

	//Init SDL_mixer
	if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) == -1)
	{
		printf("%s", Mix_GetError());
		return -1;
	}

	//Load Sound Effect
	chunk = Mix_LoadWAV("sound_effects.wav");
	if (chunk == NULL)
	{
		printf("%s", Mix_GetError());
		return -1;
	}

	//Load Music
	music = Mix_LoadMUS("background_music.mp3");
	if (music == NULL)
	{
		printf("%s", Mix_GetError());
	}

	//set background color
	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
	//main loop
	while (isRunning)
	{
		// clear the window to black
		SDL_RenderClear(renderer);
		//main event
		while (SDL_PollEvent(&mainEvent))
		{
			switch (mainEvent.type)
			{
				//User - requested quit
			case SDL_QUIT:
			{
				isRunning = false;
				break;
			}
			case SDL_KEYDOWN:
			{
				if (mainEvent.key.keysym.sym == SDLK_RETURN)
				{
					if (!Mix_PlayingMusic())
						Mix_PlayMusic(music, 0);
				}

				if (mainEvent.key.keysym.sym == SDLK_SPACE)
				{
					if (!Mix_Playing(-1))
						Mix_PlayChannel(-1, chunk, 0);
				}
				break;
			}
			default:
			{
				break;
			}
			}
		}

		// copy a portion of the texture to the current rendering target.
		SDL_RenderCopy(renderer, texture, NULL, NULL);
		//draw to the screen
		SDL_RenderPresent(renderer);
	}


	Mix_CloseAudio();
	//Destroy a window.
	SDL_DestroyWindow(window);

	//Destroy a renderer
	SDL_DestroyRenderer(renderer);

	//cleans up all initialized subsystems
	SDL_Quit();
	return 0;
}

Nhấn phím Enter play background music và phím Space để play sound effects:

ss_6

Download demo

Stdio_SDL_PlayAudio_VS2013.zip

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024