C++ 试图将几个较小的、不同大小的数据块复制到一个较大的数据块中

C++ Trying to copy several smaller, differently sized, blocks of data into one larger block of data

我有一个奇怪的问题。我的音频引擎 (FMOD) 正在请求不同大小块的数据,我的文件流服务 (Theoraplay) 也在可变大小块中提供它的音频数据。

我想做的是将音频样本背对背推入,最后一个可能只被部分压入,差异保存为下次调用时的偏移量。我遇到的问题是 A:memcpy_s 对 FMOD 使用的 void 指针不满意,B:我担心使用错误的偏移量可能会导致不同架构的内存问题,并且希望使它可靠。

这是目前的回调函数。 pData 是指向 FMOD 想要填充的内容的指针,nDatalen 是它的大小。

A​​udioCallbackQueue 是一个 linked 列表,它包含音频样本,link 到下一个样本,它有自己的当前偏移量。由于“框架”,样本本身的大小也有所不同。

数据清理在程序的其他地方。

FMOD_RESULT F_CALLBACK pcmQueue(FMOD_SOUND* pSound, void* pData, unsigned int nDataLen)
{
    FMOD::Sound*            pCurrentSound = (FMOD::Sound*)pSound; //required or else we get compiler errors
    void*                   pUserData = 0;
    AudioCallbackQueue*     pCurrent = 0;
    FMOD_RESULT             fError = FMOD_OK;
    unsigned int            nCurrentOffSet = 0;
    unsigned int            nRemainingLength = nDataLen;

    fError = pCurrentSound->getUserData( &pUserData );

    pCurrent = (AudioCallbackQueue*)pUserData;

    if(pCurrent != 0) //Error checking.
    {
        while (nRemainingLength != 0) //break when full
        {
            unsigned int nSize = (sizeof(float) * (pCurrent->pRawAudio->frames) * (pCurrent->pRawAudio->channels)) - pCurrent->nOffset; //This is the size of the current sample, minus whatever has been used previously
            
            if (nRemainingLength < nSize) //if here our sample is longer than what data is left to fill, so fill it to max and set the offset.
            {
                nSize = nRemainingLength;
                memcpy_s((pData + nCurrentOffSet), nSize, ((pCurrent->pRawAudio->samples) + pCurrent->nOffset), nSize);
                pCurrent->nOffset += nSize;
            }
            else //If here we are using the last of the sample, move on to the next
            {
                memcpy_s((pData + nCurrentOffSet), nSize, ((pCurrent->pRawAudio->samples) + pCurrent->nOffset), nSize);
                pCurrent = pCurrent->pNext;
            }

            nCurrentOffSet += nSize;
            nRemainingLength -= nSize;

            if (nSize > nDataLen)
                nSize = nDataLen;


        }
    }
    else //No samples around, nothing to process
        return FMOD_RESULT::FMOD_ERR_FILE_ENDOFDATA;

    pCurrentSound->setUserData(pCurrent);

    return FMOD_RESULT::FMOD_OK;
}

正如@Retired Ninja 在链接的答案中所说,您需要将 pData 转换为 char * 以便您可以对其进行指针运算,就像这样(我使用的是 C-为简洁起见的风格转换):

memcpy_s(((char *) pData + nCurrentOffSet), nSize, ((pCurrent->pRawAudio->samples) + pCurrent->nOffset), nSize);

另外,让我印象深刻的是,当你有部分框架遗留下来时,你会怎么做?下次调用 pcmQueue.

时,您需要一些方案来处理它