FVorbisAudioInfo access issues in Unreal Engine 4.23

Getting this error in a .cpp file trying to create an FVorbisAudioInfo object.

LogPlayLevel: C:~~~~~\Source\Turf\Private\ImportAudioToSoundWave.cpp(113): error C2065: ‘FVorbisAudioInfo’: undeclared identifier
LogPlayLevel: Error: C:~~~~~\Source\Turf\Private\ImportAudioToSoundWave.cpp(113): error C2146: syntax error: missing ‘;’ before identifier ‘vorbis_obj’
LogPlayLevel: C:~~~~~\Source\Turf\Private\ImportAudioToSoundWave.cpp(113): error C2065: ‘vorbis_obj’: undeclared identifier
LogPlayLevel: C:~~~~~~\Source\Private\ImportAudioToSoundWave.cpp(117): error C2065: ‘vorbis_obj’: undeclared identifier

What reason could there be for this error? I’ve searched everywhere and come up empty.




#include "ImportAudioToSoundWave.h"

#include "Runtime/Engine/Classes/Sound/SoundWave.h"
#include "Runtime/Engine/Public/VorbisAudioInfo.h"
#include "Developer/TargetPlatform/Public/Interfaces/IAudioFormat.h"



USoundWave* UImportAudioToSoundWave::GetSoundWaveFromRawOGGData(TArray<uint8> Bytes)
{
    TArray <uint8> rawFile;  //creates rawFile TArray on the stack
    rawFile = Bytes;  //pulls passed in paramters TArray to the TArray on the stack

    UE_LOG(LogTemp, Log, TEXT("Raw File Data Size-> %u"), rawFile.Num());


**(113)FVorbisAudioInfo vorbis_obj;**
    FSoundQualityInfo SoundQualityInfo;



**(117)if (vorbis_obj.ReadCompressedInfo(rawFile.GetData(), rawFile.Num(), &SoundQualityInfo))**
    {
        USoundWave* sw = NewObject<USoundWave>(USoundWave::StaticClass());  //creates a placeholder SoundWave on the stack
        if (!sw)
        {
            UE_LOG(LogTemp, Error, TEXT("There was a nullptr when creating the USoundWave object."));
            return nullptr;  //checks to be sure it was created, if not return NullPtr 
        }


        // Fill in all the Data we have 
        //sw->DecompressionType = EDecompressionType::DTYPE_RealTime;
        sw->SoundGroup = ESoundGroup::SOUNDGROUP_Default;
        sw->NumChannels = SoundQualityInfo.NumChannels;
        sw->Duration = SoundQualityInfo.Duration;
        sw->RawPCMDataSize = SoundQualityInfo.SampleDataSize;
        sw->SetSampleRate(SoundQualityInfo.SampleRate);



        FByteBulkData* BulkData = &sw->CompressedFormatData.GetFormat(FName("OGG")); // Get Pointer to the Compressed OGG Data
        BulkData->Lock(LOCK_READ_WRITE); // Set the Lock of the BulkData to ReadWrite
        FMemory::Memmove(BulkData->Realloc(rawFile.Num()), rawFile.GetData(), rawFile.Num()); // Copy compressed RawFile Data to the Address of the OGG Data of the SW File
        BulkData->Unlock(); // Unlock the BulkData again


        return sw;//returns the stack allocated sound wave, and following end of function, releases it from memory??????
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("There was an error reading from the Vorbis Converion Information"));
        return nullptr;  //checks to be sure it was created, if not return NullPtr 
    }
}


So after some experiments, I figured out a few things.

  1. If I don’t make a call to FVorbisAudioInfo and don’t include it in my application, I can load in WAV files through the means of RawData.Realloc() directly through the USoundWave instance. However, this will give me a different error (ONLY WHEN PACKAGING) that states

FVorbisAudioInfo::ReadCompressedInfo, ov_open_callbacks error code: -132

Here is the code I am using in my application to get this error:



USoundWave* UImportAudioToSoundWave::GetSoundWaveFromRawWavData(TArray<uint8> Bytes)
{
    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()))
    {    
        USoundWave* sw = NewObject<USoundWave>(USoundWave::StaticClass());  //creates a placeholder SoundWave on the stack
            if (!sw)
            {    
                UE_LOG(LogTemp, Error, TEXT("There was a nullptr when creating the USoundWave object."));
                return nullptr;  //checks to be sure it was created, if not return NullPtr 
            }

        int32 DurationDiv = *WaveInfo.pChannels * *WaveInfo.pBitsPerSample * *WaveInfo.pSamplesPerSec;   //calucates the duration divider const
        if (DurationDiv)  //IF dureation div is not null
        {
                //PRE Debug logs
                UE_LOG(LogTemp, Log, TEXT("SQ NumChannels-> %i"), *WaveInfo.pChannels);
                UE_LOG(LogTemp, Log, TEXT("SQ Duration-> %f"), *WaveInfo.pWaveDataSize * 8.0f / DurationDiv);
                UE_LOG(LogTemp, Log, TEXT("SQ RawPCMDataSize-> %i"), WaveInfo.SampleDataSize);
                UE_LOG(LogTemp, Log, TEXT("SQ SampleRate-> %u"), *WaveInfo.pSamplesPerSec);
            // Fill in all the Data we have
            sw->DecompressionType = EDecompressionType::DTYPE_Streaming;
            sw->SoundGroup = ESoundGroup::SOUNDGROUP_Default;
            sw->NumChannels = *WaveInfo.pChannels;
            sw->Duration = *WaveInfo.pWaveDataSize * 8.0f / DurationDiv; ;
            sw->RawPCMDataSize = WaveInfo.SampleDataSize;
            sw->SetSampleRate(*WaveInfo.pSamplesPerSec);
                //POST Debug logs
                UE_LOG(LogTemp, Log, TEXT("SW NumChannels-> %i"), sw->NumChannels);
                UE_LOG(LogTemp, Log, TEXT("SW Duration-> %f"), sw->Duration);
                UE_LOG(LogTemp, Log, TEXT("SW RawPCMDataSize-> %i"), sw->RawPCMDataSize);
                UE_LOG(LogTemp, Log, TEXT("SW SampleRate-> %f"), sw->GetSampleRateForCurrentPlatform());
        }
        else
        {
            UE_LOG(LogTemp, Error, TEXT("There was an error reading data from WaveInfo. Duration Div Error."));
            return nullptr;
        }            

        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();

        return sw;//returns the stack allocated sound wave, and following end of function, releases it from memory??????
    }
    else 
    {
        return nullptr;
    }

}


  1. I’ve narrowed down this callback to the following function in FVorbisAudioInfo.cpp



