#pragma once #pragma bss_seg(".syncbss") static ID3D11Buffer* SyncBuffer; static SyncStruct_audio* Sync; #pragma data_seg(".syncBufferDesc") static D3D11_BUFFER_DESC syncBufferDesc = { sizeof(SyncStruct_audio), D3D11_USAGE_DEFAULT, D3D11_BIND_CONSTANT_BUFFER, 0, 0, 0 }; #pragma code_seg(".SyncInit") INLINE void SyncInit() { device->CreateBuffer(&syncBufferDesc, nullptr, &SyncBuffer); Sync = (SyncStruct_audio*)(syncDataAudio + 1); } #pragma code_seg(".SyncUpdate") INLINE void SyncUpdate(float t) { auto fRow = (t * SOUND_TICKS_PER_SCENE); auto iChannelCount = syncDataAudio[0]; auto pTarget = (float*)&syncDataAudio[1]; auto pChannels = (char*)(pTarget + iChannelCount); for (int iChannel = 0; iChannel < iChannelCount; ++iChannel) { auto iValueCount = *(unsigned short*)(pChannels); auto pChannelRows = (unsigned short*)(pChannels + 2); auto pChannelModes = (char*)(pChannelRows + iValueCount); auto pChannelValues = (float*)(pChannelModes + iValueCount); pChannels = (char*)(pChannelValues + iValueCount); for (int iIndex = 0; iIndex < iValueCount;) { int iRow = pChannelRows[iIndex]; int iNextRow = pChannelRows[iIndex + 1]; if (iRow <= fRow && iNextRow + 1 > fRow) { float t = (fRow - iRow) / (iNextRow - iRow + 1); switch (pChannelModes[iIndex]) { case 0: // Step t = 0.0f; break; case 1: // Linear break; case 2: // Cubic t *= t * (3 - 2 * t); break; case 3: // EaseIn t *= t; break; case 4: // EaseOut t *= -t + 2; break; } pTarget[iChannel] = (1 - t) * pChannelValues[iIndex] + t * pChannelValues[iIndex + 1]; break; } else { if (pChannelModes[iIndex] != 0) ++iIndex; pTarget[iChannel] = pChannelValues[iIndex]; ++iIndex; } } } #ifdef AUTHORING Sync = (SyncStruct_audio*)pTarget; if (SyncBuffer != NULL) SyncBuffer->Release(); syncBufferDesc.ByteWidth = iChannelCount * sizeof(float); device->CreateBuffer(&syncBufferDesc, nullptr, &SyncBuffer); if (iChannelCount != 0) #endif context->UpdateSubresource(SyncBuffer, 0, NULL, pTarget, iChannelCount * sizeof(float), sizeof(float)); }