void* thread_snd_pcm_writei(void* param) { pthread_mutex_lock(&mutex); thread_param* param_thread = (thread_param*)param; uint8_t* sndBuffer = param_thread->sndBuffer; uint8_t** sndBufferPtr = param_thread->sndBufferPtr; snd_pcm_t *pcm_handle = param_thread->pcm_handle; uint32_t* qte = param_thread->qte; pthread_mutex_unlock(&mutex); int pcm_return; while(1) { pthread_mutex_lock(&mutex_qte); int max_frames = 16384 >> 2; int frames = max_frames >> 2; if(*qte >= frames) { // DebugLogMessage("1 qte: %d, frames: %d, sndBuffer %d, sndBufferPtr %d", *qte, frames, sndBuffer, *sndBufferPtr); pcm_return = snd_pcm_writei(pcm_handle, sndBuffer, frames); if(pcm_return < frames) { snd_pcm_prepare(pcm_handle); DebugLogMessage("Underrun %d (%d)", pcm_return, frames); } (*qte) -= frames; (*sndBufferPtr) -= 1*frames*4; if((*sndBufferPtr) < sndBuffer) (*sndBufferPtr) = sndBuffer; // DebugLogMessage("2 qte: %d, frames: %d, sndBuffer %d, sndBufferPtr %d", *qte, frames, sndBuffer, *sndBufferPtr); } pthread_mutex_unlock(&mutex_qte); } /* while((pcm_return = snd_pcm_writei(pcm_handle, sndBuffer, 256)) < 0) { snd_pcm_prepare(pcm_handle); DebugLogMessage("Underrun %d", pcm_return); } */ return NULL; }
void UnityForCppTest::Update(float deltaTime) { //-------1. First part of the update code: update the position for each game object, no need to send messages //----------since the positions array is a shared array accessed directly from the C# side. //auto checkAndSolveWallCollision = [](float& pos, float dir)->bool //NOT COMPILING FOR UNITY WEBGL class Lambda { public: //the pos value for a given coordinate must not be less than -1 (for left, down directions) or more than 1 (for right, //up directions). When this happens we have a collision, returning true and flipping the exceeding position value. static inline bool checkAndSolveWallCollision(float& pos, float dir) { if (pos*dir > 1.0f) { pos = dir*(2.0f - pos*dir); return true; } return false; }; }; for (int i = 0; i < m_numberOfGameObjects; ++i) { Vec2 newPos = m_gameObjectPositions[i] + m_gameObjectVelocities[i]; //Check collisions for the left and right directions, flipping the velocity component when they happen if (Lambda::checkAndSolveWallCollision(newPos.x, -1.0f) || Lambda::checkAndSolveWallCollision(newPos.x, 1.0f)) m_gameObjectVelocities[i].x = -m_gameObjectVelocities[i].x; //Check collisions for the up and down directions, flipping the velocity component when they happen if (Lambda::checkAndSolveWallCollision(newPos.y, -1.0f) || Lambda::checkAndSolveWallCollision(newPos.y, 1.0f)) m_gameObjectVelocities[i].y = -m_gameObjectVelocities[i].y; m_gameObjectPositions[i] = newPos; //updates the position on the shared array, so the C# code can get it from here } //-------2. Second part of the update code: at each given interval perform several random operation on the game objects //---------- testing the UnityMessager class m_timeSinceStart += deltaTime; if (m_timeSinceStart - m_timeOfLastRandomUpdates > (double)m_randomUpdatesInterval) { m_timeOfLastRandomUpdates = m_timeSinceStart; for (int i = 0; i < m_numberOfGameObjects; ++i) { float randomValue = RANDOM_01; if (randomValue < 0.33) SetGameObjectRotation(i, RANDOM_NEG_POS_1*180.0f); else if (randomValue < 0.66) { if (rand() % 2 == 0) SetGameObjectColor(i, RANDOM_01, RANDOM_01, RANDOM_01); else { float color[3] = { RANDOM_01, RANDOM_01, RANDOM_01 }; SetGameObjectColor(i, color); } } //ELSE WE DO NOTHING FOR 1/3 OF THE GAME OBJECTS } } //-------3. Third part of the update code: at each given interval send random messages that result in "log to //-------- the Unity console" operations, which compromises too much the performance to happen oftenly. //-------- These random messages we are sending here perform more complex tests on parameter packing/unpacking to messages if (m_timeSinceStart - m_timeOfLastLogRelatedMessage > 1.0) //interval of 1 second hard coded here { m_timeOfLastLogRelatedMessage = m_timeSinceStart; switch (rand() % 7) { case 0: UNITY_MESSAGER.SendMessage(m_receiverId, TRM_LOG_PARAM_TYPES, 8u, 37873218932819823232.3232, 3ll, "Hey", 1.2f); break; case 1: { uint64 testArray[9] = { 829, 89873929992311, 232, 32322, 23, 87, 1, 2, 3 }; UNITY_MESSAGER.SendMessage(m_receiverId, TRM_LOG_PARAM_TYPES, UM_ARRAY_PARAM(testArray, 9), "string", 3); break; } case 2: { auto arrayToFill = UM_CREATE_ARRAY_TO_FILL_PARAM(int, 10); UNITY_MESSAGER.SendMessage(m_receiverId, TRM_LOG_PARAM_TYPES, 2.3f, "arrayToFill Test", arrayToFill, 23, "hi"); for (int i = 0; i < 10; ++i) arrayToFill[i] = i; break; } case 3: DebugLogMessage("Just test sending an string message!!"); break; case 4: { //Test a reflection based message on a component of an object find by "GameObject.Find" int iArray[5] = { 1, 2, 5, 9, 2 }; UNITY_MESSAGER.SendMessage<UnityForCppTestComp>("UnityForCppTest", "TestReflectionBasedMessage", 7, 0.2f, UM_ARRAY_PARAM(iArray, 5), "String Value", 1.1); break; } case 5: { //Test sending a message to a game object component by locating the object with "GameObject.Find", instead of using a receiverId float fArray[3] = { 1.2f, 3.1f, 9.2f }; UNITY_MESSAGER.SendMessage<UnityForCppTestComp>("UnityForCppTest", TRM_LOG_PARAM_TYPES, "String param", UM_ARRAY_PARAM(fArray, 3), 5); break; } case 6: if (m_receiverIdForReflectionTest >= 0) { //Test sending a reflection based message to a component from a game object we have instanced uint8 bArray[5] = { 1, 2, 5, 9, 2 }; UNITY_MESSAGER.SendMessage<ReceiverComponentTest>(4, "TestReflectionBasedMessage", 5, 9.1f, UM_ARRAY_PARAM(bArray, 5), "Samuel"); } break; } }
inline int AlsaAudioPlugin::update() { #if 0 if(thread) { pthread_join(*thread, NULL); free(thread); thread = NULL; } #endif #if 0 if(!thread) { pthread_mutex_lock(&mutex); param_thread.sndBuffer = sndBuffer; param_thread.sndBufferPtr = &sndBufferPtr; param_thread.qte = &qte; param_thread.pcm_handle = pcm_handle; pthread_mutex_unlock(&mutex); DebugLogMessage("Create pthread"); thread = (pthread_t*)malloc(sizeof(pthread_t)); pthread_create(thread, NULL, thread_snd_pcm_writei, (void*)¶m_thread); } pthread_mutex_lock(&mutex_qte); // if(sndBufferPtr < (sndBuffer + periodsize + 4)) { sndBufferPtr += 1*4; qte += 1; } pthread_mutex_unlock(&mutex_qte); return 0; #else const int nb = 1; sndBufferPtr += (nb*4); qte += nb; int max_frames = periodsize; // >> 2; int frames = max_frames; while(qte >= max_frames) { //DebugLogMessage("1 qte: %d, frames: %d, sndBuffer %d, sndBufferPtr %d, periodsize %d", qte, frames, sndBuffer, sndBufferPtr, periodsize); int pcm_return; pcm_return = snd_pcm_writei(pcm_handle, sndBuffer, frames); if(pcm_return < frames) { if(pcm_return == -EPIPE) { int err; if(err = snd_pcm_prepare(pcm_handle) < 0) { DebugLogMessage("Cant recover underrun (%s)", snd_strerror(err)); } else { DebugLogMessage("Underrun (%s) %d", snd_strerror(pcm_return), frames); } } else if(pcm_return < 0) { DebugLogMessage("Sound Error (%s)", snd_strerror(pcm_return)); } } //DebugLogMessage("2 qte: %d, frames: %d, sndBuffer %d, sndBufferPtr %d, periodsize %d", qte, frames, sndBuffer, sndBufferPtr, periodsize); qte -= frames; sndBufferPtr -= 1*frames*4; //DebugLogMessage("2 qte: %d, frames: %d, sndBuffer %d, sndBufferPtr %d, periodsize %d", qte, frames, sndBuffer, sndBufferPtr, periodsize); if(sndBufferPtr < sndBuffer) sndBufferPtr = sndBuffer; } return 0; #endif int pcm_return; while((pcm_return = snd_pcm_writei(pcm_handle, sndBuffer, 32)) < 0) { snd_pcm_prepare(pcm_handle); DebugLogMessage("Underrun %d", pcm_return); return 0; } return 0; // return 0; // while((pcmreturn = snd_pcm_writei(pcm_handle, sndBuffer, 1)) < 0) { // snd_pcm_prepare(pcm_handle); // ErrorLogMessage("Buffer Underrun"); // return 0; // } }