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
|
//-------------------------------------------------------------------------
// 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 block 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 processOneBlock ();
//-------------------------------------------------------------------
// 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 * block,
const FLAC__int32 * const buffer[]);
//------------------------------------------------------------
// Does all the real work for read callbacks for non-seekable
// streams.
//------------------------------------------------------------
FLAC__StreamDecoderReadStatus
realReadCallBack (FLAC__byte buffer[],
size_t * bytes);
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 * block,
const FLAC__int32 * const buffer[],
void * client_data);
static FLAC__StreamDecoderReadStatus
readCallBack (const FLAC__StreamDecoder * decoder,
FLAC__byte buffer[],
size_t * bytes,
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)
{
return false;
}
} // namespace Flac
#endif // _FLAC_STREAM_H_
|