Eine einfache Sound-Klasse mit dem SDL_Mixer
Inhaltsverzeichnis
1.Einleitung
2.Einrichtung der Umgebung
3.Erstellung der Sound-Klasse
4.Sonstiges
1.Einleitung
Ich versuche mich heute mal im schreiben eines kleinen Tutorials. Ich will auch gleich zur Sache kommen, es geht um den SDL_Mixer. Großartig viel kann man damit zwar nicht machen, aber für den Anfang dürfte es ausreichen. Im nachfolgenden werde ich nicht zu weit ins Detail gehen, Details über die Wirkungsweise der einzelnen SDL_Mixer Funktionen findet man recht gut erklärt in der SDL_Mixer Dokumentation.
2.Einrichtung der Umgebung
Als erstes sollte man eine lauffähige SDL-Umgebung haben. Wer hier noch Probleme mit der Einrichtung des ganzen hat, ich hatte es auch.
Hier ist ein Link, ganz unten ist ein MiniTutorial zu finden welches hier bei der Einrichtung hilft. https://www.spieleprogrammierer.de/phpBB2/viewtopic.php?t=11358
Der SDL_Mixer ist als Erweiterung der SDL-Umgebung nicht in dieser vorhanden man muss also die Dateien herunterladen. Das geht am besten bei der libsdl.org und zwar hier, http://www.libsdl.org/projects/SDL_mixer/. Ich habe mir hier unter Binary/Win32 denSDL mixer-devel-1.2.8-VC8 heruntergeladen, wenn ihr Linux oder so verwendet ist das natürlich anders...Ach ja wenn man schon gerade da ist, am besten auch die SDL_Mixer Dokumentation ganz oben herunterladen.
Als nächstes öffnet ihr die zip-file und kopiert die include Dateien in den include Ordner der SDL und die lib Dateien in den lib-Ordner der SDL ganz einfach. Eine potentielle Fehlerquelle besteht darin wenn ihr eine höhere SDL-Version als 1.2.8 verwendet, es kann dann zu Ausführungsfehlern mit dem SDL_Mixer kommen, war bei mir jedenfalls so.
Als nächstes jetzt noch unter Eigenschaften sdl_mixer.lib ins Programm linken und nicht vergessen die Datei sdl_mixer.dll aus dem include Ordner noch zusätzlich in die Projektmappe zu kopieren. Dann ist alles soweit eingerichtet.
3.Erstellung der Sound-Klasse
Die Soundklasse ist darauf zugeschnitten das sie nicht seperat arbeitet sondern in ein bestehendes SDL-Projekt eingebunden wird.
Wer etwas sucht was von sich aus läuft bitte hier gucken.
http://sppro.fkrauthan.de/2008/09/12/sdl-eine-einfuehrung/4/
Zunächst jetzt die Headerdatei Sound.hpp und dann Sound.cpp.
Sound.hpp
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#ifndef SOUND_HPP
#define SOUND_HPP
#include <SDL.h>
#include <SDL_mixer.h>
#include <string>
#include <iostream>
//statt using namespace std; wurde an den einzelnen Stellen std:: verwendet
class CSound
{
public:
//Konstruktor und Destruktor
//Im Konstruktor wurden bereits Standartwerte gesetzt, bei der
//Initialisierung von CSound können diese aber geändert werden
// so in etwa: m_pSound = new CSound(10000, AUDIO_U8, 1, 1024);
CSound(int audio_rate = 44100, Uint16 audio_format = AUDIO_S16SYS,
int audio_channels = 2,int audio_buffers = 4096);
~CSound();
//Funktionen für einzelne Sounds
void LoadSound(const std::string sFilename, int Volume);
void PlaySound();
//Funktionen für die Hintergrundmusik
void LoadMusic(const std::string sFilename, int Volume);
void PlayMusic();
private:
int m_audio_rate;//Abspielrate, höherer Wert besserer Sound aber mehr Rechenzeit nötig
Uint16 m_audio_format;//Audio-Format
int m_audio_channels;//1=mono, 2=stereo
int m_audio_buffers;//Audio_Puffer
Mix_Chunk *m_psound; //Instanz für den Sound
Mix_Music *m_pmusic; //Instanz für die Hintergrundmusik
};
#endif
|
Und Sound.cpp
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
#include "Sound.hpp"
//Konstruktor CSound()
//Aufgabe: Allgemeine Initialisierungen
CSound::CSound(int audio_rate, Uint16 audio_format,int audio_channels,int audio_buffers)
{
//Membervariablen setzen
m_audio_rate = audio_rate;
m_audio_format = audio_format;
m_audio_channels = audio_channels;
m_audio_buffers = audio_buffers;
//Zeiger auf Null setzen
m_psound = NULL;
m_pmusic = NULL;
//Anzahl der Channels setzen
//Je mehr gleichzeitig abgespielt werden soll desto höher, ausprobieren...
Mix_AllocateChannels(10);
}//Ende Konstruktor CSound()
//Destruktor CSound()
//Aufgabe: SDL_Mixer schließen
CSound::~CSound()
{
Mix_FreeMusic(m_pmusic);//Zeiger für Hintergrundmusik freigeben
Mix_FreeChunk(m_psound);//Zeiger für Sound freigeben
Mix_CloseAudio();//Audio schließen
}//Ende Destruktor CSound()
////////////////////////////Toneffekte///////////////////////////////////////
//LoadSound()
//Aufgabe: Einen einzelnen Ton laden
void CSound::LoadSound(const std::string sFilename, int Volume)
{
//Initialisieren
if(Mix_OpenAudio(m_audio_rate, m_audio_format, m_audio_channels, m_audio_buffers) != 0) {
std::cout << "Konnte Sound nicht starten: " << Mix_GetError() << std::endl;
}
//Sound-File laden
m_psound = Mix_LoadWAV(sFilename.c_str ());
if(m_psound == NULL) {
std::cout << "Konnte Sound WAV File nicht laden: " << Mix_GetError() << std::endl;
}
//Lautstärke einrichten
//Volume soll ein Wert zwischen 0 und 128 sein.
Mix_VolumeChunk(m_psound,Volume);
}//Ende LoadSound()
//PlaySound()
//Aufgabe: Einen einzelnen Ton wiedergeben
void CSound::PlaySound()
{
//Sound abspielen
if(Mix_PlayChannel(-1, m_psound, 0)==-1) {
std::cout << "Konnte Sound WAV Datei nicht abspielen: " << Mix_GetError() << std::endl;
}
}//Ende PlaySound()
////////////////////////////Hintergrundmusik///////////////////////////////////
//LoadMusic()
//Aufgabe: Eine Musikstück laden
void CSound::LoadMusic(const std::string sFilename,int Volume)
{
//Initialisieren
if(Mix_OpenAudio(m_audio_rate, m_audio_format, m_audio_channels, m_audio_buffers) != 0) {
std::cout << "Konnte Sound nicht starten: " << Mix_GetError() << std::endl;
}
//Hintergrundmusik
//Datei laden
m_pmusic = Mix_LoadMUS(sFilename.c_str ());
if(m_pmusic == NULL) {
std::cout << "Konnte Music WAV File nicht laden: " << Mix_GetError() << std::endl;
}
//Lautstärke für Hintergrundmusik einstellen
//Volume soll ein Wert zwischen 0 und 128 sein.
Mix_VolumeMusic(Volume);
}//Ende LoadMusic
//PlayMusic()
//Aufgabe: Eine Hintergrundmusik abspielen
void CSound::PlayMusic()
{
//Musik abspielen
if(Mix_PlayMusic(m_pmusic, -1) == -1) {
std::cout << "Konnte Music WAV File nicht abspielen: " << Mix_GetError() << std::endl;
}
}//Ende PlayMusic()
|
Damit das ganze nun auch wirklich läuft, muss an der Stelle wo die einzelnen Systeme der SDL aufgerufen werden noch eine Ergänzung um SDL_INIT_AUDIO hinzugefügt werden.
|
C-/C++-Quelltext
|
1
|
if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO ) == -1 )
|
Nun noch einen Zeiger auf eine Instanz der Klasse CSound erstellen.
|
C-/C++-Quelltext
|
1
2
|
#include "Sound.hpp"
CSound *m_pSound; // Sound-Instanz
|
Im Konstruktor den Zeiger auf NULL setzen
|
C-/C++-Quelltext
|
1
|
m_pSound = NULL;
|
In der Initialisierung Speicherbereich auf dem Heap reservieren und
auch gleich alles soweit laden
|
C-/C++-Quelltext
|
1
2
|
m_pSound = new CSound;
m_pSound->LoadMusic("ACDC/thunderstruck.wav",100);
|
An der gewünschten Stelle das ganze starten
|
C-/C++-Quelltext
|
1
|
m_pSound->PlayMusic();
|
Und am Schluss nicht vergessen den Speicherbereich wieder freizugeben
|
C-/C++-Quelltext
|
1
|
delete (m_pSound);
|
Das war's, möchte man einen einzelnen Toneffekt abspielen läuft dieses im Grunde genommen genauso ab. Nur mit dem Unterschied das es bei einer Hintergrundmusik eine Wiederholungsschleife gibt und bei einem einzelnen Toneffekt eben nicht.
4.Sonstiges
Insbesondere bei Toneffekten bietet es sich natürlich an diese nicht selber zu erstellen, sondern wo zu laden. Es gibt dafür haufenweise Internetseiten, diese hier habe ich verwendet.
http://www.stonewashed.net/sfx.html
Manchmal bietet es sich an die Töne zu kürzen, insbesondere bei der Hintergrundmusik kann man sehr simple Kompositionen leicht so schneiden das man den Neubeginn des Stückes nicht mehr hören kann.
Das Wave-Pad ist hierfür eine gute Wahl.
http://www.chip.de/downloads/WavePad_28979806.html
Laut SDL_Mixer Doku ist es möglich unter bestimmten Voraussetzungen die Hintergrundmusik auch als mp3 abzuspielen. Was aber auch geht ist das man den mp3-2-wav converter verwendet.
http://www.netzwelt.de/software/2418-mp3-2-wav-converter.html
Ich hoffe mein Tutorial war nicht zu lang, aber es hat sich angeboten ein Kochrezept draus zu machen da ich mich selber gerade frisch in den SDL_Mixer eingearbeitet habe. Viel Spaß damit
MFG Toxic