스트리밍 된 ogg vorbis 파일을 반복하는 데 문제가 있습니다. 코드의루프 스트리밍 .ogg 오디오 - OpenAL
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,§ion);
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);
}
주 2 선 내가 ***로 표시 한 :
이
는 코드입니다.모든 경우에 파일이 잘 재생되기 시작하고 끝날 때 되감습니다. 그러나 :
코드가없는이 2 줄의 코드를 반복하면 파일이 "손상됨"으로 들립니다. 다시 반복하도록하면 더 "부패한"소리가납니다. 이것은 OpenAl과 Vorbis 디코더가 스트림이 반복 될 때 버퍼를 읽거나 쓰는 "비동기식"이기 때문에 이것이라고 생각합니다.
두 줄의 코드를 개 추가하면 파일이 손상되지 않고 반복됩니다. 그러나 파일은 매끄럽게 반복되지 않습니다.이 끝나기 전에 수십 초를 되감습니다. 나는 버퍼가 시작 되감기 전에 끝까지 재생되지 않기 때문에 이것이 의심 스럽다.
누군가가 도움의 손길을 빌릴 수 있다면 나는 의무가 있습니다. 사전에
많은 감사,
빌
안녕하세요, 저는 아주 비슷한 문제가 있습니다 (매우 유사한'Update' 함수로, 같은 튜토리얼을 읽은 것처럼 보입니다). 이 솔루션을 가지고 가나 요? 루핑에 관한 나의 문제는 당신과 동일했다. 스트림을 다시 시작하기 전에 몇 밀리 초 뒤로 이동합니다. 그러나 루핑 없이도이 작업을 수행 할 수 있습니다. 오디오 파일이 끝나면 멈추기 전에 마지막 몇 ms의 사운드를 재생합니다. 성가신 작은 지터. 이 솔루션을 어떻게 나왔습니까? – Anthony