c++ - C++ 试图将几个较小的、不同大小的数据块复制到一个较大的数据块中
问题描述
我有一个奇怪的问题。我的音频引擎 (FMOD) 以不同大小的块请求数据,而我的文件流服务 (Theoraplay) 也在以可变大小的块提供它的音频数据。
我想做的是背靠背地推入音频样本,最后一个可能只是部分压入,差异保存为下次调用时的偏移量。我遇到的问题是 A:memcpy_s 对 FMOD 正在使用的 void 指针不满意,并且 B:我担心使用错误的偏移量可能会导致不同架构的内存问题,并且希望使其可靠。
这是当前的回调函数。pData 是指向 FMOD 想要填充的内容的指针,而 nDatalen 是它的大小。
AudioCallbackQueue 是一个链表,其中包含音频样本、指向下一个样本的链接以及它自己的当前偏移量。由于“框架”,样本本身的大小也有所不同。
数据清理在程序的其他地方。
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
为 achar *
以便您可以对其进行指针运算,如下所示(为了简洁起见,我使用了 C 风格的转换):
memcpy_s(((char *) pData + nCurrentOffSet), nSize, ((pCurrent->pRawAudio->samples) + pCurrent->nOffset), nSize);
另外,让我印象深刻的事情是,当您留下部分框架时,您会怎么做?下次调用时,您需要一些方案来处理它pcmQueue
。
推荐阅读
- regex - invert reqular expression for excluding folders/files (used for Electron Packager)
- php - Woocommerce 如何创建自己的新订单电子邮件模板?
- r - 考虑使用 r 的午夜时间的时差计算
- angularjs - css网格的砌体布局
- crystal-reports - 使用 Crystal Report 生成发票
- javascript - 有没有办法在reactjs中更改react-datepicker的月份或年份时选择日期?
- ios - 使用 Countly 从最终二进制文件中排除 IDFA
- mongodb - 如何将子文档复制到同一个文档中
- java - Java - 总和变量
- python - 为什么我的逻辑回归预测为 0 或 1