renamed all .h to .hpp
[supertux.git] / src / audio / stream_sound_source.cpp
1 #include <config.h>
2
3 #include "stream_sound_source.hpp"
4 #include "sound_manager.hpp"
5 #include "sound_file.hpp"
6
7 StreamSoundSource::StreamSoundSource(SoundFile* file)
8 {
9   this->file = file;
10   alGenBuffers(STREAMFRAGMENTS, buffers);
11   SoundManager::check_al_error("Couldn't allocate audio buffers: ");
12   format = SoundManager::get_sample_format(file);
13   try {
14     for(size_t i = 0; i < STREAMFRAGMENTS; ++i) {
15       fillBufferAndQueue(buffers[i]);
16     }
17   } catch(...) {
18     alDeleteBuffers(STREAMFRAGMENTS, buffers);
19   }
20 }
21
22 StreamSoundSource::~StreamSoundSource()
23 {
24   alDeleteBuffers(STREAMFRAGMENTS, buffers);
25   SoundManager::check_al_error("Couldn't delete audio buffers: ");
26 }
27
28 void
29 StreamSoundSource::update()
30 {
31   if(!playing())
32     return;
33
34   ALint processed = 0;
35   alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
36   while(processed > 0) {
37     processed--;
38
39     ALuint buffer;
40     alSourceUnqueueBuffers(source, 1, &buffer);
41     SoundManager::check_al_error("Couldn't unqueu audio buffer: ");
42
43     fillBufferAndQueue(buffer);
44   }
45   
46   // we might have to restart the source if we had a buffer underrun
47   if(!playing()) {
48     std::cerr << "Restarting audio source because of buffer underrun.\n";
49     alSourcePlay(source);
50     SoundManager::check_al_error("Couldn't restart audio source: ");
51   }
52
53   // TODO handle fading
54 }
55
56 void
57 StreamSoundSource::fillBufferAndQueue(ALuint buffer)
58 {
59   // fill buffer
60   char* bufferdata = new char[STREAMFRAGMENTSIZE];
61   size_t bytesread = 0;
62   do {
63     bytesread += file->read(bufferdata + bytesread,
64         STREAMFRAGMENTSIZE - bytesread);
65     if(bytesread < STREAMFRAGMENTSIZE) {
66       file->reset();
67     }
68   } while(bytesread < STREAMFRAGMENTSIZE);
69   
70   alBufferData(buffer, format, bufferdata, STREAMFRAGMENTSIZE, file->rate);
71   delete[] bufferdata;
72   SoundManager::check_al_error("Couldn't refill audio buffer: ");
73
74   alSourceQueueBuffers(source, 1, &buffer);
75   SoundManager::check_al_error("Couldn't queue audio buffer: ");
76 }