Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.1 / cinelerra / playbackprefs.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
5  * 
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * 
20  */
21
22 #include "adeviceprefs.h"
23 #include "audioconfig.h"
24 #include "audiodevice.inc"
25 #include "bcsignals.h"
26 #include "clip.h"
27 #include "bchash.h"
28 #include "edl.h"
29 #include "edlsession.h"
30 #include "language.h"
31 #include "mainsession.h"
32 #include "mwindow.h"
33 #include "overlayframe.inc"
34 #include "playbackprefs.h"
35 #include "preferences.h"
36 #include "theme.h"
37 #include "vdeviceprefs.h"
38 #include "videodevice.inc"
39
40
41
42 PlaybackPrefs::PlaybackPrefs(MWindow *mwindow, PreferencesWindow *pwindow, int config_number)
43  : PreferencesDialog(mwindow, pwindow)
44 {
45         this->config_number = config_number;
46         audio_device = 0;
47         video_device = 0;
48         audio_offset = 0;
49         play_gain = 0;
50 }
51
52 PlaybackPrefs::~PlaybackPrefs()
53 {
54         delete audio_device;
55         delete video_device;
56         delete audio_offset;
57         delete play_gain;
58 }
59
60 void PlaybackPrefs::create_objects()
61 {
62         int x, y, x2, y2;
63         char string[BCTEXTLEN];
64         BC_WindowBase *window;
65
66
67         playback_config = pwindow->thread->edl->session->playback_config;
68
69         x = mwindow->theme->preferencesoptions_x;
70         y = mwindow->theme->preferencesoptions_y;
71         //int margin = mwindow->theme->widget_border;
72
73 // Audio
74         add_subwindow(new BC_Title(x, 
75                 y, 
76                 _("Audio Out"), 
77                 LARGEFONT));
78
79
80         y += get_text_height(LARGEFONT) + 5;
81
82
83         BC_Title *title1, *title2;
84         add_subwindow(title2 = new BC_Title(x, y, _("Playback buffer samples:"), MEDIUMFONT));
85         x2 = MAX(title2->get_w(), title2->get_w()) + 10;
86
87 SET_TRACE
88         sprintf(string, "%d", playback_config->aconfig->fragment_size);
89         PlaybackModuleFragment *menu;
90         add_subwindow(menu = new PlaybackModuleFragment(x2, 
91                 y, 
92                 pwindow, 
93                 this, 
94                 string));
95         menu->add_item(new BC_MenuItem("1024"));
96         menu->add_item(new BC_MenuItem("2048"));
97         menu->add_item(new BC_MenuItem("4096"));
98         menu->add_item(new BC_MenuItem("8192"));
99         menu->add_item(new BC_MenuItem("16384"));
100         menu->add_item(new BC_MenuItem("32768"));
101         menu->add_item(new BC_MenuItem("65536"));
102         menu->add_item(new BC_MenuItem("131072"));
103         menu->add_item(new BC_MenuItem("262144"));
104
105         y += menu->get_h() + 5;
106         x2 = x;
107         add_subwindow(title1 = new BC_Title(x2, y, _("Audio offset (sec):")));
108         x2 += title1->get_w() + 5;
109         audio_offset = new PlaybackAudioOffset(pwindow, this, x2, y);
110         audio_offset->create_objects();
111         y += audio_offset->get_h() + 5;
112
113 SET_TRACE
114         add_subwindow(new PlaybackViewFollows(pwindow,
115                 pwindow->thread->edl->session->view_follows_playback, y));
116         y += 30;
117         add_subwindow(new PlaybackSoftwareTimer(pwindow,
118                 pwindow->thread->edl->session->playback_software_position, y));
119         y += 30;
120         add_subwindow(new PlaybackRealTime(pwindow,
121                 pwindow->thread->edl->session->real_time_playback, y));
122         y += 30;
123         PlaybackMap51_2 *map51_2 = new PlaybackMap51_2(pwindow, this,
124                 playback_config->aconfig->map51_2, y);
125         add_subwindow(map51_2);
126         x2 =  map51_2->get_x() + map51_2->get_w() + 15;
127         y2 = y + BC_TextBox::calculate_h(this,MEDIUMFONT,1,1) - get_text_height(MEDIUMFONT);
128
129         add_subwindow(title2 = new BC_Title(x2, y2, _("Gain:")));
130         x2 += title2->get_w() + 8;
131         play_gain = new PlaybackGain(x2, y, pwindow, this);
132         play_gain->create_objects();
133         y += 40;
134         add_subwindow(new BC_Title(x, y, _("Audio Driver:")));
135         audio_device = new ADevicePrefs(x + 100, y, pwindow, 
136                 this, playback_config->aconfig, 0, MODEPLAY);
137         audio_device->initialize(0);
138
139 SET_TRACE
140
141
142
143 // Video
144         y += audio_device->get_h();
145
146 SET_TRACE
147         add_subwindow(new BC_Bar(5, y,  get_w() - 10));
148         y += 5;
149
150 SET_TRACE
151         add_subwindow(new BC_Title(x, y, _("Video Out"), LARGEFONT));
152         y += 30;
153
154 SET_TRACE
155         add_subwindow(window = new VideoEveryFrame(pwindow, this, x, y));
156
157         add_subwindow(new BC_Title(x + 200, y + 5, _("Framerate achieved:")));
158         add_subwindow(framerate_title = new BC_Title(x + 350, y + 5, "--", MEDIUMFONT, RED));
159         draw_framerate(0);
160         y += window->get_h() + 5;
161
162         add_subwindow(asynchronous = new VideoAsynchronous(pwindow, x, y));
163         y += asynchronous->get_h() + 10;
164
165 SET_TRACE
166         add_subwindow(title1 = new BC_Title(x, y, _("Scaling equation: Enlarge / Reduce ")));
167         VScalingEquation *vscaling_equation =
168                 new VScalingEquation(x + title1->get_w() + 10, y,
169                         &pwindow->thread->edl->session->interpolation_type);
170         add_subwindow(vscaling_equation);
171         vscaling_equation->create_objects();
172 SET_TRACE
173         y += 35;
174
175         add_subwindow(title1 = new BC_Title(x, y, _("DVD Subtitle to display:")));
176         PlaybackSubtitleNumber *subtitle_number;
177         subtitle_number = new PlaybackSubtitleNumber(x + title1->get_w() + 10, 
178                 y, 
179                 pwindow, 
180                 this);
181         subtitle_number->create_objects();
182
183         x2 = x + title1->get_w() + 10 + subtitle_number->get_w() + 30;
184         PlaybackSubtitle *subtitle_toggle;
185         add_subwindow(subtitle_toggle = new PlaybackSubtitle(x2, y, pwindow, this));
186         y += subtitle_toggle->get_h();
187
188         PlaybackLabelCells *label_cells_toggle;
189         add_subwindow(label_cells_toggle = new PlaybackLabelCells(x2, y, pwindow, this));
190         y2 = y + label_cells_toggle->get_h();
191
192         add_subwindow(title1=new BC_Title(x2, y2, _("TOC Program No:"), MEDIUMFONT));
193         PlaybackProgramNumber *program_number;
194         program_number = new PlaybackProgramNumber(
195                 x2 + title1->get_w() + 10, y2, pwindow, this);
196         program_number->create_objects();
197
198         add_subwindow(interpolate_raw = new PlaybackInterpolateRaw( x, y,
199                 pwindow, this));
200         y += interpolate_raw->get_h();
201
202         add_subwindow(white_balance_raw = new PlaybackWhiteBalanceRaw( x, y,
203                 pwindow, this));
204         y += white_balance_raw->get_h() + 10;
205         if(!pwindow->thread->edl->session->interpolate_raw) 
206                 white_balance_raw->disable();
207
208
209 SET_TRACE
210 //      y += 30;
211 //      add_subwindow(new PlaybackDeblock(pwindow, 10, y));
212
213         x2 = x;
214         x += 370;
215         title1 = new BC_Title(x, y, _("Timecode offset:"), MEDIUMFONT);
216         add_subwindow(title1);  x += title1->get_w();
217         for( int i=3;;) {
218                 sprintf(string, "%d", pwindow->thread->edl->session->timecode_offset[i]);
219                 TimecodeOffset *tcofs = new TimecodeOffset(x, y, pwindow, this, string, i);
220                 add_subwindow(tcofs);   x += tcofs->get_w();
221                 if( --i < 0 ) break;
222                 title1 = new BC_Title(x, y, ":", MEDIUMFONT);
223                 add_subwindow(title1);  x += title1->get_w();
224         }
225
226         x = x2;
227         y += white_balance_raw->get_h() + 5;
228         add_subwindow(vdevice_title = new BC_Title(x, y, _("Video Driver:")));
229         video_device = new VDevicePrefs(x + vdevice_title->get_w() + 10, y, 
230                 pwindow, this, playback_config->vconfig, 0, MODEPLAY);
231         video_device->initialize(0);
232 SET_TRACE       
233
234 }
235
236
237 int PlaybackPrefs::draw_framerate(int flush)
238 {
239 //printf("PlaybackPrefs::draw_framerate 1 %f\n", mwindow->session->actual_frame_rate);
240         char string[BCTEXTLEN];
241         sprintf(string, "%.4f", mwindow->session->actual_frame_rate);
242         framerate_title->update(string, flush);
243         return 0;
244 }
245
246
247
248 PlaybackAudioOffset::PlaybackAudioOffset(PreferencesWindow *pwindow, 
249         PlaybackPrefs *playback, int x, int y)
250  : BC_TumbleTextBox(playback, playback->playback_config->aconfig->audio_offset,
251         -10.0, 10.0, x, y, 100)
252 {
253         this->pwindow = pwindow;
254         this->playback = playback;
255         set_precision(2);
256         set_increment(0.1);
257 }
258
259 int PlaybackAudioOffset::handle_event()
260 {
261         playback->playback_config->aconfig->audio_offset = atof(get_text());
262         return 1;
263 }
264
265
266
267
268 PlaybackModuleFragment::PlaybackModuleFragment(int x, int y, 
269         PreferencesWindow *pwindow, PlaybackPrefs *playback, char *text)
270  : BC_PopupMenu(x, y, 100, text, 1)
271
272         this->pwindow = pwindow;
273         this->playback = playback;
274 }
275
276 int PlaybackModuleFragment::handle_event() 
277 {
278         playback->playback_config->aconfig->fragment_size = atol(get_text()); 
279         return 1;
280 }
281
282
283 PlaybackViewFollows::PlaybackViewFollows(PreferencesWindow *pwindow, int value, int y)
284  : BC_CheckBox(10, y, value, _("View follows playback"))
285
286         this->pwindow = pwindow; 
287 }
288
289 int PlaybackViewFollows::handle_event() 
290
291         pwindow->thread->edl->session->view_follows_playback = get_value(); 
292         return 1;
293 }
294
295
296 PlaybackSoftwareTimer::PlaybackSoftwareTimer(PreferencesWindow *pwindow, int value, int y)
297  : BC_CheckBox(10, y, value, _("Disable hardware synchronization"))
298
299         this->pwindow = pwindow; 
300 }
301
302 int PlaybackSoftwareTimer::handle_event() 
303
304         pwindow->thread->edl->session->playback_software_position = get_value(); 
305         return 1;
306 }
307
308
309 PlaybackRealTime::PlaybackRealTime(PreferencesWindow *pwindow, int value, int y)
310  : BC_CheckBox(10, y, value, _("Audio playback in real time priority (root only)"))
311
312         this->pwindow = pwindow; 
313 }
314
315 int PlaybackRealTime::handle_event() 
316
317         pwindow->thread->edl->session->real_time_playback = get_value(); 
318         return 1;
319 }
320
321
322 PlaybackMap51_2::PlaybackMap51_2(PreferencesWindow *pwindow,
323                 PlaybackPrefs *playback_prefs, int value, int y)
324  : BC_CheckBox(10, y, value, _("Map 5.1->2"))
325 {
326         this->pwindow = pwindow;
327         this->playback_prefs = playback_prefs; 
328 }
329
330 int PlaybackMap51_2::handle_event() 
331 {
332         playback_prefs->playback_config->aconfig->map51_2 = get_value();
333         return 1;
334 }
335
336
337 PlaybackInterpolateRaw::PlaybackInterpolateRaw( int x, int y, 
338                 PreferencesWindow *pwindow, PlaybackPrefs *playback)
339  : BC_CheckBox(x, 
340         y, 
341         pwindow->thread->edl->session->interpolate_raw, 
342         _("Interpolate CR2 images"))
343 {
344         this->pwindow = pwindow;
345         this->playback = playback;
346 }
347
348 int PlaybackInterpolateRaw::handle_event()
349 {
350         pwindow->thread->edl->session->interpolate_raw = get_value();
351         if(!pwindow->thread->edl->session->interpolate_raw) {
352                 playback->white_balance_raw->update(0, 0);
353                 playback->white_balance_raw->disable();
354         }
355         else {
356                 playback->white_balance_raw->update(pwindow->thread->edl->session->white_balance_raw, 0);
357                 playback->white_balance_raw->enable();
358         }
359         return 1;
360 }
361
362
363 PlaybackWhiteBalanceRaw::PlaybackWhiteBalanceRaw( int x, int y, 
364                 PreferencesWindow *pwindow, PlaybackPrefs *playback)
365  : BC_CheckBox(x, 
366         y, 
367         pwindow->thread->edl->session->interpolate_raw &&
368                 pwindow->thread->edl->session->white_balance_raw, 
369         _("White balance CR2 images"))
370 {
371         this->pwindow = pwindow;
372         this->playback = playback;
373         if(!pwindow->thread->edl->session->interpolate_raw) disable();
374 }
375
376 int PlaybackWhiteBalanceRaw::handle_event()
377 {
378         pwindow->thread->edl->session->white_balance_raw = get_value();
379         return 1;
380 }
381
382
383 VideoAsynchronous::VideoAsynchronous(PreferencesWindow *pwindow, int x, int y)
384  : BC_CheckBox(x, y, 
385         pwindow->thread->edl->session->video_every_frame &&
386                 pwindow->thread->edl->session->video_asynchronous, 
387         _("Decode frames asynchronously"))
388 {
389         this->pwindow = pwindow;
390         if(!pwindow->thread->edl->session->video_every_frame)
391                 disable();
392 }
393
394 int VideoAsynchronous::handle_event()
395 {
396         pwindow->thread->edl->session->video_asynchronous = get_value();
397         return 1;
398 }
399
400
401 VideoEveryFrame::VideoEveryFrame(PreferencesWindow *pwindow, 
402         PlaybackPrefs *playback_prefs, int x, int y)
403  : BC_CheckBox(x, y, pwindow->thread->edl->session->video_every_frame, _("Play every frame"))
404 {
405         this->pwindow = pwindow;
406         this->playback_prefs = playback_prefs;
407 }
408
409 int VideoEveryFrame::handle_event()
410 {
411         pwindow->thread->edl->session->video_every_frame = get_value();
412         if(!pwindow->thread->edl->session->video_every_frame) {
413                 playback_prefs->asynchronous->update(0, 0);
414                 playback_prefs->asynchronous->disable();
415         }
416         else {
417                 playback_prefs->asynchronous->update(pwindow->thread->edl->session->video_asynchronous, 0);
418                 playback_prefs->asynchronous->enable();
419         }
420         return 1;
421 }
422
423
424 PlaybackSubtitle::PlaybackSubtitle(int x, int y, 
425         PreferencesWindow *pwindow, PlaybackPrefs *playback)
426  : BC_CheckBox(x, y, 
427         pwindow->thread->edl->session->decode_subtitles,
428         _("Enable subtitles/captioning"))
429 {
430         this->pwindow = pwindow;
431         this->playback = playback;
432 }
433
434 int PlaybackSubtitle::handle_event()
435 {
436         pwindow->thread->edl->session->decode_subtitles = get_value();
437         return 1;
438 }
439
440
441 PlaybackSubtitleNumber::PlaybackSubtitleNumber(int x, int y, 
442         PreferencesWindow *pwindow, PlaybackPrefs *playback)
443  : BC_TumbleTextBox(playback, pwindow->thread->edl->session->subtitle_number,
444         0, 31, x, y, 50)
445 {
446         this->pwindow = pwindow;
447         this->playback = playback;
448 }
449
450 int PlaybackSubtitleNumber::handle_event()
451 {
452         pwindow->thread->edl->session->subtitle_number = atoi(get_text());
453         return 1;
454 }
455
456
457 PlaybackLabelCells::PlaybackLabelCells(int x, int y, 
458         PreferencesWindow *pwindow, PlaybackPrefs *playback)
459  : BC_CheckBox(x, y, 
460         pwindow->thread->edl->session->label_cells,
461         _("Label cells"))
462 {
463         this->pwindow = pwindow;
464         this->playback = playback;
465 }
466
467 int PlaybackLabelCells::handle_event()
468 {
469         pwindow->thread->edl->session->label_cells = get_value();
470         return 1;
471 }
472
473
474 PlaybackProgramNumber::PlaybackProgramNumber(int x, int y, 
475         PreferencesWindow *pwindow, PlaybackPrefs *playback)
476  : BC_TumbleTextBox(playback,
477         pwindow->thread->edl->session->program_no,
478         0, 31, x, y, 50)
479 {
480         this->pwindow = pwindow;
481         this->playback = playback;
482 }
483
484 int PlaybackProgramNumber::handle_event()
485 {
486         pwindow->thread->edl->session->program_no = atoi(get_text());
487         return 1;
488 }
489
490 PlaybackGain::PlaybackGain(int x, int y,
491         PreferencesWindow *pwindow, PlaybackPrefs *playback)
492  : BC_TumbleTextBox(playback,
493                 pwindow->thread->edl->session->playback_config->aconfig->play_gain,
494                 0.0001f, 10000.0f, x, y, 72)
495 {
496         this->pwindow = pwindow; 
497         this->set_increment(0.1);
498 }
499
500 int PlaybackGain::handle_event()
501 {
502         pwindow->thread->edl->session->playback_config->
503                 aconfig->play_gain = atof(get_text());
504         return 1;
505 }
506
507 TimecodeOffset::TimecodeOffset(int x, int y, PreferencesWindow *pwindow,
508       PlaybackPrefs *playback, char *text, int unit)
509  : BC_TextBox(x, y, 30, 1, text)
510 {
511    this->pwindow = pwindow;
512    this->playback = playback;
513         this->unit = unit;
514 }
515
516 int TimecodeOffset::handle_event()
517 {
518         pwindow->thread->edl->session->timecode_offset[unit] = atol(get_text());
519         return 1;
520 }
521