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 
42 static int write_buffer(char *buf, int bufsize, FILE *fp)
43 {
44  return fwrite(buf, 1, bufsize, fp);
45 }
46 
47 void LameEncoder::init_id3tags(lame_global_flags *gf)
48 {
49  // Very basic ID3v2 Header. Rewritten later, but libid3tag.
50  id3tag_init(gf);
51 
52  // Dummy tag. It'll get overwritten later by the more flexible
53  // libid3 (MAD). Unf. it wont write the id3 tag to the file if
54  // none exists, hense this dummy entry.
55  id3tag_set_title(gf, "Title");
56 
57  // write v2 tags.
58  id3tag_v2_only(gf);
59 }
60 
61 int LameEncoder::init_encoder(lame_global_flags *gf, int quality, bool vbr) const
62 {
63  int lameret = 0;
64  int meanbitrate = 128;
65  int preset = STANDARD;
66 
67  switch (quality)
68  {
69  case 0: // low, always use CBR
70  meanbitrate = 128;
71  vbr = false;
72  break;
73  case 1: // medium
74  meanbitrate = 192;
75  break;
76  case 2: // high
77  meanbitrate = 256;
78  preset = EXTREME;
79  break;
80  }
81 
82  if (vbr)
83  lame_set_preset(gf, preset);
84  else
85  {
86  lame_set_preset(gf, meanbitrate);
87  lame_set_VBR(gf, vbr_off);
88  }
89 
90  if (m_channels == 1)
91  {
92  lame_set_mode(gf, MONO);
93  }
94 
95  lameret = lame_init_params(gf);
96 
97  return lameret;
98 }
99 
100 LameEncoder::LameEncoder(const QString &outfile, int qualitylevel,
101  MusicMetadata *metadata, bool vbr) :
102  Encoder(outfile, qualitylevel, metadata),
103  m_mp3Buf(new char[m_mp3BufSize]),
104  m_gf(lame_init())
105 {
107 
108  int lameret = init_encoder(m_gf, qualitylevel, vbr);
109  if (lameret < 0)
110  {
111  LOG(VB_GENERAL, LOG_ERR,
112  QString("Error initializing LAME encoder. Got return code: %1")
113  .arg(lameret));
114  return;
115  }
116 }
117 
119 {
120  LameEncoder::addSamples(nullptr, 0); //flush
121 
122  if (m_gf && m_out)
123  lame_mp3_tags_fid (m_gf, m_out);
124  if (m_gf)
125  lame_close(m_gf);
126  delete[] m_mp3Buf;
127 
128  // Need to close the file here.
129  if (m_out)
130  {
131  fclose(m_out);
132 
133  // Make sure the base class doesn't do a double clear.
134  m_out = nullptr;
135  }
136 
137  // Now write the Metadata
138  if (m_metadata)
140 }
141 
142 int LameEncoder::addSamples(int16_t * bytes, unsigned int length)
143 {
144  int lameret = 0;
145 
147 
148  if (length > 0)
149  {
150  lameret = lame_encode_buffer_interleaved(m_gf, bytes,
152  (unsigned char *)m_mp3Buf,
153  m_mp3BufSize);
154  }
155  else
156  {
157  lameret = lame_encode_flush(m_gf, (unsigned char *)m_mp3Buf,
158  m_mp3BufSize);
159  }
160 
161  if (lameret < 0)
162  {
163  LOG(VB_GENERAL, LOG_ERR, QString("LAME encoder error."));
164  }
165  else if (lameret > 0 && m_out)
166  {
167  if (write_buffer(m_mp3Buf, lameret, m_out) != lameret)
168  {
169  LOG(VB_GENERAL, LOG_ERR, "Failed to write mp3 data. Aborting.");
170  return EENCODEERROR;
171  }
172  }
173 
174  return 0;
175 }
176 
LameEncoder::m_mp3Buf
char * m_mp3Buf
Definition: lameencoder.h:65
LameEncoder::addSamples
int addSamples(int16_t *bytes, unsigned int len) override
Definition: lameencoder.cpp:142
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:100
LameEncoder::~LameEncoder
~LameEncoder() override
Definition: lameencoder.cpp:118
Encoder
Definition: mythplugins/mythmusic/mythmusic/encoder.h:13
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MusicMetadata
Definition: musicmetadata.h:80
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:42
mythlogging.h
LameEncoder::m_channels
int m_channels
Definition: lameencoder.h:59
LameEncoder::m_samplesPerChannel
int m_samplesPerChannel
Definition: lameencoder.h:61
LameEncoder::init_id3tags
static void init_id3tags(lame_global_flags *gf)
Definition: lameencoder.cpp:47
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:61
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:33
musicmetadata.h
Encoder::m_out
FILE * m_out
Definition: mythplugins/mythmusic/mythmusic/encoder.h:24