Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.04.2015, 09:56   #1
andreil
Пользователь
 
Регистрация: 19.12.2011
Сообщений: 28
По умолчанию Ошибка при удалении звука в OpenAL

Пишется простейший игровой движок с использованием OpenAL для вывода звука.
Фрагменты кода, отвечающие за звук:
Код:
SoundStream::SoundStream()
{
}

SoundStream::~SoundStream()
{
    this->stop();
    alSourcei(this->m_sourceID, AL_BUFFER, 0);
    alDeleteBuffers(NUM_OF_DYNBUF, this->m_buffers);
    alDeleteSources(1, &this->m_sourceID);
}

bool SoundStream::load(Stream *stream, bool looped)
{
    // Create source
    alGenSources(1, &this->m_sourceID);
    if (!CheckALError())
    {
        ERROR_MESSAGE("SoundStream: Unable to create source");
        return false;
    }

    ALfloat mVel[] = {0., 0., 0.};
    ALfloat mPos[] = {0., 0., 0.};

    alSourcef (this->m_sourceID, AL_PITCH,		1.0f);
    alSourcef (this->m_sourceID, AL_GAIN,		1.0f);
    alSourcefv(this->m_sourceID, AL_POSITION,	mPos);
    alSourcefv(this->m_sourceID, AL_VELOCITY,	mVel);

    alSourcef(this->m_sourceID, AL_GAIN, 1.0f);
    this->m_loop = looped;

    return load_ogg(stream);
}

bool SoundStream::load_ogg(Stream *stream)
{
    int				BlockSize;
    // OggVorbis specific structures
    ov_callbacks	cb;

    // Fill cb struct
    cb.close_func	= CloseOgg;
    cb.read_func	= ReadOgg;
    cb.seek_func	= SeekOgg;
    cb.tell_func	= TellOgg;

    // Create OggVorbis_File struct
    this->m_VF = new OggVorbis_File;

    // Open Ogg file

    // Generate local buffers
    if (ov_open_callbacks(stream, this->m_VF, NULL, -1, cb) < 0)
    {
        // This is not ogg bitstream. Return
        ERROR_MESSAGE("SoundStream: This is not ogg bitstream");
        return false;
    }

    // Check for existance of sound
    BlockSize	= DYNBUF_SIZE;
    alSourcei(this->m_sourceID, AL_LOOPING, AL_FALSE);

    // Return vorbis_comment and vorbis_info structures
    this->m_comment		= ov_comment(this->m_VF, -1);
    this->m_info		= ov_info(this->m_VF, -1);
    this->m_format = (this->m_info->channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;

    this->m_proceed = 0;
    alGetSourcei(this->m_sourceID, AL_BUFFERS_PROCESSED, &this->m_proceed);

    // Create buffers
    /*alGenBuffers(NUM_OF_DYNBUF, this->m_buffers);
    if (!CheckALError())
    {
        ERROR_MESSAGE("SoundStream: unable to create buffer");
        return false;
    }*/

    // Fill buffers with data each block by DYNBUF_SIZE bytes
    for (int i = 0; i < NUM_OF_DYNBUF; i++)
    {
        alGenBuffers(1, &this->m_buffers[i]);
        if (!CheckALError())
        {
            ERROR_MESSAGE("SoundStream: unable to create buffer");
            return false;
        }
        // Read amount (DYNBUF_SIZE) data into each buffer
        if (!ReadOggBlock(this->m_buffers[i], BlockSize))
        {
            //NORMA_MESSAGE("SoundStream: EOF");
            break;
        }
        if (!CheckALError())
        {
            ERROR_MESSAGE("SoundStream: unable to read buffer");
            return false;
        }
    }

    alSourcei (this->m_sourceID, AL_LOOPING,	this->m_loop);

    return true;
}

bool SoundStream::ReadOggBlock(ALuint BufID, size_t Size)
{
    // vars
    int			current_section;
    size_t		TotalRet = 0, ret = 1;
    char		*PCM;

    if (Size < 1) return false;
    PCM = new char[Size];

    // Read loop
    while ((TotalRet < Size) && (ret != 0))
    {
        ret = ov_read(this->m_VF, PCM + TotalRet, Size - TotalRet, 0, 2, 1, &current_section);

        switch (ret)
        {
        case OV_HOLE:
            ERROR_MESSAGE("SoundStream: OGG interruption in the data");
            return false;
            break;
        case OV_EBADLINK:
            ERROR_MESSAGE("SoundStream: OGG invalid stream section");
            return false;
            break;
        case OV_EINVAL:
            ERROR_MESSAGE("SoundStream: OGG initial file headers couldn't be read or are corrupt");
            return false;
            break;
        case 0:
            // if end of file or read limit exceeded
            break;
        default:
            TotalRet += ret;
            break;
        }
    }
    if (TotalRet > 0)
    {
        alBufferData(BufID, this->m_format, (void *)PCM, TotalRet, this->m_info->rate);
        //printf("Buffer: format %u, rate %u", this->m_buffers[BufID].Format, this->m_info->rate);
        if (!CheckALError())
        {
            ERROR_MESSAGE("SoundStream: unable to send buffer");
            return false;
        }
        alSourceQueueBuffers(this->m_sourceID, 1, &BufID);
    }
    delete [] PCM;
    return (TotalRet == Size);
}
Проблема в том, что второй и последующие звуки не загружаются - происходит выход после функции alGenSources со следующим сообщением:
Код:
OpenAL error: Invalid Name
SoundStream: Unable to create source
Если в деструкторе убрать строку с удалением буферов - все грузится нормально, но возникает утечка памяти.
Где-то я выстрелил себе в ногу, но вот где - понять не могу

Последний раз редактировалось andreil; 27.04.2015 в 10:02.
andreil вне форума Ответить с цитированием
Старый 27.04.2015, 10:17   #2
andreil
Пользователь
 
Регистрация: 19.12.2011
Сообщений: 28
По умолчанию

Как это ни странно, но ошибку нашел почти сразу, как написал сюда.
Проблема заключалась в том, что удалять нужно столько же буферов, сколько их было создано:
Код:
SoundStream::~SoundStream()
{
    this->stop();
    alSourcei(this->m_sourceID, AL_BUFFER, 0);
    alDeleteBuffers(this->m_allocated_bufs, this->m_buffers);
    alDeleteSources(1, &this->m_sourceID);
}

bool SoundStream::load_ogg(Stream *stream)
{
....
    this->m_allocated_bufs = 0;
    for (int i = 0; i < NUM_OF_DYNBUF; i++)
    {
        alGenBuffers(1, &this->m_buffers[i]);
        this->m_allocated_bufs++;
....
}
andreil вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка при удалении компонента Putin-mode Общие вопросы Delphi 18 24.01.2012 23:28
Что за ошибка при удалении структуры? kypck Общие вопросы C/C++ 8 23.10.2011 23:57
Ошибка при удалении из БД!!! Delphi 7. NuR1k БД в Delphi 2 21.08.2010 19:19
ошибка при удалении символа Virus191288 Общие вопросы Delphi 13 15.08.2009 14:50
Ошибка при удалении... JRcoker Общие вопросы Delphi 8 29.07.2008 22:53