Почему мой код не завершает вызов Sound :: release ()? - PullRequest
0 голосов
/ 02 апреля 2019

Я создаю простой MP3-плеер и использую FMOD Core API для управления аудио.Я написал простую программу для проверки функции play().У меня есть две функции freeSound() и freeSystem() для освобождения дескриптора sound и system соответственно.Оба вызываются через функцию cleanUp() в деструкторе.

Я использовал gdb, чтобы выяснить, что по какой-то причине моя программа застревает в вызове Sound::release() в freeSound() при вызове деструктора.

Эта проблема возникает толькокогда freeSystem() вызывается раньше freeSound().Простое обращение к последнему в первую очередь решает эту проблему.

Я поделился настолько небольшим кодом, насколько я думал, было возможно показать эту проблему.Если требуется больше / меньше, я буду добавлять / удалять.

Функция main ():

int main()
{
    musicPlayer p{"music.mp3"};
    std::cout << "load success\n";
    p.play();
    std::cout << "press enter to quit\n";
    std::cin.get();
}

Объявление класса (включает только соответствующие биты):

class musicPlayer
{
private:
    FMOD::System *m_system = nullptr;
    FMOD::Sound *m_sound = nullptr;

    /*Some more functions*/

    void cleanUp();
    void freeSystem();
    void freeSound();

public:
    ~musicPlayer();

    /*Some more functions*/
};

Деструктор:

musicPlayer::~musicPlayer()
{
    cleanUp();
    m_channel = nullptr;
}

cleanUp ():

void musicPlayer::cleanUp()
{
    freeSystem();
    freeSound();
}

freeSound () и freeSystem ():

void musicPlayer::freeSystem()
{
    if(m_system == nullptr)
        return;

    FMOD_RESULT result = m_system -> release();
    if(result != FMOD_OK){
        std::cerr << "freeSystem() Error: " << FMOD_ErrorString(result) << "\n";
        return;
    }
    else 
        m_system = nullptr;
}

void musicPlayer::freeSound()
{
    if(m_sound == nullptr)
        return;

    FMOD_RESULT result = m_sound -> release();
    if(result != FMOD_OK){
        std::cerr << "freeSound() Error: " << FMOD_ErrorString(result) << "\n";
        return;
    }
    else
        m_sound = nullptr;
}

Я ожидаю, что звук перестанет воспроизводитьсяи программа для немедленного выхода при нажатии клавиши ввода.

Вместо этого при нажатии клавиши ввода звук останавливается, и программа не завершается.

ОБНОВЛЕНИЕ:

Ранее я писал:

Blockquote Я написал небольшие тестовые программы, в которых я вызывал System::release() до Sound::release().Такие программы не показывают эту проблему.

Я был не прав.Проблема может быть воспроизведена путем воспроизведения звука, вызова cin.get() и последующего освобождения ресурсов в неправильном порядке.

1 Ответ

1 голос
/ 02 апреля 2019

Ссылка FMOD Система FMOD :: close должна объяснить поведение:

«Закрытие делает объекты, созданные с помощью этой Системы, недействительными. Убедитесь, что все объекты Sound, ChannelGroup, Geometry и DSP освобождены перед вызовом этого».

System :: close вызывается System :: release , поэтому при выпуске системы до того, как у компонентов возникнут проблемы. Как вы выяснили, просто освободите все, прежде чем выпустить систему.

...