A modded EditSaber for making beat saber maps.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
3.0 KiB

  1. // Fill out your copyright notice in the Description page of Project Settings.
  2. #include "eXiSoundVisPrivatePCH.h"
  3. #include "AudioDecompressWorker.h"
  4. #include "SoundVisComponent.h"
  5. #include "AudioDevice.h"
  6. #include "Developer/TargetPlatform/Public/Interfaces/IAudioFormat.h"
  7. FAudioDecompressWorker* FAudioDecompressWorker::Runnable = NULL;
  8. int32 FAudioDecompressWorker::ThreadCounter = 0;
  9. FAudioDecompressWorker::FAudioDecompressWorker(class USoundWave* InSoundWaveRef)
  10. : SoundWaveRef(InSoundWaveRef)
  11. , AudioInfo(NULL)
  12. , Thread(NULL)
  13. {
  14. if (GEngine && GEngine->GetMainAudioDevice())
  15. {
  16. AudioInfo = GEngine->GetMainAudioDevice()->CreateCompressedAudioInfo(SoundWaveRef);
  17. }
  18. // Higher overall ThreadCounter to avoid duplicated names
  19. FAudioDecompressWorker::ThreadCounter++;
  20. Thread = FRunnableThread::Create(this, *FString::Printf(TEXT("FAudioDecompressWorker%d"), FAudioDecompressWorker::ThreadCounter), 0, EThreadPriority::TPri_Normal);
  21. }
  22. FAudioDecompressWorker::~FAudioDecompressWorker()
  23. {
  24. delete Thread;
  25. Thread = NULL;
  26. }
  27. FAudioDecompressWorker* FAudioDecompressWorker::InitializeWorker(class USoundWave* InSoundWaveRef)
  28. {
  29. Runnable = new FAudioDecompressWorker(InSoundWaveRef);
  30. return Runnable;
  31. }
  32. void FAudioDecompressWorker::ShutdownWorker()
  33. {
  34. if (Runnable)
  35. {
  36. Runnable->EnsureCompletion();
  37. delete Runnable;
  38. Runnable = NULL;
  39. }
  40. }
  41. bool FAudioDecompressWorker::Init()
  42. {
  43. // Make sure the Worker is marked is not finished
  44. bIsFinished = false;
  45. return true;
  46. }
  47. uint32 FAudioDecompressWorker::Run()
  48. {
  49. if (!SoundWaveRef)
  50. {
  51. return 0;
  52. }
  53. if (AudioInfo != NULL)
  54. {
  55. try {
  56. FSoundQualityInfo QualityInfo = { 0 };
  57. // Parse the audio header for the relevant information
  58. if (!(SoundWaveRef->ResourceData))
  59. {
  60. return 0;
  61. }
  62. if (AudioInfo->ReadCompressedInfo(SoundWaveRef->ResourceData, SoundWaveRef->ResourceSize, &QualityInfo))
  63. {
  64. FScopeCycleCounterUObject WaveObject(SoundWaveRef);
  65. // Extract the data
  66. SoundWaveRef->SampleRate = QualityInfo.SampleRate;
  67. SoundWaveRef->NumChannels = QualityInfo.NumChannels;
  68. if (QualityInfo.Duration > 0.0f)
  69. {
  70. SoundWaveRef->Duration = QualityInfo.Duration;
  71. }
  72. const uint32 PCMBufferSize = SoundWaveRef->Duration * SoundWaveRef->SampleRate * SoundWaveRef->NumChannels;
  73. SoundWaveRef->CachedRealtimeFirstBuffer = new uint8[PCMBufferSize * 2];
  74. AudioInfo->SeekToTime(0.0f);
  75. AudioInfo->ReadCompressedData(SoundWaveRef->CachedRealtimeFirstBuffer, false, PCMBufferSize * 2);
  76. }
  77. else if (SoundWaveRef->DecompressionType == DTYPE_RealTime || SoundWaveRef->DecompressionType == DTYPE_Native)
  78. {
  79. SoundWaveRef->RemoveAudioResource();
  80. }
  81. } catch (const std::exception&) {
  82. // Yo, bad things happened
  83. }
  84. delete AudioInfo;
  85. }
  86. return 0;
  87. }
  88. void FAudioDecompressWorker::Stop()
  89. {
  90. StopTaskCounter.Increment();
  91. }
  92. void FAudioDecompressWorker::Exit()
  93. {
  94. // Make sure to mark Thread as finished
  95. bIsFinished = true;
  96. }
  97. void FAudioDecompressWorker::EnsureCompletion()
  98. {
  99. Stop();
  100. if (Thread != NULL) {
  101. Thread->WaitForCompletion();
  102. }
  103. }