~ubuntu-branches/ubuntu/wily/alsaplayer/wily

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
//-------------------------------------------------------------------------
//  This class encapsulates a flac stream.  Only the functions
//  needed by the alsaplayer flac plugin are implemented.
//
//  Copyright (c) 2002 by Drew Hess <dhess@bothan.net>
//
/*  This file is part of AlsaPlayer.
 *
 *  AlsaPlayer is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  AlsaPlayer is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
//-------------------------------------------------------------------------


#ifndef _FLAC_STREAM_H_
#define _FLAC_STREAM_H_

#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT < 8
#define LEGACY_FLAC
#else
#undef LEGACY_FLAC
#endif

#include <string>
#include "reader.h"

extern "C"
{
#include <FLAC/stream_decoder.h>
}

#undef DEBUG

namespace Flac
{

class FlacEngine;
class FlacTag;

class FlacStream
{
 public:

    //--------------------------------------------------------------
    // Return true if we think name points to  a valid flac stream.
    //--------------------------------------------------------------

    static bool isFlacStream (const std::string & name);

    
 public:

    //---------------------------------------------------------------
    // Constructor & destructor.  The reader_type f belongs to the
    // FlacStream after construction, and it will be closed
    // upon deletion of the FlacStream object.  If reportErrors is
    // false, the object will squelch all alsaplayer_error messages.
    // This is particularly useful when attempting to open streams
    // to determine whether they're FLAC streams.
    //---------------------------------------------------------------

    FlacStream (const std::string & name,
		reader_type * f,
		bool reportErrors = true);

    virtual ~FlacStream ();


    //------------------------------------------------------------------
    // Initialize the stream decoder, installing all callbacks from the
    // engine.  Returns false if the decoder could not be initialized
    // or if the engine hasn't been set (see setEngine).
    //------------------------------------------------------------------

    virtual bool        open ();


    //----------------------------------------------------------
    // Get a pointer to the FlacEngine for this stream decoder.
    //----------------------------------------------------------

    FlacEngine *        engine () const;


    //----------------------------------------------------------------------
    // Get a pointer to the FlacTag for this stream, or 0 if there is none.
    //----------------------------------------------------------------------

    FlacTag *           tag () const;


    //----------------------------------
    // Set the FlacTag for this stream.
    //----------------------------------

    void                setTag (FlacTag * tag);


    //-----------------------------------
    // Get the name of the flac stream.
    //-----------------------------------

    const std::string & name () const;


    //------------------------------------------------------
    // Get the sample rate of the uncompressed audio stream.
    //------------------------------------------------------

    unsigned int                sampleRate () const;


    //----------------------------------------
    // Number of channels in the audio stream.
    //----------------------------------------

    unsigned int                channels () const;


    //----------------------------------------------------------
    // Total number of uncompressed samples in the audio stream.
    //----------------------------------------------------------

    FLAC__uint64                totalSamples () const;


    //--------------------------------------------------------------
    // The number of uncompressd samples in one block of audio data.
    //--------------------------------------------------------------

    unsigned int                samplesPerBlock () const;


    //-----------------
    // Bits per sample.
    //-----------------

    unsigned int                bps () const;


    //----------------------------------------------------------------
    // Process the next flac frame in the stream.  This has the side-
    // effect of calling the write callback if there is data to fetch
    // in the stream.
    //
    // Returns false if there's no more data in the stream, or if
    // there's an error in the stream decoder.
    //----------------------------------------------------------------

    virtual bool                processOneFrame ();


    //-------------------------------------------------------------------
    // Seeks are unsupported.  Returns false.
    //-------------------------------------------------------------------

    virtual bool                seekAbsolute (FLAC__uint64);


 protected:

    void                        apError (const char * msg);
    void                        apError (const char * fmt, const char * str);

 protected:

    FlacStream ();


    //---------------------------------------------------------------------
    // The following 3 functions do all the real work for the
    // various callbacks and are shared by all FLAC stream implementations.
    //---------------------------------------------------------------------

    void         realMetaCallBack (const FLAC__StreamMetadata * md);

    void         realErrCallBack (const char * name,
				  FLAC__StreamDecoderErrorStatus status);

    FLAC__StreamDecoderWriteStatus 
                 realWriteCallBack (const FLAC__Frame * frame,
				    const FLAC__int32 * const buffer[]);


    //------------------------------------------------------------
    // Does all the real work for read callbacks for non-seekable
    // streams.
    //------------------------------------------------------------

    FLAC__StreamDecoderReadStatus 
                 realReadCallBack (FLAC__byte buffer[],
#ifdef LEGACY_FLAC
				   unsigned * bytes);
#else
				   size_t * bytes);
#endif


 protected:

    FlacEngine *  _engine;
    bool          _mcbSuccess;
    reader_type * _datasource;
    bool          _reportErrors;

    //---------------------------------------------------------------------
    // Stream info.  "Samples" always refers to uncompressed audio samples.
    //---------------------------------------------------------------------

    unsigned int  _channels;      // number of channels in the stream
    unsigned int  _bps;           // bits per sample
    unsigned int  _sampleRate;    // number of samples per channel per sec
    unsigned int  _sampPerBlock;  // number of samples per block of data
    FLAC__uint64  _totalSamp;     // total number of samples in the stream

    
 private:

    //-----------------------------------------------------------------
    // The flac metadata callback.  It's called as a side effect of the
    // open method.  It'll be called once for each metadata block in
    // the flac stream.  To check its success, look at _mcbSuccess.
    //-----------------------------------------------------------------

    static void metaCallBack (const FLAC__StreamDecoder * decoder,
			      const FLAC__StreamMetadata * md,
			      void * cilent_data);

    static FLAC__StreamDecoderWriteStatus 
	writeCallBack (const FLAC__StreamDecoder * decoder,
		       const FLAC__Frame * frame,
		       const FLAC__int32 * const buffer[],
		       void * client_data);

    static FLAC__StreamDecoderReadStatus
	readCallBack (const FLAC__StreamDecoder * decoder,
		      FLAC__byte buffer[],
#ifdef LEGACY_FLAC
		      unsigned * bytes,
#else
		      size_t * bytes,
#endif
		      void * client_data);

    static void errCallBack (const FLAC__StreamDecoder * decoder,
			     FLAC__StreamDecoderErrorStatus status,
			     void * client_data);


 private:

    FLAC__StreamDecoder * _decoder;
    FlacTag *             _tag;
    const std::string     _name;


}; // class FlacStream


//----------------
// Inline methods.
//----------------

inline FlacTag *
FlacStream::tag () const
{
    return _tag;
}

inline FlacEngine *
FlacStream::engine () const
{
    return _engine;
}

inline void
FlacStream::setTag (FlacTag * tag)
{
    _tag = tag;
}

inline const std::string &
FlacStream::name () const
{
    return _name;
}

inline unsigned int
FlacStream::sampleRate () const
{
    return _sampleRate;
}

inline FLAC__uint64
FlacStream::totalSamples () const
{
    return _totalSamp;
}

inline unsigned int
FlacStream::samplesPerBlock () const
{
    return _sampPerBlock;
}

inline unsigned int
FlacStream::bps () const
{
    return _bps;
}

inline unsigned int
FlacStream::channels () const
{
    return _channels;
}

inline bool
FlacStream::seekAbsolute (FLAC__uint64 sample)
{
    return false;
}

} // namespace Flac

#endif // _FLAC_STREAM_H_