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 SNDFILE_LIB "libsndfile-1.dll"
38 #elif defined(__APPLE__)
39 #define SNDFILE_LIB "libsndfile.1.dylib"
41 #define SNDFILE_LIB "libsndfile.so.1"
44 static void *sndfile_handle
;
45 #define MAKE_FUNC(x) static typeof(x)* p##x
47 MAKE_FUNC(sf_open_virtual
);
48 MAKE_FUNC(sf_readf_short
);
53 struct sndStream
: public alureStream
{
62 sndfile_handle
= OpenLib(SNDFILE_LIB
);
63 if(!sndfile_handle
) return;
65 LOAD_FUNC(sndfile_handle
, sf_close
);
66 LOAD_FUNC(sndfile_handle
, sf_open_virtual
);
67 LOAD_FUNC(sndfile_handle
, sf_readf_short
);
68 LOAD_FUNC(sndfile_handle
, sf_seek
);
73 CloseLib(sndfile_handle
);
74 sndfile_handle
= NULL
;
77 virtual bool IsValid()
78 { return sndFile
!= NULL
; }
80 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
83 format
= GetSampleFormat(sndInfo
.channels
, 16, false);
85 *frequency
= sndInfo
.samplerate
;
86 *blockalign
= sndInfo
.channels
*2;
90 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
92 const ALuint frameSize
= 2*sndInfo
.channels
;
93 return psf_readf_short(sndFile
, (short*)data
, bytes
/frameSize
) * frameSize
;
98 if(psf_seek(sndFile
, 0, SEEK_SET
) != -1)
101 SetError("Seek failed");
105 sndStream(std::istream
*_fstream
)
106 : alureStream(_fstream
), sndFile(NULL
), format(AL_NONE
)
108 memset(&sndInfo
, 0, sizeof(sndInfo
));
110 if(!sndfile_handle
) return;
112 static SF_VIRTUAL_IO streamIO
= {
116 sndFile
= psf_open_virtual(&streamIO
, SFM_READ
, &sndInfo
, this);
127 // libSndFile iostream callbacks
128 static sf_count_t
get_filelen(void *user_data
)
130 std::istream
*stream
= static_cast<sndStream
*>(user_data
)->fstream
;
133 std::streampos len
= -1;
134 std::streampos pos
= stream
->tellg();
135 if(stream
->seekg(0, std::ios_base::end
))
137 len
= stream
->tellg();
144 static sf_count_t
seek(sf_count_t offset
, int whence
, void *user_data
)
146 std::istream
*stream
= static_cast<sndStream
*>(user_data
)->fstream
;
149 if((whence
== SEEK_CUR
&& stream
->seekg(offset
, std::ios_base::cur
)) ||
150 (whence
== SEEK_SET
&& stream
->seekg(offset
, std::ios_base::beg
)) ||
151 (whence
== SEEK_END
&& stream
->seekg(offset
, std::ios_base::end
)))
152 return stream
->tellg();
157 static sf_count_t
read(void *ptr
, sf_count_t count
, void *user_data
)
159 std::istream
*stream
= static_cast<sndStream
*>(user_data
)->fstream
;
161 stream
->read(static_cast<char*>(ptr
), count
);
162 return stream
->gcount();
165 static sf_count_t
write(const void*, sf_count_t
, void*)
168 static sf_count_t
tell(void *user_data
)
170 std::istream
*stream
= static_cast<sndStream
*>(user_data
)->fstream
;
172 return stream
->tellg();
175 static DecoderDecl
<sndStream
,0> sndStream_decoder
;
176 Decoder
&alure_init_sndfile(void)
177 { return sndStream_decoder
; }