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

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

1

31.12.2010, 13:18

FMOD-Fehler mit mehreren Sounds

Hi

Ich habe eine kleine Engine programmiert, bei welcher der Sound mit FMOD läuft. Ich bin nun am Programmieren eines Spiels, mit meiner Engine und wollte mehrere Sounds auf einmal initialisieren und abspielen. Doch dann gab es Probleme mit dem Spiel.

Hier ist ein Codeausschnitt von meiner Engine:

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
// Klasse erzeugen
class VE_API veAudio
{
private:

    FMOD_SYSTEM *       m_System;
    FMOD_SOUND *        m_Sound;
    FMOD_CHANNEL *      m_Channel;
    FMOD_RESULT         m_Result;
    bool                m_bStoped;
    float               m_fVolume;
    veResult            CheckResult(FMOD_RESULT result);        // Diese Funktion prüft, ob die Funktionen erfolgreich waren

public:

    veResult            Init(char * pcFilename, bool bLoop);    // Audio initialisieren
    veResult            Play();                                 // Audio abspielen
    veResult            Stop();                                 // Audio stoppen
    veResult            SetVolume(float fVolume);               // Die Lautstärke ändern
    float               GetVolume();                            // Die Lautstäkre abfragen
    veResult            Release();                              // Audio freigeben

};

veResult veAudio::Init(char * pcFilename, bool bLoop)
{
    // -----------------------------------------------------------------------------------
    // Audio intialisieren
    // -----------------------------------------------------------------------------------

    unsigned int        version;

    m_Result = FMOD_System_Create(&m_System);
    CheckResult(m_Result);

    m_Result = FMOD_System_GetVersion(m_System, &version);
    CheckResult(m_Result);

    if(version < FMOD_VERSION)
    {
        MessageBox(NULL, "Fehler: Sie benutzen eine alte Version von FMOD", "Fehler aufgetreten",
                   MB_OK | MB_ICONEXCLAMATION);

        return VE_ERROR;
    }

    m_Result = FMOD_System_Init(m_System, 32, FMOD_INIT_NORMAL, NULL);
    CheckResult(m_Result);

    m_Result = FMOD_System_CreateStream(m_System, pcFilename, FMOD_HARDWARE | FMOD_LOOP_NORMAL | FMOD_2D, 0, &m_Sound);
    CheckResult(m_Result);

    if(bLoop)
    {
        m_Result = FMOD_Sound_SetMode(m_Sound, FMOD_LOOP_NORMAL);
        CheckResult(m_Result);
    }
    else
    {
        m_Result = FMOD_Sound_SetMode(m_Sound, FMOD_LOOP_OFF);
        CheckResult(m_Result);
    }

    m_Result = FMOD_System_PlaySound(m_System, FMOD_CHANNEL_FREE, m_Sound, 0, &m_Channel);
    CheckResult(m_Result);

    m_Result = FMOD_Channel_SetVolume(m_Channel, 1.0f);
    CheckResult(m_Result);

    m_Result = FMOD_Channel_GetVolume(m_Channel, &m_fVolume);
    CheckResult(m_Result);

    m_bStoped = false;

    return VE_OK;
}

veResult veAudio::Play()
{
    // -----------------------------------------------------------------------------------
    // Audio abspielen
    // -----------------------------------------------------------------------------------

    FMOD_System_Update(m_System);

    if (m_Channel)
    {
        unsigned int ms;
        unsigned int lenms;
        int         playing;
        int         paused;

        m_Result = FMOD_Channel_IsPlaying(m_Channel, &playing);
        if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE) && (m_Result != FMOD_ERR_CHANNEL_STOLEN))
        {
            CheckResult(m_Result);
        }

        m_Result = FMOD_Channel_GetPaused(m_Channel, &paused);
        if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE) && (m_Result != FMOD_ERR_CHANNEL_STOLEN))
        {
            CheckResult(m_Result);
        }

        m_Result = FMOD_Channel_GetPosition(m_Channel, &ms, FMOD_TIMEUNIT_MS);
        if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE) && (m_Result != FMOD_ERR_CHANNEL_STOLEN))
        {
            CheckResult(m_Result);
        }

        m_Result = FMOD_Sound_GetLength(m_Sound, &lenms, FMOD_TIMEUNIT_MS);
        if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE) && (m_Result != FMOD_ERR_CHANNEL_STOLEN))
        {
            CheckResult(m_Result);
        }
    }

    Sleep(10);

    return VE_OK;
}


Hier ein Codeausschnitt von meinem Spiel:

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
m_pAudio = new veAudio();
    m_pAudio2 = new veAudio();
    m_pAudio->Init("Data//Techno_1.wav", true);
    m_pAudio2->Init("Data//PushButton.wav", true);

