function to export soundwave to wav file

This commit is contained in:
Respirant
2021-01-10 16:59:27 +03:00
parent eedf8e91b3
commit 14469d959f
3 changed files with 57 additions and 1 deletions
@@ -14,7 +14,7 @@
"IsBetaVersion": false,
"IsExperimentalVersion": false,
"Installed": true,
"EngineVersion": "4.26.0",
"EngineVersion": "4.24.0",
"Modules": [
{
"Name": "RuntimeAudioImporter",
@@ -77,6 +77,50 @@ void unreal_free(void* p, void* pUserData)
FMemory::Free(p);
}
bool URuntimeAudioImporterLibrary::ExportSoundWaveToFile(USoundWave* SoundWaveToExport, FString PathToExport, bool Faster)
{
uint8* PCMData = SoundWaveToExport->RawPCMData;
size_t PCMDataSize = SoundWaveToExport->RawPCMDataSize;
uint32 SampleRate;
uint16 ChannelCount;
drwav_allocation_callbacks allocationCallbacksDecoding;
allocationCallbacksDecoding.pUserData = NULL;
allocationCallbacksDecoding.onMalloc = unreal_malloc;
allocationCallbacksDecoding.onRealloc = unreal_realloc;
allocationCallbacksDecoding.onFree = unreal_free;
drwav_uint64 framesToWrite = PCMDataSize / sizeof(DR_WAVE_FORMAT_PCM) / SoundWaveToExport->NumChannels;
if (Faster) {
ChannelCount = SoundWaveToExport->NumChannels;
SampleRate = FGenericPlatformMath::RoundToInt((framesToWrite / (float)SoundWaveToExport->GetDuration() * ChannelCount));
}
else {
TArray<uint8> NeedlessPCMData; //Needless PCMData array, but without it, it is not possible to get SampleRate
SoundWaveToExport->GetImportedSoundWaveData(*&NeedlessPCMData, *&SampleRate, *&ChannelCount);
NeedlessPCMData.Empty();
}
drwav wavEncode;
drwav_data_format format;
format.container = drwav_container_riff;
format.format = DR_WAVE_FORMAT_PCM;
format.channels = ChannelCount;
format.sampleRate = SampleRate;
format.bitsPerSample = 16;
if (!drwav_init_file_write(&wavEncode, TCHAR_TO_UTF8(*PathToExport), &format, &allocationCallbacksDecoding)) {
return false;
}
drwav_write_pcm_frames(&wavEncode, framesToWrite, PCMData);
drwav_uninit(&wavEncode);
return true;
}
URuntimeAudioImporterLibrary* URuntimeAudioImporterLibrary::GetUSoundWaveFromAudioFile_Internal(const FString& filePath, TEnumAsByte < AudioFormat > Format, bool DefineFormatAutomatically)
{
TEnumAsByte < TranscodingStatus > Status;
@@ -101,6 +101,18 @@ public:
UFUNCTION(BlueprintCallable, meta = (Keywords = "MP3, FLAC, WAV, Destroy"), Category = "RuntimeAudioImporter")
static bool DestroySoundWave(USoundWave * ReadySoundWave);
/**
* Export (save) SoundWave object to .WAV audio file to device memory. So far beta and it is not recommended to use due to the fact that the engine can clear the sound data itself
*
* @param SoundWaveToExport SoundWave object need to be exported
* @param PathToExport Path where to save audio file
* @param Faster Get SampleRate faster. Less clear, but fast. The difference is very insignificant, True is recommended
* @return Whether the save was successfull or not
* @warning It is very important that USoundWave should not used by the engine so that it can be read from physical memory.
*/
UFUNCTION(BlueprintCallable, meta = (Keywords = "Exporter, Export, Save, Runtime, WAV"), Category = "RuntimeAudioImporter")
static bool ExportSoundWaveToFile(USoundWave * SoundWaveToExport, FString PathToExport, bool Faster = true);
private:
/**
* Internal main audio transcoding function