ExtendedRead.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include "main.h"
  2. #include <stddef.h>
  3. struct ExtendedRead
  4. {
  5. SF_INFO info;
  6. SNDFILE *soundFile;
  7. int bits;
  8. int frameSize;
  9. };
  10. extern "C"
  11. {
  12. //returns handle!=0 if successful, 0 if error
  13. //size will return the final nb of bytes written to the output, -1 if unknown
  14. __declspec( dllexport ) intptr_t winampGetExtendedRead_openW( const wchar_t *fn, int *size, int *bps, int *nch, int *srate )
  15. {
  16. ExtendedRead *extRead = (ExtendedRead *)calloc( 1, sizeof( ExtendedRead ) );
  17. extRead->info.format = 0;
  18. extRead->soundFile = sf_wchar_open( fn, SFM_READ, &extRead->info );
  19. if ( !extRead->soundFile )
  20. {
  21. free( extRead );
  22. return 0;
  23. }
  24. switch ( extRead->info.format & SF_FORMAT_SUBMASK )
  25. {
  26. case SF_FORMAT_FLOAT:
  27. case SF_FORMAT_DOUBLE:
  28. sf_command( extRead->soundFile, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE );
  29. break;
  30. }
  31. extRead->bits = 16; // TODO: calculate bits per sample (what we want to use, not necessarily what the file has)
  32. *bps = extRead->bits;
  33. *nch = extRead->info.channels;
  34. *srate = extRead->info.samplerate;
  35. extRead->frameSize = ( extRead->bits / 8 ) * extRead->info.channels;
  36. *size = (int)extRead->info.frames * extRead->frameSize; // TODO: is this correct?
  37. return (intptr_t)extRead;
  38. }
  39. //returns nb of bytes read. -1 if read error (like CD ejected). if (ret<len), EOF is assumed
  40. __declspec( dllexport ) intptr_t winampGetExtendedRead_getData( intptr_t handle, char *dest, int len, int *killswitch )
  41. {
  42. ExtendedRead *extRead = (ExtendedRead *)handle;
  43. sf_count_t framesRead = sf_readf_short( extRead->soundFile, (short *)dest, len / extRead->frameSize );
  44. return (int)framesRead * extRead->frameSize;
  45. }
  46. // return nonzero on success, zero on failure.
  47. __declspec( dllexport ) int winampGetExtendedRead_setTime( intptr_t handle, int time_in_ms )
  48. {
  49. ExtendedRead *extRead = (ExtendedRead *)handle;
  50. if ( !extRead->info.seekable )
  51. return 0;
  52. int frames = MulDiv( time_in_ms, extRead->info.samplerate, 1000 ); // TODO: verify calculation
  53. sf_seek( extRead->soundFile, frames, SEEK_SET );
  54. return 1;
  55. }
  56. __declspec( dllexport ) void winampGetExtendedRead_close( intptr_t handle )
  57. {
  58. ExtendedRead *extRead = (ExtendedRead *)handle;
  59. sf_close( extRead->soundFile );
  60. free( extRead );
  61. }
  62. }