~njh-aelius/maxosx/musicbrainz-tags

« back to all changes in this revision

Viewing changes to Frameworks/taglib/taglib/taglib/ogg/vorbis/vorbisproperties.cpp

  • Committer: stephen_booth
  • Date: 2008-04-30 02:09:12 UTC
  • Revision ID: svn-v4:6b6cea13-1402-0410-9567-a7afb52bf336:trunk:1372
Update to latest taglib SVN

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
    copyright            : (C) 2002 - 2008 by Scott Wheeler
 
3
    email                : wheeler@kde.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 <oggpageheader.h>
 
30
 
 
31
#include "vorbisproperties.h"
 
32
#include "vorbisfile.h"
 
33
 
 
34
using namespace TagLib;
 
35
 
 
36
class Vorbis::Properties::PropertiesPrivate
 
37
{
 
38
public:
 
39
  PropertiesPrivate(File *f, ReadStyle s) :
 
40
    file(f),
 
41
    style(s),
 
42
    length(0),
 
43
    bitrate(0),
 
44
    sampleRate(0),
 
45
    channels(0),
 
46
    vorbisVersion(0),
 
47
    bitrateMaximum(0),
 
48
    bitrateNominal(0),
 
49
    bitrateMinimum(0) {}
 
50
 
 
51
  File *file;
 
52
  ReadStyle style;
 
53
  int length;
 
54
  int bitrate;
 
55
  int sampleRate;
 
56
  int channels;
 
57
  int vorbisVersion;
 
58
  int bitrateMaximum;
 
59
  int bitrateNominal;
 
60
  int bitrateMinimum;
 
61
};
 
62
 
 
63
namespace TagLib {
 
64
  /*!
 
65
   * Vorbis headers can be found with one type ID byte and the string "vorbis" in
 
66
   * an Ogg stream.  0x01 indicates the setup header.
 
67
   */
 
68
  static const char vorbisSetupHeaderID[] = { 0x01, 'v', 'o', 'r', 'b', 'i', 's', 0 };
 
69
}
 
70
 
 
71
////////////////////////////////////////////////////////////////////////////////
 
72
// public members
 
73
////////////////////////////////////////////////////////////////////////////////
 
74
 
 
75
Vorbis::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style)
 
76
{
 
77
  d = new PropertiesPrivate(file, style);
 
78
  read();
 
79
}
 
80
 
 
81
Vorbis::Properties::~Properties()
 
82
{
 
83
  delete d;
 
84
}
 
85
 
 
86
int Vorbis::Properties::length() const
 
87
{
 
88
  return d->length;
 
89
}
 
90
 
 
91
int Vorbis::Properties::bitrate() const
 
92
{
 
93
  return int(float(d->bitrate) / float(1000) + 0.5);
 
94
}
 
95
 
 
96
int Vorbis::Properties::sampleRate() const
 
97
{
 
98
  return d->sampleRate;
 
99
}
 
100
 
 
101
int Vorbis::Properties::channels() const
 
102
{
 
103
  return d->channels;
 
104
}
 
105
 
 
106
int Vorbis::Properties::vorbisVersion() const
 
107
{
 
108
  return d->vorbisVersion;
 
109
}
 
110
 
 
111
int Vorbis::Properties::bitrateMaximum() const
 
112
{
 
113
  return d->bitrateMaximum;
 
114
}
 
115
 
 
116
int Vorbis::Properties::bitrateNominal() const
 
117
{
 
118
  return d->bitrateNominal;
 
119
}
 
120
 
 
121
int Vorbis::Properties::bitrateMinimum() const
 
122
{
 
123
  return d->bitrateMinimum;
 
124
}
 
125
 
 
126
////////////////////////////////////////////////////////////////////////////////
 
127
// private members
 
128
////////////////////////////////////////////////////////////////////////////////
 
129
 
 
130
void Vorbis::Properties::read()
 
131
{
 
132
  // Get the identification header from the Ogg implementation.
 
133
 
 
134
  ByteVector data = d->file->packet(0);
 
135
 
 
136
  int pos = 0;
 
137
 
 
138
  if(data.mid(pos, 7) != vorbisSetupHeaderID) {
 
139
    debug("Vorbis::Properties::read() -- invalid Vorbis identification header");
 
140
    return;
 
141
  }
 
142
 
 
143
  pos += 7;
 
144
 
 
145
  d->vorbisVersion = data.mid(pos, 4).toUInt(false);
 
146
  pos += 4;
 
147
 
 
148
  d->channels = uchar(data[pos]);
 
149
  pos += 1;
 
150
 
 
151
  d->sampleRate = data.mid(pos, 4).toUInt(false);
 
152
  pos += 4;
 
153
 
 
154
  d->bitrateMaximum = data.mid(pos, 4).toUInt(false);
 
155
  pos += 4;
 
156
 
 
157
  d->bitrateNominal = data.mid(pos, 4).toUInt(false);
 
158
  pos += 4;
 
159
 
 
160
  d->bitrateMinimum = data.mid(pos, 4).toUInt(false);
 
161
 
 
162
  // TODO: Later this should be only the "fast" mode.
 
163
  d->bitrate = d->bitrateNominal;
 
164
 
 
165
  // Find the length of the file.  See http://wiki.xiph.org/VorbisStreamLength/
 
166
  // for my notes on the topic.
 
167
 
 
168
  const Ogg::PageHeader *first = d->file->firstPageHeader();
 
169
  const Ogg::PageHeader *last = d->file->lastPageHeader();
 
170
 
 
171
  if(first && last) {
 
172
    long long start = first->absoluteGranularPosition();
 
173
    long long end = last->absoluteGranularPosition();
 
174
 
 
175
    if(start >= 0 && end >= 0 && d->sampleRate > 0)
 
176
      d->length = (end - start) / (long long) d->sampleRate;
 
177
    else
 
178
      debug("Vorbis::Properties::read() -- Either the PCM values for the start or "
 
179
            "end of this file was incorrect or the sample rate is zero.");
 
180
  }
 
181
  else
 
182
    debug("Vorbis::Properties::read() -- Could not find valid first and last Ogg pages.");
 
183
}