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
41 const Decoder::ListType
& Decoder::GetList()
44 Decoder::ListType
& Decoder::AddList(Decoder::FactoryType func
, ALint prio
)
46 static ListType FuncList
;
49 assert(SearchSecond(FuncList
.begin(), FuncList
.end(), func
) == FuncList
.end());
50 FuncList
.insert(std::make_pair(prio
, func
));
56 struct customStream
: public alureStream
{
65 virtual bool IsValid()
66 { return usrFile
!= NULL
; }
68 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
72 if(!cb
.get_fmt
|| !cb
.get_fmt(usrFile
, &format
, &samplerate
, &blockAlign
))
75 if(DetectBlockAlignment(format
) != blockAlign
)
79 *frequency
= samplerate
;
80 *blockalign
= blockAlign
;
84 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
85 { return cb
.decode(usrFile
, data
, bytes
); }
89 if(cb
.rewind
&& cb
.rewind(usrFile
))
91 SetError("Rewind failed");
95 customStream(const char *fname
, const UserCallbacks
&callbacks
)
96 : alureStream(NULL
), usrFile(NULL
), format(AL_NONE
), samplerate(0),
97 blockAlign(0), cb(callbacks
)
98 { if(cb
.open_file
) usrFile
= cb
.open_file(fname
); }
100 customStream(const MemDataInfo
&memData
, const UserCallbacks
&callbacks
)
101 : alureStream(NULL
), usrFile(NULL
), format(AL_NONE
), samplerate(0),
102 blockAlign(0), memInfo(memData
), cb(callbacks
)
103 { if(cb
.open_mem
) usrFile
= cb
.open_mem(memInfo
.Data
, memInfo
.Length
); }
105 customStream(void *userdata
, ALenum fmt
, ALuint srate
, const UserCallbacks
&callbacks
)
106 : alureStream(NULL
), usrFile(userdata
), format(fmt
), samplerate(srate
),
107 blockAlign(DetectBlockAlignment(format
)), cb(callbacks
)
110 virtual ~customStream()
112 if(cb
.close
&& usrFile
)
119 template <typename T
>
120 static alureStream
*get_stream_decoder(const T
&fdata
)
122 std::map
<ALint
,UserCallbacks
>::iterator i
= InstalledCallbacks
.begin();
123 while(i
!= InstalledCallbacks
.end() && i
->first
< 0)
125 std::auto_ptr
<alureStream
> stream(new customStream(fdata
, i
->second
));
126 if(stream
->IsValid()) return stream
.release();
130 std::istream
*file
= new InStream(fdata
);
133 const Decoder::ListType Factories
= Decoder::GetList();
134 Decoder::ListType::const_reverse_iterator factory
= Factories
.rbegin();
135 Decoder::ListType::const_reverse_iterator end
= Factories
.rend();
136 while(factory
!= end
)
139 file
->seekg(0, std::ios_base::beg
);
141 std::auto_ptr
<alureStream
> stream(factory
->second(file
));
142 if(stream
.get() != NULL
) return stream
.release();
147 SetError("Unsupported type");
152 SetError("Failed to open file");
156 while(i
!= InstalledCallbacks
.end())
158 std::auto_ptr
<alureStream
> stream(new customStream(fdata
, i
->second
));
159 if(stream
->IsValid()) return stream
.release();
166 alureStream
*create_stream(const char *fname
)
167 { return get_stream_decoder(fname
); }
168 alureStream
*create_stream(const MemDataInfo
&memData
)
169 { return get_stream_decoder(memData
); }
171 alureStream
*create_stream(ALvoid
*userdata
, ALenum format
, ALuint rate
, const UserCallbacks
&cb
)
172 { return new customStream(userdata
, format
, rate
, cb
); }