MythTV  master
lameencoder.cpp
Go to the documentation of this file.
1 /*
2  MP3 encoding support using liblame for MythMusic
3 
4  (c) 2003 Stefan Frank
5 
6  Please send an e-mail to sfr@gmx.net if you have
7  questions or comments.
8 
9  Project Website: out http://www.mythtv.org/
10 
11  This program is free software; you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation; either version 2 of the License, or
14  (at your option) any later version.
15 
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25 
26 // qt
27 #include <QApplication>
28 #include <QString>
29 
30 // myth
31 #include <mythcontext.h>
32 #include <mythlogging.h>
33 #include "musicmetadata.h"
34 #include "metaioid3.h"
35 
36 // mythmusic
37 #include "lameencoder.h"
38 
39 // c++
40 #include <iostream>
41 using namespace std;
42 
43 static int write_buffer(char *buf, int bufsize, FILE *fp)
44 {
45  return fwrite(buf, 1, bufsize, fp);
46 }
47 
48 void LameEncoder::init_id3tags(lame_global_flags *gf)
49 {
50  // Very basic ID3v2 Header. Rewritten later, but libid3tag.
51  id3tag_init(gf);
52 
53  // Dummy tag. It'll get overwritten later by the more flexible
54  // libid3 (MAD). Unf. it wont write the id3 tag to the file if
55  // none exists, hense this dummy entry.
56  id3tag_set_title(gf, "Title");
57 
58  // write v2 tags.
59  id3tag_v2_only(gf);
60 }
61 
62 int LameEncoder::init_encoder(lame_global_flags *gf, int quality, bool vbr) const
63 {
64  int lameret = 0;
65  int meanbitrate = 128;
66  int preset = STANDARD;
67 
68  switch (quality)
69  {
70  case 0: // low, always use CBR
71  meanbitrate = 128;
72  vbr = false;
73  break;
74  case 1: // medium
75  meanbitrate = 192;
76  break;
77  case 2: // high
78  meanbitrate = 256;
79  preset = EXTREME;
80  break;
81  }
82 
83  if (vbr)
84  lame_set_preset(gf, preset);
85  else
86  {
87  lame_set_preset(gf, meanbitrate);
88  lame_set_VBR(gf, vbr_off);
89  }
90 
91  if (m_channels == 1)
92  {
93  lame_set_mode(gf, MONO);
94  }
95 
96  lameret = lame_init_params(gf);
97 
98  return lameret;
99 }
100 
101 LameEncoder::LameEncoder(const QString &outfile, int qualitylevel,
102  MusicMetadata *metadata, bool vbr) :
103  Encoder(outfile, qualitylevel, metadata),
104  m_mp3Buf(new char[m_mp3BufSize]),
105  m_gf(lame_init())
106 {
108 
109  int lameret = init_encoder(m_gf, qualitylevel, vbr);
110  if (lameret < 0)
111  {
112  LOG(VB_GENERAL, LOG_ERR,
113  QString("Error initializing LAME encoder. Got return code: %1")
114  .arg(lameret));
115  return;
116  }
117 }
118 
120 {
121  LameEncoder::addSamples(nullptr, 0); //flush
122 
123  if (m_gf && m_out)
124  lame_mp3_tags_fid (m_gf, m_out);
125  if (m_gf)
126  lame_close(m_gf);
127  delete[] m_mp3Buf;
128 
129  // Need to close the file here.
130  if (m_out)
131  {
132  fclose(m_out);
133 
134  // Make sure the base class doesn't do a double clear.
135  m_out = nullptr;
136  }
137 
138  // Now write the Metadata
139  if (m_metadata)
141 }
142 
143 int LameEncoder::addSamples(int16_t * bytes, unsigned int length)
144 {
145  int lameret = 0;
146 
148 
149  if (length > 0)
150  {
151  lameret = lame_encode_buffer_interleaved(m_gf, bytes,
153  (unsigned char *)m_mp3Buf,
154  m_mp3BufSize);
155  }
156  else
157  {
158  lameret = lame_encode_flush(m_gf, (unsigned char *)m_mp3Buf,
159  m_mp3BufSize);
160  }
161 
162  if (lameret < 0)
163  {
164  LOG(VB_GENERAL, LOG_ERR, QString("LAME encoder error."));
165  }
166  else if (lameret > 0 && m_out)
167  {
168  if (write_buffer(m_mp3Buf, lameret, m_out) != lameret)
169  {
170  LOG(VB_GENERAL, LOG_ERR, "Failed to write mp3 data. Aborting.");
171  return EENCODEERROR;
172  }
173  }
174 
175  return 0;
176 }
177 
LameEncoder::m_mp3Buf
char * m_mp3Buf
Definition: lameencoder.h:65
LameEncoder::addSamples
int addSamples(int16_t *bytes, unsigned int len) override
Definition: lameencoder.cpp:143
arg
arg(title).arg(filename).arg(doDelete))
LameEncoder::m_bytesPerSample
int m_bytesPerSample
Definition: lameencoder.h:60
LameEncoder::LameEncoder
LameEncoder(const QString &outfile, int qualitylevel, MusicMetadata *metadata, bool vbr=false)
Definition: lameencoder.cpp:101
LameEncoder::~LameEncoder
~LameEncoder() override
Definition: lameencoder.cpp:119
Encoder
Definition: mythplugins/mythmusic/mythmusic/encoder.h:14
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MusicMetadata
Definition: musicmetadata.h:81
EENCODEERROR
#define EENCODEERROR
Definition: mythplugins/mythmusic/mythmusic/encoder.h:7
MetaIOID3::write
bool write(const QString &filename, MusicMetadata *mdata) override
Writes all metadata back to a file.
Definition: metaioid3.cpp:153
mythburn.FILE
int FILE
Definition: mythburn.py:139
LameEncoder::m_gf
lame_global_flags * m_gf
Definition: lameencoder.h:67
write_buffer
static int write_buffer(char *buf, int bufsize, FILE *fp)
Definition: lameencoder.cpp:43
mythlogging.h
LameEncoder::m_samplesPerChannel
int m_samplesPerChannel
Definition: lameencoder.h:61
LameEncoder::init_id3tags
static void init_id3tags(lame_global_flags *gf)
Definition: lameencoder.cpp:48
LameEncoder::m_mp3BufSize
int m_mp3BufSize
Definition: lameencoder.h:64
LameEncoder::init_encoder
int init_encoder(lame_global_flags *gf, int quality, bool vbr) const
Definition: lameencoder.cpp:62
Encoder::m_metadata
MusicMetadata * m_metadata
Definition: mythplugins/mythmusic/mythmusic/encoder.h:26
musicbrainzngs.compat.bytes
bytes
Definition: compat.py:49
mythcontext.h
lameencoder.h
metaioid3.h
Encoder::m_outfile
const QString m_outfile
Definition: mythplugins/mythmusic/mythmusic/encoder.h:23
MetaIOID3
Read and write metadata in MPEG (mp3) ID3V2 tags.
Definition: metaioid3.h:34
musicmetadata.h
Encoder::m_out
FILE * m_out
Definition: mythplugins/mythmusic/mythmusic/encoder.h:24