00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "common.h"
00020 #include "MP3FileSink.h"
00021
00022 #ifdef MARSYAS_LAME
00023 #include "lame/lame.h"
00024 #endif
00025
00026 using std::ostringstream;
00027 using namespace Marsyas;
00028
00029 MP3FileSink::MP3FileSink(mrs_string name):AbsSoundFileSink("MP3FileSink",name)
00030 {
00031
00032
00033 #ifdef MARSYAS_LAME
00034 gfp_ = NULL;
00035 #endif
00036 sfp_ = NULL;
00037 leftpcm_ = NULL;
00038 rightpcm_ = NULL;
00039
00040 mp3Buffer_ = NULL;
00041 addControls();
00042 }
00043
00044 MP3FileSink::~MP3FileSink()
00045 {
00046
00047 #ifdef MARSYAS_LAME
00048
00049 if (sfp_)
00050 {
00051 mrs_natural encodeCheck = lame_encode_flush(gfp_, mp3Buffer_, 0);
00052 mrs_natural owrite = (int) fwrite(mp3Buffer_, 1, encodeCheck, sfp_);
00053 if (owrite != encodeCheck) {
00054 MRSWARN("Writing MP3 data to "+filename_+" failed.");
00055 }
00056 fclose(sfp_);
00057 }
00058
00059
00060 #endif
00061 delete [] mp3Buffer_;
00062 delete [] leftpcm_;
00063 delete [] rightpcm_;
00064 }
00065
00066 MarSystem*
00067 MP3FileSink::clone() const
00068 {
00069 return new MP3FileSink(*this);
00070 }
00071
00072 void
00073 MP3FileSink::addControls()
00074 {
00075 addctrl("mrs_string/filename", "default");
00076 setctrlState("mrs_string/filename", true);
00077 addctrl("mrs_natural/bitrate", 128);
00078 setctrlState("mrs_natural/bitrate", true);
00079 addctrl("mrs_natural/encodingQuality", 2);
00080 setctrlState("mrs_natural/encodingQuality", true);
00081 addctrl("mrs_string/id3tags", "noTitle|noArtist|noAlbum|1978|noComment|1|0");
00082 setctrlState("mrs_string/filename", true);
00083 }
00084
00085 bool
00086 MP3FileSink::checkExtension(mrs_string filename)
00087 {
00088 FileName fn(filename);
00089 mrs_string mp3ext = "mp3";
00090
00091 if (fn.ext() == mp3ext)
00092 return true;
00093 else
00094 return false;
00095 }
00096
00097 void
00098 MP3FileSink::myUpdate(MarControlPtr sender)
00099 {
00100 (void) sender;
00101 MRSDIAG("MP3FileSink::myUpdate");
00102
00103 setctrl("mrs_natural/onSamples", getctrl("mrs_natural/inSamples"));
00104 setctrl("mrs_natural/onObservations", getctrl("mrs_natural/inObservations"));
00105 setctrl("mrs_real/osrate", getctrl("mrs_real/israte"));
00106
00107 nChannels_ = getctrl("mrs_natural/inObservations")->to<mrs_natural>();
00108
00109 #ifdef MARSYAS_LAME
00110
00111 gfp_ = lame_init();
00112
00113 mrs_natural lameNbChannels = getctrl("mrs_natural/inObservations")->to<mrs_natural>();
00114 delete [] mp3Buffer_;
00115 mrs_natural mp3BufferSize = (int) ceil(1.25*inSamples_ + 7200);
00116 mp3Buffer_ = new unsigned char[mp3BufferSize];
00117 delete [] leftpcm_;
00118 delete [] rightpcm_;
00119 leftpcm_ = new short[getctrl("mrs_natural/inSamples")->to<mrs_natural>()];
00120 rightpcm_ = new short[getctrl("mrs_natural/inSamples")->to<mrs_natural>()];
00121
00122 if (lameNbChannels>2) {
00123 MRSWARN("Lame can handle up to 2 channels. Only the first 2 observation vectors will be written.");
00124 lameNbChannels = 2;
00125 }
00126 if (lameNbChannels==1)
00127 lame_set_mode(gfp_, (MPEG_mode) 3);
00128 else
00129 lame_set_mode(gfp_, (MPEG_mode) 1);
00130
00131 lame_set_num_channels(gfp_,lameNbChannels);
00132 lame_set_in_samplerate(gfp_,(int) ceil(getctrl("mrs_real/israte")->to<mrs_real>()));
00133 lame_set_brate(gfp_,128);
00134 lame_set_quality(gfp_,2);
00135
00136
00137 mrs_string id3tags = getctrl("mrs_string/id3tags")->to<mrs_string>();
00138 mrs_natural pos=0;
00139 pos = id3tags.find("|", 0);
00140 id3tag_set_title(gfp_, id3tags.substr(0, pos).c_str());
00141 id3tags = id3tags.substr(pos+1);
00142 pos = id3tags.find("|", 0);
00143 id3tag_set_artist(gfp_, id3tags.substr(0, pos).c_str());
00144 id3tags = id3tags.substr(pos+1);
00145 pos = id3tags.find("|", 0);
00146 id3tag_set_album(gfp_, id3tags.substr(0, pos).c_str());
00147 id3tags = id3tags.substr(pos+1);
00148 pos = id3tags.find("|", 0);
00149 id3tag_set_year(gfp_, id3tags.substr(0, pos).c_str());
00150 id3tags = id3tags.substr(pos+1);
00151 pos = id3tags.find("|", 0);
00152 id3tag_set_comment(gfp_, id3tags.substr(0, pos).c_str());
00153 id3tags = id3tags.substr(pos+1);
00154 pos = id3tags.find("|", 0);
00155 id3tag_set_track(gfp_, id3tags.substr(0, pos).c_str());
00156 id3tags = id3tags.substr(pos+1);
00157 pos = id3tags.find("|", 0);
00158 id3tag_set_genre(gfp_, id3tags.substr(0, pos).c_str());
00159
00160 int ret_code = lame_init_params(gfp_);
00161 if (ret_code == -1)
00162 MRSWARN("Initialization of the lame encoder failed.");
00163
00164
00165 #endif
00166
00167 filename_ = getctrl("mrs_string/filename")->to<mrs_string>();
00168 }
00169
00170 void
00171 MP3FileSink::putHeader(mrs_string filename)
00172 {
00173 #ifdef MARSYAS_LAME
00174 sfp_ = fopen(filename.c_str(), "wb");
00175 #endif
00176 }
00177
00178 void
00179 MP3FileSink::myProcess(realvec& in, realvec& out)
00180 {
00181
00182
00183 mrs_natural t,o;
00184
00185
00186 for (o=0; o < inObservations_; o++)
00187 for (t=0; t < inSamples_; t++)
00188 {
00189 out(o,t) = in(o,t);
00190 }
00191 #ifdef MARSYAS_LAME
00192
00193 mrs_natural encodeCheck=-1;
00194
00195
00196 for (t=0; t < inSamples_; t++)
00197 leftpcm_[t] = (short)(in(0,t) * PCM_MAXSHRT);
00198 if (inObservations_>1) {
00199
00200 for (t=0; t < inSamples_; t++)
00201 rightpcm_[t] = (short)(in(1,t) * PCM_MAXSHRT);
00202
00203 encodeCheck = lame_encode_buffer(gfp_,
00204 leftpcm_, rightpcm_,
00205 inSamples_, mp3Buffer_, 0);
00206 }
00207 else
00208 encodeCheck = lame_encode_buffer(gfp_,
00209 leftpcm_, leftpcm_,
00210 inSamples_, mp3Buffer_,0);
00211
00212
00213
00214 if (encodeCheck < 0) {
00215 if (encodeCheck == -1) {
00216 MRSWARN("mp3 buffer is not big enough... \n");
00217 }
00218 else
00219 MRSWARN("mp3 internal error");
00220 }
00221 mrs_natural owrite = (int) fwrite(mp3Buffer_, 1, encodeCheck, sfp_);
00222 if (owrite != encodeCheck) {
00223 MRSWARN("Writing MP3 data to "+filename_+" failed.");
00224 }
00225
00226
00227 #endif
00228
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247