diff options
Diffstat (limited to 'smelt/glfw_m/sfx_oal.cpp')
-rw-r--r-- | smelt/glfw_m/sfx_oal.cpp | 368 |
1 files changed, 0 insertions, 368 deletions
diff --git a/smelt/glfw_m/sfx_oal.cpp b/smelt/glfw_m/sfx_oal.cpp deleted file mode 100644 index 5b8d135..0000000 --- a/smelt/glfw_m/sfx_oal.cpp +++ /dev/null @@ -1,368 +0,0 @@ -// -*- C++ -*- -/* - * Simple MultimEdia LiTerator(SMELT) - * by Chris Xiong 2015 - * GFX implementation based on OpenAL - * - * WARNING: This library is in development and interfaces would be very - * unstable. - * - */ -#include "smelt_internal.hpp" - -static const char* SFX_OAL_SRCFN="smelt/glfw/sfx_oal.cpp"; -#ifndef ENABLE_DUMB -#ifdef ENABLE_OGG_SUPPORT -struct oggdata{const BYTE *data;DWORD size,pos;}; -static void* readVorbis(const BYTE *data,const DWORD size, ALsizei *decomp_size,ALenum *fmt,ALsizei *freq); -#endif -static void* readRiffWv(const BYTE *data,const DWORD size, ALsizei *decomp_size,ALenum *fmt,ALsizei *freq); -SMSFX SMELT_IMPL::smSFXLoad(const char *path) -{ - FILE *pFile;DWORD size,rsize; char *buff; - pFile=fopen(path,"rb"); - if(!pFile)return 0; - fseek(pFile,0,SEEK_END);size=ftell(pFile);rewind(pFile); - buff=(char*)malloc(sizeof(char)*size); - if(!buff)return 0; - rsize=fread(buff,1,size,pFile); - if(rsize!=size)return 0; - SMSFX ret=smSFXLoadFromMemory(buff,size); - free(buff); - fclose(pFile); - return ret; -} -SMSFX SMELT_IMPL::smSFXLoadFromMemory(const char *ptr,DWORD size) -{ - if(pOpenALDevice&&!mute) - { -#ifdef ENABLE_OGG_SUPPORT - bool isOgg=size>4&&ptr[0]=='O'&&ptr[1]=='g'&&ptr[2]=='g'&&ptr[3]=='S'; -#endif - void *decompdata=NULL,*decomp=NULL; - ALsizei decompsize=0,freq=0; - ALenum fmt=AL_FORMAT_STEREO16; - decompdata=readRiffWv((const BYTE*)ptr,size,&decompsize,&fmt,&freq); -#ifdef ENABLE_OGG_SUPPORT - if(!decompdata) - { - if(!isOgg)return 0; - else decompdata=readVorbis((const BYTE*)ptr,size,&decompsize,&fmt,&freq); - } -#endif - if(!decompdata)return 0; - decomp=decompdata; - ALuint buff=0;alGenBuffers(1,&buff); - alBufferData(buff,fmt,decomp,decompsize,freq); - free(decompdata);return(SMSFX)buff; - } - return 0; -} -SMCHN SMELT_IMPL::smSFXPlay(SMSFX fx,int vol,int pan,float pitch,bool loop) -{ - if(pOpenALDevice) - { - ALuint src=getSource(); - if(src) - { - if(vol<0)vol=0;if(vol>100)vol=100; - if(pan<-100)pan=-100;if(pan>100)pan=100; - alSourceStop(src); - alSourcei(src,AL_BUFFER,(ALint)fx); - alSourcef(src,AL_GAIN,((ALfloat)vol)/100.); - alSourcef(src,AL_PITCH,pitch); - alSource3f(src,AL_POSITION,((ALfloat)pan)/100.,.0,.0); - alSourcei(src,AL_LOOPING,loop?AL_TRUE:AL_FALSE); - alSourcePlay(src); - } - return src; - } - return 0; -} -float SMELT_IMPL::smSFXGetLengthf(SMSFX fx) -{ - ALuint buff=(ALuint)fx; - ALint freq; - DWORD lend=smSFXGetLengthd(fx); - alGetBufferi(buff,AL_FREQUENCY,&freq); - float ret=lend/(float)freq; - return ret; -} -DWORD SMELT_IMPL::smSFXGetLengthd(SMSFX fx) -{ - if(pOpenALDevice) - { - ALint size_b,chnc,bit; - ALuint buff=(ALuint)fx; - alGetBufferi(buff,AL_SIZE,&size_b); - alGetBufferi(buff,AL_CHANNELS,&chnc); - alGetBufferi(buff,AL_BITS,&bit); - DWORD ret=size_b*8/(chnc*bit); - return ret; - } - return -1; -} -void SMELT_IMPL::smSFXSetLoopPoint(SMSFX fx,DWORD l,DWORD r) -{ - if(pOpenALDevice) - { - ALint pt[2];pt[0]=l;pt[1]=r; - alBufferiv((ALuint)fx,AL_LOOP_POINTS_SOFT,pt); - } -} -void SMELT_IMPL::smSFXFree(SMSFX fx) -{ - if(pOpenALDevice) - { - ALuint buff=(ALuint)fx; - alDeleteBuffers(1,&buff); - } -} -void SMELT_IMPL::smChannelVol(SMCHN chn,int vol) -{ - if(pOpenALDevice) - { - if(vol<0)vol=0;if(vol>100)vol=100; - alSourcef((ALuint)chn,AL_GAIN,((ALfloat)vol)/100.); - } -} -void SMELT_IMPL::smChannelPan(SMCHN chn,int pan) -{ - if(pOpenALDevice) - { - if(pan<-100)pan=-100;if(pan>100)pan=100; - alSource3f((ALuint)chn,AL_POSITION,((ALfloat)pan)/100.,.0,.0); - } -} -void SMELT_IMPL::smChannelPitch(SMCHN chn,float pitch) -{ - if(pOpenALDevice)alSourcef((ALuint)chn,AL_PITCH,pitch); -} -void SMELT_IMPL::smChannelPause(SMCHN chn) -{ - if(pOpenALDevice)alSourcePause((ALuint)chn); -} -void SMELT_IMPL::smChannelResume(SMCHN chn) -{ - if(pOpenALDevice)alSourcePlay((ALuint)chn); -} -void SMELT_IMPL::smChannelStop(SMCHN chn) -{ - if(pOpenALDevice)alSourceStop((ALuint)chn); -} -void SMELT_IMPL::smChannelPauseAll() -{ - if(pOpenALDevice) - { - ALCcontext *ctx=alcGetCurrentContext(); - alcSuspendContext(ctx); - } -} -void SMELT_IMPL::smChannelResumeAll() -{ - if(pOpenALDevice) - { - ALCcontext *ctx=alcGetCurrentContext(); - alcProcessContext(ctx); - } -} -void SMELT_IMPL::smChannelStopAll() -{ - if(pOpenALDevice) - { - for(int i=0;i<scnt;++i)alSourceStop(src[i]); - } -} -bool SMELT_IMPL::smChannelIsPlaying(SMCHN chn) -{ - if(pOpenALDevice) - { - ALint state=AL_STOPPED; - alGetSourceiv((ALuint)chn,AL_SOURCE_STATE,&state); - return state==AL_PLAYING; - } - return false; -} -float SMELT_IMPL::smChannelGetPosf(SMCHN chn) -{ - if(pOpenALDevice) - { - ALfloat ret; - alGetSourcef((ALuint)chn,AL_SEC_OFFSET,&ret); - return (float)ret; - } - return -1.; -} -void SMELT_IMPL::smChannelSetPosf(SMCHN chn,float pos) -{ - if(pOpenALDevice)alSourcef((ALuint)chn,AL_SEC_OFFSET,(ALfloat)pos); -} -int SMELT_IMPL::smChannelGetPosd(SMCHN chn) -{ - if(pOpenALDevice) - { - ALint ret; - alGetSourcei((ALuint)chn,AL_SAMPLE_OFFSET,&ret); - return (int)ret; - } - return -1; -} -void SMELT_IMPL::smChannelSetPosd(SMCHN chn,int pos) -{ - if(pOpenALDevice)alSourcei((ALuint)chn,AL_SAMPLE_OFFSET,(ALint)pos); -} - -#ifdef ENABLE_OGG_SUPPORT -static size_t oggRead(void *ptr,size_t size,size_t nmemb,void *ds) -{ - oggdata *data=(oggdata*)ds; - const DWORD avail=data->size-data->pos; - size_t want=nmemb*size; - if(want>avail)want=avail-(avail%size); - if(want>0) - { - memcpy(ptr,data->data+data->pos,want); - data->pos+=want; - } - return want/size; -} -static int oggSeek(void *ds,ogg_int64_t offset,int whence) -{ - oggdata *data=(oggdata*)ds; - ogg_int64_t pos=0; - switch(whence) - { - case SEEK_SET:pos=offset;break; - case SEEK_CUR:pos=((ogg_int64_t)data->pos)+offset;break; - case SEEK_END:pos=((ogg_int64_t)data->size)+offset;break; - default: return -1; - } - if((pos<0)||(pos>((ogg_int64_t)data->size)))return -1; - data->pos=(DWORD)pos; - return 0; -} -static long oggLocate(void *ds) -{ - oggdata* data=(oggdata*)ds; - return (long)data->pos; -} -static int oggClose(void *ds){return 0;} - -static ov_callbacks oggrt={oggRead,oggSeek,oggClose,oggLocate}; -static void* readVorbis(const BYTE *data,const DWORD size, ALsizei *decomp_size,ALenum *fmt,ALsizei *freq) -{ - oggdata adata={data,size,0}; - OggVorbis_File vf; - memset(&vf,0,sizeof(vf)); - if(ov_open_callbacks(&adata,&vf,NULL,0,oggrt)==0) - { - int bs=0; - vorbis_info *info=ov_info(&vf,-1); - *decomp_size=0; - *fmt=(info->channels==1)?AL_FORMAT_MONO16:AL_FORMAT_STEREO16; - *freq=info->rate; - if(!(info->channels==1||info->channels==2)){ov_clear(&vf);return NULL;} - char buf[1024*16];long rc=0;size_t allocated=1024*16; - BYTE *ret=(ALubyte*)malloc(allocated); - while((rc=ov_read(&vf,buf,sizeof(buf),0,2,1,&bs))!=0) - { - if(rc>0) - { - *decomp_size+=rc; - if((unsigned)*decomp_size>=allocated) - { - allocated<<=1; - ALubyte *tmp=(ALubyte*)realloc(ret,allocated); - if(!tmp){free(ret);ret=NULL;break;} - ret=tmp; - } - memcpy(ret+(*decomp_size-rc),buf,rc); - } - } - ov_clear(&vf); - return ret; - } - return NULL; -} -#endif -static void* readRiffWv(const BYTE *data,const DWORD size, ALsizei *decomp_size,ALenum *fmt,ALsizei *freq) -{ - if(data[0x0]!='R'||data[0x1]!='I'||data[0x2]!='F'||data[0x3]!='F')return NULL; - if(data[0x8]!='W'||data[0x9]!='A'||data[0xA]!='V'||data[0xB]!='E')return NULL; - if(data[0xC]!='f'||data[0xD]!='m'||data[0xE]!='t'||data[0xF]!=' ')return NULL; - if(data[0x16]==2) - { - if(data[0x22]==16)*fmt=AL_FORMAT_STEREO16; - else if(data[0x22]==8)*fmt=AL_FORMAT_STEREO8; - else return NULL; - } - else if(data[0x16]==1) - { - if(data[0x22]==16)*fmt=AL_FORMAT_MONO16; - else if(data[0x22]==8)*fmt=AL_FORMAT_MONO8; - else return NULL; - }else return NULL; - *decomp_size=(ALsizei)(data[0x28]|(data[0x29]<<8L)|(data[0x2A]<<16L)|(data[0x2B]<<24L)); - *freq=(ALsizei)(data[0x18]|(data[0x19]<<8L)|(data[0x1A]<<16L)|(data[0x1B]<<24L)); - ALubyte *ret=(ALubyte*)malloc(*decomp_size); - memcpy(ret,data+44,*decomp_size); - return ret; -} -ALuint SMELT_IMPL::getSource() -{ - for(int i=0;i<scnt;++i) - { - ALint state=AL_PLAYING; - alGetSourceiv(src[i],AL_SOURCE_STATE,&state); - if(!(state==AL_PLAYING||state==AL_PAUSED))return src[i]; - } - if(scnt>=SRC_MAX)return 0; - ALuint ret=0; - alGenSources(1,&ret);if(!ret)return 0; - src[scnt++]=ret;return ret; -} -bool SMELT_IMPL::initOAL() -{ - if(pOpenALDevice)return true; - scnt=0;memset(src,0,sizeof(src)); - smLog("%s:" SLINE ": Initializing OpenAL...\n",SFX_OAL_SRCFN); - ALCdevice *dev=alcOpenDevice(NULL); - if(!dev) - { - smLog("%s:" SLINE ": alcOpenDevice() failed.\n",SFX_OAL_SRCFN); - return mute=true; - } - ALint caps[]={ALC_FREQUENCY,44100,0}; - ALCcontext *ctx=alcCreateContext(dev,caps); - if(!ctx) - { - smLog("%s:" SLINE ": alcCreateContext() failed.\n",SFX_OAL_SRCFN); - return mute=true; - } - alcMakeContextCurrent(ctx);alcProcessContext(ctx); - smLog("%s:" SLINE ": Done OpenAL initialization\n",SFX_OAL_SRCFN); - smLog("%s:" SLINE ": AL_VENDOR: %s\n",SFX_OAL_SRCFN,(char*)alGetString(AL_VENDOR)); - smLog("%s:" SLINE ": AL_RENDERER: %s\n",SFX_OAL_SRCFN,(char*)alGetString(AL_RENDERER)); - smLog("%s:" SLINE ": AL_VERSION: %s\n",SFX_OAL_SRCFN,(char*)alGetString(AL_VERSION)); - const char* ext=(const char*)alGetString(AL_EXTENSIONS); - lpp=strstr(ext,"AL_SOFT_loop_points")!=NULL; - if(!lpp)smLog("%s:" SLINE ": Warning: loop points not supported. Please recompile with OpenAL Soft.\n",SFX_OAL_SRCFN); - pOpenALDevice=(void*)dev; - return true; -} -void SMELT_IMPL::finiOAL() -{ - if(pOpenALDevice) - { - for(int i=0;i<scnt;++i)alSourceStop(src[i]); - alDeleteSources(scnt,src);scnt=0;memset(src,0,sizeof(src)); - ALCcontext *ctx=alcGetCurrentContext(); - ALCdevice *dev=alcGetContextsDevice(ctx); - alcMakeContextCurrent(NULL); - alcSuspendContext(ctx);alcDestroyContext(ctx); - alcCloseDevice(dev);pOpenALDevice=NULL; - } -} -#else -#include "sfx_dumb.cpp" -#endif //ifndef ENABLE_DUMB |