Mix_LoadWAV在不应该返回NULL时返回NULL

时间:2015-07-21 16:38:17

标签: c++ audio sdl sdl-mixer

我正在用C ++制作游戏,但是我遇到了一个问题,当涉及到声音时我无法弄清楚。我正在使用SDL_Mixer,Mix_Music用于音乐,Mix_Chunk用于音效,但出于某种原因,当我尝试使用MIX_LoadWAV加载声音效果文件时,它返回NULL。

问题是,当我使用MIX_LoadMUS加载相同的文件(加载为音乐而不是音效)时,它加载正常。

我找不到可以解释这个问题的任何差异;唯一的区别是Mix_LoadWAV而不是Mix_LoadMUS,但为什么呢? Mix_LoadMUS不适用于Mix_Chunk,否则我只是使用它,但......

在这里,我将向您展示我使用的声音管理器的代码。 MusicClip是Mix_Music,SoundClip是Mix_Chunk。

#include "stdafx.h"
#include "SoundManager.h"
#include "MusicClip.h"
#include "SoundClip.h"

SoundManager::SoundManager()
{
}

SoundManager::~SoundManager()
{
    Shutdown();
}

bool SoundManager::Initialize()
{
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
    {
        printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
    }

    if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
    {
        printf(" SDL_mixer :: Msx_OpenAudio %s\n", Mix_GetError());
        return false;
    }

    return true;
}

void SoundManager::Shutdown()
{
    for (unsigned int i = 0; i < m_axSoundClips.size(); i++)
    {
        delete m_axSoundClips[i];
        m_axSoundClips[i] = nullptr;
    }
    m_axSoundClips.clear();

    for (unsigned int i = 0; i < m_axMusicClips.size(); i++)
    {
        delete m_axMusicClips[i];
        m_axMusicClips[i] = nullptr;
    }
    m_axMusicClips.clear();

    {
        std::map<std::string, Mix_Chunk*>::iterator it = m_axSounds.begin();
        while (it != m_axSounds.end())
        {
            Mix_FreeChunk(it->second);
            it->second = nullptr;
            it++;
        }
        m_axSounds.clear();
    }

    {
        std::map<std::string, Mix_Music*>::iterator it = m_axMusic.begin();
        while (it != m_axMusic.end())
        {
            Mix_FreeMusic(it->second);
            it->second = nullptr;
            it++;
        }
        m_axMusic.clear();
    }

    Mix_CloseAudio();
}

MusicClip *SoundManager::CreateMusicClip(std::string p_sFilename)
{
    MusicClip *Ret = nullptr;

    std::map<std::string, Mix_Music*>::iterator it = m_axMusic.find(p_sFilename);
    if (it == m_axMusic.end())
    {
        Mix_Music* Music = Mix_LoadMUS(p_sFilename.c_str());
        if (Music == NULL) {
            printf("Error; music will not play\n");
            printf(p_sFilename.c_str());
            printf("\n");
            printf(Mix_GetError());
        }
        std::pair<std::string, Mix_Music*> Pair;
        Pair = std::make_pair(p_sFilename, Music);
        Ret = new MusicClip(Music);
    }
    else
        Ret = new MusicClip(it->second);

    m_axMusicClips.push_back(Ret);

    return Ret;
}

SoundClip *SoundManager::CreateSoundClip(std::string p_sFilename)
{
    SoundClip *Ret = nullptr;
    std::map<std::string, Mix_Chunk*>::iterator it = m_axSounds.find(p_sFilename);

    if (it == m_axSounds.end())
    {

        Mix_Chunk* Sound = Mix_LoadWAV(p_sFilename.c_str());

        if (Sound == NULL) {
            printf("\nError; sound will not play\n");
            printf(p_sFilename.c_str());
            printf("\n");
            printf(Mix_GetError());
        }
        std::pair<std::string, Mix_Chunk*> Pair;
        Pair = std::make_pair(p_sFilename, Sound);
        Ret = new SoundClip(Sound);
    }
    else
        Ret = new SoundClip(it->second);

    m_axSoundClips.push_back(Ret);

    return Ret;
}

