gpt4 book ai didi

c++ - 循环流式传输 .ogg 音频 - OpenAL

转载 作者:太空狗 更新时间:2023-10-29 22:53:00 24 4
gpt4 key购买 nike

我在循环流式传输的 ogg vorbis 文件时遇到问题。

这是代码:

fslStream_OGG::fslStream_OGG()
{
className = "fslSound";
iMemSize = 0;
iLength = 0;
bSourceRelative = false;
bIsLooping = false;
bForceStop = false;
bActive = false;
source = buffer = 0;
current_gain = 1.0f;
outer_gain = 0;
snd_info.uiChannels = snd_info.uiFrequency = snd_info.uiSampling = 0;
}

fslStream_OGG::~fslStream_OGG()
{
if (bStreamCreated)
{
alSourceStop(source);
Empty();
alDeleteSources(1,&source);
alDeleteBuffers(2,buffers);
ov_clear(&oggStream);
}
}

bool fslStream_OGG::Update()
{
ALenum state;
alGetSourcei(source,AL_SOURCE_STATE,&state);

if (state == AL_PAUSED || !bActive) return false;

int processed;
alGetSourcei(source,AL_BUFFERS_PROCESSED,&processed);

while (processed--)
{
ALuint bufferI;
alSourceUnqueueBuffers(source,1,&bufferI);
Stream(bufferI);
if (bActive) alSourceQueueBuffers(source,1,&bufferI);
}

if (state == AL_STOPPED || !bActive)
{
bActive = false;
StreamSetPos(0.0f);
if (bForceStop) return false;

if (bIsLooping)
{
alSourceStop(source); // <- *** note these ***
Empty(); // <- *** 2 lines of code ***
StreamPlay();
alSourcePlay(source);
}
else
{
return true;
}
}

return false;
}

void fslStream_OGG::StreamPlay()
{
if (!bActive)
{
bActive = true;
bForceStop = false;
Stream(buffers[0]);
Stream(buffers[1]);

alSourceQueueBuffers(source,2,buffers);
}
}

bool fslStream_OGG::Open(const char* strFile)
{
bStreamCreated = false;
vorbis_info* vorbisInfo;
oggFile = fopen(strFile,"rb");

if (!oggFile) return false;

if (ov_open_callbacks(oggFile,&oggStream,NULL,0,OV_CALLBACKS_DEFAULT) != 0)
{
fclose(oggFile);
return false;
}

vorbisInfo = ov_info(&oggStream,-1);

if (vorbisInfo->channels == 1)
format = AL_FORMAT_MONO16;
else format = AL_FORMAT_STEREO16;

alGenBuffers(2,buffers);
alGenSources(1,&source);

iLength = (long)(ov_time_total(&oggStream,-1) * 1000.0);
snd_info.uiChannels = (format == AL_FORMAT_MONO8 || format == AL_FORMAT_MONO16)? 1:2;
snd_info.uiSampling = (format == AL_FORMAT_MONO8 || format == AL_FORMAT_STEREO8)? 8:16;
snd_info.uiFrequency = vorbisInfo->rate;

bStreamCreated = true;
bIsStream = true;

return true;
}

void fslStream_OGG::Stream(ALuint bufferI)
{
int size = 0;
int section;
int result;

bActive = true;

while (size < OGG_STREAM_BUFFER_SIZE)
{
result = ov_read(&oggStream,data + size,OGG_STREAM_BUFFER_SIZE - size,0,2,1,&section);

if (result > 0)
{
size += result;
}
else
{
if (result < 0) return; else break;
}
}

if (size == 0) { bActive = false; return; }

alBufferData(bufferI,format,data,size,snd_info.uiFrequency);
}

void fslStream_OGG::Empty()
{
int queued;
alGetSourcei(source,AL_BUFFERS_QUEUED,&queued);

while (queued--)
{
ALuint bufferI;
alSourceUnqueueBuffers(source,1,&bufferI);
}
}

void fslStream_OGG::StreamSetPos(float p)
{
ov_time_seek(&oggStream,p);
}

float fslStream_OGG::StreamGetPos()
{
return (float)ov_time_tell(&oggStream);
}

注意我用***标记的两行代码。

在所有情况下,文件开始正常播放并在结束时倒带。然而:

没有这两行代码,重复时文件听起来“已损坏”。如果让再重复一遍,听起来就更“腐败”了。我相信这是因为 OpenAl 和 Vorbis 解码器在重复流时“不同步”写入/读取缓冲区。

如果我添加这两行代码,文件会重复出现而不会听起来损坏。但是,该文件并没有无缝重复;它在结束前快退了几厘秒。我怀疑这是因为在倒带开始之前缓冲区没有播放到最后。

如果有人能伸出援手,我将不胜感激。

非常感谢,

比尔

最佳答案

似乎我已经解决了这个问题(如果不进行广泛的测试,我将无法确定)。

我已经修复了 Update 方法如下:

bool fslStream_OGG::Update()
{
ALenum state;
alGetSourcei(source,AL_SOURCE_STATE,&state);

//if (state == AL_PAUSED || !bActive) return false; // <- WRONG
if (state == AL_PAUSED) return false;

int processed;
alGetSourcei(source,AL_BUFFERS_PROCESSED,&processed);

while (processed--)
{
ALuint bufferI;
alSourceUnqueueBuffers(source,1,&bufferI);
Stream(bufferI);
if (bActive) alSourceQueueBuffers(source,1,&bufferI);
}

//if (state == AL_STOPPED || !bActive) /// <- WRONG
if (state == AL_STOPPED)
{
bActive = false;
StreamSetPos(0.0f);
if (bForceStop) return false;

if (bIsLooping)
{
//alSourceStop(source); // <- I have added these
//Empty(); // <- 2 lines of code
StreamPlay();
alSourcePlay(source);
}
else
{
return true;
}
}

return false;
}

那两行代码现在似乎没有必要了。必须使用不同的操作系统、硬件等对其进行测试...

关于c++ - 循环流式传输 .ogg 音频 - OpenAL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3307903/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com