Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Meandor

Frischling

  • »Meandor« ist der Autor dieses Themas

Beiträge: 55

Wohnort: Oberhausen

Beruf: Student

  • Private Nachricht senden

1

16.02.2007, 13:17

SDL soll wav Datei abspielen

Hallo zusammen,

ich schaffe es nicht ein blöde wav Datei in meinem Programm abspielen zu lassen und zwar über die SDL.

Ich wollte eigentlich das halb fertige Spiel von Heiko Kalista aus dem Buch C++ für Spieleprogrammierer mit Sound füttern (so als Hintergrundmusik dafür habe ich schon eine schöne Wav Datei :-)).

Alle Beispiele dazu die ich dazu gefunden habe weisen bestimmte Macken auf oder lassen sich nicht 1zu1 übersetzen. (Bin auch jetzt nicht so der Hacker - also ich weiß das mit DirektX wohl wesentlich bessere Effekte erzielt werden können, aber ich will jetzt erstmal mich mit der SDL beschäftigen (da auch das Framework in dem Spiel bereits damit realisiert ist)

Viel Text hier kommt der Code was ich gemacht habe.
Einmal die Framework.hpp
und die Framework.cpp Datei

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
#ifndef FRAMEWORK_HPP
#define FRAMEWORK_HPP

//Neu

#include <stdlib.h>

#include <iostream>
#include "Singleton.hpp"
#include "Timer.hpp"

using namespace std;

#define g_pFramework CFramework::Get()

class CFramework : public TSingleton<CFramework>
{
  public:
    bool  Init    (int ScreenWidth, int ScreenHeight,
                   int ColorDepth, bool bFullscreen);
    void  Quit    ();
    void  Update  ();
    void  Clear   ();
    void  Flip    ();
    bool  KeyDown (int Key_ID);
    SDL_Surface *GetScreen () {return m_pScreen;}

  private:
    SDL_Surface *m_pScreen;   // Surface für den Screen

    Uint8       *m_pKeystate; // Array für aktuellen Tastaturstatus


    ////ab hier ist neu für die Sounddaten  aus Tutorial kopiert///

    SDL_AudioSpec spec;
    Uint32 sound_len;
    Uint8 *sound_buffer;
    int sound_pos=0; 
};
#endif


Und jetzt die Cpp Datei

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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "Framework.hpp"

//das ist neu!!!

void Callback (void *userdata, Uint8 *stream, int len)
{
  Uint8 *waveptr;
  waveptr = sound_buffer + sound_pos;
  SDL_MixAudio(stream, waveptr, len, SDL_MIX_MAXVOLUME);
  sound_pos += len;
}


// Init

//

// Aufgabe: Framework initialisieren

//

bool CFramework::Init (int ScreenWidth, int ScreenHeight,
                       int ColorDepth, bool bFullscreen)
{
  // Alle Systeme der SDL initialisieren

  if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO ) == -1 ) //hier ist noch der Audio Modus hinzugefügt worden

  {
    cout << "SDL konnte nicht initialisiert werden!" << endl;
    cout << "Fehlermeldung: " << SDL_GetError () << endl;
    Quit ();
    return (false);
  }

  // Vollbild oder Fenstermodus einstellen

  if (bFullscreen == true)
  {
    m_pScreen = SDL_SetVideoMode (ScreenWidth, ScreenHeight, ColorDepth,
                                 SDL_HWSURFACE | SDL_DOUBLEBUF | 
                                 SDL_FULLSCREEN);
  }
  else
  {
    m_pScreen = SDL_SetVideoMode (ScreenWidth, ScreenHeight, ColorDepth,
                                 SDL_HWSURFACE | SDL_DOUBLEBUF);
  }

  // Prüfen, ob alles funktioniert hat

  if (m_pScreen == NULL)
  {
    cout << "Videomodus konnte nicht gesetzt werden!" << endl;
    cout << "Fehlermeldung: " << SDL_GetError () << endl;
    Quit ();
    return (false);
  }

  // Zeiger auf internes Array für Tastaturstatus ermitteln

  m_pKeystate = SDL_GetKeyState (NULL);

  if (SDL_LoadWAV ("Data/sound2.wav", &spec, &sound_buffer, &sound_len) == NULL)
  {
    cout << "SDL_LoadWAV fehlt geschlagen!" << endl;
    cout << "Fehlermeldung: " << SDL_GetError () << endl;
    Quit ();
  }
  spec.callback = Callback;
  if (SDL_OpenAudio (&spec, NULL) < 0)
    {
        cout << "Musik Datei konnte nicht geöffnet werden!" << endl;
        cout << "Fehlermeldung: " << SDL_GetError () << endl;
        Quit ();
    }
  SDL_PauseAudio (0);


  // Alles ging glatt, also true zurückliefern

  return (true);

} // Init



// Quit

//

// Aufgabe: Framework (SDL) beenden

//

void CFramework::Quit ()
{
  // SDL beenden

  SDL_Quit ();

} // Quit



// Update

//

// Aufgabe: Timer und Keyboardstatus updaten

//

void CFramework::Update ()
{
  // Timer updaten

  g_pTimer->Update ();

  // Tastaturstatus ermitteln

  SDL_PumpEvents ();

} // Update



// Keydown

//

// Aufgabe: Tastendruck abfragen

//

bool CFramework::KeyDown (int Key_ID)
{
  // Prüfen, ob Taste gedrückt ist

  return (m_pKeystate[Key_ID] ? true : false);

} // KeyDown



// Clear

//

// Aufgabe: Buffer  löschen

//

void CFramework::Clear ()
{
  // Buffer (Surface) mit Hintergrundfarbe füllen

  SDL_FillRect (m_pScreen, NULL,
                SDL_MapRGB (m_pScreen->format, 0, 0, 0));

} // Clear



// Flip

//

// Aufgabe: Surface umschalten (flippen)

//

void CFramework::Flip ()
{
  // Surface umschalten

  SDL_Flip (m_pScreen);

} // Flip



Die Fehlermeldung ist :

d:\Projekte\SDL_Game\SDL_Game\Framework.hpp(35) : error C2864: 'sound_pos': Es können nur konstante statische integrale Datenmember innerhalb einer Klasse oder einer Struktur initialisiert werden

Was mache ist falsch bzw. was muss ich ergänzen damit die sound2.wav im Hintergrund des Spiels vor sich hin dudelt.

Falls jemand das schon mal mit der SDL gemacht hat wäre es echt Klasse wenn mir jemand weiterhelfen könnte.
Besten Gruß
WATT, VOLT, AMPERE, OHM
OHNE MICH GIBST KEINEN STROM
"DER ELEKTRO-LURCH" :-)

Meandor

Frischling

  • »Meandor« ist der Autor dieses Themas

Beiträge: 55

Wohnort: Oberhausen

Beruf: Student

  • Private Nachricht senden

2

16.02.2007, 13:58

Ergänzung:

In der Framework.cpp Datei.
Initialisiere ich mittels

C-/C++-Quelltext

1
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDI) ==-1)


Die Audioschnittstelle zur Hardware.

Das nächste was zu tun ist sind 3 Dinge aber die Reihenfolge scheint mir noch nicht klar zu sein.

1. SDL_LoadWAV ()

2. SDL_OpenAudio()

3. callback Funktion.

Genauso wie man für Bitmaps eine Surface benötigt mit
SDL_Surface *m_pSchreen;

Benötigt man eine Stuktur für Wav
SDL_AudioSpec spec; //Spezifikation

muss jetzt zuerst die Funktion SDL_LoadWAV() oder SDL_OpenAudio()
aufgerufen werden.

und drittens ist meine Callback Funktion richtig?

Ich möchte nur während des Spiels durchgängig eine Hintergrundmusik haben.
WATT, VOLT, AMPERE, OHM
OHNE MICH GIBST KEINEN STROM
"DER ELEKTRO-LURCH" :-)

Meandor

Frischling

  • »Meandor« ist der Autor dieses Themas

Beiträge: 55

Wohnort: Oberhausen

Beruf: Student

  • Private Nachricht senden

3

16.02.2007, 14:19

Also mal ganz ehrlich eine vernüftige Doku mit Beispielen auf Deutsch
meintwegen auch auf Englisch habe ich nicht gefunden. Überall nur Codefragmente die man alleine nicht übersetzen kann.

Gibt es denn nirgendwo ein Beispiel was komplett dokumentiert worden ist.

So was ist echt nervig.
WATT, VOLT, AMPERE, OHM
OHNE MICH GIBST KEINEN STROM
"DER ELEKTRO-LURCH" :-)

Lares

1x Contest-Sieger

  • Private Nachricht senden

