Announcement

Collapse
No announcement yet.

FVorbisAudioInfo access issues in Unreal Engine 4.23

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    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.



    Code:
    #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 
        }
    }
    Director/Owner of Turf 3D Drill
    Marching Band Drill Design Software
    http://www.turf3d.com

    #2
    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

    Code:
    FVorbisAudioInfo::ReadCompressedInfo, ov_open_callbacks error code: -132
    Here is the code I am using in my application to get this error:

    Code:
    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;
        }
    
    }





    2) I've narrowed down this callback to the following function in FVorbisAudioInfo.cpp

    Code:
    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.
    Director/Owner of Turf 3D Drill
    Marching Band Drill Design Software
    http://www.turf3d.com

    Comment


      #3
      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.

      Comment


        #4
        Hi, 上陡坡 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

        Comment


          #5
          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.

          Comment


            #6
            Originally posted by 3RD-HOPE View Post
            Hi, 上陡坡 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
            I am going to upload to github, load .wav and .mp3 at runtime, improve the UE4 plugin version of OVRLipsync

            Comment

            Working...
            X