aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_wave/ExtendedRead.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_wave/ExtendedRead.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-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.cpp80
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 );
+ }
+}