4

16.02.2007, 19:09

Wenn es dir darum geht .wav Dateien abzuspielen schau mal ob SDL_Mixer das Richtige ist. Auf http://www.robsite.de/ ist ein Tutorial was so ein Spiel wie aus dem Buch mit SDL_Mixer aufbaut, allerdings auf englisch. Wenn es dir allerdings darum geht deinem Spiel Hintergrundmusik zu geben, solltest du nach etwas anderen suchen,weil der Mixer nur für .wav Dateien gedacht ist (zumindest habe ich nicht herausgefunden, wie man andere Dateiformate damit öffnet :roll: )

Das Tut heißt GFX with SDL 6:Space Shooter

Kasenoru

Frischling

Beiträge: 79

Beruf: Softwareentwickler

  • Private Nachricht senden

5

16.02.2007, 21:00

Nun, ohne die SDL_Mixer Zusatzbibilothek wirst du in Sachen Musik/Sound nicht weit kommen.
Besuch mal die Seite www.libsdl.org, das ist die offizielle Seite zur SDL.
Dort suchst du bei Download->Libraries nach der SDL_Mixer erweiterung.
Hier der direkte Link:
http://www.libsdl.org/projects/SDL_mixer/
Hier ladest du dir SDL_mixer-devel-1.2.7-VC6.zip herrunter.

Wenn du das Paket entpackt hast, findest du dort 2 wichtige Ordner, include und lib.
Diese musst du deiner IDE, z.B. Visual Studio 6.0, klar machen, ähnlich wie du es auch schon mit der normalen SDL gemacht hast.
Anschließent bist du in der lage Musik und Sound abzuspielen.

Damit die Funktionen von SDL_Mixer zur verfügung stehen, musst du SDL_mixer.h einbinden und SDL_mixer.lib zu deinem Projekt linken.

Musik/Sound abspielen geht dann ganz einfach:

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
#include <SDL.h>
#include <SDL_mixer.h>

int main(int argc, char* argv[])
{
    // Zeiger für den Bildschirm.

    SDL_Surface* display = NULL; 

    // Zeiger für die Musik.

    Mix_Music* music = NULL;

    // Zeiger für den Sound.

    Mix_Chunk* sound = NULL;

    // Variable die angibt, ob das Programm beendet werden soll.

    bool quit = false;

    // SDL Video und Audio System initialisieren

    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);

    // Videomodus setzen

    display = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);

    // Zuerst das Audio-Greät öffnen, bevor Musik/Sound geladen und abgespielt werden können.

    Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 4096);

    // Musik laden

    music = Mix_LoadMUS("Musik.mp3");

    // Sound laden

    sound = Mix_LoadWAV("Sound.wav");

    // Musik abspielen, der 2. Parameter gibt hierbei die Anzahl

    // der loops an, -1 steht für unendlich viele loops.

    Mix_PlayMusic(music, -1);

    // Sound abspielen, der 1. Parameter gibt den Channel an, in dem

    // der Sound abgespielt werden soll.

    Mix_PlayChannel(0, sound, -1);

    // Hauptschleife

    while(!quit)
    {
        // Event

        SDL_Event evt;

        // Event holen

        SDL_PollEvent(&evt);
        
        // War es ein SDL_QUIT Event?

        if(evt.type == SDL_QUIT)
        {
            // Beenden

            quit = true;
        }
    }
    
    // Musik wieder freigeben

    Mix_FreeMusic(music);

    // Sound wieder freigeben

    Mix_FreeChunk(sound);

    // Audio-Gerät wieder schließen

    Mix_CloseAudio();

    // SDL herrunterfahren.

    SDL_Quit();

    // 0 zurückliefern

    return 0;   
}


Interessiert dich nur die Hintergrund Musik, dann kannst du die ganzen Sachen mit den Chunks auch weg lassen.

Noch etwas zu Mix_PlayChannel.
In einem Spiel gibt es meist nur eine Hintergrundmusik, und das ist wie du siehst kein Problem, aber bei Sounds ist das natürlich anders.
In einem Spiel werden meistents mehrere Sounds gleichzeitig abgespielt.

Bei SDL_mixer wird dies mit sogenannten Channels gelöst.
Willst du also 2 Sounds gleichzeitig abspielen, dann darfst du beim Abspielen nicht den gleichen Channel angeben.
Folgendes würde also nicht richtig funktionieren:

