Improve copying for the MidiTrack struct
[alure.git] / src / streamdec.cpp
blob59df6d9353a735223f464547c92283b06d2c93e3
1 /*
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
21 * IN THE SOFTWARE.
24 #include "config.h"
26 #include "main.h"
28 #include <string.h>
30 #include <algorithm>
31 #include <vector>
32 #include <memory>
33 #include <string>
34 #include <istream>
35 #include <fstream>
36 #include <iostream>
37 #include <sstream>
40 struct Decoder {
41 typedef std::auto_ptr<alureStream>(*FactoryType)(std::istream*);
42 typedef std::vector<FactoryType> ListType;
44 static const ListType& GetList()
45 { return AddList(NULL); }
47 protected:
48 template<typename T>
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);
60 return FuncList;
63 template<typename T>
64 struct DecoderDecl : public Decoder {
65 DecoderDecl() { AddList(Factory<T>); }
69 static inline ALuint read_le32(std::istream *file)
71 ALubyte buffer[4];
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)
78 ALubyte buffer[2];
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)
85 ALubyte buffer[4];
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)
92 ALubyte buffer[2];
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)
99 ALubyte buffer[10];
100 if(!file->read(reinterpret_cast<char*>(buffer), 10)) return 0;
101 ALuint mantissa, last = 0;
102 ALubyte exp = buffer[1];
103 exp = 30 - exp;
104 mantissa = (buffer[2]<<24) | (buffer[3]<<16) | (buffer[4]<<8) | buffer[5];
105 while (exp--)
107 last = mantissa;
108 mantissa >>= 1;
110 if((last&1)) mantissa++;
111 return 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 {
125 void *usrFile;
126 ALenum format;
127 ALuint samplerate;
128 ALuint blockAlign;
129 MemDataInfo memInfo;
131 UserCallbacks cb;
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))
141 return false;
143 if(DetectBlockAlignment(format) != blockAlign)
144 format = AL_NONE;
147 *fmt = format;
148 *frequency = samplerate;
149 *blockalign = blockAlign;
150 return true;
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))
159 return true;
160 SetError("Rewind failed");
161 return false;
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)
182 cb.close(usrFile);
183 usrFile = NULL;
188 struct wavStream : public alureStream {
189 ALenum format;
190 int samplerate;
191 int blockAlign;
192 int sampleSize;
193 long dataStart;
194 long dataLen;
195 size_t remLen;
197 virtual bool IsValid()
198 { return (dataStart > 0 && format != AL_NONE); }
200 virtual bool GetFormat(ALenum *fmt, ALuint *frequency, ALuint *blockalign)
202 *fmt = format;
203 *frequency = samplerate;
204 *blockalign = blockAlign;
205 return true;
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;
215 remLen -= got;
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]);
241 return got;
244 virtual bool Rewind()
246 fstream->clear();
247 if(fstream->seekg(dataStart))
249 remLen = dataLen;
250 return true;
253 SetError("Seek failed");
254 return false;
257 wavStream(std::istream *_fstream)
258 : alureStream(_fstream), format(0), dataStart(0)
260 ALubyte buffer[25];
261 int length;
263 if(!fstream->read(reinterpret_cast<char*>(buffer), 12) ||
264 memcmp(buffer, "RIFF", 4) != 0 || memcmp(buffer+8, "WAVE", 4) != 0)
265 return;
267 while(!dataStart || format == AL_NONE)
269 char tag[4];
270 if(!fstream->read(tag, 4))
271 break;
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)
282 break;
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 */
291 fstream->ignore(4);
293 /* bytes per block */
294 blockAlign = read_le16(fstream);
295 if(blockAlign == 0)
296 break;
298 /* bits per sample */
299 sampleSize = read_le16(fstream);
301 length -= 16;
303 /* Look for any extra data and try to find the format */
304 int extrabytes = 0;
305 if(length >= 2)
307 extrabytes = read_le16(fstream);
308 length -= 2;
310 extrabytes = std::min(extrabytes, length);
312 if(type == 0x0001)
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);
319 length -= 2;
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"))
326 if(channels == 1)
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);
346 virtual ~wavStream()
349 static DecoderDecl<wavStream> wavStream_decoder;
352 struct aiffStream : public alureStream {
353 ALenum format;
354 int samplerate;
355 int blockAlign;
356 int sampleSize;
357 long dataStart;
358 long dataLen;
359 size_t remLen;
361 virtual bool IsValid()
362 { return (dataStart > 0 && format != AL_NONE); }
364 virtual bool GetFormat(ALenum *fmt, ALuint *frequency, ALuint *blockalign)
366 *fmt = format;
367 *frequency = samplerate;
368 *blockalign = blockAlign;
369 return true;
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;
379 remLen -= got;
381 if(LittleEndian)
383 if(sampleSize == 2)
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]);
398 return got;
401 virtual bool Rewind()
403 fstream->clear();
404 if(fstream->seekg(dataStart))
406 remLen = dataLen;
407 return true;
410 SetError("Seek failed");
411 return false;
414 aiffStream(std::istream *_fstream)
415 : alureStream(_fstream), format(0), dataStart(0)
417 ALubyte buffer[25];
418 int length;
420 if(!fstream->read(reinterpret_cast<char*>(buffer), 12) ||
421 memcmp(buffer, "FORM", 4) != 0 || memcmp(buffer+8, "AIFF", 4) != 0)
422 return;
424 while(!dataStart || format == AL_NONE)
426 char tag[4];
427 if(!fstream->read(tag, 4))
428 break;
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 */
439 fstream->ignore(4);
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);
452 length -= 18;
454 else if(memcmp(tag, "SSND", 4) == 0)
456 dataStart = fstream->tellg();
457 dataStart += 8;
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;
473 #ifdef HAS_SNDFILE
474 struct sndStream : public alureStream {
475 SNDFILE *sndFile;
476 SF_INFO sndInfo;
477 ALenum format;
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);
486 *fmt = format;
487 *frequency = sndInfo.samplerate;
488 *blockalign = sndInfo.channels*2;
489 return true;
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)
501 return true;
503 SetError("Seek failed");
504 return false;
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 = {
515 get_filelen, seek,
516 read, write, tell
518 sndFile = psf_open_virtual(&streamIO, SFM_READ, &sndInfo, this);
521 virtual ~sndStream()
523 if(sndFile)
524 psf_close(sndFile);
525 sndFile = NULL;
528 private:
529 // libSndFile iostream callbacks
530 static sf_count_t get_filelen(void *user_data)
532 std::istream *stream = static_cast<sndStream*>(user_data)->fstream;
533 stream->clear();
535 std::streampos len = -1;
536 std::streampos pos = stream->tellg();
537 if(stream->seekg(0, std::ios_base::end))
539 len = stream->tellg();
540 stream->seekg(pos);
543 return len;
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;
549 stream->clear();
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);
557 else
558 return -1;
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;
566 stream->clear();
567 stream->read(static_cast<char*>(ptr), count);
568 return stream->gcount();
571 static sf_count_t write(const void*, sf_count_t, void*)
572 { return -1; }
574 static sf_count_t tell(void *user_data)
576 std::istream *stream = static_cast<sndStream*>(user_data)->fstream;
577 stream->clear();
578 return stream->tellg();
581 static DecoderDecl<sndStream> sndStream_decoder;
582 #endif
584 #ifdef HAS_VORBISFILE
585 struct oggStream : public alureStream {
586 OggVorbis_File oggFile;
587 vorbis_info *oggInfo;
588 int oggBitstream;
589 ALenum format;
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);
598 *fmt = format;
599 *frequency = oggInfo->rate;
600 *blockalign = oggInfo->channels*2;
601 return true;
604 virtual ALuint GetData(ALubyte *data, ALuint bytes)
606 ALuint got = 0;
607 while(bytes > 0)
609 int res = pov_read(&oggFile, (char*)&data[got], bytes, BigEndian?1:0, 2, 1, &oggBitstream);
610 if(res <= 0)
611 break;
612 bytes -= res;
613 got += res;
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
617 // re-ordered
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]);
657 return got;
660 virtual bool Rewind()
662 if(pov_pcm_seek(&oggFile, 0) == 0)
663 return true;
665 SetError("Seek failed");
666 return false;
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);
681 if(!oggInfo)
682 pov_clear(&oggFile);
686 virtual ~oggStream()
688 if(oggInfo)
689 pov_clear(&oggFile);
690 oggInfo = NULL;
693 private:
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;
698 stream->clear();
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);
706 else
707 return -1;
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;
715 stream->clear();
717 stream->read(static_cast<char*>(ptr), nmemb*size);
718 size_t ret = stream->gcount();
719 return ret/size;
722 static long tell(void *user_data)
724 std::istream *stream = static_cast<oggStream*>(user_data)->fstream;
725 stream->clear();
726 return stream->tellg();
729 static int close(void*)
731 return 0;
734 static DecoderDecl<oggStream> oggStream_decoder;
735 #endif
737 #ifdef HAS_FLAC
738 struct flacStream : public alureStream {
739 FLAC__StreamDecoder *flacFile;
740 ALenum format;
741 ALuint samplerate;
742 ALuint blockAlign;
743 ALboolean useFloat;
745 std::vector<ALubyte> initialData;
747 ALubyte *outBytes;
748 ALuint outLen;
749 ALuint outTotal;
751 virtual bool IsValid()
752 { return flacFile != NULL; }
754 virtual bool GetFormat(ALenum *fmt, ALuint *frequency, ALuint *blockalign)
756 *fmt = format;
757 *frequency = samplerate;
758 *blockalign = blockAlign;
759 return true;
762 virtual ALuint GetData(ALubyte *data, ALuint bytes)
764 outBytes = data;
765 outTotal = 0;
766 outLen = bytes;
768 if(initialData.size() > 0)
770 size_t rem = std::min(initialData.size(), (size_t)bytes);
771 memcpy(data, &initialData[0], rem);
772 outTotal += 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)
780 break;
783 return outTotal;
786 virtual bool Rewind()
788 if(pFLAC__stream_decoder_seek_absolute(flacFile, 0) != false)
790 initialData.clear();
791 return true;
794 SetError("Seek failed");
795 return false;
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();
805 if(flacFile)
807 if(pFLAC__stream_decoder_init_stream(flacFile, ReadCallback, SeekCallback, TellCallback, LengthCallback, EofCallback, WriteCallback, MetadataCallback, ErrorCallback, this) == FLAC__STREAM_DECODER_INIT_STATUS_OK)
809 if(InitFlac())
811 // all ok
812 return;
815 pFLAC__stream_decoder_finish(flacFile);
817 pFLAC__stream_decoder_delete(flacFile);
818 flacFile = NULL;
822 virtual ~flacStream()
824 if(flacFile)
826 pFLAC__stream_decoder_finish(flacFile);
827 pFLAC__stream_decoder_delete(flacFile);
828 flacFile = NULL;
832 private:
833 bool InitFlac()
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
838 // Ogg files.
839 outLen = 0;
840 outTotal = 0;
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)
845 break;
848 if(initialData.size() > 0)
849 return true;
850 return false;
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;
857 ALuint i = 0;
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;
868 bps = 32;
870 else bps = 16;
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)
889 if(useFloat)
890 ((ALfloat*)data)[c] = ((buffer[c][i]>=0) ?
891 buffer[c][i]/(float)0x7FFFFF :
892 buffer[c][i]/(float)0x800000);
893 else
894 ((ALshort*)data)[c] = buffer[c][i]>>8;
896 else if(frame->header.bits_per_sample == 32)
898 if(useFloat)
899 ((ALfloat*)data)[c] = ((buffer[c][i]>=0) ?
900 buffer[c][i]/(float)0x7FFFFFFF :
901 buffer[c][i]/(float)0x80000000u);
902 else
903 ((ALshort*)data)[c] = buffer[c][i]>>16;
906 self->outTotal += self->blockAlign;
907 data += self->blockAlign;
908 i++;
911 if(i < frame->header.blocksize)
913 ALuint blocklen = (frame->header.blocksize-i) *
914 self->blockAlign;
915 ALuint start = self->initialData.size();
917 self->initialData.resize(start+blocklen);
918 data = &self->initialData[start];
920 do {
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)
929 if(useFloat)
930 ((ALfloat*)data)[c] = ((buffer[c][i]>=0) ?
931 buffer[c][i]/(float)0x7FFFFF :
932 buffer[c][i]/(float)0x800000);
933 else
934 ((ALshort*)data)[c] = buffer[c][i]>>8;
936 else if(frame->header.bits_per_sample == 32)
938 if(useFloat)
939 ((ALfloat*)data)[c] = ((buffer[c][i]>=0) ?
940 buffer[c][i]/(float)0x7FFFFFFF :
941 buffer[c][i]/(float)0x80000000u);
942 else
943 ((ALshort*)data)[c] = buffer[c][i]>>16;
946 data += self->blockAlign;
947 i++;
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;
963 stream->clear();
965 if(*bytes <= 0)
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;
978 stream->clear();
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;
987 stream->clear();
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;
995 stream->clear();
997 std::streampos pos = stream->tellg();
998 if(stream->seekg(0, std::ios_base::end))
1000 *stream_length = stream->tellg();
1001 stream->seekg(pos);
1004 if(!stream->good())
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;
1015 #endif
1018 #ifdef HAS_MPG123
1019 struct mp3Stream : public alureStream {
1020 mpg123_handle *mp3File;
1021 long samplerate;
1022 int channels;
1023 ALenum format;
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)
1032 *fmt = format;
1033 *frequency = samplerate;
1034 *blockalign = channels*2;
1035 return true;
1038 virtual ALuint GetData(ALubyte *data, ALuint bytes)
1040 ALuint amt = 0;
1041 while(bytes > 0)
1043 size_t got = 0;
1044 int ret = pmpg123_read(mp3File, data, bytes, &got);
1046 bytes -= got;
1047 data += got;
1048 amt += got;
1050 if(ret == MPG123_NEW_FORMAT)
1052 long newrate;
1053 int newchans, enc;
1054 pmpg123_getformat(mp3File, &newrate, &newchans, &enc);
1055 continue;
1057 if(ret == MPG123_NEED_MORE)
1059 unsigned char data[4096];
1060 ALint insize = std::min((ALint)sizeof(data),
1061 (ALint)(dataEnd-fstream->tellg()));
1062 if(insize > 0)
1064 fstream->read((char*)data, insize);
1065 insize = fstream->gcount();
1067 if(insize > 0 && pmpg123_feed(mp3File, data, insize) == MPG123_OK)
1068 continue;
1070 if(got == 0)
1071 break;
1073 return amt;
1076 virtual bool Rewind()
1078 fstream->clear();
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];
1086 long newrate;
1087 int newchans;
1088 int enc;
1090 ALuint amt, total = 0;
1091 int ret = MPG123_OK;
1092 do {
1093 amt = std::min((ALint)sizeof(data),
1094 (ALint)(dataEnd-fstream->tellg()));
1095 fstream->read((char*)data, amt);
1096 amt = fstream->gcount();
1097 if(amt == 0) break;
1098 total += amt;
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)
1108 // All OK
1109 pmpg123_delete(mp3File);
1110 mp3File = newFile;
1111 return true;
1114 pmpg123_delete(newFile);
1117 fstream->seekg(oldpos);
1118 SetError("Restart failed");
1119 return false;
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())
1129 return;
1131 mp3File = pmpg123_new(NULL, NULL);
1132 if(pmpg123_open_feed(mp3File) == MPG123_OK)
1134 unsigned char data[4096];
1135 int enc;
1137 ALuint amt, total = 0;
1138 int ret = MPG123_OK;
1139 do {
1140 amt = std::min((ALint)sizeof(data),
1141 (ALint)(dataEnd-fstream->tellg()));
1142 fstream->read((char*)data, amt);
1143 amt = fstream->gcount();
1144 if(amt == 0) break;
1145 total += amt;
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)
1156 // All OK
1157 return;
1161 pmpg123_delete(mp3File);
1162 mp3File = NULL;
1165 virtual ~mp3Stream()
1167 if(mp3File)
1168 pmpg123_delete(mp3File);
1169 mp3File = NULL;
1172 private:
1173 bool FindDataChunk()
1175 ALubyte buffer[25];
1176 int length;
1178 if(!fstream->read(reinterpret_cast<char*>(buffer), 12))
1179 return false;
1181 if(memcmp(buffer, "RIFF", 4) != 0 || memcmp(buffer+8, "WAVE", 4) != 0)
1183 dataStart = 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);
1202 return true;
1205 int type = 0;
1206 while(1)
1208 char tag[4];
1209 if(!fstream->read(tag, 4))
1210 break;
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)
1220 break;
1221 length -= 2;
1222 /* Ignore the rest of the chunk. Everything we need is in the
1223 * data stream */
1225 else if(memcmp(tag, "data", 4) == 0)
1227 if(type == 0x0050 || type == 0x0055)
1229 dataStart = fstream->tellg();
1230 dataEnd = dataStart;
1231 dataEnd += length;
1232 return true;
1236 fstream->seekg(length, std::ios_base::cur);
1239 return false;
1242 static DecoderDecl<mp3Stream> mp3Stream_decoder;
1243 #endif
1246 #ifdef HAS_DUMB
1247 struct dumbStream : public alureStream {
1248 DUMBFILE_SYSTEM vfs;
1249 DUMBFILE *dumbFile;
1250 DUH *duh;
1251 DUH_SIGRENDERER *renderer;
1252 std::vector<sample_t> sampleBuf;
1253 ALuint lastOrder;
1254 ALenum format;
1255 ALCint samplerate;
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;
1268 *fmt = format;
1269 *frequency = samplerate;
1270 *blockalign = 2 * ((format==AL_FORMAT_STEREO16) ? sizeof(ALshort) :
1271 sizeof(ALfloat));
1272 return true;
1275 virtual ALuint GetData(ALubyte *data, ALuint bytes)
1277 ALuint ret = 0;
1279 if(pdumb_it_sr_get_speed(pduh_get_it_sigrenderer(renderer)) == 0)
1280 return 0;
1282 ALuint sample_count = bytes / ((format==AL_FORMAT_STEREO16) ?
1283 sizeof(ALshort) : sizeof(ALfloat));
1285 sampleBuf.resize(sample_count);
1286 sample_t *samples[] = {
1287 &sampleBuf[0]
1290 pdumb_silence(samples[0], sample_count);
1291 ret = pduh_sigrenderer_generate_samples(renderer, 1.0f, 65536.0f/samplerate, sample_count/2, samples);
1292 ret *= 2;
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);
1298 else
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));
1307 return ret;
1310 virtual bool Rewind()
1312 DUH_SIGRENDERER *newrenderer = pdumb_it_start_at_order(duh, 2, lastOrder);
1313 if(!newrenderer)
1315 SetError("Could start renderer");
1316 return false;
1318 pduh_end_sigrenderer(renderer);
1319 renderer = newrenderer;
1320 return true;
1323 virtual bool SetOrder(ALuint order)
1325 DUH_SIGRENDERER *newrenderer = pdumb_it_start_at_order(duh, 2, order);
1326 if(!newrenderer)
1328 SetError("Could not set order");
1329 return false;
1331 pduh_end_sigrenderer(renderer);
1332 renderer = newrenderer;
1334 lastOrder = order;
1335 return true;
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());
1345 if(device)
1346 alcGetIntegerv(device, ALC_FREQUENCY, 1, &samplerate);
1348 DUH* (*funcs[])(DUMBFILE*) = {
1349 pdumb_read_it,
1350 pdumb_read_xm,
1351 pdumb_read_s3m,
1352 pdumb_read_mod,
1353 NULL
1356 vfs.open = NULL;
1357 vfs.skip = skip;
1358 vfs.getc = read_char;
1359 vfs.getnc = read;
1360 vfs.close = NULL;
1362 for(size_t i = 0;funcs[i];i++)
1364 dumbFile = pdumbfile_open_ex(this, &vfs);
1365 if(dumbFile)
1367 duh = funcs[i](dumbFile);
1368 if(duh)
1370 renderer = pdumb_it_start_at_order(duh, 2, lastOrder);
1371 if(renderer)
1373 pdumb_it_set_loop_callback(pduh_get_it_sigrenderer(renderer), loop_cb, this);
1374 break;
1377 punload_duh(duh);
1378 duh = NULL;
1381 pdumbfile_close(dumbFile);
1382 dumbFile = NULL;
1384 fstream->clear();
1385 fstream->seekg(0);
1389 virtual ~dumbStream()
1391 if(renderer)
1392 pduh_end_sigrenderer(renderer);
1393 renderer = NULL;
1395 if(duh)
1396 punload_duh(duh);
1397 duh = NULL;
1399 if(dumbFile)
1400 pdumbfile_close(dumbFile);
1401 dumbFile = NULL;
1404 private:
1405 // DUMBFILE iostream callbacks
1406 static int skip(void *user_data, long offset)
1408 std::istream *stream = static_cast<dumbStream*>(user_data)->fstream;
1409 stream->clear();
1411 if(stream->seekg(offset, std::ios_base::cur))
1412 return 0;
1413 return -1;
1416 static long read(char *ptr, long size, void *user_data)
1418 std::istream *stream = static_cast<dumbStream*>(user_data)->fstream;
1419 stream->clear();
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;
1428 stream->clear();
1430 unsigned char ret;
1431 stream->read(reinterpret_cast<char*>(&ret), 1);
1432 if(stream->gcount() > 0)
1433 return ret;
1434 return -1;
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);
1441 return 0;
1444 static DecoderDecl<dumbStream> dumbStream_decoder;
1445 #endif
1448 #ifdef HAS_MODPLUG
1449 struct modStream : public alureStream {
1450 ModPlugFile *modFile;
1451 int lastOrder;
1453 virtual bool IsValid()
1454 { return modFile != NULL; }
1456 virtual bool GetFormat(ALenum *fmt, ALuint *frequency, ALuint *blockalign)
1458 *fmt = AL_FORMAT_STEREO16;
1459 *frequency = 44100;
1460 *blockalign = 2 * sizeof(ALshort);
1461 return true;
1464 virtual ALuint GetData(ALubyte *data, ALuint bytes)
1466 int ret = pModPlug_Read(modFile, data, bytes);
1467 if(ret < 0) return 0;
1468 return ret;
1471 virtual bool Rewind()
1472 { return SetOrder(lastOrder); }
1474 virtual bool SetOrder(ALuint order)
1476 std::vector<char> data(16384);
1477 ALuint total = 0;
1478 while(1)
1480 fstream->read(&data[total], data.size()-total);
1481 if(fstream->gcount() == 0) break;
1482 total += fstream->gcount();
1483 data.resize(total*2);
1485 data.resize(total);
1487 ModPlugFile *newMod = pModPlug_Load(&data[0], data.size());
1488 if(!newMod)
1490 SetError("Could not reload data");
1491 return false;
1493 pModPlug_Unload(modFile);
1494 modFile = newMod;
1496 // There seems to be no way to tell if the seek succeeds
1497 pModPlug_SeekOrder(modFile, order);
1498 lastOrder = order;
1500 return true;
1503 modStream(std::istream *_fstream)
1504 : alureStream(_fstream), modFile(NULL), lastOrder(0)
1506 if(!mod_handle) return;
1508 std::vector<char> data(16384);
1509 ALuint total = 0;
1510 while(1)
1512 fstream->read(&data[total], data.size()-total);
1513 if(fstream->gcount() == 0) break;
1514 total += fstream->gcount();
1515 data.resize(total*2);
1517 data.resize(total);
1519 modFile = pModPlug_Load(&data[0], data.size());
1522 virtual ~modStream()
1524 if(modFile)
1525 pModPlug_Unload(modFile);
1526 modFile = NULL;
1529 static DecoderDecl<modStream> modStream_decoder;
1530 #endif
1533 #ifdef HAS_FLUIDSYNTH
1534 struct fluidStream : public alureStream {
1535 private:
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
1557 struct MidiTrack {
1558 std::vector<ALubyte> data;
1559 size_t Offset;
1560 ALubyte LastEvent;
1561 ALdouble SamplesLeft;
1563 MidiTrack() : Offset(0), LastEvent(0), SamplesLeft(0.)
1565 MidiTrack(const MidiTrack &rhs)
1566 : data(rhs.data), Offset(rhs.Offset), LastEvent(rhs.LastEvent),
1567 SamplesLeft(rhs.SamplesLeft)
1570 void Reset()
1572 Offset = 0;
1573 LastEvent = 0;
1574 SamplesLeft = 0.;
1577 const MidiTrack& operator=(const MidiTrack &rhs)
1579 data = rhs.data;
1580 Offset = rhs.Offset;
1581 LastEvent = rhs.LastEvent;
1582 SamplesLeft = rhs.SamplesLeft;
1583 return *this;
1586 unsigned long ReadVarLen()
1588 if(Offset >= data.size())
1589 return 0;
1591 unsigned long len = data[Offset]&0x7F;
1592 while((data[Offset]&0x80))
1594 if(++Offset >= data.size())
1595 return 0;
1596 len = (len<<7) | (data[Offset]&0x7F);
1598 Offset++;
1600 return len;
1604 ALuint Divisions;
1605 std::vector<MidiTrack> Tracks;
1607 ALenum format;
1608 ALsizei sampleRate;
1609 ALdouble samplesPerTick;
1611 fluid_settings_t *fluidSettings;
1612 fluid_synth_t *fluidSynth;
1613 int fontID;
1615 public:
1616 virtual bool IsValid()
1617 { return fluidSynth != NULL; }
1619 virtual bool GetFormat(ALenum *fmt, ALuint *frequency, ALuint *blockalign)
1621 if(format == AL_NONE)
1623 format = GetSampleFormat(2, 32, true);
1624 if(format == AL_NONE)
1625 format = AL_FORMAT_STEREO16;
1627 *fmt = format;
1628 *frequency = sampleRate;
1629 *blockalign = 2 * ((format==AL_FORMAT_STEREO16) ? sizeof(ALshort) :
1630 sizeof(ALfloat));
1631 return true;
1634 virtual ALuint GetData(ALubyte *data, ALuint bytes)
1636 ALuint ret;
1638 if(format == AL_FORMAT_STEREO16)
1640 ALshort *ptr = reinterpret_cast<ALshort*>(data);
1641 ret = FillBuffer(ptr, bytes/2/sizeof(ALshort));
1642 ret *= 2 * sizeof(ALshort);
1644 else
1646 ALfloat *ptr = reinterpret_cast<ALfloat*>(data);
1647 ret = FillBuffer(ptr, bytes/2/sizeof(ALfloat));
1648 ret *= 2 * sizeof(ALfloat);
1651 return ret;
1654 virtual bool Rewind()
1656 for(std::vector<MidiTrack>::iterator i = Tracks.begin(), end = Tracks.end();i != end;i++)
1658 i->Reset();
1659 unsigned long val = i->ReadVarLen();
1660 i->SamplesLeft += val * samplesPerTick;
1662 pfluid_synth_program_reset(fluidSynth);
1663 UpdateTempo(500000);
1664 return true;
1667 virtual bool SetPatchset(const char *sfont)
1669 int newid = pfluid_synth_sfload(fluidSynth, sfont, true);
1670 if(newid == FLUID_FAILED)
1672 SetError("Failed to load soundfont");
1673 return false;
1676 if(fontID != FLUID_FAILED)
1677 pfluid_synth_sfunload(fluidSynth, fontID, true);
1678 fontID = newid;
1680 return true;
1683 fluidStream(std::istream *_fstream)
1684 : alureStream(_fstream), Divisions(100),
1685 format(AL_NONE), sampleRate(48000), samplesPerTick(1.),
1686 fluidSettings(NULL), fluidSynth(NULL), fontID(FLUID_FAILED)
1688 if(!fsynth_handle) return;
1690 ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
1691 if(device)
1692 alcGetIntegerv(device, ALC_FREQUENCY, 1, &sampleRate);
1694 char hdr[4];
1695 if(!fstream->read(hdr, 4))
1696 return;
1698 if(memcmp(hdr, "MThd", 4) == 0)
1700 ALuint len = read_be32(fstream);
1701 if(len != 6)
1702 return;
1704 int type = read_be16(fstream);
1705 if(type != 0 && type != 1)
1706 return;
1708 ALuint numtracks = read_be16(fstream);
1710 Divisions = read_be16(fstream);
1711 UpdateTempo(500000);
1713 Tracks.resize(numtracks);
1714 for(std::vector<MidiTrack>::iterator i = Tracks.begin(), end = Tracks.end();i != end;i++)
1716 if(!fstream->read(hdr, 4) || memcmp(hdr, "MTrk", 4) != 0)
1717 return;
1719 ALuint len = read_be32(fstream);
1720 i->data.resize(len);
1721 if(!fstream->read(reinterpret_cast<char*>(&i->data[0]), len))
1722 return;
1724 unsigned long val = i->ReadVarLen();
1725 i->SamplesLeft += val * samplesPerTick;
1727 SetupSynth();
1731 virtual ~fluidStream()
1733 if(fontID != FLUID_FAILED)
1734 pfluid_synth_sfunload(fluidSynth, fontID, true);
1735 fontID = FLUID_FAILED;
1737 if(fluidSynth != NULL)
1738 pdelete_fluid_synth(fluidSynth);
1739 fluidSynth = NULL;
1741 if(fluidSettings != NULL)
1742 pdelete_fluid_settings(fluidSettings);
1743 fluidSettings = NULL;
1746 private:
1747 template<typename T>
1748 ALuint FillBuffer(T *Buffer, ALuint BufferSamples)
1750 ALuint SamplesInBuffer = 0;
1751 while(SamplesInBuffer < BufferSamples)
1753 // Check if any tracks are still playing and how many samples are waiting to render
1754 size_t TracksPlaying = 0;
1755 ALuint SamplesToDo = BufferSamples - SamplesInBuffer;
1756 for(std::vector<MidiTrack>::iterator i = Tracks.begin(),
1757 end = Tracks.end();i != end;i++)
1759 if(i->Offset < i->data.size())
1761 SamplesToDo = std::min<ALuint>(SamplesToDo, i->SamplesLeft);
1762 TracksPlaying++;
1765 if(TracksPlaying == 0)
1766 break;
1768 if(SamplesToDo == 0)
1770 ProcessMidi();
1771 continue;
1774 // Render samples
1775 WriteSamples(SamplesToDo, Buffer);
1776 Buffer += SamplesToDo*2;
1777 SamplesInBuffer += SamplesToDo;
1779 for(std::vector<MidiTrack>::iterator i = Tracks.begin(),
1780 end = Tracks.end();i != end;i++)
1782 if(i->Offset < i->data.size())
1783 i->SamplesLeft -= SamplesToDo;
1787 return SamplesInBuffer;
1790 void WriteSamples(ALuint count, short *buffer)
1791 { pfluid_synth_write_s16(fluidSynth, count, buffer, 0, 2, buffer, 1, 2); }
1792 void WriteSamples(ALuint count, float *buffer)
1793 { pfluid_synth_write_float(fluidSynth, count, buffer, 0, 2, buffer, 1, 2); }
1795 void ProcessMidi()
1797 ALuint newtempo = 0;
1799 // Process more events
1800 std::vector<MidiTrack>::iterator i=Tracks.begin(), end=Tracks.end();
1801 while(i != end)
1803 if(i->Offset >= i->data.size() || i->SamplesLeft >= 1.)
1805 i++;
1806 continue;
1809 if(i->data.size() - i->Offset < 3)
1811 i->Offset = i->data.size();
1812 i++;
1813 continue;
1816 ALubyte event = i->data[i->Offset++];
1817 ALubyte parm1, parm2;
1818 if(!(event&0x80))
1820 event = i->LastEvent;
1821 i->Offset--;
1823 if((event&MIDI_EVENT_MASK) != MIDI_SPECIAL)
1824 i->LastEvent = event;
1825 parm1 = i->data[i->Offset];
1826 parm2 = i->data[i->Offset+1];
1828 int channel = event&MIDI_CHANNEL_MASK;
1829 switch(event&MIDI_EVENT_MASK)
1831 case MIDI_NOTEOFF:
1832 pfluid_synth_noteoff(fluidSynth, channel, parm1);
1833 i->Offset += 2;
1834 break;
1835 case MIDI_NOTEON:
1836 pfluid_synth_noteon(fluidSynth, channel, parm1, parm2);
1837 i->Offset += 2;
1838 break;
1839 case MIDI_POLYPRESS:
1840 i->Offset += 2;
1841 break;
1843 case MIDI_CTRLCHANGE:
1844 pfluid_synth_cc(fluidSynth, channel, parm1, parm2);
1845 i->Offset += 2;
1846 break;
1847 case MIDI_PRGMCHANGE:
1848 pfluid_synth_program_change(fluidSynth, channel, parm1);
1849 i->Offset += 1;
1850 break;
1852 case MIDI_CHANPRESS:
1853 pfluid_synth_channel_pressure(fluidSynth, channel, parm1);
1854 i->Offset += 1;
1855 break;
1857 case MIDI_PITCHBEND:
1858 pfluid_synth_pitch_bend(fluidSynth, channel, (parm1&0x7F) | ((parm2&0x7F)<<7));
1859 i->Offset += 2;
1860 break;
1862 case MIDI_SPECIAL:
1863 switch(event)
1865 case MIDI_SYSEX:
1867 unsigned long len = i->ReadVarLen();
1868 if(i->data.size() - i->Offset < len)
1870 i->Offset = i->data.size();
1871 break;
1874 if(len > 1 && i->data[len-1] == MIDI_SYSEXEND)
1876 char *data = reinterpret_cast<char*>(&i->data[i->Offset]);
1877 pfluid_synth_sysex(fluidSynth, data, len-1, NULL, NULL, NULL, false);
1879 i->Offset += len;
1880 break;
1882 case MIDI_SYSEXEND:
1884 unsigned long len = i->ReadVarLen();
1885 if(i->data.size() - i->Offset < len)
1887 i->Offset = i->data.size();
1888 break;
1890 i->Offset += len;
1891 break;
1894 case MIDI_SONGPOS:
1895 i->Offset += 2;
1896 break;
1898 case MIDI_SONGSEL:
1899 i->Offset += 1;
1900 break;
1902 case MIDI_META:
1904 ALubyte metatype = i->data[i->Offset++];
1905 unsigned long val = i->ReadVarLen();
1907 if(i->data.size() - i->Offset < val)
1909 i->Offset = i->data.size();
1910 break;
1913 if(metatype == MIDI_META_EOT)
1915 i->Offset = i->data.size();
1916 break;
1919 if(metatype == MIDI_META_TEMPO && val >= 3)
1921 newtempo = (i->data[i->Offset] << 16) |
1922 (i->data[i->Offset+1] << 8) |
1923 (i->data[i->Offset+2]);
1926 i->Offset += val;
1927 break;
1930 default:
1931 /* The rest of the special events don't have any
1932 * data bytes */
1933 break;
1935 break;
1937 default:
1938 /* Shouldn't ever get to here */
1939 break;
1942 unsigned long val = i->ReadVarLen();
1943 i->SamplesLeft += val * samplesPerTick;
1945 if(newtempo)
1946 UpdateTempo(newtempo);
1949 void UpdateTempo(ALuint tempo)
1951 ALdouble sampletickrate = sampleRate / (1000000. / tempo) / Divisions;
1953 for(std::vector<MidiTrack>::iterator i = Tracks.begin(),
1954 end = Tracks.end();i != end;i++)
1956 if(i->Offset >= i->data.size())
1957 continue;
1958 i->SamplesLeft = i->SamplesLeft / samplesPerTick * sampletickrate;
1960 samplesPerTick = sampletickrate;
1963 void SetupSynth()
1965 fluidSettings = pnew_fluid_settings();
1966 if(fluidSettings)
1968 pfluid_settings_setnum(fluidSettings, "synth.gain", 0.5);
1969 pfluid_settings_setstr(fluidSettings, "synth.reverb.active", "yes");
1970 pfluid_settings_setstr(fluidSettings, "synth.chorus.active", "yes");
1971 pfluid_settings_setint(fluidSettings, "synth.polyphony", 256);
1972 pfluid_settings_setnum(fluidSettings, "synth.sample-rate", (double)sampleRate);
1974 fluidSynth = pnew_fluid_synth(fluidSettings);
1975 if(fluidSynth)
1977 const char *soundfont = getenv("FLUID_SOUNDFONT");
1978 if(soundfont && soundfont[0])
1979 fontID = pfluid_synth_sfload(fluidSynth, soundfont, true);
1984 static DecoderDecl<fluidStream> fluidStream_decoder;
1985 #endif
1988 template <typename T>
1989 alureStream *get_stream_decoder(const T &fdata)
1991 std::map<ALint,UserCallbacks>::iterator i = InstalledCallbacks.begin();
1992 while(i != InstalledCallbacks.end() && i->first < 0)
1994 std::auto_ptr<alureStream> stream(new customStream(fdata, i->second));
1995 if(stream->IsValid()) return stream.release();
1996 i++;
1999 std::istream *file = new InStream(fdata);
2000 if(!file->fail())
2002 Decoder::ListType Factories = Decoder::GetList();
2003 Decoder::ListType::iterator factory = Factories.begin();
2004 Decoder::ListType::iterator end = Factories.end();
2005 while(factory != end)
2007 file->clear();
2008 file->seekg(0, std::ios_base::beg);
2010 std::auto_ptr<alureStream> stream((*factory)(file));
2011 if(stream.get() != NULL) return stream.release();
2013 factory++;
2016 SetError("Unsupported type");
2017 delete file;
2019 else
2021 SetError("Failed to open file");
2022 delete file;
2025 while(i != InstalledCallbacks.end())
2027 std::auto_ptr<alureStream> stream(new customStream(fdata, i->second));
2028 if(stream->IsValid()) return stream.release();
2029 i++;
2032 return new nullStream;
2035 alureStream *create_stream(const char *fname)
2036 { return get_stream_decoder(fname); }
2037 alureStream *create_stream(const MemDataInfo &memData)
2038 { return get_stream_decoder(memData); }
2040 alureStream *create_stream(ALvoid *userdata, ALenum format, ALuint rate, const UserCallbacks &cb)
2041 { return new customStream(userdata, format, rate, cb); }