I am having some issues with the following function. I originally found this function on a post from Frisco, and decided to try and debug the same problem, but I have come up empty.
THE FUNCTION: I am trying to load a .wav file into a USoundWave file at runtime. The user should click a button, select a file from the file dialog, and the audio should be loaded in to the application. The user should be able to play and stop the audio at will.
WHAT SHOULD HAPPEN:
1) A function loads in a raw audio file (wav) in the form of a raw TArray<uint8> byte data.
2) This data is passed to the function from another function I have that loads the data from an absolute file path using TinyFileDialogs (https://github.com/native-toolkit/tinyfiledialogs).
3) From there, the data is parsed with this function, and returns the WAV file loaded into a new USoundWave.
4) AFTER this function, the USoundWave reference is pushed to another component that handles playing the audio.
5) The audio is played from an audio player component when the user inputs the proper input
THE ISSUES:
1) The file is loading, the data is being passed in, and the audio will even play at runtime..... in the PIE.
2) When the audio does get loaded in, the first time the audio is attempted to be played, the whole application hangs for a few seconds (assuming this is while the audio is being decompressed)
3) When I package the build, the audio doesn't play. The settings for the SoundWave inside the function are being set (after debugging) but the audio is either not being set to the local variable of the AudioPlayer or there are issues with the actual loading the of the .wav file.

***Take note that the audio is played on a separate component. Here you can see the audio is saved to a USoundWave reference in the settings manager, and the audio manager component pulls from the settings manager to play the audio.***
Code from the "Open File Dialog" function
Code from the "Return Raw Binary Data" function
Code from the "Get Sound Wave from Raw Data" function
THE FUNCTION: I am trying to load a .wav file into a USoundWave file at runtime. The user should click a button, select a file from the file dialog, and the audio should be loaded in to the application. The user should be able to play and stop the audio at will.
WHAT SHOULD HAPPEN:
1) A function loads in a raw audio file (wav) in the form of a raw TArray<uint8> byte data.
2) This data is passed to the function from another function I have that loads the data from an absolute file path using TinyFileDialogs (https://github.com/native-toolkit/tinyfiledialogs).
3) From there, the data is parsed with this function, and returns the WAV file loaded into a new USoundWave.
4) AFTER this function, the USoundWave reference is pushed to another component that handles playing the audio.
5) The audio is played from an audio player component when the user inputs the proper input
THE ISSUES:
1) The file is loading, the data is being passed in, and the audio will even play at runtime..... in the PIE.
2) When the audio does get loaded in, the first time the audio is attempted to be played, the whole application hangs for a few seconds (assuming this is while the audio is being decompressed)
3) When I package the build, the audio doesn't play. The settings for the SoundWave inside the function are being set (after debugging) but the audio is either not being set to the local variable of the AudioPlayer or there are issues with the actual loading the of the .wav file.
***Take note that the audio is played on a separate component. Here you can see the audio is saved to a USoundWave reference in the settings manager, and the audio manager component pulls from the settings manager to play the audio.***
Code from the "Open File Dialog" function
Code:
FString UFileDialogLibrary::openFileDialog() { //creates the char const for saving the file char const* lTheOpenFileName; //the filepath to be returned at end of function FString filePath; //the types of file filters that can be passed in char const* lFilterPatterns[1] = { "*.trf", }; //open the open file dialog lTheOpenFileName = tinyfd_openFileDialog( "Open File", "", 1, lFilterPatterns, NULL, 0); //sets filePath to the returned filePath in order to change data with the FString filePath = (FString)lTheOpenFileName; //removes the backslash and replaces it with the OS independent forward slash for (int x = 0; x < (int)filePath.Len(); x++) { if (filePath[x] == '\\') { filePath[x] = '/'; } } //returns the SAFE filePath with corrected slashes return filePath; }
Code from the "Return Raw Binary Data" function
Code:
TArray<uint8> UFileDialogLibrary::returnRawBinaryData(FString filePath) { /* --------------------------------- READING THE OBJECT FROM BINARY --------------------------------- */ TArray<uint8> dataArray; //creates a placeholder bytes array FFileHelper::LoadFileToArray(dataArray, *filePath); //loads serialized data into byte array FMemoryReader memoryReader = FMemoryReader(dataArray, true); //creates a memory reader object that reads from the dataArray return dataArray; }
Code from the "Get Sound Wave from Raw Data" function
Code:
USoundWave* UImportAudioToSoundWave::GetSoundWaveFromRawData(TArray<uint8> Bytes) { USoundWave* sw = NewObject<USoundWave>(USoundWave::StaticClass()); //creates a placeholder SoundWave on the stack if (!sw) { GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("NULLPTR"))); return nullptr; //checks to be sure it was created, if not return NullPtr } TArray <uint8> rawFile; //creates rawFile TArray on the stack rawFile = Bytes; //pulls passed in paramters TArray to the TArray on the stack FWaveModInfo WaveInfo; //creates new WaveInfo for the SoundWave, will be passed to it later if (WaveInfo.ReadWaveInfo(rawFile.GetData(), rawFile.Num())) { sw->InvalidateCompressedData(); //changes the GUID and flushes all the compressed data sw->RawData.Lock(LOCK_READ_WRITE); FMemory::Memcpy(sw->RawData.Realloc(rawFile.Num()), rawFile.GetData(), rawFile.Num()); sw->RawData.Unlock(); int32 DurationDiv = *WaveInfo.pChannels * *WaveInfo.pBitsPerSample * *WaveInfo.pSamplesPerSec; //calucates the duration divider const if (DurationDiv) //IF dureation div is not null { sw->Duration = *WaveInfo.pWaveDataSize * 8.0f / DurationDiv; //it sets the USOUNDWAVE.Duration to thid calculation result } else { sw->Duration = 0.0f; //otherwise, it sets the duration to 0.0f } sw->SetSampleRate(*WaveInfo.pSamplesPerSec); //sets the sample rate of the USoundWave sw->NumChannels = *WaveInfo.pChannels; //sets the number of channels of the USoundWave sw->RawPCMDataSize = WaveInfo.SampleDataSize; //sets the rawPCMDataSize of the USoundWave sw->SoundGroup = ESoundGroup::SOUNDGROUP_Default; //sets the sound group of the USoundWave } else { return nullptr; } return sw; //returns the stack allocated sound wave, and following end of function, releases it from memory?????? }
Comment