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