// ...

// Intro rendern
                m_pIntro->RenderIntro();
                m_pAudio->Play();

// ...

if(Scene.KeyDown(VE_KEY_RETURN))
                {
                    m_pIntro->ExitIntro();
                    m_pAudio->Stop();
                    m_pAudio2->Play();
                    SetNewGameState(GS_MENU);
                    Sleep(100);
                    m_pAudio2->Stop();
                }

// ...


Wenn ich das Spiel starte, wird zwar die Musik von m_pAudio abgespielt, aber es wird keine Grafik auf dem Bildschirm angezeigt.

Warum entsteht dieser Fehler, was habe ich falsch programmiert?

LG Patrick

2

31.12.2010, 15:33

Mir sind gleich mehere Dinge aufgefallen:

1. Warum benutzt du das C-Interface??
2. Warum hat jeder Sound ein eigenes System?
3. Du solltest das Update pro Frame ausführen. So steht es übrigens auch in der Doku. ;)
4. Du solltest die Initialisierung des System so machen wie in der Doku beschrieben.

Tipp: Gliedere die Klassen etwas besser. Du solltest eine Klasse für einen Sound machen und eine für das System.

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

3

31.12.2010, 16:58

Oops, ich werde gleich die C++-Api verwenden.
Das war keine gute Idee für jeden Sound ein einzelndes System zu machen.
Ein Update pro Frame, bedeutet mit einer while Schleife, oder? Wenn ja, dann werden die weiteren Eingaben vom Benutzer nicht mehr in der Nachrichten-Schleife aufgenommen, und das ganze Spiel funktioniert nicht mehr.
Welche Doku meinst du? Diese, welche im FMOD Ordner liegt unter documentation?

Ja, ich werde zwei Klassen erzeugen, eine für das System und das andere für den Sound.

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

4

31.12.2010, 17:10

Ein Update pro Frame, bedeutet mit einer while Schleife, oder? Wenn ja, dann werden die weiteren Eingaben vom Benutzer nicht mehr in der Nachrichten-Schleife aufgenommen, und das ganze Spiel funktioniert nicht mehr.


Du rufst deine render funktionen doch auch in einer while-Schleife auf... in der gleichen Schleife musst du auch das soundsystem updaten...


Welche Doku meinst du? Diese, welche im FMOD Ordner liegt unter documentation?


Genau die meint er.

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

5

31.12.2010, 18:06

So, ich habe nun zwei Klassen erzeugt, eine für das System und ein für den Sound. Doch wenn ich nun das Spiel starte, kommt die Meldung "An invalid Object was used".

Hier ist der Code:

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
// Klasse erzeugen
class VE_API veAudioSystem
{
private:

    FMOD::System *      m_pSystem;
    FMOD_RESULT         m_Result;
    unsigned int        m_Version;
    int                 m_NumDrivers;
    FMOD_SPEAKERMODE    m_Speakermode;
    FMOD_CAPS           m_Caps;
    char                m_Name[256];
    veResult            CheckResult(FMOD_RESULT result);

public:

    veResult            InitAudioSystem();
    FMOD::System *      GetSystem() {return m_pSystem;}
    veResult            DeleteAudioSystem();

};

// Klasse erzeugen
class VE_API veAudio
{
private:

    FMOD::System *      m_pSystem;
    FMOD::Sound *       m_pSound;
    FMOD::Channel *     m_pChannel;
    FMOD_RESULT         m_Result;
    bool                m_bStoped;
    float               m_fVolume;
    veResult            CheckResult(FMOD_RESULT result);        // Diese Funktion prüft, ob die Funktionen erfolgreich waren

public:

    veResult            Init(FMOD::System * System, char * pcFilename, bool bLoop);     // Audio initialisieren
    veResult            Play();                                                         // Audio abspielen
    veResult            Stop();                                                         // Audio stoppen
    veResult            SetVolume(float fVolume);                                       // Die Lautstärke ändern
    float               GetVolume();                                                    // Die Lautstäkre abfragen
    veResult            Release();                                                      // Audio freigeben

};


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
138
139
140
141
142
veResult veAudioSystem::InitAudioSystem()
{
    // -----------------------------------------------------------------------------------
    // Diese Funktion erzeugt ein SoundSystem
    // -----------------------------------------------------------------------------------

    m_Result = FMOD::System_Create(&m_pSystem);
    CheckResult(m_Result);

    m_Result = m_pSystem->getVersion(&m_Version);
    CheckResult(m_Result);

    if(m_Version < FMOD_VERSION)
    {
        MessageBox(NULL,  "Sie verwenden eine alte Version von FMOD", "Fehler aufgetreten",
                   MB_OK | MB_ICONEXCLAMATION);

        return VE_ERROR;
    }

    m_Result = m_pSystem->getNumDrivers(&m_NumDrivers);
    CheckResult (m_Result);

    if(m_NumDrivers == 0)
    {
        m_Result = m_pSystem->setOutput(FMOD_OUTPUTTYPE_NOSOUND);
        CheckResult(m_Result);
    }
    else
    {
        m_Result = m_pSystem->getDriverCaps(0, &m_Caps, 0, 0, &m_Speakermode);
        CheckResult(m_Result);

        m_Result = m_pSystem->setSpeakerMode(m_Speakermode);
        CheckResult(m_Result);

        if(m_Caps & FMOD_CAPS_HARDWARE_EMULATED)
        {
            m_Result = m_pSystem->setDSPBufferSize(1024, 10);
            CheckResult(m_Result);
        }

        m_Result = m_pSystem->getDriverInfo(0, m_Name, 256, 0);
        CheckResult(m_Result);

        if(strstr(m_Name, "SigmaTel"))
        {
            m_Result = m_pSystem->setSoftwareFormat(48000, FMOD_SOUND_FORMAT_PCMFLOAT, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
            CheckResult(m_Result);
        }
    }

    m_Result = m_pSystem->init(100, FMOD_INIT_NORMAL, 0);
    if(m_Result == FMOD_ERR_OUTPUT_CREATEBUFFER)
    {
        m_Result = m_pSystem->setSpeakerMode(FMOD_SPEAKERMODE_STEREO);
        CheckResult(m_Result);

        m_Result = m_pSystem->init(100, FMOD_INIT_NORMAL, 0);
    }

    return VE_OK;
}

veResult veAudio::Init(FMOD::System * System, char * pcFilename, bool bLoop)
{
    // -----------------------------------------------------------------------------------
    // Audio intialisieren
    // -----------------------------------------------------------------------------------

    m_Result = System->createStream(pcFilename, FMOD_HARDWARE | FMOD_LOOP_NORMAL | FMOD_2D, 0, &m_pSound);
    CheckResult(m_Result);

    if(bLoop)
    {
        m_Result = m_pSound->setMode(FMOD_LOOP_NORMAL);
        CheckResult(m_Result);
    }
    else
    {
        m_Result = m_pSound->setMode(FMOD_LOOP_OFF);
        CheckResult(m_Result);
    }

    m_Result = m_pSystem->playSound(FMOD_CHANNEL_FREE, m_pSound, false, &m_pChannel);
    CheckResult(m_Result);

    m_pChannel->setVolume(1.0f);
    CheckResult(m_Result);

    m_pChannel->getVolume(&m_fVolume);
    CheckResult(m_Result);

    m_bStoped = false;

    return VE_OK;
}

veResult veAudio::Play()
{
    // -----------------------------------------------------------------------------------
    // Audio abspielen
    // -----------------------------------------------------------------------------------

    m_pSystem->update();

    if (m_pChannel)
    {
        unsigned int ms;
        unsigned int lenms;
        bool        playing;
        bool         paused;

        m_Result = m_pChannel->isPlaying(&playing);
        if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE))
        {
            CheckResult(m_Result);
        }

        m_Result = m_pChannel->getPaused(&paused);
        if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE))
        {
            CheckResult(m_Result);
        }

        m_Result = m_pChannel->getPosition(&ms, FMOD_TIMEUNIT_MS);
        if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE))
        {
            CheckResult(m_Result);
        }

        m_Result = m_pSound->getLength(&lenms, FMOD_TIMEUNIT_MS);
        if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE))
        {
            CheckResult(m_Result);
        }
    }

    Sleep(10);

    return VE_OK;
}


Die Init Aufrufe im Spiel:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
// Instanz von CIntro erzeugen und Init-Funktion aufrufen
    m_pIntro = new CIntro();
    m_pMenu = new CMenu();
    m_pIntro->InitIntro();
    m_pMenu->InitMenu();

    m_pSystem = new veAudioSystem();
    m_pAudio = new veAudio();
    m_pAudio2 = new veAudio();
    m_pSystem->InitAudioSystem();
    m_pAudio->Init(m_pSystem->GetSystem(), "Data//Techno_1.wav", true);
    m_pAudio->Init(m_pSystem->GetSystem(), "Data//PushButton.wav", true);


Warum kommt dieser Fehler?

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

6

01.01.2011, 14:01

Ich habe den Fehler bereits gefunden. Ich habe die Zeigerübergabe vergessen.

