2 * ALURE OpenAL utility library
3 * Copyright (c) 2009-2010 by Chris Robinson.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
37 #define MODPLUG_LIB "libmodplug.dll"
38 #elif defined(__APPLE__)
39 #define MODPLUG_LIB "libmodplug.1.dylib"
41 #define MODPLUG_LIB "libmodplug.so.1"
44 static void *mod_handle
;
45 #define MAKE_FUNC(x) static typeof(x)* p##x
46 MAKE_FUNC(ModPlug_Load
);
47 MAKE_FUNC(ModPlug_Unload
);
48 MAKE_FUNC(ModPlug_Read
);
49 MAKE_FUNC(ModPlug_SeekOrder
);
53 struct modStream
: public alureStream
{
61 mod_handle
= OpenLib(MODPLUG_LIB
);
62 if(!mod_handle
) return;
64 LOAD_FUNC(mod_handle
, ModPlug_Load
);
65 LOAD_FUNC(mod_handle
, ModPlug_Unload
);
66 LOAD_FUNC(mod_handle
, ModPlug_Read
);
67 LOAD_FUNC(mod_handle
, ModPlug_SeekOrder
);
76 virtual bool IsValid()
77 { return modFile
!= NULL
; }
79 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
81 *fmt
= AL_FORMAT_STEREO16
;
83 *blockalign
= 2 * sizeof(ALshort
);
87 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
89 int ret
= pModPlug_Read(modFile
, data
, bytes
);
95 { return SetOrder(lastOrder
); }
97 virtual bool SetOrder(ALuint order
)
99 std::vector
<char> data(16384);
103 fstream
->read(&data
[total
], data
.size()-total
);
104 if(fstream
->gcount() == 0) break;
105 total
+= fstream
->gcount();
106 data
.resize(total
*2);
110 ModPlugFile
*newMod
= pModPlug_Load(&data
[0], data
.size());
113 SetError("Could not reload data");
116 pModPlug_Unload(modFile
);
119 // There seems to be no way to tell if the seek succeeds
120 pModPlug_SeekOrder(modFile
, order
);
126 modStream(std::istream
*_fstream
)
127 : alureStream(_fstream
), modFile(NULL
), lastOrder(0)
129 if(!mod_handle
) return;
131 std::vector
<char> data(1024);
134 fstream
->read(&data
[total
], data
.size()-total
);
135 total
+= fstream
->gcount();
136 if(total
< 32) return;
138 if(memcmp(&data
[0], "Extended Module: ", 17) == 0 || /* XM */
139 (data
[28] == 0x1A && data
[29] == 0x10) || /* S3M */
140 memcmp(&data
[0], "IMPM", 4) == 0) /* IT */
144 data
.resize(total
*2);
145 fstream
->read(&data
[total
], data
.size()-total
);
146 if(fstream
->gcount() == 0) break;
147 total
+= fstream
->gcount();
151 modFile
= pModPlug_Load(&data
[0], data
.size());
158 pModPlug_Unload(modFile
);
162 // Priority = -1, because mod loading can find false-positives
163 static DecoderDecl
<modStream
,-1> modStream_decoder
;
164 Decoder
&alure_init_modplug(void)
165 { return modStream_decoder
; }