bool FVorbisAudioInfo::GetCompressedInfoCommon(void* Callbacks, FSoundQualityInfo* QualityInfo)
{
    if (!bDllLoaded)
    {
        UE_LOG(LogAudio, Error, TEXT("FVorbisAudioInfo::GetCompressedInfoCommon failed due to vorbis DLL not being loaded."));
        return false;
    }

    // Set up the read from memory variables
    int Result = ov_open_callbacks(this, &VFWrapper->vf, NULL, 0, (*(ov_callbacks*)Callbacks));
    if (Result < 0)
    {
        UE_LOG(LogAudio, Error, TEXT("FVorbisAudioInfo::ReadCompressedInfo, ov_open_callbacks error code: %d"), Result);
        return false;
    }

    if( QualityInfo )
    {
        // The compression could have resampled the source to make loopable
        vorbis_info* vi = ov_info( &VFWrapper->vf, -1 );
        QualityInfo->SampleRate = vi->rate;
        QualityInfo->NumChannels = vi->channels;
        ogg_int64_t PCMTotal = ov_pcm_total( &VFWrapper->vf, -1 );
        if (PCMTotal >= 0)
        {
            QualityInfo->SampleDataSize = PCMTotal * QualityInfo->NumChannels * sizeof( int16 );
            QualityInfo->Duration = ( float )ov_time_total( &VFWrapper->vf, -1 );
        }
        else if (PCMTotal == OV_EINVAL)
        {
            // indicates an error or that the bitstream is non-seekable
            QualityInfo->SampleDataSize = 0;
            QualityInfo->Duration = 0.0f;
        }
    }

    return true;
}



Here, I can not continue to trace back what is causing the error from the ov_open_callbacks (defined in vorbis,h). However, I believe it has something to do with a lack of access to FVorbisAudioInfo during a packaged build. Hence the reason I got errors when trying to declare and FVorbisAudioInfo object, or when attempting to convert a WAV file to an OGG through the VorbisFileWrapper. Maybe it has something to do with the headers of my audio?

Can I get some staff support here, as there is not much documentation beyond this point.

After importing the .wav file, UE4 is only stored in USoundWave in an uncompressed way, but if it is packaged, the USoundWave resource will be compressed into OGG format. I mixed the header information in Wav format and the CompressedData in OGG format to fill the running USoundWave and heard the sound of the playback. In this direction, I seem to have only two choices: First, the wav format read in runtime should be converted to OGG, and second, I have to implement the player that plays the original wav format myself. Please give me some tips, thank you.

Hi, **上陡坡](https://forums.unrealengine.com/member/3364696-上陡坡) **Can you share your code? I’ve managed to load a Wav file at runtime and it plays in PIE and in Standalone, But won’t play in packaged game… How did you go about it

WheezyDaStarfish : By thoroughly tracking the source code of UE4, I finally got this problem. it’s actually really easy. Most of your problems lie in the wrong use of vorbis to read wave files. What vorbis reads is OGG.

I am going to upload to github, load .wav and .mp3 at runtime, improve the UE4 plugin version of OVRLipsync

Why not here

Yes, FVorbisAudioInfo reads OGG files, but using the FWaveModInfo you should be able to parse the headers and read the raw PCM data into what UE4 views as an OGG file. UE4 ONLY uses OGG files to play audio, which is why it is essential to convert all incoming files to OGG format. Even in the content browser when you load in a WAV file, it is converted to OGG. Essentially you are creating and OGG file that contains the header information from the WAV file and the raw PCM data from the WAV file. (At least that is my understanding)

But also, I’ve run into a bigger problem that I’ve put in a bug report for, and that is the direct use of FVorbisAudioInfo becomes inaccessible during packaging. I tested in a template, and even creating a raw source file with an FVorbisAudioInfo reference will throw errors during packaging. This means that playing the compressed and converted data from an OGG file will be practically impossible, since at the time being we cant even load in an OGG file at runtime in a packaged build.

However, if you have managed to get a PACKAGED build where a WAV file or an OGG file is being loaded in, please send a github link and share source!

Thanks!

It seems that adding


PublicDefinitions.Add("WITH_OGGVORBIS");

you out build.cs file allows the vorbis file to compile

My Man! I have been beating my head against the wall for 4 months on this. This was the correct answer. I will be naming my first born child after you.

Having the same issue as you’ve been having across a few threads regarding the Vorbis compilation error 132, adding the public definition did not fix it for me. Could you elaborate on everything you’ve done to allow for runtime import of WAV files in a packaged build? Thanks!