C-/C++-Quelltext

1
m_pSystem = System;

Nun habe ich meine Engine nochmals etwas umgeschrieben. Ich habe gemacht, dass der Benutzer nur eine Instanz der Klasse veAudio erzeugen muss, und kann im Konstruktor angeben, wie viele Sounds er gerne möchte. Doch der Sound wird momentan noch nicht abgespielt im Spiel.

Hier ist ein Codeausschnitt:

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
veAudio::veAudio(int NumSounds)
{
    m_UserSounds = NumSounds;
}

veResult veAudio::Init(FMOD::System * System, char * pcFilename, bool bLoop, int NumSound)
{
    // -----------------------------------------------------------------------------------
    // Audio intialisieren
    // -----------------------------------------------------------------------------------

    m_Result = System->createSound(pcFilename, FMOD_LOOP_NORMAL, 0, &m_pSound[NumSound]);
    CheckResult(m_Result);

    if(bLoop)
    {
        m_Result = m_pSound[NumSound]->setMode(FMOD_LOOP_NORMAL);
        CheckResult(m_Result);
    }
    else
    {
        m_Result = m_pSound[NumSound]->setMode(FMOD_LOOP_OFF);
        CheckResult(m_Result);
    }

    m_pChannel[NumSound]->setVolume(1.0f);
    CheckResult(m_Result);

    m_pChannel[NumSound]->getVolume(&m_fVolume[NumSound]);
    CheckResult(m_Result);

    m_pChannel[NumSound] = 0;
    m_bPausedSound[NumSound] = false;

    m_pSystem = System;

    m_bStoped = false;

    return VE_OK;
}

veResult veAudio::Play(int NumSound)
{
    // -----------------------------------------------------------------------------------
    // Audio abspielen
    // -----------------------------------------------------------------------------------

    m_Result = m_pChannel[NumSound]->isPlaying(&m_bPausedSound[NumSound]);
    if(m_bPausedSound[NumSound] == false)
    {
        m_Result = m_pSystem->playSound(FMOD_CHANNEL_FREE, m_pSound[NumSound], false, &m_pChannel[NumSound]);
        CheckResult(m_Result);
    }

    return VE_OK;
}

veResult veAudio::Update()
{
    // -----------------------------------------------------------------------------------
    // Audio updaten
    // -----------------------------------------------------------------------------------

    m_pSystem->update();

    {
        for(int i = 0; i < m_UserSounds; i++)
        {
            if(m_pChannel[i])
            {
                unsigned int ms;
                unsigned int lenms;
                bool        playing;
                bool        paused;

                m_Result = m_pChannel[i]->isPlaying(&playing);
                if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE))
                {
                    CheckResult(m_Result);
                }

                m_Result = m_pChannel[i]->getPaused(&paused);
                if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE))
                {
                    CheckResult(m_Result);
                }

                m_Result = m_pChannel[i]->getPosition(&ms, FMOD_TIMEUNIT_MS);
                if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE))
                {
                    CheckResult(m_Result);
                }

                m_Result = m_pSound[i]->getLength(&lenms, FMOD_TIMEUNIT_MS);
                if ((m_Result != FMOD_OK) && (m_Result != FMOD_ERR_INVALID_HANDLE))
                {
                    CheckResult(m_Result);
                }

            }
        }
    }

    return VE_OK;
}


Ich habe den Verdacht, dass die Update-Funktion falsch ist, denn das Spiel läuft soweit, nur der Sound wird nicht abgespielt.

7

01.01.2011, 14:32

Warum muss der Benutzer schon vorher festlegen wie viele Sounds er haben will?
Und was soll die seltsame Update Methode in der veAudio Klasse?
Schau doch bitte einfach mal die Tutorials in der Doku an, dann hättest du jetzt keine Probleme.

Zum Problem:
Benutze andere Mode-Flags beim erzeugen eines Sounds (createSound()),
siehe dazu wie schon vorgeschlagen einfach in die Doku.

Patrick Egli

Treue Seele

  • »Patrick Egli« ist der Autor dieses Themas

Beiträge: 161

Wohnort: Rainstrasse 38

  • Private Nachricht senden

8

01.01.2011, 15:04

Danke für den Tipp. Ich werde die Doku mal gründlich durchlesen. Ich habe es nun zum laufen gebracht.

Jetzt könnte ich die Klasse wieder ändern, denn es ist schon nicht ideal gelöst, wenn der Benutzer zu Beginn festlegen muss, wie viele Sounds er gerne haben möchte.

Dann wird die UpdateFunktion bestimmt wieder besser.

LG Patrick

Werbeanzeige