'------------------------------------------------------------------------------------------------------------ ' ' This is an MP3 player plugin based on libmpg123 for the OPENAL context. PvE - MIT License 2016. ' ' Web address: http://www.mpg123.de ' '------------------------------------------------------------------------------------------------------------ ' ' MP3_OPEN(file$) ' => Load the MP3 file and the sound font, song ID is returned ' ' MP3_PLAY(songID) ' => Start playing the MP3 file ' ' MP3_PAUSE(songID) ' => Pause playing the MP3 file ' ' MP3_STOP(songID) ' => Stop playing the MP3 file ' ' MP3_UPDATE(songID) ' => Keep the OpenAL buffers filled, to be used in callback function. ' ' MP3_BUSY(songID) ' => Check if we're still playing (TRUE) or not e.g. song is finished (FALSE) ' ' MP3_VOLUME(songID, volume) ' => Set the volume of the source in range 0.0 - 1.0 ' ' MP3_CLOSE(songID) ' => Free resources for the current file ' ' MP3_FREE ' => Free all memory resources for the complete MP3 context ' '------------------------------------------------------------------------------------------------------------ RECORD MP3 LOCAL data TYPE unsigned char* LOCAL buffer[2] TYPE int LOCAL handle TYPE void* LOCAL size TYPE size_t LOCAL rate LOCAL channels, encoding TYPE int END RECORD CALL MP3_INIT '------------------------------------------------------------------------------------------------------------ SUB MP3_INIT LOCAL lib$ LOCAL seq = -1 CATCH GOTO lib_import_retry lib$ = "libmpg123.so.0" LABEL lib_import_retry INCR seq IF seq > 100 THEN PRINT "ERROR: libmpg123 not found on this system! Exiting..." END 1 ENDIF lib$ = LEFT$(lib$, INSTRREV(lib$, ".")) & STR$(seq) IMPORT "mpg123_init(void)" FROM lib$ TYPE int CATCH RESET IMPORT "mpg123_exit(void)" FROM lib$ TYPE void IMPORT "mpg123_new(char*,int*)" FROM lib$ TYPE void* IMPORT "mpg123_delete(void*)" FROM lib$ TYPE void IMPORT "mpg123_close(void*)" FROM lib$ TYPE int IMPORT "mpg123_open(void*,char*)" FROM lib$ TYPE int IMPORT "mpg123_outblock(void*)" FROM lib$ TYPE size_t IMPORT "mpg123_getformat(void*,long*,int*,int*)" FROM lib$ TYPE int IMPORT "mpg123_encsize(int)" FROM lib$ TYPE int IMPORT "mpg123_read(void*,char*,size_t,size_t*)" FROM lib$ TYPE int CONST MPG123_OK = 0 mpg123_init() END SUB FUNCTION MP3_OPEN(file$) LOCAL source, err TYPE int LOCAL done1, done2 TYPE size_t IF NOT(FILEEXISTS(file$)) THEN PRINT "ERROR: cannot find file '", file$, "'! Exiting..." END 1 END IF MP3.handle = mpg123_new(NULL, &err) MP3.size = mpg123_outblock(MP3.handle) OPTION MEMTYPE unsigned char MP3.data = MEMORY(MP3.size) ' Open file mpg123_open(MP3.handle, file$) mpg123_getformat(MP3.handle, &MP3.rate, &MP3.channels, &MP3.encoding) ' Error cleanup alGetError() alGenBuffers(2, MP3.buffer) IF mpg123_read(MP3.handle, MP3.data, MP3.size, &done1) = MPG123_OK THEN alBufferData(MP3.buffer[0], AL_FORMAT_STEREO16, MP3.data, done1, MP3.rate) ENDIF IF mpg123_read(MP3.handle, MP3.data, MP3.size, &done2) = MPG123_OK THEN alBufferData(MP3.buffer[1], AL_FORMAT_STEREO16, MP3.data, done2, MP3.rate) ENDIF alGenSources(1, &source) alSourceQueueBuffers(source, 2, MP3.buffer) ' Returned source is used as song ID RETURN source END FUNCTION SUB MP3_SHOW_INFO PRINT "Rate: ", MP3.rate PRINT "Channels: ", MP3.channels 'PRINT "Encoding: ", MP3.encoding END SUB SUB MP3_PLAY(int Source) alSourcePlay(Source) END SUB SUB MP3_PAUSE(int Source) alSourcePause(Source) END SUB SUB MP3_STOP(int Source) alSourceStop(Source) END SUB SUB MP3_UPDATE(int Source) LOCAL processed, which TYPE int LOCAL done TYPE size_t alGetSourcei(Source, AL_BUFFERS_PROCESSED, &processed) IF processed THEN IF mpg123_read(MP3.handle, MP3.data, MP3.size, &done) = MPG123_OK THEN alSourceUnqueueBuffers(Source, 1, &which) alBufferData(which, AL_FORMAT_STEREO16, MP3.data, done, MP3.rate) alSourceQueueBuffers(Source, 1, &which) ENDIF ENDIF END SUB FUNCTION MP3_BUSY(int Source) LOCAL state TYPE int alGetSourcei(Source, AL_SOURCE_STATE, &state) IF state = AL_PLAYING THEN RETURN TRUE RETURN FALSE END FUNCTION SUB MP3_VOLUME(int Source, volume#) alSourcef(Source, AL_GAIN, volume#) END SUB SUB MP3_CLOSE(int Source) alDeleteSources(1, &Source) mpg123_close(MP3.handle) mpg123_delete(MP3.handle) FREE MP3.data END SUB SUB MP3_FREE mpg123_exit() alDeleteBuffers(2, MP3.buffer) END SUB