aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2015-12-07 23:49:44 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2015-12-07 23:49:44 +0800
commit49e67bc8566e8c5017b931837792a648cb0048c2 (patch)
tree2096cada4bc57e2f89ea4983aa1b045d6780ea4e
parente8a4c69dd159cf248c2335775a69a1214f0c9bc7 (diff)
downloadSMELT-49e67bc8566e8c5017b931837792a648cb0048c2.tar.xz
Add RIFF wave format support. Update documentation.
-rw-r--r--doc/SMELTdoc9
-rw-r--r--include/smelt.hpp86
-rw-r--r--smelt/sdl/sfx_sdl.cpp35
-rw-r--r--smelt/sdl/smelt_internal.hpp2
4 files changed, 112 insertions, 20 deletions
diff --git a/doc/SMELTdoc b/doc/SMELTdoc
index 2f6bdd2..4bbc7a3 100644
--- a/doc/SMELTdoc
+++ b/doc/SMELTdoc
@@ -158,10 +158,13 @@ float smGetTime() [core/FPS]
Gets the time in milliseconds since the call to smInit().
SMSFX smSFXLoad(const char *path) [core/SFX]
-Loads a sound file from the given path. Only ogg files are supported.
+Loads a sound file from the given path. Only ogg and wav files are supported.
+Further more, due to the restrictions of OpenAL, only 8/16bit mono/stereo formats
+are supported.
SMSFX smSFXLoadFromMemory(const char *ptr,DWORD size) [core/SFX]
-Loads a sound file from the given memory block. Only ogg files are supported.
+Loads a sound file from the given memory block. Limitations are the same to that
+of smSFXLoad.
SMCHN smSFXPlay(SMSFX fx,int vol=100,int pan=0,float pitch=1.,bool loop=0)
[core/SFX]
@@ -170,7 +173,7 @@ A channel is generated and can be used to control the playing of the SFX.
The channel is valid until it stops.
Volume should be 0~100.
Panning should be -100~100.
-The values would be clamped to the range given above.
+The values will be clamped to the range given above.
float smSFXGetLengthf(SMSFX fx) [core/SFX]
Gets the sound length in seconds.
diff --git a/include/smelt.hpp b/include/smelt.hpp
index 111c4b8..5435d15 100644
--- a/include/smelt.hpp
+++ b/include/smelt.hpp
@@ -73,7 +73,9 @@ typedef size_t SMCHN;//Audio channel Handle
typedef bool (*smHook)();
//Special FPS modes
+//Unlimited FPS
#define FPS_FREE 0
+//VSync
#define FPS_VSYNC -1
//Primitives
@@ -127,29 +129,29 @@ class SMELT
public:
SMELT(){}
virtual ~SMELT(){}
- /*
+ /**
* Releases the acquired SMELT interface.
* Decreases the internal reference counter by one. If the counter
* reaches 0, SMELT core will release all resources managed by it
* (if smFinale() is not yet called) and destroy the interface.
*/
virtual void smRelease()=0;
- /*
+ /**
* Initializes SMELT core.
* Creates application window, initializes video, audio and input
* handling. No functions in these categories can be called before
* the core is initialized.
* Returns true on succees, false on failure. Error details will be
- * written to the log file.
+ * written to the log file and stderr.
*/
virtual bool smInit()=0;
- /*
+ /**
* Deinitializes SMELT core.
* Closes application window and frees resources managed by the core.
* The core will return to the status before calling smInit().
*/
virtual void smFinale()=0;
- /*
+ /**
* Enters the main loop.
* The main loop calls update function, focus gain function, focus
* lost function and quit function periodally, handles input events
@@ -159,27 +161,27 @@ public:
* The main loop breaks when the update function returns true.
*/
virtual void smMainLoop()=0;
- /*
+ /**
* Sets the update function.
* Update function is called every frame.
* It returns true when you want to terminate the main loop.
*/
virtual void smUpdateFunc(smHook func)=0;
- /*
+ /**
* Sets the focus lost function.
* Focus lost function is called when the application window loses
* focus.
* The return value of the focus lost function has no effect.
*/
virtual void smUnFocFunc(smHook func)=0;
- /*
+ /**
* Sets the focus gain function.
* Focus gain function is called when the application window gains
* focus. Also called when the application window is created.
* The return value of the focus gain function has no effect.
*/
virtual void smFocFunc(smHook func)=0;
- /*
+ /**
* Sets the quit function.
* Quit function is called when the user attempts to close the
* application window.
@@ -187,16 +189,17 @@ public:
* Otherwise the main loop will break.
*/
virtual void smQuitFunc(smHook func)=0;
- /*
+ /**
* Sets the window title of the application window.
* The default window title is "untitled".
*/
virtual void smWinTitle(const char* title)=0;
- /*
+ /**
* Tests if the application window has focus.
+ * Returns the test result.
*/
virtual bool smIsActive()=0;
- /*
+ /**
* Changes the behavior when the application window loses focus.
* By default, the main loop pauses when the application loses focus
* (para=false).
@@ -225,21 +228,78 @@ public:
virtual void smLog(const char* format,...)=0;
/*
* Saves the content of the application window to the given path.
- * The picture is saved in BMP format.
+ * The picture is saved in the BMP format.
*/
virtual void smScreenShot(const char* path)=0;
+ /*
+ * Sets the desired FPS value. The macros FPS_* can be used
+ */
virtual void smSetFPS(int fps)=0;
+ /*
+ * Get *current* FPS value your application is running at.
+ * Not the value you set!
+ * Returns the FPS value, which is updated once a second.
+ */
virtual float smGetFPS()=0;
+ /*
+ * Get delta time between the current frame and the last frame.
+ * Return the value in seconds.
+ */
virtual float smGetDelta()=0;
+ /*
+ * Get elapsed time since calling smInit() in seconds.
+ * Returns the result.
+ */
virtual float smGetTime()=0;
+ /*
+ * Load a single sound file into memory.
+ * Currently only ogg and wav files are supported.
+ * This function loads and decodes the ogg data, which may take
+ * noticeable time to complete. Consider running it in a seperate
+ * thread if you are loading a larger file.
+ * Returns the SFX handle on success, or 0 on failure.
+ */
virtual SMSFX smSFXLoad(const char *path)=0;
+ /*
+ * Loads sound file from the given memory block.
+ * Only ogg and wav formats are supported.
+ * Returns the SFX handle on success, or 0 on failure.
+ */
virtual SMSFX smSFXLoadFromMemory(const char *ptr,DWORD size)=0;
+ /*
+ * Plays the sound.
+ * If loop is set to false, the audio won't loop even if loop points
+ * are set.
+ * Volume should be between 0 to 100.
+ * Panning should be between -100 to 100.
+ * The values will be clamped to the range given above.
+ * Returns the audio channel it occupies, or 0 if there's no audio
+ * channel available.
+ * Max audio channels can be modified in smelt_config.hpp.
+ */
virtual SMCHN smSFXPlay(SMSFX fx,int vol=100,int pan=0,float pitch=1.,bool loop=0)=0;
+ /*
+ * Gets the length of the audio, in seconds.
+ * Returns the result.
+ */
virtual float smSFXGetLengthf(SMSFX fx)=0;
+ /*
+ * Gets the length of the audio, in sample numbers.
+ * Returns the result.
+ */
virtual DWORD smSFXGetLengthd(SMSFX fx)=0;
+ /*
+ * Sets the loop points of the given sound.
+ * By default, the whole sound is looped.
+ * This function uses AL_SOFT_loop_points. So it may not work if
+ * SMELT isn't build against OpenAL Soft
+ */
virtual void smSFXSetLoopPoint(SMSFX fx,DWORD l,DWORD r)=0;
+ /*
+ * Unloads the audio file from memory.
+ */
virtual void smSFXFree(SMSFX fx)=0;
virtual void smChannelVol(SMCHN chn,int vol)=0;
diff --git a/smelt/sdl/sfx_sdl.cpp b/smelt/sdl/sfx_sdl.cpp
index b61a8a0..c49162a 100644
--- a/smelt/sdl/sfx_sdl.cpp
+++ b/smelt/sdl/sfx_sdl.cpp
@@ -13,6 +13,7 @@
static const char* SFX_SDL_SRCFN="smelt/sdl/sfx_sdl.cpp";
struct oggdata{const BYTE *data;DWORD size,pos;};
static void* readVorbis(const BYTE *data,const DWORD size, ALsizei *decomp_size,ALenum *fmt,ALsizei *freq);
+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;
@@ -33,15 +34,20 @@ SMSFX SMELT_IMPL::smSFXLoadFromMemory(const char *ptr,DWORD size)
if(pOpenALDevice&&!mute)
{
bool isOgg=size>4&&ptr[0]=='O'&&ptr[1]=='g'&&ptr[2]=='g'&&ptr[3]=='S';
- if(!isOgg)return 0;
void *decompdata=NULL,*decomp=NULL;
ALsizei decompsize=0,freq=0;
ALenum fmt=AL_FORMAT_STEREO16;
- decompdata=readVorbis((const BYTE*)ptr,size,&decompsize,&fmt,&freq);
+ decompdata=readRiffWv((const BYTE*)ptr,size,&decompsize,&fmt,&freq);
+ if(!decompdata)
+ {
+ if(!isOgg)return 0;
+ else decompdata=readVorbis((const BYTE*)ptr,size,&decompsize,&fmt,&freq);
+ }
+ if(!decompdata)return 0;
decomp=decompdata;
ALuint buff=0;alGenBuffers(1,&buff);
alBufferData(buff,fmt,decomp,decompsize,freq);
- free(decompdata);return (SMSFX)buff;
+ free(decompdata);return(SMSFX)buff;
}
return 0;
}
@@ -270,6 +276,29 @@ static void* readVorbis(const BYTE *data,const DWORD size, ALsizei *decomp_size,
}
return NULL;
}
+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)
diff --git a/smelt/sdl/smelt_internal.hpp b/smelt/sdl/smelt_internal.hpp
index 2688fdd..a434079 100644
--- a/smelt/sdl/smelt_internal.hpp
+++ b/smelt/sdl/smelt_internal.hpp
@@ -12,6 +12,7 @@
#define SMELT_INTERNAL_H
#include "../../include/smelt.hpp"
+#include "smelt_config.hpp"
#include <cstdio>
#include <cstring>
#include <cstdlib>
@@ -25,7 +26,6 @@
#include <AL/alext.h>
#include <ogg/ogg.h>
#include <vorbis/vorbisfile.h>
-#include <smelt_config.hpp>
#ifdef WIN32
#include <windows.h>
#include <intrin.h>