2

私は C++ でゲームを作成していますが、サウンドに関しては理解できない問題に直面しています。音楽はMix_Music、効果音はMix_ChunkというSDL_Mixerを使っているのですが、MIX_LoadWAVで効果音ファイルを読み込もうとするとなぜかNULLが返ってきます。

問題は、MIX_LoadMUS (効果音ではなく音楽としてロード) を使用して同じファイルをロードすると、正常にロードされることです。

問題を説明する違いは見つかりません。唯一の違いは Mix_LoadMUS ではなく Mix_LoadWAV ですが、なぜですか? 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 とフェードアウトを 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は.oggや.mp3にも対応しているはずなのに、wav以外のファイルを読み込めないのでは?

4

0 に答える 0