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