3 Copyright (C) 2008 jlh (jlh at gmx dot ch)
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2 of the License, version 3 of
8 the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 The GNU General Public License version 2 is included with the source of
20 this program under the file name COPYING. You can also get a copy on
26 #include <lame/lame.h>
28 #include "mp3writer.h"
30 #include "preferences.h"
32 Mp3Writer::~Mp3Writer() {
35 bool Mp3Writer::open(const QString
&fn
, long sr
, bool s
) {
36 bool b
= AudioFileWriter::open(fn
+ ".mp3", sr
, s
);
45 bitRate
= preferences
.get("output.format.mp3.bitrate").toInt();
47 lame_set_in_samplerate(lame
, sampleRate
);
48 lame_set_num_channels(lame
, stereo
? 2 : 1);
49 lame_set_out_samplerate(lame
, sampleRate
);
50 // TODO: do we need this?
51 lame_set_bWriteVbrTag(lame
, 0);
52 lame_set_mode(lame
, stereo
? STEREO
: MONO
);
53 lame_set_brate(lame
, bitRate
);
54 if (lame_init_params(lame
) == -1)
60 void Mp3Writer::close() {
61 AudioFileWriter::close();
66 ID3_Frame
*getOrCreateTag(ID3_Tag
&tag
, ID3_FrameID id
) {
67 ID3_Frame
*frame
= tag
.Find(id
);
70 frame
= new ID3_Frame(id
);
71 tag
.AttachFrame(frame
);
78 void Mp3Writer::writeTags() {
82 debug("Writing tags to MP3 file");
84 QByteArray fn
= QFile::encodeName(file
.fileName());
85 ID3_Tag
tag(fn
.constData());
87 // NOTE: we don't set ID3FID_TITLE as the file name is already meant to
88 // be a good enough description of the content
90 QString str
= tagTime
.toString("yyyyddMMhhmm");
91 // TODO: the following would be better but doesn't work. find out why
92 //getOrCreateTag(tag, ID3FID_COMMENT )->GetField(ID3FN_TEXT)->Set(tagComment.utf16());
93 getOrCreateTag(tag
, ID3FID_COMMENT
)->GetField(ID3FN_TEXT
)->Set(tagComment
.toAscii().constData());
94 getOrCreateTag(tag
, ID3FID_CONTENTTYPE
)->GetField(ID3FN_TEXT
)->Set("(101)Skype Call");
95 getOrCreateTag(tag
, ID3FID_YEAR
)->GetField(ID3FN_TEXT
)->Set(str
.mid(0, 4).toAscii().constData());
96 getOrCreateTag(tag
, ID3FID_DATE
)->GetField(ID3FN_TEXT
)->Set(str
.mid(4, 4).toAscii().constData());
97 getOrCreateTag(tag
, ID3FID_TIME
)->GetField(ID3FN_TEXT
)->Set(str
.mid(8, 4).toAscii().constData());
100 mustWriteTags
= false;
103 bool Mp3Writer::write(QByteArray
&left
, QByteArray
&right
, int samples
, bool flush
) {
106 // rough upper bound formula taken from lame.h
107 int size
= samples
+ samples
/ 4 + 7200;
113 ret
= lame_encode_buffer(lame
, reinterpret_cast<const short *>(left
.constData()),
114 reinterpret_cast<const short *>(right
.constData()), samples
,
115 reinterpret_cast<unsigned char *>(output
.data()), output
.size());
117 // lame.h claims to write to the buffers, even though they're declared const, be safe
118 // TODO: this mixes both channels again! can lame take only mono samples?
119 ret
= lame_encode_buffer(lame
, reinterpret_cast<const short *>(left
.data()),
120 reinterpret_cast<const short *>(left
.data()), samples
,
121 reinterpret_cast<unsigned char *>(output
.data()), output
.size());
125 // there wasn't enough space in output
132 debug(QString("Error while writing MP3 file, code = %1").arg(ret
));
136 samplesWritten
+= samples
;
139 output
.truncate(ret
);
143 left
.remove(0, samples
* 2);
145 right
.remove(0, samples
* 2);
152 output
.resize(10240);
153 ret
= lame_encode_flush(lame
, reinterpret_cast<unsigned char *>(output
.data()), output
.size());
156 debug(QString("Error while flushing MP3 file, code = %1").arg(ret
));
161 output
.truncate(ret
);