summaryrefslogtreecommitdiff
path: root/engine/audio/private/snd_wave_temp.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /engine/audio/private/snd_wave_temp.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'engine/audio/private/snd_wave_temp.cpp')
-rw-r--r--engine/audio/private/snd_wave_temp.cpp149
1 files changed, 149 insertions, 0 deletions
diff --git a/engine/audio/private/snd_wave_temp.cpp b/engine/audio/private/snd_wave_temp.cpp
new file mode 100644
index 0000000..b1c6702
--- /dev/null
+++ b/engine/audio/private/snd_wave_temp.cpp
@@ -0,0 +1,149 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Create an output wave stream. Used to record audio for in-engine movies or
+// mixer debugging.
+//
+//=====================================================================================//
+
+#include "audio_pch.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+extern IFileSystem *g_pFileSystem;
+// FIXME: shouldn't this API be part of IFileSystem?
+extern bool COM_CopyFile( const char *netpath, const char *cachepath );
+
+// Create a wave file
+void WaveCreateTmpFile( const char *filename, int rate, int bits, int nChannels )
+{
+ char tmpfilename[MAX_PATH];
+ Q_StripExtension( filename, tmpfilename, sizeof( tmpfilename ) );
+ Q_DefaultExtension( tmpfilename, ".WAV", sizeof( tmpfilename ) );
+
+ FileHandle_t file;
+ file = g_pFileSystem->Open( tmpfilename, "wb" );
+ if ( file == FILESYSTEM_INVALID_HANDLE )
+ return;
+
+ int chunkid = LittleLong( RIFF_ID );
+ int chunksize = LittleLong( 0 );
+ g_pFileSystem->Write( &chunkid, sizeof(int), file );
+ g_pFileSystem->Write( &chunksize, sizeof(int), file );
+
+ chunkid = LittleLong( RIFF_WAVE );
+ g_pFileSystem->Write( &chunkid, sizeof(int), file );
+
+ // create a 16-bit PCM stereo output file
+ PCMWAVEFORMAT fmt = { { 0 } };
+ fmt.wf.wFormatTag = LittleWord( (short)WAVE_FORMAT_PCM );
+ fmt.wf.nChannels = LittleWord( (short)nChannels );
+ fmt.wf.nSamplesPerSec = LittleDWord( rate );
+ fmt.wf.nAvgBytesPerSec = LittleDWord( rate * bits * nChannels / 8 );
+ fmt.wf.nBlockAlign = LittleWord( (short)( 2 * nChannels) );
+ fmt.wBitsPerSample = LittleWord( (short)bits );
+
+ chunkid = LittleLong( WAVE_FMT );
+ chunksize = LittleLong( sizeof(fmt) );
+ g_pFileSystem->Write( &chunkid, sizeof(int), file );
+ g_pFileSystem->Write( &chunksize, sizeof(int), file );
+ g_pFileSystem->Write( &fmt, sizeof( PCMWAVEFORMAT ), file );
+
+ chunkid = LittleLong( WAVE_DATA );
+ chunksize = LittleLong( 0 );
+ g_pFileSystem->Write( &chunkid, sizeof(int), file );
+ g_pFileSystem->Write( &chunksize, sizeof(int), file );
+
+ g_pFileSystem->Close( file );
+}
+
+void WaveAppendTmpFile( const char *filename, void *pBuffer, int sampleBits, int numSamples )
+{
+ char tmpfilename[MAX_PATH];
+ Q_StripExtension( filename, tmpfilename, sizeof( tmpfilename ) );
+ Q_DefaultExtension( tmpfilename, ".WAV", sizeof( tmpfilename ) );
+
+ FileHandle_t file;
+ file = g_pFileSystem->Open( tmpfilename, "r+b" );
+ if ( file == FILESYSTEM_INVALID_HANDLE )
+ return;
+
+ g_pFileSystem->Seek( file, 0, FILESYSTEM_SEEK_TAIL );
+
+ if ( IsX360() && sampleBits == 16 )
+ {
+ short *pSwapped = (short * )_alloca( numSamples * sampleBits/8 );
+ for ( int i=0; i<numSamples; i++ )
+ {
+ pSwapped[i] = LittleShort( ((short*)pBuffer)[i] );
+ }
+ g_pFileSystem->Write( pSwapped, numSamples * sizeof( short ), file );
+ }
+ else
+ {
+ g_pFileSystem->Write( pBuffer, numSamples * sampleBits/8, file );
+ }
+
+ g_pFileSystem->Close( file );
+}
+
+void WaveFixupTmpFile( const char *filename )
+{
+ char tmpfilename[MAX_PATH];
+ Q_StripExtension( filename, tmpfilename, sizeof( tmpfilename ) );
+ Q_DefaultExtension( tmpfilename, ".WAV", sizeof( tmpfilename ) );
+
+ FileHandle_t file;
+ file = g_pFileSystem->Open( tmpfilename, "r+b" );
+ if ( FILESYSTEM_INVALID_HANDLE == file )
+ {
+ Warning( "WaveFixupTmpFile( '%s' ) failed to open file for editing\n", tmpfilename );
+ return;
+ }
+
+ // file size goes in RIFF chunk
+ int size = g_pFileSystem->Size( file ) - 2*sizeof( int );
+ // offset to data chunk
+ int headerSize = (sizeof(int)*5 + sizeof(PCMWAVEFORMAT));
+ // size of data chunk
+ int dataSize = size - headerSize;
+
+ size = LittleLong( size );
+ g_pFileSystem->Seek( file, sizeof( int ), FILESYSTEM_SEEK_HEAD );
+ g_pFileSystem->Write( &size, sizeof( int ), file );
+
+ // skip the header and the 4-byte chunk tag and write the size
+ dataSize = LittleLong( dataSize );
+ g_pFileSystem->Seek( file, headerSize+sizeof( int ), FILESYSTEM_SEEK_HEAD );
+ g_pFileSystem->Write( &dataSize, sizeof( int ), file );
+
+ g_pFileSystem->Close( file );
+}
+
+CON_COMMAND( movie_fixwave, "Fixup corrupted .wav file if engine crashed during startmovie/endmovie, etc." )
+{
+ if ( args.ArgC() != 2 )
+ {
+ Msg ("Usage: movie_fixwave wavname\n");
+ return;
+ }
+
+ char const *wavname = args.Arg( 1 );
+ if ( !g_pFileSystem->FileExists( wavname ) )
+ {
+ Warning( "movie_fixwave: File '%s' does not exist\n", wavname );
+ return;
+ }
+
+ char tmpfilename[256];
+ Q_StripExtension( wavname, tmpfilename, sizeof( tmpfilename ) );
+ Q_strncat( tmpfilename, "_fixed", sizeof( tmpfilename ), COPY_ALL_CHARACTERS );
+ Q_DefaultExtension( tmpfilename, ".wav", sizeof( tmpfilename ) );
+
+ // Now copy the file
+ Msg( "Copying '%s' to '%s'\n", wavname, tmpfilename );
+ COM_CopyFile( wavname, tmpfilename );
+
+ Msg( "Performing fixup on '%s'\n", tmpfilename );
+ WaveFixupTmpFile( tmpfilename );
+}