00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <QApplication>
00027 #include <QString>
00028
00029 #include "metadata.h"
00030 #include "lameencoder.h"
00031 #include "metaioid3.h"
00032
00033 #include <iostream>
00034
00035 #include <mythcontext.h>
00036 #include <mythlogging.h>
00037
00038 using namespace std;
00039
00040 static int write_buffer(char *buf, int bufsize, FILE *fp)
00041 {
00042 return fwrite(buf, 1, bufsize, fp);
00043 }
00044
00045 void LameEncoder::init_id3tags(lame_global_flags *gf)
00046 {
00047
00048 id3tag_init(gf);
00049
00050
00051
00052
00053 id3tag_set_title(gf, "Title");
00054
00055
00056 id3tag_v2_only(gf);
00057 }
00058
00059 int LameEncoder::init_encoder(lame_global_flags *gf, int quality, bool vbr)
00060 {
00061 int lameret = 0;
00062 int meanbitrate = 128;
00063 int preset = STANDARD;
00064
00065 switch (quality)
00066 {
00067 case 0:
00068 meanbitrate = 128;
00069 vbr = false;
00070 break;
00071 case 1:
00072 meanbitrate = 192;
00073 break;
00074 case 2:
00075 meanbitrate = 256;
00076 preset = EXTREME;
00077 break;
00078 }
00079
00080 if (vbr)
00081 lame_set_preset(gf, preset);
00082 else
00083 {
00084 lame_set_preset(gf, meanbitrate);
00085 lame_set_VBR(gf, vbr_off);
00086 }
00087
00088 if (channels == 1)
00089 {
00090 lame_set_mode(gf, MONO);
00091 }
00092
00093 lameret = lame_init_params(gf);
00094
00095 return lameret;
00096 }
00097
00098 LameEncoder::LameEncoder(const QString &outfile, int qualitylevel,
00099 Metadata *metadata, bool vbr) :
00100 Encoder(outfile, qualitylevel, metadata),
00101 bits(16),
00102 channels(2),
00103 samplerate(44100),
00104 bytes_per_sample(channels * bits / 8),
00105 samples_per_channel(0),
00106 mp3buf_size((int)(1.25 * 16384 + 7200)),
00107 mp3buf(new char[mp3buf_size]),
00108 mp3bytes(0),
00109 gf(lame_init())
00110 {
00111 init_id3tags(gf);
00112
00113 int lameret = init_encoder(gf, qualitylevel, vbr);
00114 if (lameret < 0)
00115 {
00116 LOG(VB_GENERAL, LOG_ERR,
00117 QString("Error initializing LAME encoder. Got return code: %1")
00118 .arg(lameret));
00119 return;
00120 }
00121 }
00122
00123 LameEncoder::~LameEncoder()
00124 {
00125 addSamples(0, 0);
00126
00127 if (gf && m_out)
00128 lame_mp3_tags_fid (gf, m_out);
00129 if (gf)
00130 lame_close(gf);
00131 if (mp3buf)
00132 delete[] mp3buf;
00133
00134
00135 if (m_out)
00136 {
00137 fclose(m_out);
00138
00139
00140 m_out = NULL;
00141 }
00142
00143
00144 if (m_metadata)
00145 {
00146 QString filename = m_metadata->Filename();
00147 m_metadata->setFilename(m_outfile);
00148 MetaIOID3().write(m_metadata);
00149 m_metadata->setFilename(filename);
00150 }
00151 }
00152
00153 int LameEncoder::addSamples(int16_t * bytes, unsigned int length)
00154 {
00155 int lameret = 0;
00156
00157 samples_per_channel = length / bytes_per_sample;
00158
00159 if (length > 0)
00160 {
00161 lameret = lame_encode_buffer_interleaved(gf, (short int *)bytes,
00162 samples_per_channel,
00163 (unsigned char *)mp3buf,
00164 mp3buf_size);
00165 }
00166 else
00167 {
00168 lameret = lame_encode_flush(gf, (unsigned char *)mp3buf,
00169 mp3buf_size);
00170 }
00171
00172 if (lameret < 0)
00173 {
00174 LOG(VB_GENERAL, LOG_ERR, QString("LAME encoder error."));
00175 }
00176 else if (lameret > 0 && m_out)
00177 {
00178 if (write_buffer(mp3buf, lameret, m_out) != lameret)
00179 {
00180 LOG(VB_GENERAL, LOG_ERR, "Failed to write mp3 data. Aborting.");
00181 return EENCODEERROR;
00182 }
00183 }
00184
00185 return 0;
00186 }
00187