XnStatus XnSharedMemoryBufferPool::AllocateBuffers() { XnStatus nRetVal = XN_STATUS_OK; if (m_nBufferSize > m_nMaxBufferSize) { return XN_STATUS_ALLOC_FAILED; } if (m_pSharedMemoryAddress != NULL) { // already allocated. nothing to do here return (XN_STATUS_OK); } // first time. allocate shared memory XnUInt32 nTotalSize = m_nMaxBufferSize * m_nBufferCount; nRetVal = xnOSCreateSharedMemory(m_strName, nTotalSize, XN_OS_FILE_READ | XN_OS_FILE_WRITE, &m_hSharedMemory); XN_IS_STATUS_OK(nRetVal); void* pAddress; nRetVal = xnOSSharedMemoryGetAddress(m_hSharedMemory, &pAddress); if (nRetVal != XN_STATUS_OK) { xnOSCloseSharedMemory(m_hSharedMemory); m_hSharedMemory = NULL; return (nRetVal); } m_pSharedMemoryAddress = (XnUChar*)pAddress; // now allocate buffers for (XnUInt32 i = 0; i < m_nBufferCount; ++i) { XnBufferInPool* pBuffer = XN_NEW(XnBufferInPool); if (pBuffer == NULL) { Free(); return (XN_STATUS_ALLOC_FAILED); } pBuffer->m_nID = i; pBuffer->SetExternalBuffer(m_pSharedMemoryAddress + i*m_nMaxBufferSize, m_nMaxBufferSize); xnDumpWriteString(Dump(), "Allocated buffer %u with size %u\n", i, m_nMaxBufferSize); // add it to free list m_AllBuffers.AddLast(pBuffer); m_FreeBuffers.AddLast(pBuffer); } return (XN_STATUS_OK); }
XnStatus XnSensorAudioStream::ReallocBuffer() { XnStatus nRetVal = XN_STATUS_OK; XnDevicePrivateData* pDevicePrivateData = m_Helper.GetPrivateData(); if (m_hSharedMemory == NULL) { // first time, create shared memory // we allocate enough for 5 seconds of audio XnUInt32 nSampleSize = 2 * 2; // 16-bit per channel (2 bytes) * max number of channels (2) XnUInt32 nSamples = 48000 * 5; // max sample rate * number of seconds XnUInt32 nMaxBufferSize = nSamples * nSampleSize; // find min packet size (so we'll have max packet count) XnUInt32 nMinPacketSize = XN_MIN(XN_SENSOR_PROTOCOL_AUDIO_PACKET_SIZE_BULK, XN_SENSOR_PROTOCOL_AUDIO_PACKET_SIZE_ISO); XnUInt32 nMaxPacketCount = nMaxBufferSize / nMinPacketSize - 1; XnUInt32 nSharedBufferSize = sizeof(XnAudioSharedBuffer) + // header sizeof(XnUInt64) * nMaxPacketCount + // packet timestamps nMaxBufferSize; // to make the name unique, we'll add process ID XN_PROCESS_ID procID; xnOSGetCurrentProcessID(&procID); XnChar strSharedName[XN_DEVICE_MAX_STRING_LENGTH]; sprintf(strSharedName, "%u_%s_%s", procID, m_strDeviceName, GetName()); nRetVal = m_SharedBufferName.UnsafeUpdateValue(strSharedName); XN_IS_STATUS_OK(nRetVal); nRetVal = RequiredSizeProperty().UnsafeUpdateValue(nMaxBufferSize); XN_IS_STATUS_OK(nRetVal); nRetVal = xnOSCreateSharedMemory(strSharedName, nSharedBufferSize, XN_OS_FILE_READ | XN_OS_FILE_WRITE, &m_hSharedMemory); XN_IS_STATUS_OK(nRetVal); XnUChar* pAddress; nRetVal = xnOSSharedMemoryGetAddress(m_hSharedMemory, (void**)&pAddress); XN_IS_STATUS_OK(nRetVal); m_pSharedHeader = (XnAudioSharedBuffer*)pAddress; pDevicePrivateData->pAudioPacketsTimestamps = (XnUInt64*)(pAddress + sizeof(XnAudioSharedBuffer)); pDevicePrivateData->pAudioBuffer = (XN_AUDIO_TYPE*)(pAddress + sizeof(XnAudioSharedBuffer) + sizeof(XnUInt64) * nMaxPacketCount); pDevicePrivateData->nAudioBufferSize = nMaxBufferSize; m_pSharedHeader->nTimestampsListOffset = sizeof(XnAudioSharedBuffer); m_pSharedHeader->nBufferOffset = pDevicePrivateData->pAudioBuffer - pAddress; } // calculate current packet size pDevicePrivateData->nAudioPacketSize = m_nOrigAudioPacketSize; if (m_Helper.GetFirmwareVersion() >= XN_SENSOR_FW_VER_5_2 && GetNumberOfChannels() == 1) { pDevicePrivateData->nAudioPacketSize /= 2; } pDevicePrivateData->nAudioBufferNumOfPackets = pDevicePrivateData->nAudioBufferSize / pDevicePrivateData->nAudioPacketSize; pDevicePrivateData->nAudioBufferSize = pDevicePrivateData->nAudioBufferNumOfPackets * pDevicePrivateData->nAudioPacketSize; m_pSharedHeader->nPacketCount = pDevicePrivateData->nAudioBufferNumOfPackets; m_pSharedHeader->nPacketSize = pDevicePrivateData->nAudioPacketSize; // set read and write indices pDevicePrivateData->nAudioReadIndex = 0; pDevicePrivateData->nAudioWriteIndex = 0; return (XN_STATUS_OK); }