Требуется установить позицию звука на указанное в параметрах функции значение.
Код:
ALfloat getBufferLengthInSec(ALuint buffer) { ALint size, bits, channels, freq; alGetBufferi( buffer, AL_SIZE, &size); alGetBufferi( buffer, AL_BITS, &bits); alGetBufferi( buffer, AL_CHANNELS, &channels); alGetBufferi( buffer, AL_FREQUENCY, &freq); if ( alGetError( ) != AL_NO_ERROR) return -1.0f; return ( ALfloat)( ( ALuint)( size*8)/channels/bits) / ( ALfloat)freq; } void SoundStream::seek_to_ms( int64_t seek_to) { float seek_target = seek_to / 1000.f; float all_duration = 0.f; ALint tot = 0; stop( ); for ( int i=0 ; i<m_allocated_bufs ; i++) { all_duration += getBufferLengthInSec( m_buffers[i]); ALint sz = 0; alGetBufferi( m_buffers[i], AL_SIZE, &sz); tot += sz; if ( seek_target < all_duration) { alSourcei( m_sourceID, AL_BUFFER, m_buffers[i]); alSourcei( m_sourceID, AL_BYTE_OFFSET, seek_target*tot); break; } } play( ); }
Имеется набор буферов (поскольку требуемый размер очень сильно варьируется и заранее узнать его тяжело - работа ведется с OGG), среди которых ищется подходящий по времени воспроизведения. После чего выбирается этот буфер и устанавливается позиция в потоке, соответствующая искомому моменту.
Проблема в том, что собственно установки позиции не происходит - звук проигрывается с самого начала :(
В отладке проверял - значения в последний вызов alSourcei передаются вроде бы корректные (считал на бумажке, зная требуемую позицию).
Изменил на позиционирование по времени и всё заработало:
void SoundStream::seek_to_ms(int64_t seek_to) { stop( ); alSourcef( m_sourceID, AL_SEC_OFFSET, seek_to / 1000.f); }
Если в конце этой функции начать воспроизведение (вызвать play()), то играть будет с самого начала. Проблема в том, что движок сам еще раз вызывает play() для данного звука - видит, что действие еще не запущено.
Тема в архиве.