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 typedef std::auto_ptr
<alureStream
>(*FactoryType
)(std::istream
*);
42 typedef std::vector
<FactoryType
> ListType
;
44 static const ListType
& GetList()
45 { return AddList(NULL
); }
49 static std::auto_ptr
<alureStream
> Factory(std::istream
*file
)
51 std::auto_ptr
<alureStream
> ret(new T(file
));
52 if(ret
->IsValid()) return ret
;
53 return std::auto_ptr
<alureStream
>();
56 static const ListType
& AddList(FactoryType func
)
58 static ListType FuncList
;
59 if(func
) FuncList
.push_back(func
);
64 struct DecoderDecl
: public Decoder
{
65 DecoderDecl() { AddList(Factory
<T
>); }
69 static inline ALuint
read_le32(std::istream
*file
)
72 if(!file
->read(reinterpret_cast<char*>(buffer
), 4)) return 0;
73 return buffer
[0] | (buffer
[1]<<8) | (buffer
[2]<<16) | (buffer
[3]<<24);
76 static inline ALushort
read_le16(std::istream
*file
)
79 if(!file
->read(reinterpret_cast<char*>(buffer
), 2)) return 0;
80 return buffer
[0] | (buffer
[1]<<8);
83 static inline ALuint
read_be32(std::istream
*file
)
86 if(!file
->read(reinterpret_cast<char*>(buffer
), 4)) return 0;
87 return (buffer
[0]<<24) | (buffer
[1]<<16) | (buffer
[2]<<8) | buffer
[3];
90 static inline ALushort
read_be16(std::istream
*file
)
93 if(!file
->read(reinterpret_cast<char*>(buffer
), 2)) return 0;
94 return (buffer
[0]<<8) | buffer
[1];
97 static inline ALuint
read_be80extended(std::istream
*file
)
100 if(!file
->read(reinterpret_cast<char*>(buffer
), 10)) return 0;
101 ALuint mantissa
, last
= 0;
102 ALubyte exp
= buffer
[1];
104 mantissa
= (buffer
[2]<<24) | (buffer
[3]<<16) | (buffer
[4]<<8) | buffer
[5];
110 if((last
&1)) mantissa
++;
115 struct nullStream
: public alureStream
{
116 virtual bool IsValid() { return false; }
117 virtual bool GetFormat(ALenum
*,ALuint
*,ALuint
*) { return false; }
118 virtual ALuint
GetData(ALubyte
*,ALuint
) { return 0; }
119 virtual bool Rewind() { return false; }
120 nullStream():alureStream(NULL
) {}
124 struct customStream
: public alureStream
{
133 virtual bool IsValid()
134 { return usrFile
!= NULL
; }
136 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
138 if(format
== AL_NONE
)
140 if(!cb
.get_fmt
|| !cb
.get_fmt(usrFile
, &format
, &samplerate
, &blockAlign
))
143 if(DetectBlockAlignment(format
) != blockAlign
)
148 *frequency
= samplerate
;
149 *blockalign
= blockAlign
;
153 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
154 { return cb
.decode(usrFile
, data
, bytes
); }
156 virtual bool Rewind()
158 if(cb
.rewind
&& cb
.rewind(usrFile
))
160 SetError("Rewind failed");
164 customStream(const char *fname
, const UserCallbacks
&callbacks
)
165 : alureStream(NULL
), usrFile(NULL
), format(0), samplerate(0),
166 blockAlign(0), cb(callbacks
)
167 { if(cb
.open_file
) usrFile
= cb
.open_file(fname
); }
169 customStream(const MemDataInfo
&memData
, const UserCallbacks
&callbacks
)
170 : alureStream(NULL
), usrFile(NULL
), format(0), samplerate(0),
171 blockAlign(0), memInfo(memData
), cb(callbacks
)
172 { if(cb
.open_mem
) usrFile
= cb
.open_mem(memInfo
.Data
, memInfo
.Length
); }
174 customStream(void *userdata
, ALenum fmt
, ALuint srate
, const UserCallbacks
&callbacks
)
175 : alureStream(NULL
), usrFile(userdata
), format(fmt
), samplerate(srate
),
176 blockAlign(DetectBlockAlignment(format
)), cb(callbacks
)
179 virtual ~customStream()
181 if(cb
.close
&& usrFile
)
188 struct wavStream
: public alureStream
{
197 virtual bool IsValid()
198 { return (dataStart
> 0 && format
!= AL_NONE
); }
200 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
203 *frequency
= samplerate
;
204 *blockalign
= blockAlign
;
208 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
210 std::streamsize rem
= ((remLen
>= bytes
) ? bytes
: remLen
) / blockAlign
;
211 fstream
->read(reinterpret_cast<char*>(data
), rem
*blockAlign
);
213 std::streamsize got
= fstream
->gcount();
214 got
-= got
%blockAlign
;
217 if(BigEndian
&& sampleSize
== 16)
219 for(std::streamsize i
= 0;i
< got
;i
+=2)
220 swap(data
[i
], data
[i
+1]);
222 else if(BigEndian
&& sampleSize
== 32)
224 for(std::streamsize i
= 0;i
< got
;i
+=4)
226 swap(data
[i
+0], data
[i
+3]);
227 swap(data
[i
+1], data
[i
+2]);
230 else if(BigEndian
&& sampleSize
== 64)
232 for(std::streamsize i
= 0;i
< got
;i
+=8)
234 swap(data
[i
+0], data
[i
+7]);
235 swap(data
[i
+1], data
[i
+6]);
236 swap(data
[i
+2], data
[i
+5]);
237 swap(data
[i
+3], data
[i
+4]);
244 virtual bool Rewind()
247 if(fstream
->seekg(dataStart
))
253 SetError("Seek failed");
257 wavStream(std::istream
*_fstream
)
258 : alureStream(_fstream
), format(0), dataStart(0)
263 if(!fstream
->read(reinterpret_cast<char*>(buffer
), 12) ||
264 memcmp(buffer
, "RIFF", 4) != 0 || memcmp(buffer
+8, "WAVE", 4) != 0)
267 while(!dataStart
|| format
== AL_NONE
)
270 if(!fstream
->read(tag
, 4))
273 /* read chunk length */
274 length
= read_le32(fstream
);
276 if(memcmp(tag
, "fmt ", 4) == 0 && length
>= 16)
278 /* Data type (should be 1 for PCM data, 3 for float PCM data,
279 * and 17 for IMA4 data) */
280 int type
= read_le16(fstream
);
281 if(type
!= 0x0001 && type
!= 0x0003 && type
!= 0x0011)
284 /* mono or stereo data */
285 int channels
= read_le16(fstream
);
287 /* sample frequency */
288 samplerate
= read_le32(fstream
);
290 /* skip average bytes per second */
293 /* bytes per block */
294 blockAlign
= read_le16(fstream
);
298 /* bits per sample */
299 sampleSize
= read_le16(fstream
);
303 /* Look for any extra data and try to find the format */
307 extrabytes
= read_le16(fstream
);
310 extrabytes
= std::min(extrabytes
, length
);
313 format
= GetSampleFormat(channels
, sampleSize
, false);
314 else if(type
== 0x0003)
315 format
= GetSampleFormat(channels
, sampleSize
, true);
316 else if(type
== 0x0011 && extrabytes
>= 2)
318 int samples
= read_le16(fstream
);
321 /* AL_EXT_IMA4 only supports 36 bytes-per-channel block
322 * alignment, which has 65 uncompressed sample frames */
323 if(blockAlign
== 36*channels
&& samples
== 65*channels
&&
324 alIsExtensionPresent("AL_EXT_IMA4"))
327 format
= AL_FORMAT_MONO_IMA4
;
328 else if(channels
== 2)
329 format
= AL_FORMAT_STEREO_IMA4
;
333 else if(memcmp(tag
, "data", 4) == 0)
335 dataStart
= fstream
->tellg();
336 dataLen
= remLen
= length
;
339 fstream
->seekg(length
, std::ios_base::cur
);
342 if(dataStart
> 0 && format
!= AL_NONE
)
343 fstream
->seekg(dataStart
);
349 static DecoderDecl
<wavStream
> wavStream_decoder
;
352 struct aiffStream
: public alureStream
{
361 virtual bool IsValid()
362 { return (dataStart
> 0 && format
!= AL_NONE
); }
364 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
367 *frequency
= samplerate
;
368 *blockalign
= blockAlign
;
372 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
374 std::streamsize rem
= ((remLen
>= bytes
) ? bytes
: remLen
) / blockAlign
;
375 fstream
->read(reinterpret_cast<char*>(data
), rem
*blockAlign
);
377 std::streamsize got
= fstream
->gcount();
378 got
-= got
%blockAlign
;
385 for(std::streamsize i
= 0;i
< got
;i
+=2)
386 swap(data
[i
], data
[i
+1]);
388 else if(sampleSize
== 4)
390 for(std::streamsize i
= 0;i
< got
;i
+=4)
392 swap(data
[i
+0], data
[i
+3]);
393 swap(data
[i
+1], data
[i
+2]);
401 virtual bool Rewind()
404 if(fstream
->seekg(dataStart
))
410 SetError("Seek failed");
414 aiffStream(std::istream
*_fstream
)
415 : alureStream(_fstream
), format(0), dataStart(0)
420 if(!fstream
->read(reinterpret_cast<char*>(buffer
), 12) ||
421 memcmp(buffer
, "FORM", 4) != 0 || memcmp(buffer
+8, "AIFF", 4) != 0)
424 while(!dataStart
|| format
== AL_NONE
)
427 if(!fstream
->read(tag
, 4))
430 /* read chunk length */
431 length
= read_be32(fstream
);
433 if(memcmp(tag
, "COMM", 4) == 0 && length
>= 18)
435 /* mono or stereo data */
436 int channels
= read_be16(fstream
);
438 /* number of sample frames */
441 /* bits per sample */
442 sampleSize
= read_be16(fstream
) / 8;
444 /* sample frequency */
445 samplerate
= read_be80extended(fstream
);
447 /* block alignment */
448 blockAlign
= channels
* sampleSize
;
450 format
= GetSampleFormat(channels
, sampleSize
*8, false);
454 else if(memcmp(tag
, "SSND", 4) == 0)
456 dataStart
= fstream
->tellg();
458 dataLen
= remLen
= length
- 8;
461 fstream
->seekg(length
, std::ios_base::cur
);
464 if(dataStart
> 0 && format
!= AL_NONE
)
465 fstream
->seekg(dataStart
);
468 virtual ~aiffStream()
471 static DecoderDecl
<aiffStream
> aiffStream_decoder
;
474 struct sndStream
: public alureStream
{
479 virtual bool IsValid()
480 { return sndFile
!= NULL
; }
482 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
484 if(format
== AL_NONE
)
485 format
= GetSampleFormat(sndInfo
.channels
, 16, false);
487 *frequency
= sndInfo
.samplerate
;
488 *blockalign
= sndInfo
.channels
*2;
492 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
494 const ALuint frameSize
= 2*sndInfo
.channels
;
495 return psf_readf_short(sndFile
, (short*)data
, bytes
/frameSize
) * frameSize
;
498 virtual bool Rewind()
500 if(psf_seek(sndFile
, 0, SEEK_SET
) != -1)
503 SetError("Seek failed");
507 sndStream(std::istream
*_fstream
)
508 : alureStream(_fstream
), sndFile(NULL
), format(AL_NONE
)
510 memset(&sndInfo
, 0, sizeof(sndInfo
));
512 if(!sndfile_handle
) return;
514 static SF_VIRTUAL_IO streamIO
= {
518 sndFile
= psf_open_virtual(&streamIO
, SFM_READ
, &sndInfo
, this);
529 // libSndFile iostream callbacks
530 static sf_count_t
get_filelen(void *user_data
)
532 std::istream
*stream
= static_cast<sndStream
*>(user_data
)->fstream
;
535 std::streampos len
= -1;
536 std::streampos pos
= stream
->tellg();
537 if(stream
->seekg(0, std::ios_base::end
))
539 len
= stream
->tellg();
546 static sf_count_t
seek(sf_count_t offset
, int whence
, void *user_data
)
548 std::istream
*stream
= static_cast<sndStream
*>(user_data
)->fstream
;
551 if(whence
== SEEK_CUR
)
552 stream
->seekg(offset
, std::ios_base::cur
);
553 else if(whence
== SEEK_SET
)
554 stream
->seekg(offset
, std::ios_base::beg
);
555 else if(whence
== SEEK_END
)
556 stream
->seekg(offset
, std::ios_base::end
);
560 return stream
->tellg();
563 static sf_count_t
read(void *ptr
, sf_count_t count
, void *user_data
)
565 std::istream
*stream
= static_cast<sndStream
*>(user_data
)->fstream
;
567 stream
->read(static_cast<char*>(ptr
), count
);
568 return stream
->gcount();
571 static sf_count_t
write(const void*, sf_count_t
, void*)
574 static sf_count_t
tell(void *user_data
)
576 std::istream
*stream
= static_cast<sndStream
*>(user_data
)->fstream
;
578 return stream
->tellg();
581 static DecoderDecl
<sndStream
> sndStream_decoder
;
584 #ifdef HAS_VORBISFILE
585 struct oggStream
: public alureStream
{
586 OggVorbis_File oggFile
;
587 vorbis_info
*oggInfo
;
591 virtual bool IsValid()
592 { return oggInfo
!= NULL
; }
594 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
596 if(format
== AL_NONE
)
597 format
= GetSampleFormat(oggInfo
->channels
, 16, false);
599 *frequency
= oggInfo
->rate
;
600 *blockalign
= oggInfo
->channels
*2;
604 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
609 int res
= pov_read(&oggFile
, (char*)&data
[got
], bytes
, BigEndian
?1:0, 2, 1, &oggBitstream
);
615 // 1, 2, and 4 channel files decode into the same channel order as
616 // OpenAL, however 6(5.1), 7(6.1), and 8(7.1) channel files need to be
618 if(oggInfo
->channels
== 6)
620 ALshort
*samples
= (ALshort
*)data
;
621 for(ALuint i
= 0;i
< got
/sizeof(ALshort
);i
+=6)
623 // OpenAL : FL, FR, FC, LFE, RL, RR
624 // Vorbis : FL, FC, FR, RL, RR, LFE
625 swap(samples
[i
+1], samples
[i
+2]);
626 swap(samples
[i
+3], samples
[i
+5]);
627 swap(samples
[i
+4], samples
[i
+5]);
630 else if(oggInfo
->channels
== 7)
632 ALshort
*samples
= (ALshort
*)data
;
633 for(ALuint i
= 0;i
< got
/sizeof(ALshort
);i
+=7)
635 // OpenAL : FL, FR, FC, LFE, RC, SL, SR
636 // Vorbis : FL, FC, FR, SL, SR, RC, LFE
637 swap(samples
[i
+1], samples
[i
+2]);
638 swap(samples
[i
+3], samples
[i
+6]);
639 swap(samples
[i
+4], samples
[i
+6]);
640 swap(samples
[i
+5], samples
[i
+6]);
643 else if(oggInfo
->channels
== 8)
645 ALshort
*samples
= (ALshort
*)data
;
646 for(ALuint i
= 0;i
< got
/sizeof(ALshort
);i
+=8)
648 // OpenAL : FL, FR, FC, LFE, RL, RR, SL, SR
649 // Vorbis : FL, FC, FR, SL, SR, RL, RR, LFE
650 swap(samples
[i
+1], samples
[i
+2]);
651 swap(samples
[i
+3], samples
[i
+7]);
652 swap(samples
[i
+4], samples
[i
+5]);
653 swap(samples
[i
+5], samples
[i
+6]);
654 swap(samples
[i
+6], samples
[i
+7]);
660 virtual bool Rewind()
662 if(pov_pcm_seek(&oggFile
, 0) == 0)
665 SetError("Seek failed");
669 oggStream(std::istream
*_fstream
)
670 : alureStream(_fstream
), oggInfo(NULL
), oggBitstream(0), format(AL_NONE
)
672 if(!vorbisfile_handle
) return;
674 const ov_callbacks streamIO
= {
675 read
, seek
, close
, tell
678 if(pov_open_callbacks(this, &oggFile
, NULL
, 0, streamIO
) == 0)
680 oggInfo
= pov_info(&oggFile
, -1);
694 // libVorbisFile iostream callbacks
695 static int seek(void *user_data
, ogg_int64_t offset
, int whence
)
697 std::istream
*stream
= static_cast<oggStream
*>(user_data
)->fstream
;
700 if(whence
== SEEK_CUR
)
701 stream
->seekg(offset
, std::ios_base::cur
);
702 else if(whence
== SEEK_SET
)
703 stream
->seekg(offset
, std::ios_base::beg
);
704 else if(whence
== SEEK_END
)
705 stream
->seekg(offset
, std::ios_base::end
);
709 return stream
->tellg();
712 static size_t read(void *ptr
, size_t size
, size_t nmemb
, void *user_data
)
714 std::istream
*stream
= static_cast<oggStream
*>(user_data
)->fstream
;
717 stream
->read(static_cast<char*>(ptr
), nmemb
*size
);
718 size_t ret
= stream
->gcount();
722 static long tell(void *user_data
)
724 std::istream
*stream
= static_cast<oggStream
*>(user_data
)->fstream
;
726 return stream
->tellg();
729 static int close(void*)
734 static DecoderDecl
<oggStream
> oggStream_decoder
;
738 struct flacStream
: public alureStream
{
739 FLAC__StreamDecoder
*flacFile
;
745 std::vector
<ALubyte
> initialData
;
751 virtual bool IsValid()
752 { return flacFile
!= NULL
; }
754 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
757 *frequency
= samplerate
;
758 *blockalign
= blockAlign
;
762 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
768 if(initialData
.size() > 0)
770 size_t rem
= std::min(initialData
.size(), (size_t)bytes
);
771 memcpy(data
, &initialData
[0], rem
);
773 initialData
.erase(initialData
.begin(), initialData
.begin()+rem
);
776 while(outTotal
< bytes
)
778 if(pFLAC__stream_decoder_process_single(flacFile
) == false ||
779 pFLAC__stream_decoder_get_state(flacFile
) == FLAC__STREAM_DECODER_END_OF_STREAM
)
786 virtual bool Rewind()
788 if(pFLAC__stream_decoder_seek_absolute(flacFile
, 0) != false)
794 SetError("Seek failed");
798 flacStream(std::istream
*_fstream
)
799 : alureStream(_fstream
), flacFile(NULL
), format(AL_NONE
), samplerate(0),
800 blockAlign(0), useFloat(AL_FALSE
)
802 if(!flac_handle
) return;
804 flacFile
= pFLAC__stream_decoder_new();
807 if(pFLAC__stream_decoder_init_stream(flacFile
, ReadCallback
, SeekCallback
, TellCallback
, LengthCallback
, EofCallback
, WriteCallback
, MetadataCallback
, ErrorCallback
, this) == FLAC__STREAM_DECODER_INIT_STATUS_OK
)
815 pFLAC__stream_decoder_finish(flacFile
);
817 pFLAC__stream_decoder_delete(flacFile
);
822 virtual ~flacStream()
826 pFLAC__stream_decoder_finish(flacFile
);
827 pFLAC__stream_decoder_delete(flacFile
);
835 // We need to decode some data to be able to get the channel count, bit
836 // depth, and sample rate. It also ensures the file has FLAC data, as
837 // the FLAC__stream_decoder_init_* functions can succeed on non-FLAC
841 while(initialData
.size() == 0)
843 if(pFLAC__stream_decoder_process_single(flacFile
) == false ||
844 pFLAC__stream_decoder_get_state(flacFile
) == FLAC__STREAM_DECODER_END_OF_STREAM
)
848 if(initialData
.size() > 0)
853 static FLAC__StreamDecoderWriteStatus
WriteCallback(const FLAC__StreamDecoder
*, const FLAC__Frame
*frame
, const FLAC__int32
*const buffer
[], void *client_data
)
855 flacStream
*self
= static_cast<flacStream
*>(client_data
);
856 ALubyte
*data
= self
->outBytes
+ self
->outTotal
;
859 if(self
->format
== AL_NONE
)
861 ALuint bps
= frame
->header
.bits_per_sample
;
862 if(bps
== 24 || bps
== 32)
864 self
->format
= GetSampleFormat(frame
->header
.channels
, 32, true);
865 if(self
->format
!= AL_NONE
)
867 self
->useFloat
= AL_TRUE
;
872 if(self
->format
== AL_NONE
)
873 self
->format
= GetSampleFormat(frame
->header
.channels
, bps
, false);
874 self
->blockAlign
= frame
->header
.channels
* bps
/8;
875 self
->samplerate
= frame
->header
.sample_rate
;
878 const ALboolean useFloat
= self
->useFloat
;
879 while(self
->outTotal
< self
->outLen
&& i
< frame
->header
.blocksize
)
881 for(ALuint c
= 0;c
< frame
->header
.channels
;c
++)
883 if(frame
->header
.bits_per_sample
== 8)
884 ((ALubyte
*)data
)[c
] = buffer
[c
][i
]+128;
885 else if(frame
->header
.bits_per_sample
== 16)
886 ((ALshort
*)data
)[c
] = buffer
[c
][i
];
887 else if(frame
->header
.bits_per_sample
== 24)
890 ((ALfloat
*)data
)[c
] = ((buffer
[c
][i
]>=0) ?
891 buffer
[c
][i
]/(float)0x7FFFFF :
892 buffer
[c
][i
]/(float)0x800000);
894 ((ALshort
*)data
)[c
] = buffer
[c
][i
]>>8;
896 else if(frame
->header
.bits_per_sample
== 32)
899 ((ALfloat
*)data
)[c
] = ((buffer
[c
][i
]>=0) ?
900 buffer
[c
][i
]/(float)0x7FFFFFFF :
901 buffer
[c
][i
]/(float)0x80000000u
);
903 ((ALshort
*)data
)[c
] = buffer
[c
][i
]>>16;
906 self
->outTotal
+= self
->blockAlign
;
907 data
+= self
->blockAlign
;
911 if(i
< frame
->header
.blocksize
)
913 ALuint blocklen
= (frame
->header
.blocksize
-i
) *
915 ALuint start
= self
->initialData
.size();
917 self
->initialData
.resize(start
+blocklen
);
918 data
= &self
->initialData
[start
];
921 for(ALuint c
= 0;c
< frame
->header
.channels
;c
++)
923 if(frame
->header
.bits_per_sample
== 8)
924 ((ALubyte
*)data
)[c
] = buffer
[c
][i
]+128;
925 else if(frame
->header
.bits_per_sample
== 16)
926 ((ALshort
*)data
)[c
] = buffer
[c
][i
];
927 else if(frame
->header
.bits_per_sample
== 24)
930 ((ALfloat
*)data
)[c
] = ((buffer
[c
][i
]>=0) ?
931 buffer
[c
][i
]/(float)0x7FFFFF :
932 buffer
[c
][i
]/(float)0x800000);
934 ((ALshort
*)data
)[c
] = buffer
[c
][i
]>>8;
936 else if(frame
->header
.bits_per_sample
== 32)
939 ((ALfloat
*)data
)[c
] = ((buffer
[c
][i
]>=0) ?
940 buffer
[c
][i
]/(float)0x7FFFFFFF :
941 buffer
[c
][i
]/(float)0x80000000u
);
943 ((ALshort
*)data
)[c
] = buffer
[c
][i
]>>16;
946 data
+= self
->blockAlign
;
948 } while(i
< frame
->header
.blocksize
);
951 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE
;
953 static void MetadataCallback(const FLAC__StreamDecoder
*,const FLAC__StreamMetadata
*,void*)
956 static void ErrorCallback(const FLAC__StreamDecoder
*,FLAC__StreamDecoderErrorStatus
,void*)
960 static FLAC__StreamDecoderReadStatus
ReadCallback(const FLAC__StreamDecoder
*, FLAC__byte buffer
[], size_t *bytes
, void *client_data
)
962 std::istream
*stream
= static_cast<flacStream
*>(client_data
)->fstream
;
966 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
968 stream
->read(reinterpret_cast<char*>(buffer
), *bytes
);
969 *bytes
= stream
->gcount();
970 if(*bytes
== 0 && stream
->eof())
971 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
;
973 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE
;
975 static FLAC__StreamDecoderSeekStatus
SeekCallback(const FLAC__StreamDecoder
*, FLAC__uint64 absolute_byte_offset
, void *client_data
)
977 std::istream
*stream
= static_cast<flacStream
*>(client_data
)->fstream
;
980 if(!stream
->seekg(absolute_byte_offset
))
981 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
982 return FLAC__STREAM_DECODER_SEEK_STATUS_OK
;
984 static FLAC__StreamDecoderTellStatus
TellCallback(const FLAC__StreamDecoder
*, FLAC__uint64
*absolute_byte_offset
, void *client_data
)
986 std::istream
*stream
= static_cast<flacStream
*>(client_data
)->fstream
;
989 *absolute_byte_offset
= stream
->tellg();
990 return FLAC__STREAM_DECODER_TELL_STATUS_OK
;
992 static FLAC__StreamDecoderLengthStatus
LengthCallback(const FLAC__StreamDecoder
*, FLAC__uint64
*stream_length
, void *client_data
)
994 std::istream
*stream
= static_cast<flacStream
*>(client_data
)->fstream
;
997 std::streampos pos
= stream
->tellg();
998 if(stream
->seekg(0, std::ios_base::end
))
1000 *stream_length
= stream
->tellg();
1005 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR
;
1006 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK
;
1008 static FLAC__bool
EofCallback(const FLAC__StreamDecoder
*, void *client_data
)
1010 std::istream
*stream
= static_cast<flacStream
*>(client_data
)->fstream
;
1011 return (stream
->eof()) ? true : false;
1014 static DecoderDecl
<flacStream
> flacStream_decoder
;
1019 struct mp3Stream
: public alureStream
{
1020 mpg123_handle
*mp3File
;
1024 std::ios::pos_type dataStart
;
1025 std::ios::pos_type dataEnd
;
1027 virtual bool IsValid()
1028 { return mp3File
!= NULL
; }
1030 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
1033 *frequency
= samplerate
;
1034 *blockalign
= channels
*2;
1038 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
1044 int ret
= pmpg123_read(mp3File
, data
, bytes
, &got
);
1050 if(ret
== MPG123_NEW_FORMAT
)
1054 pmpg123_getformat(mp3File
, &newrate
, &newchans
, &enc
);
1057 if(ret
== MPG123_NEED_MORE
)
1059 unsigned char data
[4096];
1060 ALint insize
= std::min((ALint
)sizeof(data
),
1061 (ALint
)(dataEnd
-fstream
->tellg()));
1064 fstream
->read((char*)data
, insize
);
1065 insize
= fstream
->gcount();
1067 if(insize
> 0 && pmpg123_feed(mp3File
, data
, insize
) == MPG123_OK
)
1076 virtual bool Rewind()
1079 std::istream::pos_type oldpos
= fstream
->tellg();
1080 fstream
->seekg(dataStart
);
1082 mpg123_handle
*newFile
= pmpg123_new(NULL
, NULL
);
1083 if(pmpg123_open_feed(newFile
) == MPG123_OK
)
1085 unsigned char data
[4096];
1090 ALuint amt
, total
= 0;
1091 int ret
= MPG123_OK
;
1093 amt
= std::min((ALint
)sizeof(data
),
1094 (ALint
)(dataEnd
-fstream
->tellg()));
1095 fstream
->read((char*)data
, amt
);
1096 amt
= fstream
->gcount();
1099 ret
= pmpg123_decode(newFile
, data
, amt
, NULL
, 0, NULL
);
1100 } while(ret
== MPG123_NEED_MORE
&& total
< 64*1024);
1102 if(ret
== MPG123_NEW_FORMAT
&&
1103 pmpg123_getformat(newFile
, &newrate
, &newchans
, &enc
) == MPG123_OK
)
1105 if(pmpg123_format_none(newFile
) == MPG123_OK
&&
1106 pmpg123_format(newFile
, samplerate
, channels
, MPG123_ENC_SIGNED_16
) == MPG123_OK
)
1109 pmpg123_delete(mp3File
);
1114 pmpg123_delete(newFile
);
1117 fstream
->seekg(oldpos
);
1118 SetError("Restart failed");
1122 mp3Stream(std::istream
*_fstream
)
1123 : alureStream(_fstream
), mp3File(NULL
), format(AL_NONE
),
1124 dataStart(0), dataEnd(0)
1126 if(!mp123_handle
) return;
1128 if(!FindDataChunk())
1131 mp3File
= pmpg123_new(NULL
, NULL
);
1132 if(pmpg123_open_feed(mp3File
) == MPG123_OK
)
1134 unsigned char data
[4096];
1137 ALuint amt
, total
= 0;
1138 int ret
= MPG123_OK
;
1140 amt
= std::min((ALint
)sizeof(data
),
1141 (ALint
)(dataEnd
-fstream
->tellg()));
1142 fstream
->read((char*)data
, amt
);
1143 amt
= fstream
->gcount();
1146 ret
= pmpg123_decode(mp3File
, data
, amt
, NULL
, 0, NULL
);
1147 } while(ret
== MPG123_NEED_MORE
&& total
< 64*1024);
1149 if(ret
== MPG123_NEW_FORMAT
&&
1150 pmpg123_getformat(mp3File
, &samplerate
, &channels
, &enc
) == MPG123_OK
)
1152 format
= GetSampleFormat(channels
, 16, false);
1153 if(pmpg123_format_none(mp3File
) == MPG123_OK
&&
1154 pmpg123_format(mp3File
, samplerate
, channels
, MPG123_ENC_SIGNED_16
) == MPG123_OK
)
1161 pmpg123_delete(mp3File
);
1165 virtual ~mp3Stream()
1168 pmpg123_delete(mp3File
);
1173 bool FindDataChunk()
1178 if(!fstream
->read(reinterpret_cast<char*>(buffer
), 12))
1181 if(memcmp(buffer
, "RIFF", 4) != 0 || memcmp(buffer
+8, "WAVE", 4) != 0)
1185 // Check for an ID3v2 tag, and skip it
1186 if(memcmp(buffer
, "ID3", 3) == 0 &&
1187 buffer
[3] <= 4 && buffer
[4] != 0xff &&
1188 (buffer
[5]&0x0f) == 0 && (buffer
[6]&0x80) == 0 &&
1189 (buffer
[7]&0x80) == 0 && (buffer
[8]&0x80) == 0 &&
1190 (buffer
[9]&0x80) == 0)
1192 dataStart
= (buffer
[6]<<21) | (buffer
[7]<<14) |
1193 (buffer
[8]<< 7) | (buffer
[9] );
1194 dataStart
+= ((buffer
[5]&0x10) ? 20 : 10);
1197 if(fstream
->seekg(0, std::ios_base::end
))
1199 dataEnd
= fstream
->tellg();
1200 fstream
->seekg(dataStart
);
1209 if(!fstream
->read(tag
, 4))
1212 /* read chunk length */
1213 length
= read_le32(fstream
);
1215 if(memcmp(tag
, "fmt ", 4) == 0 && length
>= 16)
1217 /* Data type (should be 0x0050 or 0x0055 for MP3 data) */
1218 type
= read_le16(fstream
);
1219 if(type
!= 0x0050 && type
!= 0x0055)
1222 /* Ignore the rest of the chunk. Everything we need is in the
1225 else if(memcmp(tag
, "data", 4) == 0)
1227 if(type
== 0x0050 || type
== 0x0055)
1229 dataStart
= fstream
->tellg();
1230 dataEnd
= dataStart
;
1236 fstream
->seekg(length
, std::ios_base::cur
);
1242 static DecoderDecl
<mp3Stream
> mp3Stream_decoder
;
1247 struct dumbStream
: public alureStream
{
1248 DUMBFILE_SYSTEM vfs
;
1251 DUH_SIGRENDERER
*renderer
;
1252 std::vector
<sample_t
> sampleBuf
;
1257 virtual bool IsValid()
1258 { return renderer
!= NULL
; }
1260 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
1262 if(format
== AL_NONE
)
1264 format
= GetSampleFormat(2, 32, true);
1265 if(format
== AL_NONE
)
1266 format
= AL_FORMAT_STEREO16
;
1269 *frequency
= samplerate
;
1270 *blockalign
= 2 * ((format
==AL_FORMAT_STEREO16
) ? sizeof(ALshort
) :
1275 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
1279 if(pdumb_it_sr_get_speed(pduh_get_it_sigrenderer(renderer
)) == 0)
1282 ALuint sample_count
= bytes
/ ((format
==AL_FORMAT_STEREO16
) ?
1283 sizeof(ALshort
) : sizeof(ALfloat
));
1285 sampleBuf
.resize(sample_count
);
1286 sample_t
*samples
[] = {
1290 pdumb_silence(samples
[0], sample_count
);
1291 ret
= pduh_sigrenderer_generate_samples(renderer
, 1.0f
, 65536.0f
/samplerate
, sample_count
/2, samples
);
1293 if(format
== AL_FORMAT_STEREO16
)
1295 for(ALuint i
= 0;i
< ret
;i
++)
1296 ((ALshort
*)data
)[i
] = clamp(samples
[0][i
]>>8, -32768, 32767);
1300 for(ALuint i
= 0;i
< ret
;i
++)
1301 ((ALfloat
*)data
)[i
] = ((samples
[0][i
]>=0) ?
1302 samples
[0][i
]/(float)0x7FFFFF :
1303 samples
[0][i
]/(float)0x800000);
1305 ret
*= ((format
==AL_FORMAT_STEREO16
) ? sizeof(ALshort
) : sizeof(ALfloat
));
1310 virtual bool Rewind()
1312 DUH_SIGRENDERER
*newrenderer
= pdumb_it_start_at_order(duh
, 2, lastOrder
);
1315 SetError("Could start renderer");
1318 pduh_end_sigrenderer(renderer
);
1319 renderer
= newrenderer
;
1323 virtual bool SetOrder(ALuint order
)
1325 DUH_SIGRENDERER
*newrenderer
= pdumb_it_start_at_order(duh
, 2, order
);
1328 SetError("Could not set order");
1331 pduh_end_sigrenderer(renderer
);
1332 renderer
= newrenderer
;
1338 dumbStream(std::istream
*_fstream
)
1339 : alureStream(_fstream
), dumbFile(NULL
), duh(NULL
), renderer(NULL
),
1340 lastOrder(0), format(AL_NONE
), samplerate(48000)
1342 if(!dumb_handle
) return;
1344 ALCdevice
*device
= alcGetContextsDevice(alcGetCurrentContext());
1346 alcGetIntegerv(device
, ALC_FREQUENCY
, 1, &samplerate
);
1348 DUH
* (*funcs
[])(DUMBFILE
*) = {
1358 vfs
.getc
= read_char
;
1362 for(size_t i
= 0;funcs
[i
];i
++)
1364 dumbFile
= pdumbfile_open_ex(this, &vfs
);
1367 duh
= funcs
[i
](dumbFile
);
1370 renderer
= pdumb_it_start_at_order(duh
, 2, lastOrder
);
1373 pdumb_it_set_loop_callback(pduh_get_it_sigrenderer(renderer
), loop_cb
, this);
1381 pdumbfile_close(dumbFile
);
1389 virtual ~dumbStream()
1392 pduh_end_sigrenderer(renderer
);
1400 pdumbfile_close(dumbFile
);
1405 // DUMBFILE iostream callbacks
1406 static int skip(void *user_data
, long offset
)
1408 std::istream
*stream
= static_cast<dumbStream
*>(user_data
)->fstream
;
1411 if(stream
->seekg(offset
, std::ios_base::cur
))
1416 static long read(char *ptr
, long size
, void *user_data
)
1418 std::istream
*stream
= static_cast<dumbStream
*>(user_data
)->fstream
;
1421 stream
->read(ptr
, size
);
1422 return stream
->gcount();
1425 static int read_char(void *user_data
)
1427 std::istream
*stream
= static_cast<dumbStream
*>(user_data
)->fstream
;
1431 stream
->read(reinterpret_cast<char*>(&ret
), 1);
1432 if(stream
->gcount() > 0)
1437 static int loop_cb(void *user_data
)
1439 dumbStream
*self
= static_cast<dumbStream
*>(user_data
);
1440 pdumb_it_sr_set_speed(pduh_get_it_sigrenderer(self
->renderer
), 0);
1444 static DecoderDecl
<dumbStream
> dumbStream_decoder
;
1449 struct modStream
: public alureStream
{
1450 ModPlugFile
*modFile
;
1453 virtual bool IsValid()
1454 { return modFile
!= NULL
; }
1456 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
1458 *fmt
= AL_FORMAT_STEREO16
;
1460 *blockalign
= 2 * sizeof(ALshort
);
1464 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
1466 int ret
= pModPlug_Read(modFile
, data
, bytes
);
1467 if(ret
< 0) return 0;
1471 virtual bool Rewind()
1472 { return SetOrder(lastOrder
); }
1474 virtual bool SetOrder(ALuint order
)
1476 std::vector
<char> data(16384);
1480 fstream
->read(&data
[total
], data
.size()-total
);
1481 if(fstream
->gcount() == 0) break;
1482 total
+= fstream
->gcount();
1483 data
.resize(total
*2);
1487 ModPlugFile
*newMod
= pModPlug_Load(&data
[0], data
.size());
1490 SetError("Could not reload data");
1493 pModPlug_Unload(modFile
);
1496 // There seems to be no way to tell if the seek succeeds
1497 pModPlug_SeekOrder(modFile
, order
);
1503 modStream(std::istream
*_fstream
)
1504 : alureStream(_fstream
), modFile(NULL
), lastOrder(0)
1506 if(!mod_handle
) return;
1508 std::vector
<char> data(16384);
1512 fstream
->read(&data
[total
], data
.size()-total
);
1513 if(fstream
->gcount() == 0) break;
1514 total
+= fstream
->gcount();
1515 data
.resize(total
*2);
1519 modFile
= pModPlug_Load(&data
[0], data
.size());
1522 virtual ~modStream()
1525 pModPlug_Unload(modFile
);
1529 static DecoderDecl
<modStream
> modStream_decoder
;
1533 #ifdef HAS_FLUIDSYNTH
1534 struct fluidStream
: public alureStream
{
1536 static const ALubyte MIDI_CHANNEL_MASK
= 0x0F;
1537 static const ALubyte MIDI_EVENT_MASK
= 0xF0;
1539 static const ALubyte MIDI_NOTEOFF
= 0x80; // + note + velocity
1540 static const ALubyte MIDI_NOTEON
= 0x90; // + note + velocity
1541 static const ALubyte MIDI_POLYPRESS
= 0xA0; // + pressure (2 bytes)
1542 static const ALubyte MIDI_CTRLCHANGE
= 0xB0; // + ctrl + value
1543 static const ALubyte MIDI_PRGMCHANGE
= 0xC0; // + new patch
1544 static const ALubyte MIDI_CHANPRESS
= 0xD0; // + pressure (1 byte)
1545 static const ALubyte MIDI_PITCHBEND
= 0xE0; // + pitch bend (2 bytes)
1546 static const ALubyte MIDI_SPECIAL
= 0xF0; // Special event
1548 static const ALubyte MIDI_SYSEX
= 0xF0; // SysEx begin
1549 static const ALubyte MIDI_SYSEXEND
= 0xF7; // SysEx end
1550 static const ALubyte MIDI_SONGPOS
= 0xF2; // Song position
1551 static const ALubyte MIDI_SONGSEL
= 0xF3; // Song select
1552 static const ALubyte MIDI_META
= 0xFF; // Meta event begin
1554 static const ALubyte MIDI_META_EOT
= 0x2F; // End-of-track
1555 static const ALubyte MIDI_META_TEMPO
= 0x51; // Tempo change
1558 std::vector
<ALubyte
> data
;
1561 ALdouble SamplesLeft
;
1563 MidiTrack() : Offset(0), LastEvent(0), SamplesLeft(0.)
1572 MidiTrack
& operator=(const MidiTrack
&rhs
)
1575 Offset
= rhs
.Offset
;
1576 LastEvent
= rhs
.LastEvent
;
1577 SamplesLeft
= rhs
.SamplesLeft
;
1581 unsigned long ReadVarLen()
1583 if(Offset
>= data
.size())
1586 unsigned long len
= data
[Offset
]&0x7F;
1587 while((data
[Offset
]&0x80))
1589 if(++Offset
>= data
.size())
1591 len
= (len
<<7) | (data
[Offset
]&0x7F);
1600 std::vector
<MidiTrack
> Tracks
;
1604 ALdouble samplesPerTick
;
1606 fluid_settings_t
*fluidSettings
;
1607 fluid_synth_t
*fluidSynth
;
1611 virtual bool IsValid()
1612 { return fluidSynth
!= NULL
; }
1614 virtual bool GetFormat(ALenum
*fmt
, ALuint
*frequency
, ALuint
*blockalign
)
1616 if(format
== AL_NONE
)
1618 format
= GetSampleFormat(2, 32, true);
1619 if(format
== AL_NONE
)
1620 format
= AL_FORMAT_STEREO16
;
1623 *frequency
= sampleRate
;
1624 *blockalign
= 2 * ((format
==AL_FORMAT_STEREO16
) ? sizeof(ALshort
) :
1629 virtual ALuint
GetData(ALubyte
*data
, ALuint bytes
)
1633 if(format
== AL_FORMAT_STEREO16
)
1635 ALshort
*ptr
= reinterpret_cast<ALshort
*>(data
);
1636 ret
= FillBuffer(ptr
, bytes
/2/sizeof(ALshort
));
1637 ret
*= 2 * sizeof(ALshort
);
1641 ALfloat
*ptr
= reinterpret_cast<ALfloat
*>(data
);
1642 ret
= FillBuffer(ptr
, bytes
/2/sizeof(ALfloat
));
1643 ret
*= 2 * sizeof(ALfloat
);
1649 virtual bool Rewind()
1651 for(std::vector
<MidiTrack
>::iterator i
= Tracks
.begin(), end
= Tracks
.end();i
!= end
;i
++)
1654 unsigned long val
= i
->ReadVarLen();
1655 i
->SamplesLeft
+= val
* samplesPerTick
;
1657 pfluid_synth_program_reset(fluidSynth
);
1658 UpdateTempo(500000);
1662 virtual bool SetPatchset(const char *sfont
)
1664 int newid
= pfluid_synth_sfload(fluidSynth
, sfont
, true);
1665 if(newid
== FLUID_FAILED
)
1667 SetError("Failed to load soundfont");
1671 if(fontID
!= FLUID_FAILED
)
1672 pfluid_synth_sfunload(fluidSynth
, fontID
, true);
1678 fluidStream(std::istream
*_fstream
)
1679 : alureStream(_fstream
), Divisions(100),
1680 format(AL_NONE
), sampleRate(48000), samplesPerTick(1.),
1681 fluidSettings(NULL
), fluidSynth(NULL
), fontID(FLUID_FAILED
)
1683 if(!fsynth_handle
) return;
1685 ALCdevice
*device
= alcGetContextsDevice(alcGetCurrentContext());
1687 alcGetIntegerv(device
, ALC_FREQUENCY
, 1, &sampleRate
);
1690 if(!fstream
->read(hdr
, 4))
1693 if(memcmp(hdr
, "MThd", 4) == 0)
1695 ALuint len
= read_be32(fstream
);
1699 int type
= read_be16(fstream
);
1700 if(type
!= 0 && type
!= 1)
1703 ALuint numtracks
= read_be16(fstream
);
1705 Divisions
= read_be16(fstream
);
1706 UpdateTempo(500000);
1708 Tracks
.resize(numtracks
);
1709 for(std::vector
<MidiTrack
>::iterator i
= Tracks
.begin(), end
= Tracks
.end();i
!= end
;i
++)
1711 if(!fstream
->read(hdr
, 4) || memcmp(hdr
, "MTrk", 4) != 0)
1714 ALuint len
= read_be32(fstream
);
1715 i
->data
.resize(len
);
1716 if(!fstream
->read(reinterpret_cast<char*>(&i
->data
[0]), len
))
1719 unsigned long val
= i
->ReadVarLen();
1720 i
->SamplesLeft
+= val
* samplesPerTick
;
1726 virtual ~fluidStream()
1728 if(fontID
!= FLUID_FAILED
)
1729 pfluid_synth_sfunload(fluidSynth
, fontID
, true);
1730 fontID
= FLUID_FAILED
;
1732 if(fluidSynth
!= NULL
)
1733 pdelete_fluid_synth(fluidSynth
);
1736 if(fluidSettings
!= NULL
)
1737 pdelete_fluid_settings(fluidSettings
);
1738 fluidSettings
= NULL
;
1742 template<typename T
>
1743 ALuint
FillBuffer(T
*Buffer
, ALuint BufferSamples
)
1745 ALuint SamplesInBuffer
= 0;
1746 while(SamplesInBuffer
< BufferSamples
)
1748 // Check if any tracks are still playing and how many samples are waiting to render
1749 size_t TracksPlaying
= 0;
1750 ALuint SamplesToDo
= BufferSamples
- SamplesInBuffer
;
1751 for(std::vector
<MidiTrack
>::iterator i
= Tracks
.begin(),
1752 end
= Tracks
.end();i
!= end
;i
++)
1754 if(i
->Offset
< i
->data
.size())
1756 SamplesToDo
= std::min
<ALuint
>(SamplesToDo
, i
->SamplesLeft
);
1760 if(TracksPlaying
== 0)
1763 if(SamplesToDo
== 0)
1770 WriteSamples(SamplesToDo
, Buffer
);
1771 Buffer
+= SamplesToDo
*2;
1772 SamplesInBuffer
+= SamplesToDo
;
1774 for(std::vector
<MidiTrack
>::iterator i
= Tracks
.begin(),
1775 end
= Tracks
.end();i
!= end
;i
++)
1777 if(i
->Offset
< i
->data
.size())
1778 i
->SamplesLeft
-= SamplesToDo
;
1782 return SamplesInBuffer
;
1785 void WriteSamples(ALuint count
, short *buffer
)
1786 { pfluid_synth_write_s16(fluidSynth
, count
, buffer
, 0, 2, buffer
, 1, 2); }
1787 void WriteSamples(ALuint count
, float *buffer
)
1788 { pfluid_synth_write_float(fluidSynth
, count
, buffer
, 0, 2, buffer
, 1, 2); }
1792 ALuint newtempo
= 0;
1794 // Process more events
1795 std::vector
<MidiTrack
>::iterator i
=Tracks
.begin(), end
=Tracks
.end();
1798 if(i
->Offset
>= i
->data
.size() || i
->SamplesLeft
>= 1.)
1804 if(i
->data
.size() - i
->Offset
< 3)
1806 i
->Offset
= i
->data
.size();
1811 ALubyte event
= i
->data
[i
->Offset
++];
1812 ALubyte parm1
, parm2
;
1815 event
= i
->LastEvent
;
1818 if((event
&MIDI_EVENT_MASK
) != MIDI_SPECIAL
)
1819 i
->LastEvent
= event
;
1820 parm1
= i
->data
[i
->Offset
];
1821 parm2
= i
->data
[i
->Offset
+1];
1823 int channel
= event
&MIDI_CHANNEL_MASK
;
1824 switch(event
&MIDI_EVENT_MASK
)
1827 pfluid_synth_noteoff(fluidSynth
, channel
, parm1
);
1831 pfluid_synth_noteon(fluidSynth
, channel
, parm1
, parm2
);
1834 case MIDI_POLYPRESS
:
1838 case MIDI_CTRLCHANGE
:
1839 pfluid_synth_cc(fluidSynth
, channel
, parm1
, parm2
);
1842 case MIDI_PRGMCHANGE
:
1843 pfluid_synth_program_change(fluidSynth
, channel
, parm1
);
1847 case MIDI_CHANPRESS
:
1848 pfluid_synth_channel_pressure(fluidSynth
, channel
, parm1
);
1852 case MIDI_PITCHBEND
:
1853 pfluid_synth_pitch_bend(fluidSynth
, channel
, (parm1
&0x7F) | ((parm2
&0x7F)<<7));
1862 unsigned long len
= i
->ReadVarLen();
1863 if(i
->data
.size() - i
->Offset
< len
)
1865 i
->Offset
= i
->data
.size();
1869 if(len
> 1 && i
->data
[len
-1] == MIDI_SYSEXEND
)
1871 char *data
= reinterpret_cast<char*>(&i
->data
[i
->Offset
]);
1872 pfluid_synth_sysex(fluidSynth
, data
, len
-1, NULL
, NULL
, NULL
, false);
1879 unsigned long len
= i
->ReadVarLen();
1880 if(i
->data
.size() - i
->Offset
< len
)
1882 i
->Offset
= i
->data
.size();
1899 ALubyte metatype
= i
->data
[i
->Offset
++];
1900 unsigned long val
= i
->ReadVarLen();
1902 if(i
->data
.size() - i
->Offset
< val
)
1904 i
->Offset
= i
->data
.size();
1908 if(metatype
== MIDI_META_EOT
)
1910 i
->Offset
= i
->data
.size();
1914 if(metatype
== MIDI_META_TEMPO
&& val
>= 3)
1916 newtempo
= (i
->data
[i
->Offset
] << 16) |
1917 (i
->data
[i
->Offset
+1] << 8) |
1918 (i
->data
[i
->Offset
+2]);
1926 /* The rest of the special events don't have any
1933 /* Shouldn't ever get to here */
1937 unsigned long val
= i
->ReadVarLen();
1938 i
->SamplesLeft
+= val
* samplesPerTick
;
1941 UpdateTempo(newtempo
);
1944 void UpdateTempo(ALuint tempo
)
1946 ALdouble sampletickrate
= sampleRate
/ (1000000. / tempo
) / Divisions
;
1948 for(std::vector
<MidiTrack
>::iterator i
= Tracks
.begin(),
1949 end
= Tracks
.end();i
!= end
;i
++)
1951 if(i
->Offset
>= i
->data
.size())
1953 i
->SamplesLeft
= i
->SamplesLeft
/ samplesPerTick
* sampletickrate
;
1955 samplesPerTick
= sampletickrate
;
1960 fluidSettings
= pnew_fluid_settings();
1963 pfluid_settings_setnum(fluidSettings
, "synth.gain", 0.5);
1964 pfluid_settings_setstr(fluidSettings
, "synth.reverb.active", "yes");
1965 pfluid_settings_setstr(fluidSettings
, "synth.chorus.active", "yes");
1966 pfluid_settings_setint(fluidSettings
, "synth.polyphony", 256);
1967 pfluid_settings_setnum(fluidSettings
, "synth.sample-rate", (double)sampleRate
);
1969 fluidSynth
= pnew_fluid_synth(fluidSettings
);
1972 const char *soundfont
= getenv("FLUID_SOUNDFONT");
1973 if(soundfont
&& soundfont
[0])
1974 fontID
= pfluid_synth_sfload(fluidSynth
, soundfont
, true);
1979 static DecoderDecl
<fluidStream
> fluidStream_decoder
;
1983 template <typename T
>
1984 alureStream
*get_stream_decoder(const T
&fdata
)
1986 std::map
<ALint
,UserCallbacks
>::iterator i
= InstalledCallbacks
.begin();
1987 while(i
!= InstalledCallbacks
.end() && i
->first
< 0)
1989 std::auto_ptr
<alureStream
> stream(new customStream(fdata
, i
->second
));
1990 if(stream
->IsValid()) return stream
.release();
1994 std::istream
*file
= new InStream(fdata
);
1997 Decoder::ListType Factories
= Decoder::GetList();
1998 Decoder::ListType::iterator factory
= Factories
.begin();
1999 Decoder::ListType::iterator end
= Factories
.end();
2000 while(factory
!= end
)
2003 file
->seekg(0, std::ios_base::beg
);
2005 std::auto_ptr
<alureStream
> stream((*factory
)(file
));
2006 if(stream
.get() != NULL
) return stream
.release();
2011 SetError("Unsupported type");
2016 SetError("Failed to open file");
2020 while(i
!= InstalledCallbacks
.end())
2022 std::auto_ptr
<alureStream
> stream(new customStream(fdata
, i
->second
));
2023 if(stream
->IsValid()) return stream
.release();
2027 return new nullStream
;
2030 alureStream
*create_stream(const char *fname
)
2031 { return get_stream_decoder(fname
); }
2032 alureStream
*create_stream(const MemDataInfo
&memData
)
2033 { return get_stream_decoder(memData
); }
2035 alureStream
*create_stream(ALvoid
*userdata
, ALenum format
, ALuint rate
, const UserCallbacks
&cb
)
2036 { return new customStream(userdata
, format
, rate
, cb
); }