00001 #include "asset.h"
00002 #include "clip.h"
00003 #include "fileac3.h"
00004 #include "language.h"
00005 #include "mwindow.inc"
00006 #include "mainerror.h"
00007
00008
00009
00010 #include <string.h>
00011
00012 FileAC3::FileAC3(Asset *asset, File *file)
00013 : FileBase(asset, file)
00014 {
00015 reset_parameters();
00016 }
00017
00018 FileAC3::~FileAC3()
00019 {
00020 close_file();
00021 }
00022
00023 int FileAC3::reset_parameters_derived()
00024 {
00025 codec = 0;
00026 codec_context = 0;
00027 fd = 0;
00028 temp_raw = 0;
00029 temp_raw_size = 0;
00030 temp_raw_allocated = 0;
00031 temp_compressed = 0;
00032 compressed_allocated = 0;
00033 }
00034
00035 void FileAC3::get_parameters(BC_WindowBase *parent_window,
00036 Asset *asset,
00037 BC_WindowBase* &format_window,
00038 int audio_options,
00039 int video_options)
00040 {
00041 if(audio_options)
00042 {
00043
00044 AC3ConfigAudio *window = new AC3ConfigAudio(parent_window, asset);
00045 format_window = window;
00046 window->create_objects();
00047 window->run_window();
00048 delete window;
00049 }
00050 }
00051
00052 int FileAC3::check_sig()
00053 {
00054
00055 return 0;
00056 }
00057
00058 int FileAC3::open_file(int rd, int wr)
00059 {
00060 this->wr = wr;
00061 this->rd = rd;
00062
00063
00064 if(wr)
00065 {
00066 avcodec_init();
00067 avcodec_register_all();
00068 codec = avcodec_find_encoder(CODEC_ID_AC3);
00069 if(!codec)
00070 {
00071 eprintf("codec not found.\n");
00072 return 1;
00073 }
00074 codec_context = avcodec_alloc_context();
00075 codec_context->bit_rate = asset->ac3_bitrate * 1000;
00076 codec_context->sample_rate = asset->sample_rate;
00077 codec_context->channels = asset->channels;
00078 if(avcodec_open(codec_context, codec))
00079 {
00080 eprintf("failed to open codec.\n");
00081 return 1;
00082 }
00083
00084 if(!(fd = fopen(asset->path, "w")))
00085 {
00086 eprintf("Error while opening \"%s\" for writing. \n%m\n", asset->path);
00087 return 1;
00088 }
00089 }
00090 else
00091 {
00092 if(!(fd = fopen(asset->path, "r")))
00093 {
00094 eprintf("Error while opening \"%s\" for reading. \n%m\n", asset->path);
00095 return 1;
00096 }
00097 }
00098
00099
00100
00101
00102 return 0;
00103 }
00104
00105 int FileAC3::close_file()
00106 {
00107 if(codec_context)
00108 {
00109 avcodec_close(codec_context);
00110 free(codec_context);
00111 codec_context = 0;
00112 codec = 0;
00113 }
00114 if(fd)
00115 {
00116 fclose(fd);
00117 fd = 0;
00118 }
00119 if(temp_raw)
00120 {
00121 delete [] temp_raw;
00122 temp_raw = 0;
00123 }
00124 if(temp_compressed)
00125 {
00126 delete [] temp_compressed;
00127 temp_compressed = 0;
00128 }
00129 reset_parameters();
00130 FileBase::close_file();
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 int FileAC3::write_samples(double **buffer, int64_t len)
00149 {
00150
00151 if(temp_raw_size + len > temp_raw_allocated)
00152 {
00153 int new_allocated = temp_raw_size + len;
00154 int16_t *new_raw = new int16_t[new_allocated * asset->channels];
00155 if(temp_raw)
00156 {
00157 memcpy(new_raw,
00158 temp_raw,
00159 sizeof(int16_t) * temp_raw_size * asset->channels);
00160 delete [] temp_raw;
00161 }
00162 temp_raw = new_raw;
00163 temp_raw_allocated = new_allocated;
00164 }
00165
00166
00167 if(temp_raw_allocated * asset->channels * 2 > compressed_allocated)
00168 {
00169 compressed_allocated = temp_raw_allocated * asset->channels * 2;
00170 delete [] temp_compressed;
00171 temp_compressed = new unsigned char[compressed_allocated];
00172 }
00173
00174
00175 int16_t *out_ptr = temp_raw + temp_raw_size * asset->channels;
00176 for(int i = 0; i < len; i++)
00177 {
00178 for(int j = 0; j < asset->channels; j++)
00179 {
00180 int sample = (int)(buffer[j][i] * 32767);
00181 CLAMP(sample, -32768, 32767);
00182 *out_ptr++ = sample;
00183 }
00184 }
00185 temp_raw_size += len;
00186
00187 int frame_size = codec_context->frame_size;
00188 int output_size = 0;
00189 int current_sample = 0;
00190 for(current_sample = 0;
00191 current_sample + frame_size <= temp_raw_size;
00192 current_sample += frame_size)
00193 {
00194 int compressed_size = avcodec_encode_audio(
00195 codec_context,
00196 temp_compressed + output_size,
00197 compressed_allocated - output_size,
00198 temp_raw + current_sample * asset->channels);
00199 output_size += compressed_size;
00200 }
00201
00202
00203 memcpy(temp_raw,
00204 temp_raw + current_sample * asset->channels,
00205 (temp_raw_size - current_sample) * sizeof(int16_t) * asset->channels);
00206 temp_raw_size -= current_sample;
00207
00208 int bytes_written = fwrite(temp_compressed, 1, output_size, fd);
00209 if(bytes_written < output_size)
00210 {
00211 eprintf("Error while writing samples. \n%m\n");
00212 return 1;
00213 }
00214 return 0;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223 AC3ConfigAudio::AC3ConfigAudio(BC_WindowBase *parent_window,
00224 Asset *asset)
00225 : BC_Window(PROGRAM_NAME ": Audio Compression",
00226 parent_window->get_abs_cursor_x(1),
00227 parent_window->get_abs_cursor_y(1),
00228 500,
00229 BC_OKButton::calculate_h() + 100,
00230 500,
00231 BC_OKButton::calculate_h() + 100,
00232 0,
00233 0,
00234 1)
00235 {
00236 this->parent_window = parent_window;
00237 this->asset = asset;
00238 }
00239
00240 void AC3ConfigAudio::create_objects()
00241 {
00242 int x = 10, y = 10;
00243 int x1 = 150;
00244 add_tool(new BC_Title(x, y, "Bitrate (kbps):"));
00245 AC3ConfigAudioBitrate *bitrate;
00246 add_tool(bitrate =
00247 new AC3ConfigAudioBitrate(this,
00248 x1,
00249 y));
00250 bitrate->create_objects();
00251
00252 add_subwindow(new BC_OKButton(this));
00253 show_window();
00254 flush();
00255 }
00256
00257 int AC3ConfigAudio::close_event()
00258 {
00259 set_done(0);
00260 return 1;
00261 }
00262
00263
00264
00265
00266
00267
00268 AC3ConfigAudioBitrate::AC3ConfigAudioBitrate(AC3ConfigAudio *gui,
00269 int x,
00270 int y)
00271 : BC_PopupMenu(x,
00272 y,
00273 150,
00274 AC3ConfigAudioBitrate::bitrate_to_string(gui->string, gui->asset->ac3_bitrate))
00275 {
00276 this->gui = gui;
00277 }
00278
00279 char* AC3ConfigAudioBitrate::bitrate_to_string(char *string, int bitrate)
00280 {
00281 sprintf(string, "%d", bitrate);
00282 return string;
00283 }
00284
00285 void AC3ConfigAudioBitrate::create_objects()
00286 {
00287 add_item(new BC_MenuItem("32"));
00288 add_item(new BC_MenuItem("40"));
00289 add_item(new BC_MenuItem("48"));
00290 add_item(new BC_MenuItem("56"));
00291 add_item(new BC_MenuItem("64"));
00292 add_item(new BC_MenuItem("80"));
00293 add_item(new BC_MenuItem("96"));
00294 add_item(new BC_MenuItem("112"));
00295 add_item(new BC_MenuItem("128"));
00296 add_item(new BC_MenuItem("160"));
00297 add_item(new BC_MenuItem("192"));
00298 add_item(new BC_MenuItem("224"));
00299 add_item(new BC_MenuItem("256"));
00300 add_item(new BC_MenuItem("320"));
00301 add_item(new BC_MenuItem("384"));
00302 add_item(new BC_MenuItem("448"));
00303 add_item(new BC_MenuItem("512"));
00304 add_item(new BC_MenuItem("576"));
00305 add_item(new BC_MenuItem("640"));
00306 }
00307
00308 int AC3ConfigAudioBitrate::handle_event()
00309 {
00310 gui->asset->ac3_bitrate = atol(get_text());
00311 return 1;
00312 }
00313
00314
00315