diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_wave/ExtendedRead.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_wave/ExtendedRead.cpp')
-rw-r--r-- | Src/Plugins/Input/in_wave/ExtendedRead.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_wave/ExtendedRead.cpp b/Src/Plugins/Input/in_wave/ExtendedRead.cpp new file mode 100644 index 00000000..44bed186 --- /dev/null +++ b/Src/Plugins/Input/in_wave/ExtendedRead.cpp @@ -0,0 +1,80 @@ +#include "main.h" +#include <stddef.h> + +struct ExtendedRead +{ + SF_INFO info; + SNDFILE *soundFile; + int bits; + int frameSize; +}; + +extern "C" +{ + //returns handle!=0 if successful, 0 if error + //size will return the final nb of bytes written to the output, -1 if unknown + __declspec( dllexport ) intptr_t winampGetExtendedRead_openW( const wchar_t *fn, int *size, int *bps, int *nch, int *srate ) + { + ExtendedRead *extRead = (ExtendedRead *)calloc( 1, sizeof( ExtendedRead ) ); + + extRead->info.format = 0; + extRead->soundFile = sf_wchar_open( fn, SFM_READ, &extRead->info ); + if ( !extRead->soundFile ) + { + free( extRead ); + return 0; + } + + switch ( extRead->info.format & SF_FORMAT_SUBMASK ) + { + case SF_FORMAT_FLOAT: + case SF_FORMAT_DOUBLE: + sf_command( extRead->soundFile, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE ); + break; + } + + extRead->bits = 16; // TODO: calculate bits per sample (what we want to use, not necessarily what the file has) + + *bps = extRead->bits; + *nch = extRead->info.channels; + *srate = extRead->info.samplerate; + + extRead->frameSize = ( extRead->bits / 8 ) * extRead->info.channels; + + *size = (int)extRead->info.frames * extRead->frameSize; // TODO: is this correct? + + return (intptr_t)extRead; + } + + //returns nb of bytes read. -1 if read error (like CD ejected). if (ret<len), EOF is assumed + __declspec( dllexport ) intptr_t winampGetExtendedRead_getData( intptr_t handle, char *dest, int len, int *killswitch ) + { + ExtendedRead *extRead = (ExtendedRead *)handle; + + sf_count_t framesRead = sf_readf_short( extRead->soundFile, (short *)dest, len / extRead->frameSize ); + + return (int)framesRead * extRead->frameSize; + } + + // return nonzero on success, zero on failure. + __declspec( dllexport ) int winampGetExtendedRead_setTime( intptr_t handle, int time_in_ms ) + { + ExtendedRead *extRead = (ExtendedRead *)handle; + if ( !extRead->info.seekable ) + return 0; + + int frames = MulDiv( time_in_ms, extRead->info.samplerate, 1000 ); // TODO: verify calculation + + sf_seek( extRead->soundFile, frames, SEEK_SET ); + + return 1; + } + + __declspec( dllexport ) void winampGetExtendedRead_close( intptr_t handle ) + { + ExtendedRead *extRead = (ExtendedRead *)handle; + sf_close( extRead->soundFile ); + + free( extRead ); + } +} |