aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/Audio
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/Audio')
-rw-r--r--src/libjin/Audio/Audio.cpp15
-rw-r--r--src/libjin/Audio/Audio.h46
-rw-r--r--src/libjin/Audio/OpenAL/Audio.cpp0
-rw-r--r--src/libjin/Audio/OpenAL/Audio.h0
-rw-r--r--src/libjin/Audio/OpenAL/Source.cpp0
-rw-r--r--src/libjin/Audio/OpenAL/Source.h0
-rw-r--r--src/libjin/Audio/SDL/Audio.cpp121
-rw-r--r--src/libjin/Audio/SDL/Audio.h68
-rw-r--r--src/libjin/Audio/SDL/Source.cpp399
-rw-r--r--src/libjin/Audio/SDL/Source.h116
-rw-r--r--src/libjin/Audio/Source.cpp28
-rw-r--r--src/libjin/Audio/Source.h51
12 files changed, 844 insertions, 0 deletions
diff --git a/src/libjin/Audio/Audio.cpp b/src/libjin/Audio/Audio.cpp
new file mode 100644
index 0000000..363bf4d
--- /dev/null
+++ b/src/libjin/Audio/Audio.cpp
@@ -0,0 +1,15 @@
+#include "../modules.h"
+#if JIN_MODULES_AUDIO
+
+#include <SDL2/SDL.h>
+#include "audio.h"
+
+namespace jin
+{
+namespace audio
+{
+
+}
+}
+
+#endif // JIN_MODULES_AUDIO \ No newline at end of file
diff --git a/src/libjin/Audio/Audio.h b/src/libjin/Audio/Audio.h
new file mode 100644
index 0000000..faec4db
--- /dev/null
+++ b/src/libjin/Audio/Audio.h
@@ -0,0 +1,46 @@
+#ifndef __JIN_AUDIO_H
+#define __JIN_AUDIO_H
+#include "../modules.h"
+#if JIN_MODULES_AUDIO
+
+#include <SDL2/SDL.h>
+
+#include "../utils/macros.h"
+#include "../common/subsystem.h"
+
+namespace jin
+{
+namespace audio
+{
+ class Source;
+
+ template<class SubAudioSystem>
+ class AudioSystem : public Subsystem<SubAudioSystem>
+ {
+
+ public:
+
+ virtual void play() = 0;
+ virtual void stop() = 0;
+ virtual bool pause() = 0;
+ virtual bool pause(Source* source) = 0;
+ virtual bool resume() = 0;
+ virtual bool resume(Source* source) = 0;
+ virtual void rewind() = 0;
+ virtual void setVolume(float volume) = 0;
+ virtual float getVolume() = 0;
+
+ protected:
+
+ AudioSystem() {};
+ virtual ~AudioSystem() {};
+
+ SINGLETON(AudioSystem);
+
+ };
+
+}
+}
+
+#endif // JIN_MODULES_AUDIO
+#endif \ No newline at end of file
diff --git a/src/libjin/Audio/OpenAL/Audio.cpp b/src/libjin/Audio/OpenAL/Audio.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/libjin/Audio/OpenAL/Audio.cpp
diff --git a/src/libjin/Audio/OpenAL/Audio.h b/src/libjin/Audio/OpenAL/Audio.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/libjin/Audio/OpenAL/Audio.h
diff --git a/src/libjin/Audio/OpenAL/Source.cpp b/src/libjin/Audio/OpenAL/Source.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/libjin/Audio/OpenAL/Source.cpp
diff --git a/src/libjin/Audio/OpenAL/Source.h b/src/libjin/Audio/OpenAL/Source.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/libjin/Audio/OpenAL/Source.h
diff --git a/src/libjin/Audio/SDL/Audio.cpp b/src/libjin/Audio/SDL/Audio.cpp
new file mode 100644
index 0000000..47d8cf8
--- /dev/null
+++ b/src/libjin/Audio/SDL/Audio.cpp
@@ -0,0 +1,121 @@
+#include "../../modules.h"
+#if JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO
+
+#include <iostream>
+#include "audio.h"
+#include "source.h"
+#include "../../math/math.h"
+#include "../../utils/log.h"
+
+namespace jin
+{
+namespace audio
+{
+
+ /* עcallbackƵ̵߳ */
+ static void defaultCallback(void *userdata, Uint8 *stream, int size)
+ {
+ static SDLAudio* audio = static_cast<SDLAudio*>(userdata);
+ audio->lock();
+ audio->processCommands();
+ audio->processSources(stream, size);
+ audio->unlock();
+ }
+
+ onlyonce bool SDLAudio::initSystem(const SettingBase* s)
+ {
+ Loghelper::log(Loglevel::LV_INFO, "Init Audio System");
+
+ if (SDL_Init(SDL_INIT_AUDIO) < 0)
+ return false;
+ SDL_AudioSpec spec;
+ Setting* setting = (Setting*)s;
+ if (setting == nullptr)
+ return false;
+
+ unsigned int samplerate = setting->samplerate;
+ unsigned int samples = clamp(setting->samples, 1, setting->samplerate);
+
+ spec.freq = samplerate; // ÿsample,õ 11025, 22050, 44100 and 48000 Hz.
+ spec.format = AUDIO_S16SYS; // signed 16-bit samples in native byte order
+ spec.channels = SDLAUDIO_CHANNELS; //
+ spec.samples = samples; // ÿβʱһã=setting->samplerateÿֻ1
+ spec.userdata = this;
+ spec.callback = defaultCallback;
+
+ audioDevice = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0);
+ if (audioDevice == 0)
+ return false;
+ /* start audio */
+ SDL_PauseAudioDevice(audioDevice, 0);
+ return true;
+ }
+
+ onlyonce void SDLAudio::quitSystem()
+ {
+ SDL_CloseAudio();
+ }
+
+ void SDLAudio::lock()
+ {
+ SDL_LockAudioDevice(audioDevice);
+ }
+
+ void SDLAudio::unlock()
+ {
+ SDL_UnlockAudioDevice(audioDevice);
+ }
+
+ void SDLAudio::processCommands()
+ {
+ SDLSourceManager::get()->processCommands();
+ }
+
+ void SDLAudio::processSources(void* buffer, size_t len)
+ {
+ SDLSourceManager::get()->processSources(buffer, len);
+ }
+
+ void SDLAudio::play() {}
+
+ void SDLAudio::stop() {}
+
+ bool SDLAudio::pause()
+ {
+ return false;
+ }
+
+ bool SDLAudio::pause(Source* source)
+ {
+ return false;
+ }
+
+ bool SDLAudio::resume()
+ {
+ return false;
+ }
+
+ bool SDLAudio::resume(Source* source)
+ {
+ return false;
+ }
+
+ void SDLAudio::rewind()
+ {
+
+ }
+
+ void SDLAudio::setVolume(float volume)
+ {
+
+ }
+
+ float SDLAudio::getVolume()
+ {
+ return 0.f;
+ }
+
+}
+}
+
+#endif // JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO \ No newline at end of file
diff --git a/src/libjin/Audio/SDL/Audio.h b/src/libjin/Audio/SDL/Audio.h
new file mode 100644
index 0000000..6da6605
--- /dev/null
+++ b/src/libjin/Audio/SDL/Audio.h
@@ -0,0 +1,68 @@
+#ifndef __JIN_AUDIO_SDL_H
+#define __JIN_AUDIO_SDL_H
+#include "../../modules.h"
+#if JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO
+
+#include <vector>
+#include "../audio.h"
+
+namespace jin
+{
+namespace audio
+{
+
+#define SDLAUDIO_BITDEPTH 16
+#define SDLAUDIO_BYTEDEPTH (SDLAUDIO_BITDEPTH >> 3)
+#define SDLAUDIO_CHANNELS 2
+
+ class SDLAudio : public AudioSystem<SDLAudio>
+ {
+
+ public:
+
+ struct Setting : SettingBase
+ {
+ public:
+ int samplerate; // Ƶ
+ int samples; // sample<=samplerate
+ };
+
+ /* IAudio interface */
+ void play() override;
+ void stop() override;
+ bool pause() override;
+ bool pause(Source* source) override;
+ bool resume() override;
+ bool resume(Source* source) override;
+ void rewind() override;
+ void setVolume(float volume) override;
+ float getVolume() override;
+
+ /* process functions*/
+ void processCommands();
+ void processSources(void* buffer, size_t len);
+
+ void lock();
+ void unlock();
+
+ private:
+
+ SDLAudio() {};
+ ~SDLAudio() {};
+
+ SINGLETON(SDLAudio);
+
+ onlyonce bool initSystem(const SettingBase* setting) override;
+ onlyonce void quitSystem() override;
+
+ unsigned int audioDevice;
+
+ };
+
+ typedef SDLAudio::Setting SDLAudioSetting;
+
+}
+}
+
+#endif // JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO
+#endif \ No newline at end of file
diff --git a/src/libjin/Audio/SDL/Source.cpp b/src/libjin/Audio/SDL/Source.cpp
new file mode 100644
index 0000000..0eedbba
--- /dev/null
+++ b/src/libjin/Audio/SDL/Source.cpp
@@ -0,0 +1,399 @@
+#include "../../modules.h"
+#if JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO
+
+#include <exception>
+#include <fstream>
+
+#include "../../math/math.h"
+#include "../../utils/macros.h"
+#include "source.h"
+#include "3rdparty/wav/wav.h"
+#define STB_VORBIS_HEADER_ONLY
+#include "3rdparty/stb/stb_vorbis.c"
+
+#include "audio.h"
+
+namespace jin
+{
+namespace audio
+{
+
+#define BITS 8
+
+ typedef struct SDLSourceCommand
+ {
+ typedef enum Action
+ {
+ Nothing = 0,
+ Play,
+ Stop,
+ Pause,
+ Resume,
+ Rewind,
+ SetVolume,
+ SetLoop,
+ SetRate,
+ };
+ Action action;
+ union {
+ int _integer;
+ float _float;
+ bool _boolean;
+ const char* _string;
+ } parameter;
+
+ SDLSource* source;
+ };
+
+ typedef enum CHANNEL
+ {
+ MONO = 1, //
+ STEREO = 2, //
+ };
+
+ typedef MASK enum STATUS
+ {
+ PLAYING = 1,
+ PAUSED = 2,
+ STOPPED = 4
+ };
+
+#define Command SDLSourceCommand
+#define Action Command::Action
+#define Manager SDLSourceManager
+
+ shared std::queue<Command*> Manager::commands;
+ shared std::stack<Command*> Manager::commandsPool;
+ shared std::vector<SDLSource*> Manager::sources;
+ shared Manager* Manager::manager = nullptr;
+
+ SDLSource* SDLSource::createSource(const char* file)
+ {
+ std::ifstream fs;
+ fs.open(file, std::ios::binary);
+ if (!fs.is_open())
+ {
+ fs.close();
+ return nullptr;
+ }
+ fs.seekg(0,std::ios::end);
+ int size = fs.tellg();
+ fs.seekg(0, std::ios::beg);
+ char* buffer = (char*)malloc(size);
+ memset(buffer, 0, size);
+ fs.read(buffer, size);
+ fs.close();
+ SDLSource* source = createSource(buffer, size);
+ free(buffer);
+ return source;
+ }
+
+ SDLSource* SDLSource::createSource(void* mem, size_t size)
+ {
+ if (mem == nullptr)
+ return nullptr;
+ SDLSource* source = new SDLSource();
+ try
+ {
+ SourceType format = getType(mem, size);
+ switch (format)
+ {
+ case OGG: source->decode_ogg(mem, size); break;
+ case WAV: source->decode_wav(mem, size); break;
+ }
+ }
+ catch (SourceException& exp)
+ {
+ delete source;
+ return nullptr;
+ };
+ return source;
+ }
+
+ SDLSource::SDLSource()
+ {
+ memset(&status, 0, sizeof(status));
+ memset(&raw, 0, sizeof(raw));
+ }
+
+ SDLSource::~SDLSource()
+ {
+ delete raw.data;
+ raw.end = 0;
+ raw.data = 0;
+ }
+
+ void SDLSource::decode_wav(void* mem, int size)
+ {
+ wav_t wav;
+ if (wav_read(&wav, mem, size) == 0)
+ {
+ raw.data = wav.data;
+ raw.length = wav.length * wav.bitdepth / 8;
+ raw.end = (char*)raw.data + raw.length;
+ raw.samplerate = wav.samplerate;
+ raw.bitdepth = wav.bitdepth;
+ raw.samples = raw.length / (wav.bitdepth / 8.f) / wav.channels;
+ raw.channels = clamp(wav.channels, CHANNEL::MONO, CHANNEL::STEREO);
+ }
+ else
+ throw SourceException();
+ }
+
+ void SDLSource::decode_ogg(void* _mem, int size)
+ {
+ unsigned char* mem = (unsigned char*)_mem;
+ int channels;
+ int samplerate;
+ short* data = (short*)raw.data;
+ int samples = stb_vorbis_decode_memory(
+ mem,
+ size,
+ &channels,
+ &samplerate,
+ &data
+ );
+ const int bitdepth = sizeof(short) * BITS;
+ raw.channels = channels;
+ raw.samplerate = samplerate;
+ raw.data = data;
+ raw.samples = samples;
+ raw.length = samples * channels * sizeof(short);
+ raw.bitdepth = bitdepth;
+ raw.end = (char*)data + raw.length;
+ }
+
+#define ActionNone(T)\
+do{\
+Command* cmd = Manager::get()->getCommand();\
+cmd->action = Action::T; \
+cmd->source = this; \
+Manager::get()->pushCommand(cmd); \
+} while (0)
+
+#define ActionArg(T, ARGT, ARG)\
+do{\
+Command* cmd = Manager::get()->getCommand();\
+cmd->action = Action::T; \
+cmd->parameter.ARGT = ARG; \
+cmd->source = this; \
+Manager::get()->pushCommand(cmd); \
+}while(0)
+
+#define ActionInt(T, INT) ActionArg(T, _integer, INT)
+#define ActionFloat(T, FLT) ActionArg(T, _float, FLT)
+#define ActionString(T, STR) ActionArg(T, _string, STR)
+#define ActionBool(T, BOL) ActionArg(T, _boolean, BOL)
+
+ void SDLSource::play()
+ {
+ ActionNone(Play);
+ }
+
+ void SDLSource::stop()
+ {
+ ActionNone(Stop);
+ }
+
+ void SDLSource::pause()
+ {
+ ActionNone(Pause);
+ }
+
+ void SDLSource::resume()
+ {
+ ActionNone(Resume);
+ }
+
+ void SDLSource::rewind()
+ {
+ ActionNone(Rewind);
+ }
+
+ inline bool SDLSource::isStopped() const
+ {
+ return is(STOPPED);
+ }
+
+ bool SDLSource::isPaused() const
+ {
+ return is(PAUSED);
+ }
+
+ void SDLSource::setPitch(float pitch)
+ {
+ }
+
+ void SDLSource::setVolume(float volume)
+ {
+ ActionFloat(SetVolume, volume);
+ }
+
+ bool SDLSource::setLoop(bool loop)
+ {
+ ActionBool(SetLoop, loop);
+ return false;
+ }
+
+ void SDLSource::setRate(float rate)
+ {
+ ActionFloat(SetRate, rate);
+ }
+
+ inline void SDLSource::handle(
+ SDLSourceManager* manager,
+ SDLSourceCommand* cmd
+ )
+ {
+ switch (cmd->action)
+ {
+ case Command::Action::Play:
+ manager->removeSource(this);
+ manager->pushSource(this);
+ status.state = PLAYING;
+ status.pos = 0; // rewind
+ break;
+ case Command::Action::Stop:
+ manager->removeSource(this);
+ status.state = STOPPED;
+ status.pos = 0; // rewind
+ break;
+ case Command::Action::Pause:
+ manager->removeSource(this);
+ status.state = PAUSED;
+ break;
+ case Command::Action::Resume:
+ manager->removeSource(this);
+ manager->pushSource(this);
+ status.state = PLAYING;
+ break;
+ case Command::Action::Rewind:
+ status.state = PLAYING;
+ status.pos = 0;
+ break;
+ case Command::Action::SetVolume:
+ //float cmd->parameter._float;
+ break;
+ case Command::Action::SetLoop:
+ status.loop = cmd->parameter._boolean;
+ break;
+ }
+ }
+
+ inline void SDLSource::process(void* buf, size_t size)
+ {
+ short* buffer = (short*)buf; // AUDIO_S16SYS
+ unsigned int samples = size / SDLAUDIO_BYTEDEPTH;
+ short* sample;
+ short origin;
+
+ const char bitdepth = raw.bitdepth;
+ const char channles = raw.channels;
+
+ int pos = status.pos;
+ int pitch = status.pitch;
+ int state = status.state;
+ bool loop = status.loop;
+ int volume = status.volume;
+ short* clip16 = nullptr;
+ char* clip8 = nullptr;
+ int clip = 0;
+
+ if (bitdepth == 8)
+ clip8 = (char*)raw.data;
+ else if (bitdepth == 16)
+ clip16 = (short*)raw.data;
+
+ for (int i = 0; i < samples; i+=2 /*˫*/)
+ {
+ /* Ƶļsampleᱻ */
+ sample = buffer + i * SDLAUDIO_BYTEDEPTH;
+ origin = *sample;
+ if (bitdepth == 8)
+ {
+ clip = *clip8;
+ }
+ else if (bitdepth == 16)
+ clip = *clip16;
+
+ }
+ }
+
+ Manager* Manager::get()
+ {
+ return (manager == nullptr ? manager = new Manager() : manager);
+ }
+
+ shared void Manager::processCommands()
+ {
+ Command* cmd = nullptr;
+ SDLSource* source = nullptr;
+ while (!commands.empty())
+ {
+ cmd = commands.front();
+ if (cmd != nullptr)
+ {
+ source = cmd->source;
+ if (source != nullptr)
+ source->handle(manager, cmd);
+ }
+ commands.pop();
+ }
+ }
+
+ /* AUDIO_S16SYS[size>>1] buffer */
+ shared void Manager::processSources(void* buf, size_t size)
+ {
+ /* clear render buffer */
+ memset(buf, 0, size);
+ SDLSource* src = nullptr;
+ std::vector<SDLSource*>::iterator it = sources.begin();
+ for (; it != sources.end();)
+ {
+ src = *it;
+ if (src != nullptr)
+ src->process(buf, size);
+ ++it;
+ }
+ }
+
+ shared void Manager::removeSource(SDLSource* source)
+ {
+ std::vector<SDLSource*>::iterator it = sources.begin();
+ for (it = sources.begin(); it != sources.end(); )
+ {
+ if (*it == source)
+ {
+ it = sources.erase(it);
+ return;
+ }
+ ++it;
+ }
+ }
+
+ shared void Manager::pushSource(SDLSource* source)
+ {
+ if(source != nullptr)
+ sources.push_back(source);
+ }
+
+ shared void Manager::pushCommand(SDLSourceCommand* cmd)
+ {
+ commands.push(cmd);
+ }
+
+ shared Command* Manager::getCommand()
+ {
+ if (!commandsPool.empty())
+ {
+ Command* cmd = commandsPool.top();
+ commandsPool.pop();
+ return cmd;
+ }
+ return new Command();
+ }
+
+}
+}
+
+#endif // JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO \ No newline at end of file
diff --git a/src/libjin/Audio/SDL/Source.h b/src/libjin/Audio/SDL/Source.h
new file mode 100644
index 0000000..38f7ec4
--- /dev/null
+++ b/src/libjin/Audio/SDL/Source.h
@@ -0,0 +1,116 @@
+#ifndef __JIN_SOURCE_SDL_H
+#define __JIN_SOURCE_SDL_H
+#include "../../modules.h"
+#if JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO
+
+#include <vector>
+#include <queue>
+#include <stack>
+#include <exception>
+
+#include "../source.h"
+
+namespace jin
+{
+namespace audio
+{
+
+ typedef struct SDLSourceCommand;
+ class SDLSourceManager;
+
+ class SDLSource : public Source
+ {
+
+ public:
+
+ ~SDLSource();
+
+ static SDLSource* createSource(const char* file);
+ static SDLSource* createSource(void* mem, size_t size);
+
+ /* ISource interface */
+ void play() override;
+ void stop() override;
+ void pause() override;
+ void resume() override;
+ void rewind() override;
+ bool isStopped() const override;
+ bool isPaused() const override;
+ void setPitch(float pitch) override;
+ // Ͻ
+ void setVolume(float volume) override;
+ bool setLoop(bool loop) override;
+ void setRate(float rate) override;
+
+ inline void handle(SDLSourceManager* manager, SDLSourceCommand* cmd);
+ inline void process(void* buffer, size_t size);
+
+ private:
+
+ SDLSource();
+
+ void decode_wav(void* mem, int size);
+ void decode_ogg(void* mem, int size);
+
+ inline bool is(int state) const { return (status.state & state) == state; }
+
+ struct
+ {
+ const void* data; // Ƶ
+ int length; // dataֽڳ
+ const void* end; // dataβ = (unsigned char*)data + size
+ int samplerate; // Ƶ
+ unsigned char bitdepth; // ÿsampleıس
+ int samples; // sample = size / (bitdepth / 8)
+ unsigned char channels; // channel1(mono)2(stereo)
+ } raw;
+
+ /* Procedure controller variable */
+ struct
+ {
+ int pos; // ǰŵsample
+ int pitch; // pitch
+ int state; // ǰ״̬
+ bool loop; // loop or not
+ int volume; //
+ } status;
+
+ };
+
+ class SDLSourceManager
+ {
+
+ public:
+
+ static SDLSourceManager* get();
+
+ /* Process function */
+ static void processCommands();
+ static void processSources(void* buffer, size_t size);
+
+ static void removeSource(SDLSource* source);
+ static void pushSource(SDLSource* source);
+ static SDLSourceCommand* getCommand();
+ static void pushCommand(SDLSourceCommand* cmd);
+
+ static SDLSourceManager* manager;
+
+ static std::queue<SDLSourceCommand*> commands;
+ static std::stack<SDLSourceCommand*> commandsPool;
+ static std::vector<SDLSource*> sources; // processing sources
+
+ };
+
+ class SourceException : public std::exception
+ {
+ const char * what() const throw ()
+ {
+ return "Load Source Exception";
+ }
+ };
+
+}
+}
+
+#endif // JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO
+#endif \ No newline at end of file
diff --git a/src/libjin/Audio/Source.cpp b/src/libjin/Audio/Source.cpp
new file mode 100644
index 0000000..ceb882d
--- /dev/null
+++ b/src/libjin/Audio/Source.cpp
@@ -0,0 +1,28 @@
+#include "../modules.h"
+#if JIN_MODULES_AUDIO
+
+#include <cstring>
+#include "source.h"
+
+namespace jin
+{
+namespace audio
+{
+
+ static int check_header(const void *data, int size, char *str, int offset) {
+ int len = strlen(str);
+ return (size >= offset + len) && !memcmp((char*)data + offset, str, len);
+ }
+
+ SourceType Source::getType(const void* mem, int size)
+ {
+ if(check_header(mem, size, "WAVE", 8))
+ return SourceType::WAV;
+ if(check_header(mem, size, "OggS", 0))
+ return SourceType::OGG;
+ return SourceType::INVALID;
+ }
+
+}
+}
+#endif // JIN_MODULES_AUDIO \ No newline at end of file
diff --git a/src/libjin/Audio/Source.h b/src/libjin/Audio/Source.h
new file mode 100644
index 0000000..5b9c12b
--- /dev/null
+++ b/src/libjin/Audio/Source.h
@@ -0,0 +1,51 @@
+#ifndef __JIN_AUDIO_SOURCE_H
+#define __JIN_AUDIO_SOURCE_H
+#include "../modules.h"
+#if JIN_MODULES_AUDIO
+
+#include <SDL2/SDL.h>
+
+namespace jin
+{
+namespace audio
+{
+
+ enum SourceType
+ {
+ INVALID = 0,
+ WAV,
+ OGG,
+ };
+
+ class Source
+ {
+
+ public:
+
+ Source() {};
+ virtual ~Source() {};
+
+ /* interface */
+ virtual void play() = 0;
+ virtual void stop() = 0;
+ virtual void pause() = 0;
+ virtual void resume() = 0;
+ virtual void rewind() = 0;
+ virtual bool isStopped() const = 0;
+ virtual bool isPaused() const = 0;
+ virtual void setPitch(float pitch) = 0;
+ virtual void setVolume(float volume) = 0;
+ virtual bool setLoop(bool loop) = 0;
+ virtual void setRate(float rate) = 0;
+
+ protected:
+
+ static SourceType getType(const void* mem, int size);
+
+ };
+
+}
+}
+
+#endif // JIN_MODULES_AUDIO
+#endif \ No newline at end of file