aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/Audio/SDL/je_sdl_source.h
blob: 15676d6052dcdd0b89fb4462f4124941d8c195f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#ifndef __LIBJIN_SOURCE_SDL_H
#define __LIBJIN_SOURCE_SDL_H
#include "../../core/je_configuration.h"
#if LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO

#include <vector>
#include <queue>
#include <stack>
#include <exception>

#include "../je_source.h"

namespace jin
{
	namespace audio
	{

		typedef struct SDLSourceCommand;
		class SDLSourceManager;

		class SDLSource : public Source
		{
		public: 
			static SDLSource* createSource(const char* file);
			static SDLSource* createSource(void* mem, size_t size);

			~SDLSource();
			/* 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;
			/* handle and process anduio clip */
			inline void handle(SDLSourceManager* manager, SDLSourceCommand* cmd);
			inline void process(void* buffer, size_t size);

		protected:
			SDLSource();
			/* decode raw audio data */
			void decode_wav(void* mem, int size);
			void decode_ogg(void* mem, int size);
			/* check state */
			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
				float volume;           // 
			} status;

		};

		class SDLSourceManager
		{
		public:
			static SDLSourceManager* get();

			/* Process function */
			void processCommands();
			void processSources(void* buffer, size_t size);
			/* control flow */        
			void removeAllSource();
			void removeSource(SDLSource* source);
			void pushSource(SDLSource* source);
			SDLSourceCommand* getCommand();
			void pushCommand(SDLSourceCommand* cmd);
        
		private : 
			std::queue<SDLSourceCommand*> commands;
			std::stack<SDLSourceCommand*> commandsPool;
			std::vector<SDLSource*> sources;            // processing sources
			static SDLSourceManager* manager;

		};

		class SourceException : public std::exception
		{
			const char * what() const throw ()
			{
				return "Load Source Exception";
			}
		};

	} // namespace audio
} // namespace jin

#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO
#endif // __LIBJIN_SOURCE_SDL_H