C-/C++-Quelltext

1
2
Mix_PlayChannel(0, sound1, 0);
Mix_PlayChannel(0, sound2, 0);

Sondern so:

C-/C++-Quelltext

1
2
3
4
Mix_PlayChannel(0, sound1, 0);
Mix_PlayChannel(1, sound2, 0);
Mix_PlayChannel(2, sound3, 0);
// .....


Die 0 beim 3. Parameter steht für 0 loops, der Sound würde also nur einmal abgespielt werden.

Nunja, ich hoffe ich konnte dir etwas helfen.

Mit freundlichen Grüßen

Kasenoru

Meandor

Frischling

  • »Meandor« ist der Autor dieses Themas

Beiträge: 55

Wohnort: Oberhausen

Beruf: Student

  • Private Nachricht senden

6

16.02.2007, 21:25

Man ich bin immer wieder begeister von diesem Forum hier!
Hier sind richtig gute Leute die einem weiterhelfen.
Das mit dieser SDL_Mixer hatte ich auch schon gelesen unter
[url]
http://kekkai.org/roger/sdl/mixer/index.html
[/url]

Leider ist das wieder alles auf Englisch.
Schade das es nicht ein Tutorial gibt wo alles mal auf Deutsch ausführlich erklärt wird.

Was ich auch nicht verstehe warum ist diese Mixer Funktion eigentlich nicht schon Standardmäßig bei der SDL 1.2.8 aus Heikos Buch dabei.
Das ist ja irgendwie unvollständig.

Gut werde die vorgeschlagene SDL runter laden und mich damit versuchen, sobald ich es irgendwie geschafft habe und auch verstanden habe wie es funktioniert, werde ich meinen Code mal für alle anderen Nubis hier reinstellen.
Falls nicht werde ich mich hier wieder melden. :-)
WATT, VOLT, AMPERE, OHM
OHNE MICH GIBST KEINEN STROM
"DER ELEKTRO-LURCH" :-)

7

22.03.2007, 01:44

Hallöchen!

Ich habe heute auch mal die SDL_mixer Lib in meinem Projekt eingebastelt. Laut diesem Tutorial hier und dem von Lazyfoo scheint auch alles richtig zu sein: SDL - Audiotreiber initialisiert, SDL - Mixer initialisiert, Musik geladen, Musikloop während des Programmablaufs gestartet und zum Schluss halt Free Music und CloseAudio.

Mein Quellcode lässt sich damit auch fehlerfrei kompilieren und startet sofort, allerdings höre ich nichts :(.
Gibt es irgendwelche kbps oder kHz Beschränkungen bei Verwendung von mp3 Files oder andere Dinge, die man großartig falsch machen kann?

Würde euch gerne mehr Informationen zu meinem Problem geben, allerdings weiß ich nicht, was ich dazu jetzt noch schreiben sollte.

Vielleicht hat ja der ein -oder andere 'nen Tipp...

Lares

1x Contest-Sieger

  • Private Nachricht senden

8

22.03.2007, 14:48

Wie ich bereits vor einiger zeit sagte: SDL_Mixer ist wenn ich richtig informiert bin nur dazu da .wav dateien abzuspielen.
Falls dem nicht so ist lass ich mich gerne eines besseren belehren. ;)

9

22.03.2007, 17:10

Zitat von »"Lares"«

Wie ich bereits vor einiger zeit sagte: SDL_Mixer ist wenn ich richtig informiert bin nur dazu da .wav dateien abzuspielen.
Falls dem nicht so ist lass ich mich gerne eines besseren belehren. ;)

Und wieso schreibst du dann (?):

Zitat


// Musik laden
music = Mix_LoadMUS("Musik.mp3");

Kasenoru

Frischling

Beiträge: 79

Beruf: Softwareentwickler

  • Private Nachricht senden

10

22.03.2007, 18:47

Zitat

SDL_Mixer ist wenn ich richtig informiert bin nur dazu da .wav dateien abzuspielen.

Falsch, natürlich kann SDL_Mixer mp3 abspielen ;)

Zitat

Mein Quellcode lässt sich damit auch fehlerfrei kompilieren und startet sofort, allerdings höre ich nichts


Wenn alle benötigten DLLs vorhanden sind, dürfte es keine Probleme geben.
Zeig am besten mal deinen Quelltext. ;)

Werbeanzeige