'------------------------------------------------------------------------------------------------------------ ' ' This is a FLAC player plugin for the OPENAL context. It uses the DR_LIBS libraries. PvE - MIT License 2017. ' ' Small adaptations to let it compile properly with recent dr_flac.h file - PvE December 2018 ' ' Web address: https://github.com/mackron/dr_libs ' '------------------------------------------------------------------------------------------------------------ ' ' FLAC_OPEN(file$) ' => Load the FLAC file, song ID is returned ' ' FLAC_SHOW_INFO ' => Show sample rate and channels of the current open FLAC file ' ' FLAC_PLAY(songID) ' => Start playing the FLAC file ' ' FLAC_PAUSE(songID) ' => Pause playing the FLAC file ' ' FLAC_STOP(songID) ' => Stop playing the FLAC file ' ' FLAC_UPDATE(songID) ' => Keep the OpenAL buffers filled, to be used in callback function. ' ' FLAC_BUSY(songID) ' => Check if we're still playing (TRUE) or not e.g. song is finished (FALSE) ' ' FLAC_VOLUME(songID, volume) ' => Set the volume of the source in range 0.0 - 1.0 ' ' FLAC_CLOSE(songID) ' => Free resources for the current file ' ' FLAC_FREE ' => Free all memory resources for the complete FLAC context ' '------------------------------------------------------------------------------------------------------------ PRAGMA INCLUDE single-file-libs/dr_flac.h : ' Include the dr_libs header file PRAGMA OPTIONS -DDR_FLAC_IMPLEMENTATION PROTO drflac_close RECORD FLAC LOCAL chunk : ' This is the chunk size we will be parsing LOCAL buffer[2] TYPE int LOCAL pFlac TYPE drflac* LOCAL data TYPE drflac_int16* END RECORD FLAC.chunk = 65536 : ' Default chunk size FLAC.pFlac = NULL FUNCTION FLAC_OPEN(filename$) LOCAL samples TYPE drflac_uint64 LOCAL source TYPE int FLAC.pFlac = drflac_open_file(filename$) IF FLAC.pFlac = NULL THEN PRINT "ERROR: error loading file '", filename$, "'! Remove id3v2 tags and try again. Exiting..." END 1 ENDIF FLAC.data = MEMORY(FLAC.pFlac->totalSampleCount * sizeof(drflac_int16)*2) ' Error cleanup alGetError() alGenBuffers(2, FLAC.buffer) samples = drflac_read_pcm_frames_s16(FLAC.pFlac, FLAC.chunk, FLAC.data)*2 alBufferData(FLAC.buffer[0], AL_FORMAT_STEREO16, FLAC.data, samples*sizeof(drflac_uint16), FLAC.pFlac->sampleRate) samples = drflac_read_pcm_frames_s16(FLAC.pFlac, FLAC.chunk, FLAC.data)*2 alBufferData(FLAC.buffer[1], AL_FORMAT_STEREO16, FLAC.data, samples*sizeof(drflac_uint16), FLAC.pFlac->sampleRate) alGenSources(1, &source) alSourceQueueBuffers(source, 2, FLAC.buffer) ' Returned source is used as song ID RETURN source END FUNCTION SUB FLAC_SHOW_INFO IF FLAC.pFlac <> NULL THEN PRINT "Rate: ", FLAC.pFlac->sampleRate PRINT "Channels: ", FLAC.pFlac->channels ENDIF END SUB SUB FLAC_PLAY(int Source) alSourcePlay(Source) END SUB SUB FLAC_PAUSE(int Source) alSourcePause(Source) END SUB SUB FLAC_STOP(int Source) alSourceStop(Source) END SUB SUB FLAC_UPDATE(int Source) LOCAL processed, which TYPE int LOCAL samples TYPE drflac_uint64 alGetSourcei(Source, AL_BUFFERS_PROCESSED, &processed) IF processed THEN alSourceUnqueueBuffers(Source, 1, &which) samples = drflac_read_pcm_frames_s16(FLAC.pFlac, FLAC.chunk, FLAC.data)*2 alBufferData(which, AL_FORMAT_STEREO16, FLAC.data, samples*sizeof(drflac_uint16), FLAC.pFlac->sampleRate) alSourceQueueBuffers(Source, 1, &which) ENDIF END SUB FUNCTION FLAC_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 FLAC_VOLUME(int Source, volume#) alSourcef(Source, AL_GAIN, volume#) END SUB SUB FLAC_CLOSE(int Source) alDeleteSources(1, &Source) drflac_close(FLAC.pFlac) FLAC.pFlac = NULL END SUB SUB FLAC_FREE FREE FLAC.data alDeleteBuffers(2, FLAC.buffer) END SUB