Я создаю простой 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;
}

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

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

ОБНОВЛЕНИЕ:

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

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

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

0
DS2830 2 Апр 2019 в 17:09

1 ответ

Лучший ответ

Справочник FMOD FMOD System :: close < / a> должен объяснить поведение:

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

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

1
Yastanub 2 Апр 2019 в 14:44