2626using CUE4Parse . GameTypes . KRD . Assets . Exports ;
2727using CUE4Parse . GameTypes . Borderlands4 . Assets . Exports ;
2828using CUE4Parse . GameTypes . Borderlands4 . Wwise ;
29+ using CUE4Parse . GameTypes . Borderlands3 . Assets . Exports ;
2930using CUE4Parse . MappingsProvider ;
3031using CUE4Parse . UE4 . AssetRegistry ;
3132using CUE4Parse . UE4 . Assets ;
@@ -792,7 +793,7 @@ public void Extract(CancellationToken cancellationToken, GameFile entry, bool ad
792793 var directory = Path . GetDirectoryName ( entry . Path ) ?? "/FMOD/Desktop/" ;
793794 foreach ( var sound in extractedSounds )
794795 {
795- SaveAndPlaySound ( Path . Combine ( directory , sound . Name ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
796+ SaveAndPlaySound ( cancellationToken , Path . Combine ( directory , sound . Name ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
796797 }
797798
798799 break ;
@@ -807,7 +808,7 @@ public void Extract(CancellationToken cancellationToken, GameFile entry, bool ad
807808 var medias = WwiseProvider . ExtractBankSounds ( wwise ) ;
808809 foreach ( var media in medias )
809810 {
810- SaveAndPlaySound ( media . OutputPath , media . Extension , media . Data , saveAudio , updateUi ) ;
811+ SaveAndPlaySound ( cancellationToken , media . OutputPath , media . Extension , media . Data , saveAudio , updateUi ) ;
811812 }
812813
813814 break ;
@@ -823,7 +824,7 @@ public void Extract(CancellationToken cancellationToken, GameFile entry, bool ad
823824 var extractedSounds = CriWareProvider . ExtractCriWareSounds ( awbReader , archive . Name ) ;
824825 foreach ( var sound in extractedSounds )
825826 {
826- SaveAndPlaySound ( Path . Combine ( directory , sound . Name ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
827+ SaveAndPlaySound ( cancellationToken , Path . Combine ( directory , sound . Name ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
827828 }
828829
829830 break ;
@@ -839,7 +840,7 @@ public void Extract(CancellationToken cancellationToken, GameFile entry, bool ad
839840 var extractedSounds = CriWareProvider . ExtractCriWareSounds ( acbReader , archive . Name ) ;
840841 foreach ( var sound in extractedSounds )
841842 {
842- SaveAndPlaySound ( Path . Combine ( directory , sound . Name ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
843+ SaveAndPlaySound ( cancellationToken , Path . Combine ( directory , sound . Name ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
843844 }
844845
845846 break ;
@@ -854,7 +855,7 @@ public void Extract(CancellationToken cancellationToken, GameFile entry, bool ad
854855 // todo: CSCore.MediaFoundation.MediaFoundationException The byte stream type of the given URL is unsupported. case "aif":
855856 {
856857 var data = Provider . SaveAsset ( entry ) ;
857- SaveAndPlaySound ( entry . PathWithoutExtension , entry . Extension , data , saveAudio , updateUi ) ;
858+ SaveAndPlaySound ( cancellationToken , entry . PathWithoutExtension , entry . Extension , data , saveAudio , updateUi ) ;
858859
859860 break ;
860861 }
@@ -1114,15 +1115,24 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat
11141115 case UExternalSource when ( isNone || saveAudio ) && pointer . Object . Value is UExternalSource externalSource :
11151116 {
11161117 var audioName = Path . GetFileNameWithoutExtension ( externalSource . ExternalSourcePath ) ;
1117- SaveAndPlaySound ( audioName , "wem" , externalSource . Data ? . WemFile ?? [ ] , saveAudio , updateUi ) ;
1118+ SaveAndPlaySound ( cancellationToken , audioName , "wem" , externalSource . Data ? . WemFile ?? [ ] , saveAudio , updateUi ) ;
1119+ return false ;
1120+ }
1121+ case UAkAudioBank when ( isNone || saveAudio ) && pointer . Object . Value is UAkAudioBank soundBank :
1122+ {
1123+ var extractedSounds = WwiseProvider . ExtractBankSounds ( soundBank ) ;
1124+ foreach ( var sound in extractedSounds )
1125+ {
1126+ SaveAndPlaySound ( cancellationToken , sound . OutputPath , sound . Extension , sound . Data , saveAudio , updateUi ) ;
1127+ }
11181128 return false ;
11191129 }
11201130 case UAkAudioEvent when ( isNone || saveAudio ) && pointer . Object . Value is UAkAudioEvent audioEvent :
11211131 {
11221132 var extractedSounds = WwiseProvider . ExtractAudioEventSounds ( audioEvent ) ;
11231133 foreach ( var sound in extractedSounds )
11241134 {
1125- SaveAndPlaySound ( sound . OutputPath , sound . Extension , sound . Data , saveAudio , updateUi ) ;
1135+ SaveAndPlaySound ( cancellationToken , sound . OutputPath , sound . Extension , sound . Data , saveAudio , updateUi ) ;
11261136 }
11271137 return false ;
11281138 }
@@ -1132,7 +1142,7 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat
11321142 var directory = Path . GetDirectoryName ( fmodEvent . Owner ? . Name ) ?? "/FMOD/Desktop/" ;
11331143 foreach ( var sound in extractedSounds )
11341144 {
1135- SaveAndPlaySound ( Path . Combine ( directory , sound . Name ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
1145+ SaveAndPlaySound ( cancellationToken , Path . Combine ( directory , sound . Name ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
11361146 }
11371147 return false ;
11381148 }
@@ -1142,7 +1152,7 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat
11421152 var directory = Path . GetDirectoryName ( fmodBank . Owner ? . Name ) ?? "/FMOD/Desktop/" ;
11431153 foreach ( var sound in extractedSounds )
11441154 {
1145- SaveAndPlaySound ( Path . Combine ( directory , sound . Name ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
1155+ SaveAndPlaySound ( cancellationToken , Path . Combine ( directory , sound . Name ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
11461156 }
11471157 return false ;
11481158 }
@@ -1161,7 +1171,7 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat
11611171 directory = Path . GetDirectoryName ( atomObject . Owner . Provider . FixPath ( directory ) ) ;
11621172 foreach ( var sound in extractedSounds )
11631173 {
1164- SaveAndPlaySound ( Path . Combine ( directory , sound . Name ) . Replace ( "\\ " , "/" ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
1174+ SaveAndPlaySound ( cancellationToken , Path . Combine ( directory , sound . Name ) . Replace ( "\\ " , "/" ) , sound . Extension , sound . Data , saveAudio , updateUi ) ;
11651175 }
11661176 return false ;
11671177 }
@@ -1181,7 +1191,7 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat
11811191 return false ;
11821192 }
11831193
1184- SaveAndPlaySound ( TabControl . SelectedTab . Entry . PathWithoutExtension . Replace ( '\\ ' , '/' ) , audioFormat , data , saveAudio , updateUi ) ;
1194+ SaveAndPlaySound ( cancellationToken , TabControl . SelectedTab . Entry . PathWithoutExtension . Replace ( '\\ ' , '/' ) , audioFormat , data , saveAudio , updateUi ) ;
11851195 return false ;
11861196 }
11871197 case UAkMediaAsset when ( isNone || saveAudio ) && pointer . Object . Value is UAkMediaAsset akMediaAsset :
@@ -1192,7 +1202,7 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat
11921202 var shouldDecompress = UserSettings . Default . CompressedAudioMode is ECompressedAudio . PlayDecompressed ;
11931203 akMediaAssetData . Decode ( shouldDecompress , out var audioFormat , out var data ) ;
11941204
1195- SaveAndPlaySound ( audioName , audioFormat , data , saveAudio , updateUi ) ;
1205+ SaveAndPlaySound ( cancellationToken , audioName , audioFormat , data , saveAudio , updateUi ) ;
11961206 }
11971207 return false ;
11981208 }
@@ -1208,12 +1218,22 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat
12081218 var audioName = akMediaAsset . MediaName ?? $ "{ akAudioEventData . Outer . Name } ({ akMediaAsset . ID } )";
12091219 akMediaAssetData . Decode ( shouldDecompress , out var audioFormat , out var data ) ;
12101220
1211- SaveAndPlaySound ( audioName , audioFormat , data , saveAudio , updateUi ) ;
1221+ SaveAndPlaySound ( cancellationToken , audioName , audioFormat , data , saveAudio , updateUi ) ;
12121222 }
12131223 }
12141224 }
12151225 return false ;
12161226 }
1227+ // Borderlands 3
1228+ case UDialogPerformanceData when ( isNone || saveAudio ) && pointer . Object . Value is UDialogPerformanceData dialogPerformanceData :
1229+ {
1230+ var extractedSounds = WwiseProvider . ExtractDialogBorderlands3 ( dialogPerformanceData ) ;
1231+ foreach ( var sound in extractedSounds )
1232+ {
1233+ SaveAndPlaySound ( cancellationToken , sound . OutputPath , sound . Extension , sound . Data , saveAudio , updateUi ) ;
1234+ }
1235+ return false ;
1236+ }
12171237 // Borderlands 4
12181238 case UFaceFXAnimSet when ( isNone || saveAudio ) && pointer . Object . Value is UFaceFXAnimSet faceFXAnimSet :
12191239 {
@@ -1225,7 +1245,7 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat
12251245 var extractedSounds = WwiseProvider . ExtractAudioEventBorderlands4 ( faceFXAnimData . ID . Name , false ) ;
12261246 foreach ( var sound in extractedSounds )
12271247 {
1228- SaveAndPlaySound ( sound . OutputPath , sound . Extension , sound . Data , saveAudio , updateUi ) ;
1248+ SaveAndPlaySound ( cancellationToken , sound . OutputPath , sound . Extension , sound . Data , saveAudio , updateUi ) ;
12291249 }
12301250 }
12311251
@@ -1239,7 +1259,7 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat
12391259 var extractedSounds = WwiseProvider . ExtractAudioEventBorderlands4 ( eventName , useSoundTag ) ;
12401260 foreach ( var sound in extractedSounds )
12411261 {
1242- SaveAndPlaySound ( sound . OutputPath , sound . Extension , sound . Data , saveAudio , updateUi ) ;
1262+ SaveAndPlaySound ( cancellationToken , sound . OutputPath , sound . Extension , sound . Data , saveAudio , updateUi ) ;
12431263 }
12441264 }
12451265
@@ -1379,14 +1399,15 @@ public void Decompile(GameFile entry)
13791399 TabControl . SelectedTab . SetDocumentText ( cpp , false , false ) ;
13801400 }
13811401
1382- private void SaveAndPlaySound ( string fullPath , string ext , byte [ ] data , bool isBulk , bool updateUi )
1402+ private void SaveAndPlaySound ( CancellationToken cancellationToken , string fullPath , string ext , byte [ ] data , bool isBulk , bool updateUi )
13831403 {
13841404 if ( fullPath . StartsWith ( '/' ) ) fullPath = fullPath [ 1 ..] ;
13851405 var savedAudioPath = Path . Combine ( UserSettings . Default . AudioDirectory ,
13861406 UserSettings . Default . KeepDirectoryStructure ? fullPath : fullPath . SubstringAfterLast ( '/' ) ) . Replace ( '\\ ' , '/' ) + $ ".{ ext . ToLowerInvariant ( ) } ";
13871407
13881408 if ( isBulk )
13891409 {
1410+ cancellationToken . ThrowIfCancellationRequested ( ) ;
13901411 Directory . CreateDirectory ( savedAudioPath . SubstringBeforeLast ( '/' ) ) ;
13911412 using var stream = new FileStream ( savedAudioPath , FileMode . Create , FileAccess . Write ) ;
13921413 using ( var writer = new BinaryWriter ( stream ) )
@@ -1398,7 +1419,18 @@ private void SaveAndPlaySound(string fullPath, string ext, byte[] data, bool isB
13981419 if ( UserSettings . Default . ConvertAudioOnBulkExport )
13991420 {
14001421 AudioPlayerViewModel . TryConvert ( savedAudioPath , data , out string wavFilePath ) ;
1401- savedAudioPath = wavFilePath ;
1422+ if ( ! string . IsNullOrEmpty ( wavFilePath ) )
1423+ {
1424+ savedAudioPath = wavFilePath ;
1425+ }
1426+ else if ( updateUi )
1427+ {
1428+ FLogger . Append ( ELog . Error , ( ) =>
1429+ {
1430+ FLogger . Text ( "Failed to convert audio to WAV format, aborting extraction." , Constants . WHITE , true ) ;
1431+ } ) ;
1432+ return ;
1433+ }
14021434 }
14031435
14041436 Log . Information ( "Successfully saved {FilePath}" , savedAudioPath ) ;
0 commit comments