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