Added TagLib (with AUTORS and COPYING files)
[someplayer] / src / taglib / flac / flacproperties.cpp
1 /***************************************************************************
2     copyright            : (C) 2003 by Allan Sandfeld Jensen
3     email                : kde@carewolf.org
4  ***************************************************************************/
5
6 /***************************************************************************
7  *   This library is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU Lesser General Public License version   *
9  *   2.1 as published by the Free Software Foundation.                     *
10  *                                                                         *
11  *   This library is distributed in the hope that it will be useful, but   *
12  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
14  *   Lesser General Public License for more details.                       *
15  *                                                                         *
16  *   You should have received a copy of the GNU Lesser General Public      *
17  *   License along with this library; if not, write to the Free Software   *
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
19  *   USA                                                                   *
20  *                                                                         *
21  *   Alternatively, this file is available under the Mozilla Public        *
22  *   License Version 1.1.  You may obtain a copy of the License at         *
23  *   http://www.mozilla.org/MPL/                                           *
24  ***************************************************************************/
25
26 #include <tstring.h>
27 #include <tdebug.h>
28
29 #include "flacproperties.h"
30 #include "flacfile.h"
31
32 using namespace TagLib;
33
34 class FLAC::Properties::PropertiesPrivate
35 {
36 public:
37   PropertiesPrivate(ByteVector d, long st, ReadStyle s) :
38     data(d),
39     streamLength(st),
40     style(s),
41     length(0),
42     bitrate(0),
43     sampleRate(0),
44     sampleWidth(0),
45     channels(0) {}
46
47   ByteVector data;
48   long streamLength;
49   ReadStyle style;
50   int length;
51   int bitrate;
52   int sampleRate;
53   int sampleWidth;
54   int channels;
55 };
56
57 ////////////////////////////////////////////////////////////////////////////////
58 // public members
59 ////////////////////////////////////////////////////////////////////////////////
60
61 FLAC::Properties::Properties(ByteVector data, long streamLength, ReadStyle style) : AudioProperties(style)
62 {
63   d = new PropertiesPrivate(data, streamLength, style);
64   read();
65 }
66
67 FLAC::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style)
68 {
69   d = new PropertiesPrivate(file->streamInfoData(), file->streamLength(), style);
70   read();
71 }
72
73 FLAC::Properties::~Properties()
74 {
75   delete d;
76 }
77
78 int FLAC::Properties::length() const
79 {
80   return d->length;
81 }
82
83 int FLAC::Properties::bitrate() const
84 {
85   return d->bitrate;
86 }
87
88 int FLAC::Properties::sampleRate() const
89 {
90   return d->sampleRate;
91 }
92
93 int FLAC::Properties::sampleWidth() const
94 {
95   return d->sampleWidth;
96 }
97
98 int FLAC::Properties::channels() const
99 {
100   return d->channels;
101 }
102
103 ////////////////////////////////////////////////////////////////////////////////
104 // private members
105 ////////////////////////////////////////////////////////////////////////////////
106
107 void FLAC::Properties::read()
108 {
109   if(d->data.size() < 18) {
110     debug("FLAC::Properties::read() - FLAC properties must contain at least 18 bytes.");
111     return;
112   }
113
114   int pos = 0;
115
116   // Minimum block size (in samples)
117   pos += 2;
118
119   // Maximum block size (in samples)
120   pos += 2;
121
122   // Minimum frame size (in bytes)
123   pos += 3;
124
125   // Maximum frame size (in bytes)
126   pos += 3;
127
128   uint flags = d->data.mid(pos, 4).toUInt(true);
129   d->sampleRate = flags >> 12;
130   d->channels = ((flags >> 9) & 7) + 1;
131   d->sampleWidth = ((flags >> 4) & 31) + 1;
132
133   // The last 4 bits are the most significant 4 bits for the 36 bit
134   // stream length in samples. (Audio files measured in days)
135
136   uint highLength =d->sampleRate > 0 ? (((flags & 0xf) << 28) / d->sampleRate) << 4 : 0;
137   pos += 4;
138
139   d->length = d->sampleRate > 0 ?
140       (d->data.mid(pos, 4).toUInt(true)) / d->sampleRate + highLength : 0;
141   pos += 4;
142
143   // Uncompressed bitrate:
144
145   //d->bitrate = ((d->sampleRate * d->channels) / 1000) * d->sampleWidth;
146
147   // Real bitrate:
148
149   d->bitrate = d->length > 0 ? ((d->streamLength * 8UL) / d->length) / 1000 : 0;
150 }