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
34 struct aiffStream
: public alureStream
{
45 static void Init() { }
46 static void Deinit() { }
48 virtual bool IsValid()
49 { return (dataStart
> 0 && format
!= AL_NONE
); }
51 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
54 *frequency
= samplerate
;
55 *blockalign
= blockAlign
;
59 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
61 std::streamsize rem
= ((remLen
>= bytes
) ? bytes
: remLen
) / blockAlign
;
62 fstream
->read(reinterpret_cast<char*>(data
), rem
*blockAlign
);
64 std::streamsize got
= fstream
->gcount();
65 got
-= got
%blockAlign
;
72 for(std::streamsize i
= 0;i
< got
;i
+=2)
73 swap(data
[i
], data
[i
+1]);
75 else if(sampleSize
== 4)
77 for(std::streamsize i
= 0;i
< got
;i
+=4)
79 swap(data
[i
+0], data
[i
+3]);
80 swap(data
[i
+1], data
[i
+2]);
91 if(fstream
->seekg(dataStart
))
97 SetError("Seek failed");
101 aiffStream(std::istream
*_fstream
)
102 : alureStream(_fstream
), format(0), dataStart(0)
107 if(!fstream
->read(reinterpret_cast<char*>(buffer
), 12) ||
108 memcmp(buffer
, "FORM", 4) != 0 || memcmp(buffer
+8, "AIFF", 4) != 0)
111 while(!dataStart
|| format
== AL_NONE
)
114 if(!fstream
->read(tag
, 4))
117 /* read chunk length */
118 length
= read_be32(fstream
);
120 if(memcmp(tag
, "COMM", 4) == 0 && length
>= 18)
122 /* mono or stereo data */
123 int channels
= read_be16(fstream
);
125 /* number of sample frames */
128 /* bits per sample */
129 sampleSize
= read_be16(fstream
) / 8;
131 /* sample frequency */
132 samplerate
= read_be80extended(fstream
);
134 /* block alignment */
135 blockAlign
= channels
* sampleSize
;
137 format
= GetSampleFormat(channels
, sampleSize
*8, false);
141 else if(memcmp(tag
, "SSND", 4) == 0)
143 dataStart
= fstream
->tellg();
145 dataLen
= remLen
= length
- 8;
148 fstream
->seekg(length
, std::ios_base::cur
);
151 if(dataStart
> 0 && format
!= AL_NONE
)
152 fstream
->seekg(dataStart
);
155 virtual ~aiffStream()
158 static DecoderDecl
<aiffStream
> aiffStream_decoder
;