1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2010-2016, The OpenClonk Team and contributors
5  *
6  * Distributed under the terms of the ISC license; see accompanying file
7  * "COPYING" for details.
8  *
9  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10  * See accompanying file "TRADEMARK" for details.
11  *
12  * To redistribute this file separately, substitute the full license texts
13  * for the above references.
14  */
15 
16 #ifndef INC_C4SoundLoaders
17 #define INC_C4SoundLoaders
18 
19 #include "platform/C4SoundIncludes.h"
20 #include "platform/C4SoundSystem.h"
21 
22 namespace C4SoundLoaders
23 {
24 	struct SoundInfo
25 	{
26 	public:
27 		double sample_length;
28 		uint32_t sample_rate;
29 		std::vector<BYTE> sound_data;
30 #if AUDIO_TK == AUDIO_TK_OPENAL
31 		ALenum format;
32 #endif
33 		C4SoundHandle final_handle{0};
34 
SoundInfoSoundInfo35 		SoundInfo(): sound_data() {}
36 	};
37 
38 	class SoundLoader
39 	{
40 	public:
41 		static const int OPTION_Raw = 1;
42 	public:
43 		static SoundLoader* first_loader;
44 		SoundLoader* next;
SoundLoader()45 		SoundLoader()
46 		{
47 			next = first_loader;
48 			first_loader = this;
49 		}
50 		virtual ~SoundLoader() = default;
51 		virtual bool ReadInfo(SoundInfo* info, BYTE* data, size_t data_length, uint32_t options = 0) = 0;
52 	};
53 
54 #if AUDIO_TK == AUDIO_TK_OPENAL && defined(__APPLE__)
55 	class AppleSoundLoader: public SoundLoader
56 	{
57 	public:
AppleSoundLoader()58 		AppleSoundLoader(): SoundLoader() {}
59 		virtual bool ReadInfo(SoundInfo* result, BYTE* data, size_t data_length, uint32_t);
60 	protected:
61 		static AppleSoundLoader singleton;
62 	};
63 #endif
64 
65 #if AUDIO_TK == AUDIO_TK_OPENAL
66 	class VorbisLoader: public SoundLoader
67 	{
68 	public: // needed by C4MusicFileOgg
69 		struct CompressedData
70 		{
71 		public:
72 			BYTE* data{nullptr};
73 			size_t data_length{0};
74 			size_t data_pos{0};
75 			bool is_data_owned{false}; // if true, dtor will delete data
CompressedDataCompressedData76 			CompressedData(BYTE* data, size_t data_length): data(data), data_length(data_length) {}
77 			CompressedData() = default;
SetOwnedDataCompressedData78 			void SetOwnedData(BYTE* data, size_t data_length)
79 			{ clear(); this->data=data; this->data_length=data_length; this->data_pos=0; is_data_owned=true; }
80 
~CompressedDataCompressedData81 			~CompressedData() { clear(); }
clearCompressedData82 			void clear()  { if (is_data_owned) delete [] data; data=nullptr; }
83 		};
84 		// load from compressed data held in memory buffer
85 		static size_t mem_read_func(void* ptr, size_t byte_size, size_t size_to_read, void* datasource);
86 		static int mem_seek_func(void* datasource, ogg_int64_t offset, int whence);
87 		static int mem_close_func(void* datasource);
88 		static long mem_tell_func(void* datasource);
89 		// load directly from file
90 		static size_t file_read_func(void* ptr, size_t byte_size, size_t size_to_read, void* datasource);
91 		static int file_seek_func(void* datasource, ogg_int64_t offset, int whence);
92 		static int file_close_func(void* datasource);
93 		static long file_tell_func(void* datasource);
94 	public:
95 		bool ReadInfo(SoundInfo* result, BYTE* data, size_t data_length, uint32_t) override;
96 	protected:
97 		static VorbisLoader singleton;
98 	};
99 #ifndef __APPLE__
100 	// non-apple wav loader: using ALUT
101 	class WavLoader: public SoundLoader
102 	{
103 	public:
104 		bool ReadInfo(SoundInfo* result, BYTE* data, size_t data_length, uint32_t) override;
105 	protected:
106 		static WavLoader singleton;
107 	};
108 #endif // apple
109 
110 #elif AUDIO_TK == AUDIO_TK_SDL_MIXER
111 	class SDLMixerSoundLoader: public SoundLoader
112 	{
113 	public:
114 		static SDLMixerSoundLoader singleton;
115 		bool ReadInfo(SoundInfo* result, BYTE* data, size_t data_length, uint32_t) override;
116 	};
117 #endif
118 }
119 
120 #endif
121