Advertisement
Guest User

Untitled

a guest
May 21st, 2018
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.15 KB | None | 0 0
  1. // Fill out your copyright notice in the Description page of Project Settings.
  2.  
  3. #include <AudioActor.h>
  4. #include <Sound/SoundWave.h>
  5. #include <Sound/SoundCue.h>
  6. #include <ConstructorHelpers.h>
  7. #include <WaveFileManager.h>
  8. #include <Runtime/Engine/Classes/Components/AudioComponent.h>
  9. #include <Runtime/Engine/Public/AudioDecompress.h>
  10. #include <Engine.h>
  11. #include <AudioDevice.h>
  12.  
  13.  
  14. struct AudioBuffer
  15. {
  16. float StartTime;
  17. float EndTime;
  18. USoundWave *Wave;
  19. };
  20.  
  21. // Get wave duration
  22. // if( Endtime - starttime < Wave.Duration ) {
  23. // duration - FullSize
  24. // actualduration - desiredsize
  25. // DesiredSize = FullSize * (EndTime- Starttime) / Wave.Duration;
  26. // }
  27. // else {
  28. // DesiredSize = Wave.PCMDataSize;
  29. // }
  30.  
  31.  
  32. // Sets default values
  33. AAudioActor::AAudioActor()
  34. {
  35. // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
  36. PrimaryActorTick.bCanEverTick = true;
  37.  
  38. // Initializing AudioComponent
  39. //AudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("AudioComponent"));
  40. //AudioComp1 = CreateDefaultSubobject<UAudioComponent>(TEXT("AudioComp1"));
  41. //AudioComp2 = CreateDefaultSubobject<UAudioComponent>(TEXT("AudioComp2"));
  42.  
  43. //AudioComp1Wave = CreateDefaultSubobject<USoundWave>(TEXT("AudioComp1Wave"));
  44. //AudioComp2Wave = CreateDefaultSubobject<USoundWave>(TEXT("AudioComp2Wave"));
  45.  
  46. //Wave = CreateDefaultSubobject<USoundWave>(TEXT("SoundWave"));
  47.  
  48.  
  49. //UE_LOG(LogTemp,Warning,TEXT("Size of SoundCue list : %d"), SoundCueList.Num());
  50.  
  51. // on audio playback start
  52. // set starttime
  53. // on audio playback end
  54. // set endtime
  55. // calc actual played duration , if its less then sound duration, set Played RawPCMDataSize to ActualDuration * RaWPCMDataSize / Duration
  56.  
  57. // Fill main buffer with given amount of RawPCMdataSize
  58.  
  59. // keeping all soundcues links
  60. // assigning for every audio component its callback delegates
  61. // every delegate decompresses soundcue => pcm data buffer
  62.  
  63.  
  64. //ConstructorHelpers::FObjectFinder<USoundWave> SoundWave(TEXT("SoundWave'/Game/FirstPerson/Audio/test.test'"));
  65. //ConstructorHelpers::FObjectFinder<USoundCue> FireSoundCue(TEXT("SoundCue'/Game/FirstPerson/Audio/FireCue.FireCue'"));
  66. //ConstructorHelpers::FObjectFinder<USoundCue> TestSoundCue(TEXT("SoundCue'/Game/FirstPerson/Audio/TestCue.TestCue'"));
  67.  
  68. //if (TestSoundCue.Succeeded())
  69. //{
  70. // AudioComp1->SetSound(TestSoundCue.Object);
  71. //}
  72.  
  73. //if (FireSoundCue.Succeeded())
  74. //{
  75. // AudioComp2->SetSound(FireSoundCue.Object);
  76. //}
  77.  
  78. }
  79.  
  80. // Called when the game starts or when spawned
  81. void AAudioActor::BeginPlay()
  82. {
  83. Super::BeginPlay();
  84.  
  85. init();
  86.  
  87. // First we should register delegate
  88. //AudioComp1->OnAudioPlaybackPercent.AddDynamic(this, &AAudioActor::DelegeteCallback1);
  89. //AudioComp2->OnAudioPlaybackPercent.AddDynamic(this, &AAudioActor::DelegeteCallback2);
  90. //AudioComp1->OnAudioFinished.AddDynamic(this, &AAudioActor::DelegateFinished1);
  91. //AudioComp2->OnAudioFinished.AddDynamic(this, &AAudioActor::DelegateFinished2);
  92.  
  93. //// Starting audio component playing
  94. //AudioComp1->Play();
  95. //AudioComp2->Play();
  96.  
  97. //// initializing timer
  98. //if (GetWorld())
  99. //{
  100. // StartTimeSeconds = UGameplayStatics::GetRealTimeSeconds(GetWorld());
  101. //}
  102. }
  103.  
  104. void AAudioActor::EndPlay(const EEndPlayReason::Type EndPlayReason)
  105. {
  106. //if (GetWorld())
  107. //{
  108. // EndTimeSeconds = UGameplayStatics::GetRealTimeSeconds(GetWorld());
  109. //}
  110.  
  111. //UE_LOG(LogTemp, Warning, TEXT("Time last: %f"), EndTimeSeconds - StartTimeSeconds);
  112. //TArray<uint8> Tmp1;
  113. //TArray<uint8> Tmp2;
  114.  
  115. ////if (AudioComp1Wave->RawPCMData)
  116. ////{
  117. //// Tmp1.Append(AudioComp1Wave->RawPCMData, AudioComp1Wave->RawPCMDataSize);
  118. //// Tmp2.Append(AudioComp1Wave->RawPCMData, AudioComp1Wave->RawPCMDataSize);
  119. //// //RawPCMBuffer.Append(AudioComp1Wave->RawPCMData, AudioComp1Wave->RawPCMDataSize);
  120. //// UE_LOG(LogTemp, Warning, TEXT("Audio Wave 1 loaded"));
  121. //// UE_LOG(LogTemp, Warning, TEXT("Audio Wave 1 Size: %d"), AudioComp1Wave->RawPCMDataSize);
  122. ////}
  123.  
  124. //if (AudioComp2Wave->RawPCMData)
  125. //{
  126. // Tmp1.Append(AudioComp2Wave->RawPCMData, AudioComp2Wave->RawPCMDataSize);
  127. // Tmp1.AddZeroed(1000);
  128. // Tmp1.Append(AudioComp2Wave->RawPCMData, AudioComp2Wave->RawPCMDataSize);
  129. // //RawPCMBuffer.Append(AudioComp2Wave->RawPCMData, AudioComp2Wave->RawPCMDataSize);
  130. // UE_LOG(LogTemp, Warning, TEXT("Audio Wave 2 loaded"));
  131. // UE_LOG(LogTemp, Warning, TEXT("Audio Wave 2 Size: %d"), AudioComp2Wave->RawPCMDataSize);
  132. //}
  133.  
  134.  
  135. //// mixing buffers
  136. //int32 range = FMath::Min(Tmp1.Num(), Tmp2.Num());
  137. //
  138. //for (int i = 0; i < Tmp1.Num(); ++i)
  139. //{
  140. // //uint8 MixedVal = MixSamples(Tmp1[i], Tmp2[i]);
  141. // //UE_LOG(LogTemp, Warning, TEXT("Val1: %hi , Val2: %hi , => Mixed: %hi"), Tmp1[i], Tmp2[i], MixedVal);
  142. // MainBuffer.Add(Tmp1[i]);
  143. //}
  144.  
  145. ////int32 range_max = FMath::Max(Tmp1.Num(), Tmp2.Num());
  146.  
  147. ////TArray<uint8>& Working = Tmp1.Num() > Tmp2.Num() ? Tmp1 : Tmp2;
  148. ////for (int i = range; i < range_max; ++i)
  149. ////{
  150. //// MainBuffer.Add(Working[i]);
  151. ////}
  152.  
  153. //WaveFileManager WFManager;
  154. //uint8* Data = (uint8*)MainBuffer.GetData();
  155. //TArray<uint8> rr;
  156. //WFManager.Serialize(rr,Data, MainBuffer.Num());
  157.  
  158.  
  159.  
  160. }
  161.  
  162. // Called every frame
  163. void AAudioActor::Tick(float DeltaTime)
  164. {
  165. Super::Tick(DeltaTime);
  166. }
  167.  
  168.  
  169. void AAudioActor::DelegeteCallback1(const class USoundWave* PlayingSoundWave, const float PlaybackPercent)
  170. {
  171. UE_LOG(LogTemp, Warning, TEXT("Audio Wave callback1"));
  172.  
  173. if (PlayingSoundWave)
  174. {
  175. AudioComp1Wave = const_cast<USoundWave*>(PlayingSoundWave);
  176.  
  177. if (PlayingSoundWave->RawPCMData == NULL)
  178. {
  179. FAudioDevice* AudioDevice = GEngine->GetMainAudioDevice();
  180. if (AudioDevice)
  181. {
  182. EDecompressionType DecompressionType = AudioComp1Wave->DecompressionType;
  183. AudioComp1Wave->DecompressionType = DTYPE_Native;
  184.  
  185. FName AudioResourceFormat = AudioDevice->GetRuntimeFormat(AudioComp1Wave);
  186. if (
  187. AudioComp1Wave->InitAudioResource(AudioResourceFormat) &&
  188. (AudioComp1Wave->DecompressionType != DTYPE_RealTime || AudioComp1Wave->CachedRealtimeFirstBuffer == nullptr)
  189. )
  190. {
  191. FAsyncAudioDecompress TempDecompressor(AudioComp1Wave);
  192. TempDecompressor.StartSynchronousTask();
  193. }
  194.  
  195. AudioComp1Wave->DecompressionType = DecompressionType;
  196. }
  197. }
  198. }
  199. }
  200.  
  201. void AAudioActor::DelegeteCallback2(const USoundWave * PlayingSoundWave, const float PlaybackPercent)
  202. {
  203. UE_LOG(LogTemp, Warning, TEXT("Audio Wave callback2"));
  204.  
  205. if (PlayingSoundWave)
  206. {
  207. AudioComp2Wave = const_cast<USoundWave*>(PlayingSoundWave);
  208.  
  209. if (PlayingSoundWave->RawPCMData == NULL)
  210. {
  211. FAudioDevice* AudioDevice = GEngine->GetMainAudioDevice();
  212. if (AudioDevice)
  213. {
  214. EDecompressionType DecompressionType = AudioComp2Wave->DecompressionType;
  215. AudioComp2Wave->DecompressionType = DTYPE_Native;
  216.  
  217. FName AudioResourceFormat = AudioDevice->GetRuntimeFormat(AudioComp1Wave);
  218. if (
  219. AudioComp2Wave->InitAudioResource(AudioResourceFormat) &&
  220. (AudioComp2Wave->DecompressionType != DTYPE_RealTime || AudioComp2Wave->CachedRealtimeFirstBuffer == nullptr)
  221. )
  222. {
  223. FAsyncAudioDecompress TempDecompressor(AudioComp2Wave);
  224. TempDecompressor.StartSynchronousTask();
  225. }
  226.  
  227. AudioComp2Wave->DecompressionType = DecompressionType;
  228. }
  229. }
  230. }
  231. }
  232.  
  233. void AAudioActor::PlayBackDelegate(const USoundWave * PlayingSoundWave, const float PlayBackPercent)
  234. {
  235. // On every audio playback start fix the global start time of audio
  236. // on finish fix global end time of audio
  237.  
  238. USoundWave* TmpWave = const_cast<USoundWave *>(PlayingSoundWave);
  239.  
  240. DecodeSoundWave(TmpWave);
  241.  
  242. if (TmpWave->RawPCMData)
  243. {
  244. UE_LOG(LogTemp, Warning, TEXT("Wave File already decoded"));
  245. MainBuffer.Append(TmpWave->RawPCMData, TmpWave->RawPCMDataSize);
  246. if (GetWorld())
  247. {
  248. float CurrentTime = UGameplayStatics::GetRealTimeSeconds(GetWorld());
  249. }
  250. }
  251.  
  252. }
  253.  
  254. void AAudioActor::PlayBackFinishedDelegate()
  255. {
  256. UE_LOG(LogTemp, Warning, TEXT("Sound finished playing"));
  257. }
  258.  
  259. void AAudioActor::DelegateFinished1()
  260. {
  261. if (AudioComp1Wave->RawPCMData)
  262. {
  263. UE_LOG(LogTemp, Warning, TEXT("1"));
  264. MainBuffer.Append(AudioComp1Wave->RawPCMData, AudioComp1Wave->RawPCMDataSize);
  265. }
  266. }
  267.  
  268. void AAudioActor::DelegateFinished2()
  269. {
  270. if (AudioComp2Wave->RawPCMData)
  271. {
  272. UE_LOG(LogTemp, Warning, TEXT("2"));
  273. MainBuffer.Append(AudioComp2Wave->RawPCMData, AudioComp2Wave->RawPCMDataSize);
  274. }
  275. }
  276.  
  277. // Mixing 2 audio buffers
  278. void AAudioActor::MixBuffers(USoundWave* Buf1, int32 Buf1Size, USoundWave* Buf2, int32 Buf2Size)
  279. {
  280. UE_LOG(LogTemp, Warning, TEXT("%d"), Buf1Size);
  281. UE_LOG(LogTemp, Warning, TEXT("%d"), Buf2Size);
  282. }
  283.  
  284. void AAudioActor::DelegateCallback(const class USoundWave* PlayingSoundWave, const float PlaybackPercent)
  285. {
  286.  
  287. // if we already have data filled => do nothing
  288. if (RecordedDataSize != 0)
  289. {
  290. return;
  291. }
  292.  
  293.  
  294. if (PlayingSoundWave)
  295. {
  296. Wave = const_cast<USoundWave*>(PlayingSoundWave);
  297.  
  298. if (PlayingSoundWave->RawPCMData == NULL)
  299. {
  300. FAudioDevice* AudioDevice = GEngine->GetMainAudioDevice();
  301. if (AudioDevice)
  302. {
  303. EDecompressionType DecompressionType = Wave->DecompressionType;
  304. Wave->DecompressionType = DTYPE_Native;
  305.  
  306. FName AudioResourceFormat = AudioDevice->GetRuntimeFormat(Wave);
  307. if (
  308. Wave->InitAudioResource(AudioResourceFormat) &&
  309. (Wave->DecompressionType != DTYPE_RealTime || Wave->CachedRealtimeFirstBuffer == nullptr)
  310. )
  311. {
  312. FAsyncAudioDecompress TempDecompressor(Wave);
  313. TempDecompressor.StartSynchronousTask();
  314. }
  315.  
  316. Wave->DecompressionType = DecompressionType;
  317. }
  318. }
  319. }
  320. }
  321.  
  322. uint8 AAudioActor::MixSamples(uint8 Sample1, uint8 Sample2)
  323. {
  324. //int Remaped1 = remap_range(Sample1, 0, 255, -1, 1);
  325. //int Remaped2 = remap_range(Sample2, 0, 255, -1, 1);
  326.  
  327. //float mixed = 0;
  328.  
  329. //if (Remaped1 < 0.5 && Remaped1 < 0.5)
  330. //{
  331. // mixed = Remaped1 * Remaped2;
  332. // return remap_range(mixed, -1, 1, 0, 255);
  333. //}
  334.  
  335. //mixed = 2 * (Remaped1 + Remaped2) - 2 * Remaped1 * Remaped2 - 1;
  336. //return remap_range(mixed, -1, 1, 0 , 255);
  337.  
  338. // Best of all version
  339. return Sample1 + Sample2 - (Sample1 * Sample2) / 65536;
  340. }
  341.  
  342.  
  343. // Registers all delegates on every SoundCue in list
  344. void AAudioActor::init()
  345. {
  346. // TODO shitty hack for not include same audio components multiple times
  347. // UE4 calls this method multiple times dunno why
  348. if (AudioComponents.Num() == SoundCueList.Num())
  349. {
  350. return;
  351. }
  352.  
  353. for (const auto &Cue : SoundCueList)
  354. {
  355. // Getting SoundCue name and setting them for AudioComponents
  356. FString CueName = Cue->GetName();
  357. FName AudioCompName(*CueName);
  358.  
  359. // create AudioComponent
  360. auto NewAudioComponent = NewObject<UAudioComponent>(this, AudioCompName);
  361.  
  362. // create SoundWave
  363. auto NewSoundWave = NewObject<USoundWave>(this, TEXT("SoundWave"));
  364.  
  365. if (NewAudioComponent && NewSoundWave)
  366. {
  367. NewAudioComponent->SetSound(Cue);
  368. AudioComponents.Add(NewAudioComponent);
  369. SoundWaves.Add(NewSoundWave);
  370. }
  371. }
  372.  
  373. UE_LOG(LogTemp, Warning, TEXT("Size of AudioComponent: %d"), AudioComponents.Num());
  374. UE_LOG(LogTemp, Warning, TEXT("Size of SoundWaves: %d"), SoundWaves.Num());
  375.  
  376. // for every audio component we should register delegate
  377.  
  378. for (const auto &Comp : AudioComponents)
  379. {
  380. Comp->OnAudioPlaybackPercent.AddDynamic(this, &AAudioActor::PlayBackDelegate);
  381. Comp->OnAudioFinished.AddDynamic(this, &AAudioActor::PlayBackFinishedDelegate);
  382. Comp->Play();
  383. }
  384.  
  385. }
  386.  
  387. float AAudioActor::remap_range(int val, int in_min, int in_max, int out_min, int out_max)
  388. {
  389. return (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  390. }
  391.  
  392. // Handles SoundWave decompression
  393. void AAudioActor::DecodeSoundWave(USoundWave * PlayingSoundWave)
  394. {
  395. if (PlayingSoundWave->RawPCMData == NULL)
  396. {
  397. UE_LOG(LogTemp, Warning, TEXT("Sound Wave: %s decoded successfully."), *PlayingSoundWave->GetName());
  398. FAudioDevice* AudioDevice = GEngine->GetMainAudioDevice();
  399. if (AudioDevice)
  400. {
  401. EDecompressionType DecompressionType = PlayingSoundWave->DecompressionType;
  402. PlayingSoundWave->DecompressionType = DTYPE_Native;
  403.  
  404. FName AudioResourceFormat = AudioDevice->GetRuntimeFormat(PlayingSoundWave);
  405. if (
  406. PlayingSoundWave->InitAudioResource(AudioResourceFormat) &&
  407. (PlayingSoundWave->DecompressionType != DTYPE_RealTime || PlayingSoundWave->CachedRealtimeFirstBuffer == nullptr)
  408. )
  409. {
  410. FAsyncAudioDecompress TempDecompressor(PlayingSoundWave);
  411. TempDecompressor.StartSynchronousTask();
  412. }
  413.  
  414. PlayingSoundWave->DecompressionType = DecompressionType;
  415.  
  416. }
  417. }
  418. }
  419.  
  420. // keep all level sounds in array
  421. // decode all sounds
  422. // on any sound start keep start time and end time
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement