libopenmpt_bass.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * libopenmpt_bass.c
  3. * -----------------
  4. * Purpose: Example of how to use libopenmpt with the BASS audio library.
  5. * Notes : BASS from un4seen (http://www.un4seen.com/bass.html) is used for audio output.
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. /*
  10. * Usage: libopenmpt_bass SOMEMODULE
  11. */
  12. #include <stdio.h>
  13. #include <string.h>
  14. #if ( defined( _WIN32 ) || defined( WIN32 ) )
  15. #include <Windows.h>
  16. #define sleep(n) Sleep(n)
  17. #else
  18. #include <unistd.h>
  19. #endif
  20. #include <libopenmpt/libopenmpt.h>
  21. #include <libopenmpt/libopenmpt_stream_callbacks_file.h>
  22. #include <bass.h>
  23. #define SAMPLERATE 48000
  24. DWORD CALLBACK StreamProc(HSTREAM handle, void *buffer, DWORD length, void *user)
  25. {
  26. // length is in bytes, but libopenmpt wants samples => divide by number of channels (2) and size of a sample (float = 4)
  27. // same for return value.
  28. size_t count = openmpt_module_read_interleaved_float_stereo( (openmpt_module *)user, SAMPLERATE, length / (2 * sizeof(float)), (float *)buffer );
  29. count *= (2 * sizeof(float));
  30. // Reached end of stream?
  31. if(count < length) count |= BASS_STREAMPROC_END;
  32. return (DWORD)count;
  33. }
  34. #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
  35. int wmain( int argc, wchar_t * argv[] ) {
  36. #else
  37. int main( int argc, char * argv[] ) {
  38. #endif
  39. FILE * file = 0;
  40. openmpt_module * mod = 0;
  41. HSTREAM stream = 0;
  42. int result = 0;
  43. if ( argc != 2 ) {
  44. fprintf( stderr, "Usage: %s SOMEMODULE\n", argv[0] );
  45. return 1;
  46. }
  47. if ( HIWORD( BASS_GetVersion() ) !=BASSVERSION ) {
  48. fprintf( stderr, "Error: Wrong BASS version\n" );
  49. return 1;
  50. }
  51. if ( !BASS_Init( -1, SAMPLERATE, 0, NULL, NULL ) ) {
  52. fprintf( stderr, "Error: Cannot initialize BASS (error %d)\n", BASS_ErrorGetCode() );
  53. return 1;
  54. }
  55. #if ( defined( _WIN32 ) || defined( WIN32 ) ) && ( defined( _UNICODE ) || defined( UNICODE ) )
  56. if ( wcslen( argv[1] ) == 0 ) {
  57. fprintf( stderr, "Usage: %s SOMEMODULE\n", argv[0] );
  58. result = 1;
  59. goto fail;
  60. }
  61. file = _wfopen( argv[1], L"rb" );
  62. #else
  63. if ( strlen( argv[1] ) == 0 ) {
  64. fprintf( stderr, "Usage: %s SOMEMODULE\n", argv[0] );
  65. result = 1;
  66. goto fail;
  67. }
  68. file = fopen( argv[1], "rb" );
  69. #endif
  70. if ( !file ) {
  71. fprintf( stderr, "Error: %s\n", "fopen() failed." );
  72. result = 1;
  73. goto fail;
  74. }
  75. mod = openmpt_module_create( openmpt_stream_get_file_callbacks(), file, NULL, NULL, NULL );
  76. if ( !mod ) {
  77. fprintf( stderr, "Error: %s\n", "openmpt_module_create() failed." );
  78. goto fail;
  79. }
  80. // Create a "pull" channel. BASS will call StreamProc whenever the channel needs new data to be decoded.
  81. stream = BASS_StreamCreate(SAMPLERATE, 2, BASS_SAMPLE_FLOAT, StreamProc, mod);
  82. BASS_ChannelPlay(stream, FALSE);
  83. while ( BASS_ChannelIsActive( stream ) ) {
  84. // Do something useful here
  85. sleep(1);
  86. }
  87. BASS_StreamFree( stream );
  88. openmpt_module_destroy( mod );
  89. fail:
  90. BASS_Free();
  91. return result;
  92. }