这是MusicClip和SoundClip的代码;除了我将PlayOnce和fadeout添加到MusicClip之外,它们似乎完全相同。

#include "stdafx.h"
#include "SoundClip.h"

SoundClip::SoundClip()
{
    m_pxClip = nullptr;
    m_iChannel = -1;
}

SoundClip::~SoundClip()
{
    m_pxClip = nullptr;
}

SoundClip::SoundClip(Mix_Chunk* p_pxClip)
{
    m_pxClip = p_pxClip;
    m_iChannel = -1;
}

void SoundClip::Play()
{
    m_iChannel = Mix_PlayChannel(-1, m_pxClip, 0);
}

void SoundClip::Stop()
{
    if (m_iChannel == -1)
        return;

    Mix_HaltChannel(m_iChannel);
    m_iChannel = -1;
}

void SoundClip::Volume(int p_iVolume)
{
    if (m_iChannel == -1)
        return;

    Mix_Volume(m_iChannel, p_iVolume);
}

void SoundClip::Pause()
{
    if (m_iChannel == -1)
        return;

    if (Mix_Paused(m_iChannel))
    {
        Mix_Resume(m_iChannel);
    }
    else
    {
        Mix_Pause(m_iChannel);
    }
}

-

// MusicClip.cpp
#include "stdafx.h" 
#include "MusicClip.h"

MusicClip::MusicClip()
{
    m_xClip = nullptr;
    m_iChannel = -1;
}

MusicClip::~MusicClip()
{
    m_xClip = nullptr;
    m_iChannel = -1;
}

MusicClip::MusicClip(Mix_Music* p_xClip)
{
    m_xClip = p_xClip;
    m_iChannel = -1;
}

void MusicClip::Play()
{
    m_iChannel = Mix_PlayMusic(m_xClip, -1);
}

void MusicClip::PlayOnce()
{
    m_iChannel = Mix_PlayMusic(m_xClip, 1);
}

void MusicClip::Pause()
{
    if (m_iChannel == -1)
        return;

    if ( Mix_PausedMusic() )
        Mix_ResumeMusic();
    else
        Mix_Pause(m_iChannel);
}

void MusicClip::Volume(int p_iVolume)
{
    Mix_VolumeMusic(p_iVolume);
    oldVolume = p_iVolume;
}

void MusicClip::FadeOut()
{
    if (oldVolume>0)
        oldVolume--;
    Mix_VolumeMusic(oldVolume);
}

void MusicClip::Stop()
{
    if (m_iChannel == -1)
             return;

    Mix_HaltChannel(m_iChannel);
    m_iChannel = -1;
}

这是我用来调用函数的代码。 (SoundManager在程序的早期初始化,以启动BGM。)因此,使用Mix_Chunk * SFX2,这将无效:

void GameState::playSFX(std::string FX)
{
    SFX2 = soundManager.CreateSoundClip("../assets/sfx/sfx-bleep.wav");
    SFX2->Volume(60);
    SFX2->Play();
}

但出于某种原因,如果我将SFX2更改为Mix_Music *,则可以正常工作。

void GameState::playSFX(std::string FX)
{
SFX2 = soundManager.CreateMusicClip("../assets/sfx/sfx-bleep.wav");
    SFX2->Volume(60);
    SFX2->Play();
}

我该怎么办? Mix_GetError()也没有返回任何内容...如果我写错了路径它会返回“无法打开文件”,所以很明显它可以找到/打开文件,它只是......不会?我不能只使用Mix_Music作为我的音效,因为如果我这样做,他们会取消音乐。

顺便说一句,我不知道它是否相关,但Mix_LoadMUS不会加载非wav文件,即使它也应该支持.ogg和.mp3?

0 个答案:

没有答案