Merge branch 'ct' of git.pipapo.org:cinelerra-ct into ct
[cinelerra_cv/ct.git] / cinelerra / fileac3.C
blobac82bfec15d2d08d308d4b7485986d44c2a429d6
1 #include "asset.h"
2 #include "bcwidgetgrid.h"
3 #include "clip.h"
4 #include "fileac3.h"
5 #include "language.h"
6 #include "mwindow.inc"
7 #include "mainerror.h"
11 #include <string.h>
13 FileAC3::FileAC3(Asset_GC asset, File *file)
14  : FileBase(asset, file)
16         reset_parameters();
19 FileAC3::~FileAC3()
21         close_file();
24 int FileAC3::reset_parameters_derived()
26         codec = 0;
27         codec_context = 0;
28         fd = 0;
29         temp_raw = 0;
30         temp_raw_size = 0;
31         temp_raw_allocated = 0;
32         temp_compressed = 0;
33         compressed_allocated = 0;
36 void FileAC3::get_parameters(BC_WindowBase *parent_window, 
37                 Asset_GC asset, 
38                 BC_WindowBase* &format_window,
39                 int audio_options,
40                 int video_options)
42         if(audio_options)
43         {
45                 AC3ConfigAudio *window = new AC3ConfigAudio(parent_window, asset);
46                 format_window = window;
47                 window->create_objects();
48                 window->run_window();
49                 delete window;
50         }
53 int FileAC3::check_sig()
55 // Libmpeg3 does this in FileMPEG.
56         return 0;
59 int FileAC3::open_file(int rd, int wr)
61         this->wr = wr;
62         this->rd = rd;
65         if(wr)
66         {
67                 avcodec_init();
68                 avcodec_register_all();
69                 codec = avcodec_find_encoder(CODEC_ID_AC3);
70                 if(!codec)
71                 {
72                         eprintf("codec not found.\n");
73                         return 1;
74                 }
75                 codec_context = avcodec_alloc_context();
76                 codec_context->bit_rate = asset->ac3_bitrate * 1000;
77                 codec_context->sample_rate = asset->sample_rate;
78                 codec_context->channels = asset->channels;
79                 if(avcodec_open(codec_context, codec))
80                 {
81                         eprintf("failed to open codec.\n");
82                         return 1;
83                 }
85                 if(!(fd = fopen(asset->path, "w")))
86                 {
87                         eprintf("Error while opening \"%s\" for writing. \n%m\n", asset->path);
88                         return 1;
89                 }
90         }
91         else
92         {
93                 if(!(fd = fopen(asset->path, "r")))
94                 {
95                         eprintf("Error while opening \"%s\" for reading. \n%m\n", asset->path);
96                         return 1;
97                 }
98         }
103         return 0;
106 int FileAC3::close_file()
108         if(codec_context)
109         {
110                 avcodec_close(codec_context);
111                 free(codec_context);
112                 codec_context = 0;
113                 codec = 0;
114         }
115         if(fd)
116         {
117                 fclose(fd);
118                 fd = 0;
119         }
120         if(temp_raw)
121         {
122                 delete [] temp_raw;
123                 temp_raw = 0;
124         }
125         if(temp_compressed)
126         {
127                 delete [] temp_compressed;
128                 temp_compressed = 0;
129         }
130         reset_parameters();
131         FileBase::close_file();
134 // Channel conversion matrices because ffmpeg encodes a
135 // different channel order than liba52 decodes.
136 // Each row is an output channel.
137 // Each column is an input channel.
138 // static int channels5[] = 
139 // {
140 //      { }
141 // };
142 // 
143 // static int channels6[] = 
144 // {
145 //      { }
146 // };
149 int FileAC3::write_samples(double **buffer, int64_t len)
151 // Convert buffer to encoder format
152         if(temp_raw_size + len > temp_raw_allocated)
153         {
154                 int new_allocated = temp_raw_size + len;
155                 int16_t *new_raw = new int16_t[new_allocated * asset->channels];
156                 if(temp_raw)
157                 {
158                         memcpy(new_raw, 
159                                 temp_raw, 
160                                 sizeof(int16_t) * temp_raw_size * asset->channels);
161                         delete [] temp_raw;
162                 }
163                 temp_raw = new_raw;
164                 temp_raw_allocated = new_allocated;
165         }
167 // Allocate compressed data buffer
168         if(temp_raw_allocated * asset->channels * 2 > compressed_allocated)
169         {
170                 compressed_allocated = temp_raw_allocated * asset->channels * 2;
171                 delete [] temp_compressed;
172                 temp_compressed = new unsigned char[compressed_allocated];
173         }
175 // Append buffer to temp raw
176         int16_t *out_ptr = temp_raw + temp_raw_size * asset->channels;
177         for(int i = 0; i < len; i++)
178         {
179                 for(int j = 0; j < asset->channels; j++)
180                 {
181                         int sample = (int)(buffer[j][i] * 32767);
182                         CLAMP(sample, -32768, 32767);
183                         *out_ptr++ = sample;
184                 }
185         }
186         temp_raw_size += len;
188         int frame_size = codec_context->frame_size;
189         int output_size = 0;
190         int current_sample = 0;
191         for(current_sample = 0; 
192                 current_sample + frame_size <= temp_raw_size; 
193                 current_sample += frame_size)
194         {
195                 int compressed_size = avcodec_encode_audio(
196                         codec_context, 
197                         temp_compressed + output_size, 
198                         compressed_allocated - output_size, 
199             temp_raw + current_sample * asset->channels);
200                 output_size += compressed_size;
201         }
203 // Shift buffer back
204         memcpy(temp_raw,
205                 temp_raw + current_sample * asset->channels,
206                 (temp_raw_size - current_sample) * sizeof(int16_t) * asset->channels);
207         temp_raw_size -= current_sample;
209         int bytes_written = fwrite(temp_compressed, 1, output_size, fd);
210         if(bytes_written < output_size)
211         {
212                 eprintf("Error while writing samples. \n%m\n");
213                 return 1;
214         }
215         return 0;
224 AC3ConfigAudio::AC3ConfigAudio(BC_WindowBase *parent_window,
225         Asset_GC asset)
226  : BC_Window(PROGRAM_NAME ": Audio Compression",
227         parent_window->get_abs_cursor_x(1),
228         parent_window->get_abs_cursor_y(1),
229         500,
230         BC_OKButton::calculate_h() + 100,
231         500,
232         BC_OKButton::calculate_h() + 100,
233         0,
234         0,
235         1)
237         this->parent_window = parent_window;
238         this->asset = asset;
241 void AC3ConfigAudio::create_objects()
243         int x = 10, y = 10;
244         int x1 = 150;
246         BC_WidgetGrid *wg;
247         BC_RelocatableWidget *rw;
249         wg = add_widgetgrid(new BC_WidgetGrid(10, 10, 10, 10, 3, 3));
251         rw =
252         add_tool(new BC_Title(x, y, "Bitrate (kbps):"));
253         AC3ConfigAudioBitrate *bitrate;
254         add_tool(bitrate = 
255                 new AC3ConfigAudioBitrate(this,
256                         x1, 
257                         y));
258         bitrate->create_objects();
260         wg->add(rw, 0, 0);
261         wg->add(bitrate, 0, 1);
263         rw =
264         add_subwindow(new BC_OKButton(this));
266         wg->move_widgets();
267         resize_window(wg->get_w_wm(), wg->get_h_wm() + rw->get_h());
269         show_window();
270         flush();
273 int AC3ConfigAudio::close_event()
275         set_done(0);
276         return 1;
284 AC3ConfigAudioBitrate::AC3ConfigAudioBitrate(AC3ConfigAudio *gui, 
285         int x, 
286         int y)
287  : BC_PopupMenu(x,
288         y,
289         150,
290         AC3ConfigAudioBitrate::bitrate_to_string(gui->string, gui->asset->ac3_bitrate))
292         this->gui = gui;
295 char* AC3ConfigAudioBitrate::bitrate_to_string(char *string, int bitrate)
297         sprintf(string, "%d", bitrate);
298         return string;
301 void AC3ConfigAudioBitrate::create_objects()
303         add_item(new BC_MenuItem("32"));
304         add_item(new BC_MenuItem("40"));
305         add_item(new BC_MenuItem("48"));
306         add_item(new BC_MenuItem("56"));
307         add_item(new BC_MenuItem("64"));
308         add_item(new BC_MenuItem("80"));
309         add_item(new BC_MenuItem("96"));
310         add_item(new BC_MenuItem("112"));
311         add_item(new BC_MenuItem("128"));
312         add_item(new BC_MenuItem("160"));
313         add_item(new BC_MenuItem("192"));
314         add_item(new BC_MenuItem("224"));
315         add_item(new BC_MenuItem("256"));
316         add_item(new BC_MenuItem("320"));
317         add_item(new BC_MenuItem("384"));
318         add_item(new BC_MenuItem("448"));
319         add_item(new BC_MenuItem("512"));
320         add_item(new BC_MenuItem("576"));
321         add_item(new BC_MenuItem("640"));
324 int AC3ConfigAudioBitrate::handle_event()
326         gui->asset->ac3_bitrate = atol(get_text());
327         return 1;
333 //      Local Variables:
334 //      mode: C++
335 //      c-file-style: "linux"
336 //      End: