1
/***************************************************************************
2
copyright : (C) 2002 - 2008 by Scott Wheeler
3
email : wheeler@kde.org
4
***************************************************************************/
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. *
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. *
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 *
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
***************************************************************************/
29
#include "relativevolumeframe.h"
31
using namespace TagLib;
32
using namespace ID3v2;
34
static inline int bitsToBytes(int i)
36
return i % 8 == 0 ? i / 8 : (i - i % 8) / 8 + 1;
41
ChannelData() : channelType(RelativeVolumeFrame::Other), volumeAdjustment(0) {}
43
RelativeVolumeFrame::ChannelType channelType;
44
short volumeAdjustment;
45
RelativeVolumeFrame::PeakVolume peakVolume;
48
class RelativeVolumeFrame::RelativeVolumeFramePrivate
51
String identification;
52
Map<ChannelType, ChannelData> channels;
55
////////////////////////////////////////////////////////////////////////////////
57
////////////////////////////////////////////////////////////////////////////////
59
RelativeVolumeFrame::RelativeVolumeFrame() : Frame("RVA2")
61
d = new RelativeVolumeFramePrivate;
64
RelativeVolumeFrame::RelativeVolumeFrame(const ByteVector &data) : Frame(data)
66
d = new RelativeVolumeFramePrivate;
70
RelativeVolumeFrame::~RelativeVolumeFrame()
75
String RelativeVolumeFrame::toString() const
77
return d->identification;
80
List<RelativeVolumeFrame::ChannelType> RelativeVolumeFrame::channels() const
84
Map<ChannelType, ChannelData>::ConstIterator it = d->channels.begin();
85
for(; it != d->channels.end(); ++it)
86
l.append((*it).first);
93
RelativeVolumeFrame::ChannelType RelativeVolumeFrame::channelType() const
100
void RelativeVolumeFrame::setChannelType(ChannelType)
105
short RelativeVolumeFrame::volumeAdjustmentIndex(ChannelType type) const
107
return d->channels.contains(type) ? d->channels[type].volumeAdjustment : 0;
110
short RelativeVolumeFrame::volumeAdjustmentIndex() const
112
return volumeAdjustmentIndex(MasterVolume);
115
void RelativeVolumeFrame::setVolumeAdjustmentIndex(short index, ChannelType type)
117
d->channels[type].volumeAdjustment = index;
120
void RelativeVolumeFrame::setVolumeAdjustmentIndex(short index)
122
setVolumeAdjustmentIndex(index, MasterVolume);
125
float RelativeVolumeFrame::volumeAdjustment(ChannelType type) const
127
return d->channels.contains(type) ? float(d->channels[type].volumeAdjustment) / float(512) : 0;
130
float RelativeVolumeFrame::volumeAdjustment() const
132
return volumeAdjustment(MasterVolume);
135
void RelativeVolumeFrame::setVolumeAdjustment(float adjustment, ChannelType type)
137
d->channels[type].volumeAdjustment = short(adjustment * float(512));
140
void RelativeVolumeFrame::setVolumeAdjustment(float adjustment)
142
setVolumeAdjustment(adjustment, MasterVolume);
145
RelativeVolumeFrame::PeakVolume RelativeVolumeFrame::peakVolume(ChannelType type) const
147
return d->channels.contains(type) ? d->channels[type].peakVolume : PeakVolume();
150
RelativeVolumeFrame::PeakVolume RelativeVolumeFrame::peakVolume() const
152
return peakVolume(MasterVolume);
155
void RelativeVolumeFrame::setPeakVolume(const PeakVolume &peak, ChannelType type)
157
d->channels[type].peakVolume = peak;
160
void RelativeVolumeFrame::setPeakVolume(const PeakVolume &peak)
162
setPeakVolume(peak, MasterVolume);
165
String RelativeVolumeFrame::identification() const
167
return d->identification;
170
void RelativeVolumeFrame::setIdentification(const String &s)
172
d->identification = s;
175
////////////////////////////////////////////////////////////////////////////////
177
////////////////////////////////////////////////////////////////////////////////
179
void RelativeVolumeFrame::parseFields(const ByteVector &data)
182
d->identification = readStringField(data, String::Latin1, &pos);
184
// Each channel is at least 4 bytes.
186
while(pos <= (int)data.size() - 4) {
189
ChannelType type = ChannelType(data[pos]);
192
ChannelData &channel = d->channels[type];
194
channel.volumeAdjustment = data.mid(pos, 2).toShort();
197
channel.peakVolume.bitsRepresentingPeak = data[pos];
200
int bytes = bitsToBytes(channel.peakVolume.bitsRepresentingPeak);
201
channel.peakVolume.peakVolume = data.mid(pos, bytes);
206
ByteVector RelativeVolumeFrame::renderFields() const
210
data.append(d->identification.data(String::Latin1));
211
data.append(textDelimiter(String::Latin1));
213
Map<ChannelType, ChannelData>::ConstIterator it = d->channels.begin();
215
for(; it != d->channels.end(); ++it) {
216
ChannelType type = (*it).first;
217
const ChannelData &channel = (*it).second;
219
data.append(char(type));
220
data.append(ByteVector::fromShort(channel.volumeAdjustment));
221
data.append(char(channel.peakVolume.bitsRepresentingPeak));
222
data.append(channel.peakVolume.peakVolume);
228
////////////////////////////////////////////////////////////////////////////////
230
////////////////////////////////////////////////////////////////////////////////
232
RelativeVolumeFrame::RelativeVolumeFrame(const ByteVector &data, Header *h) : Frame(h)
234
d = new RelativeVolumeFramePrivate;
235
parseFields(fieldData(data));