1

我最近发现了Qt Game Enabler库,并想在我使用 Qt 组件的 Symbian 项目中使用它。

我已经成功地抓取了库的音频部分,并且能够播放 Ogg Vorbis 文件,但有一个小问题。当我播放一个文件并且它第一次到达结尾时,它不会回到开头(因为我已将其设置为无限循环),它将返回几秒钟并播放到最后。当它第二次结束时,那是它正确地回到起点并且整个循环再次开始的时候(走到最后,回到几秒钟,再次回到结尾,回到开头,依此类推向前)。

我已经设法找出它决定返回几秒钟的代码中的哪个位置,但不知道足以进行任何更改。

源文件称为 VorbisSource,是一个 GameEnabler::AudioSource。播放音频的相关源码如下:

unsigned int channelLength(m_decoder->decodedLength() - 2);
unsigned int samplesToWrite(bufferLength / 2);
unsigned int amount(0);
unsigned int totalMixed(0);

while (samplesToWrite > 0) {
    unsigned int samplesLeft;

    if (m_fixedInc == 0) {
        // No speed set. Will lead to division by zero error if not set.
        setSpeed(GEDefaultAudioSpeed);
    }

    samplesLeft = m_fixedInc > 0 ? channelLength - (m_fixedPos >> 12) :
        (m_fixedPos >> 12);

    // This is how much we can mix at least.
    unsigned int maxMixAmount = (int)(((long long int)(samplesLeft) << 12) /
                             qAbs(m_fixedInc));

    if (maxMixAmount > samplesToWrite) {
        maxMixAmount = samplesToWrite;
    }

    if (maxMixAmount > 0) {
        amount = mixBlock(target+totalMixed * 2, maxMixAmount);

        if (amount == 0) {
            // Error!
            break;
        }

        totalMixed += amount;
    }
    else {
        amount = 0;
        m_fixedPos = m_fixedInc > 0 ? channelLength<<12 : 0; // <------------------------------- THIS IS WHERE THE PROBLEM IS
    }

    // The sample ended. Check the looping variables and see what to do.
    if ((m_fixedPos >> 12) >= channelLength || m_fixedPos <= 0) {
        m_fixedPos += m_fixedInc > 0 ? -((qint64)channelLength << 12) :
            ((qint64)channelLength << 12);

        if (m_loopCount > 0)
            m_loopCount--;

        if (m_loopCount == 0) {
            // No more loops, stop the sample and return the amount of
            // samples already mixed.
            stop();
            break;
        }
    }

    samplesToWrite -= amount;

    if (samplesToWrite < 1)
        break;
}

在某些时候,maxMixAmount 设置为零(我相信它在文件的末尾),而不是结束声音,而是根据这行代码返回几秒钟:

m_fixedPos = m_fixedInc > 0 ? channelLength<<12 : 0;

我的第一个想法可能是因为 vorbis 文件的比特率是可变的,而 VorbisSource 并没有预料到它,但是在更改此设置后,会出现同样的问题。我选择哪个文件也没有关系,这是相同的行为。

我的下一个猜测是它移动了错误的数量,但我不知道正确的数量是多少。

如果有帮助,以下是 Game Enabler 的一些输出信息:

GE::AudioOut::AudioOut(GE::AudioSource*, QObject*) : 65 : Buffer size:  32768 
virtual void GE::AudioOut::run() : 145 : Starting thread. 
int GE::VorbisDecoder::vorbisInit() : 400 : stb vorbis init complete, used 3527 bytes, error 0 
int GE::VorbisDecoder::vorbisInit() : 408 :    sample_rate: 44100 
int GE::VorbisDecoder::vorbisInit() : 409 :       channels: 1 
int GE::VorbisDecoder::vorbisInit() : 410 : max_frame_size: 2048 

先感谢您。

4

0 回答 0