1 /*
2  * Zaz
3  * Copyright (C) Remigiusz Dybka 2009 <remigiusz.dybka@gmail.com>
4  *
5  Zaz is free software: you can redistribute it and/or modify it
6  under the terms of the GNU General Public License as published by the
7  Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  Zaz is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  See the GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "sample.h"
20 #include <vorbis/codec.h>
21 #include <vorbis/vorbisfile.h>
22 
23 namespace Scenes
24 {
StreamingOggSample(const string filename)25 StreamingOggSample::StreamingOggSample(const string filename)
26 {
27     bufflen = 0;
28     buff = 0;
29 
30     inphile = fopen(settings.getCFilename (filename), "rb");
31     if (inphile == NULL)
32     {
33         ERR("Could not open " + filename);
34     }
35 
36     if (ov_open_callbacks(inphile, &vf, NULL, 0, OV_CALLBACKS_NOCLOSE) < 0)
37     {
38         fclose(inphile);
39         ERR("Not an ogg file: " + filename);
40     }
41 
42     vi=ov_info(&vf,-1);
43 
44     channels = vi->channels;
45     length = ov_pcm_total(&vf, -1) * channels;
46 
47     loaded = true;
48 }
49 
~StreamingOggSample()50 StreamingOggSample::~StreamingOggSample()
51 {
52     if (loaded)
53     {
54         ov_clear(&vf);
55 
56         fclose(inphile);
57 
58         free(buff);
59     }
60 }
61 
getLength()62 uint StreamingOggSample::getLength()
63 {
64     return 0;
65 }
66 
getSampleData(uint requested_length,uint & returned_length)67 Sint16 * StreamingOggSample::getSampleData(uint requested_length, uint &returned_length)
68 {
69     if (bufflen != requested_length)
70     {
71         if (buff)
72             free(buff);
73 
74         buff = (Sint16*)malloc(requested_length * 2);
75         bufflen = requested_length;
76     }
77 
78     int eof=0;
79     int current_section;
80 
81     uint offset = 0;
82     uint rem = requested_length * 2;
83 
84     while (!eof && rem)
85     {
86 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
87         long ret=ov_read(&vf,((char *)buff) + offset,rem,1,2,1,&current_section);
88 #else
89         long ret=ov_read(&vf,((char *)buff) + offset,rem,0,2,1,&current_section);
90 #endif
91         if (ret == 0)
92         {
93             /* EOF */
94             eof=1;
95         }
96         else if (ret < 0)
97         {
98             // some error happened .... who cares :)
99         }
100         else
101         {
102             rem-=ret;
103             offset+=ret;
104         }
105     }
106 
107     returned_length = requested_length - (rem / 2);
108     return buff;
109 }
110 
getStreaming()111 bool StreamingOggSample::getStreaming()
112 {
113     return true;
114 };
115 
getNumChannels()116 uint StreamingOggSample::getNumChannels()
117 {
118     return channels;
119 };
120 
Restart()121 void StreamingOggSample::Restart()
122 {
123     ov_raw_seek(&vf,0);
124 };
125 }
126