]> git.tdb.fi Git - libs/al.git/blob - source/streamer.cpp
Implement seeking in sound decoders
[libs/al.git] / source / streamer.cpp
1 #include "buffer.h"
2 #include "sounddecoder.h"
3 #include "streamer.h"
4
5 using namespace std;
6
7 namespace Msp {
8 namespace AL {
9
10 Streamer::Streamer(Source &s):
11         src(s),
12         decoder(0)
13 { }
14
15 Streamer::~Streamer()
16 {
17         src.stop();
18         src.clear_buffers();
19         for(list<Buffer *>::iterator i=buffers.begin(); i!=buffers.end(); ++i)
20                 delete *i;
21 }
22
23 void Streamer::play(SoundDecoder &s)
24 {
25         decoder = &s;
26         tick();
27         src.play();
28 }
29
30 void Streamer::stop()
31 {
32         decoder = 0;
33         src.stop();
34 }
35
36 void Streamer::tick()
37 {
38         if(unsigned n = src.get_buffers_processed())
39         {
40                 for(unsigned i=0; i<n; ++i)
41                 {
42                         src.unqueue_buffer(*buffers.front());
43                         delete buffers.front();
44                         buffers.erase(buffers.begin());
45                 }
46         }
47
48         if(!decoder)
49                 return;
50
51         if(src.get_state()!=PLAYING && src.get_state()!=PAUSED)
52                 src.play();
53
54         unsigned freq = decoder->get_frequency();
55         unsigned chunk_size = freq&~0xF;
56         unsigned queued = src.get_buffers_queued();
57         vector<char> data(chunk_size);
58         for(unsigned i=queued; i<4; ++i)
59         {
60                 unsigned pos = 0;
61                 while(pos<chunk_size)
62                 {
63                         unsigned len = decoder->read(&data[0]+pos, chunk_size-pos);
64                         if(len==0)
65                                 break;
66                         pos += len;
67                 }
68
69                 if(pos)
70                 {
71                         Buffer *buf = new Buffer;
72                         buf->data(decoder->get_format(), &data[0], pos, freq);
73                         src.queue_buffer(*buf);
74                         buffers.push_back(buf);
75                 }
76         }
77
78         if(decoder->eof())
79                 decoder = 0;
80 }
81
82 } // namespace AL
83 } // namespace Msp