Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.0 / cinelerra / recordengine.C
diff --git a/cinelerra-5.0/cinelerra/recordengine.C b/cinelerra-5.0/cinelerra/recordengine.C
deleted file mode 100644 (file)
index 25b8811..0000000
+++ /dev/null
@@ -1,791 +0,0 @@
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
- */
-
-#include "assets.h"
-#include "audioconfig.h"
-#include "audiodevice.h"
-#include "file.h"
-#include "filexml.h"
-#include "mwindow.h"
-#include "patchbay.h"
-#include "playbackengine.h"
-#include "preferences.h"
-#include "recconfirmdelete.h"
-#include "record.h"
-#include "recordengine.h"
-#include "recordgui.h"
-#include "recordlabel.h"
-#include "recordpreview.h"
-#include "recordthread.h"
-#include "recordmonitor.h"
-#include "units.h"
-#include "videodevice.h"
-
-#include <ctype.h>
-
-#include <libintl.h>
-#define _(String) gettext(String)
-#define gettext_noop(String) String
-#define N_(String) gettext_noop (String)
-
-RecordEngine::RecordEngine(MWindow *mwindow, Record *record)
-{
-       this->mwindow = mwindow;
-       this->record = record;
-}
-
-
-
-
-
-RecordEngine::RecordEngine(MWindow *mwindow, 
-                       Record *record, 
-                       File *file, 
-                       Asset *asset, 
-                       RecordLabels *labels)
-{
-       this->mwindow = mwindow;
-       this->record = record; 
-       this->file = file; 
-       this->labels = labels; 
-       this->asset = asset;
-       is_saving = 0;
-       is_previewing = 0;
-       is_duplexing = 0;
-       is_monitoring = 0;
-       prev_label = -1;
-       next_label = -1;
-
-       if(record->do_audio)
-               adevice = new AudioDevice; 
-       else 
-               adevice = 0;
-
-       if(record->do_video)
-               vdevice = new VideoDevice(mwindow); 
-       else 
-               vdevice = 0;
-}
-
-RecordEngine::~RecordEngine()
-{
-       delete monitor_thread;
-       delete record_thread;
-       delete preview_thread;
-       if(adevice) delete adevice;
-       if(vdevice) delete vdevice;
-}
-
-int RecordEngine::initialize()
-{
-//     monitor_thread = new RecordThread(mwindow, record, this);
-       monitor_thread->create_objects();
-       
-//     record_thread = new RecordThread(mwindow, record, this);
-       record_thread->create_objects();
-
-       preview_thread = new RecordPreview(record, this);
-       preview_thread->initialize();
-
-// put at end of file
-       total_length = -1;
-       if(record->do_audio) current_position = file->get_audio_length();
-       else
-       if(record->do_video) current_position = Units::tosamples((float)(file->get_video_length(record->get_framerate())), record->get_samplerate(), record->get_framerate());
-
-       file->seek_end();
-
-       duplex_thread = mwindow->playback_engine;
-
-// initialize seek buttons
-       jump_delay[0] = 100;
-       jump_delay[1] = 50;
-       jump_delay[2] = 25;
-       jump_delay[3] = 10;
-       jump_delay[4] = 5;
-
-       current_jump_jumps[0] = 20;
-       current_jump_jumps[1] = 40;
-       current_jump_jumps[2] = 60;
-       current_jump_jumps[3] = 80;
-       current_jump_jumps[4] = 100;
-}
-
-int RecordEngine::run_script(FileXML *script)
-{
-       int result = 0, script_result = 0;
-       char string[1024];
-
-       while(!result && !script_result)
-       {
-               result = script->read_tag();
-
-               if(!result)
-               {
-                       if(script->tag.title_is("set_mode"))
-                       {
-                               set_record_mode(script->tag.get_property_text(0));
-                               mode_to_text(string, get_record_mode());
-                               gui->rec_mode_menu->set_text(string);
-                       }
-                       else
-                       if(script->tag.title_is("set_duration"))
-                       {
-                               record->set_loop_duration((long)record->get_samplerate() * script->tag.get_property_int(0));
-                               gui->update_duration_boxes();
-                       }
-                       else
-                       if(script->tag.title_is("start_recording"))
-                       {
-                               gui->unlock_window();
-                               start_saving();
-                               gui->lock_window();
-                       }
-                       else
-                       if(script->tag.title_is("set_monitor_video"))
-                       {
-                               set_monitor_video(script->tag.get_property_int(0));
-                               if(!script->tag.get_property_int(0) && record->video_window_open)
-                               {
-                                       record->video_window_open = 0;
-                                       gui->monitor_video_window->window->hide_window();
-                               }
-                       }
-                       else
-                       if(script->tag.title_is("set_monitor_audio"))
-                       {
-                               set_monitor_audio(script->tag.get_property_int(0));
-                       }
-                       else
-                       if(script->tag.title_is("quit_when_completed"))
-                       {
-                               record_thread->quit_when_completed = 1;
-                       }
-                       else
-                       if(script->tag.title_is("ok"))
-                       {
-                               script_result = 1;
-                       }
-               }
-       }
-       return script_result;
-}
-
-// ============================================= accounting
-
-long RecordEngine::get_dc_offset(int offset)
-{
-       return record->dc_offset[offset];
-}
-
-int RecordEngine::set_dc_offset(long new_offset, int number)
-{
-       adevice->set_dc_offset(new_offset, number);
-}
-
-long int RecordEngine::get_dc_offset(long *dc_offset, RecordGUIDCOffsetText **dc_offset_text)
-{
-       return adevice->get_dc_offset(dc_offset, dc_offset_text);
-}
-
-int RecordEngine::set_gui(RecordGUI *gui)
-{
-       this->gui = gui;
-       update_position(current_position);
-}
-
-int RecordEngine::get_duplex_enable()
-{
-       return record->enable_duplex();
-}
-
-
-
-// ================================================ operations
-
-int RecordEngine::open_input_devices(int duplex)
-{
-       int audio_opened = 0;
-       int video_opened = 0;
-       AudioConfig *aconfig /* = mwindow->preferences->aconfig */;
-
-// Initialize sharing
-       if(record->do_audio && record->do_video)
-       {
-               vdevice->set_adevice(adevice);
-               adevice->set_vdevice(vdevice);
-       }
-
-// Initialize audio
-       if(record->do_audio)
-       {
-               if(record->get_software_positioning()) 
-                       adevice->set_software_positioning();
-
-               for(int i = 0; i < asset->channels; i++)
-               {
-                       adevice->set_dc_offset(record->dc_offset[i], i);
-               }
-       }
-
-
-// Duplex is only needed if the timeline and the recording have audio
-       if(duplex &&
-               record->do_audio && 
-               mwindow->patches->total_playable_atracks())
-       {
-// duplex device is identical to input device
-               if(aconfig->audio_in_driver == aconfig->audio_duplex_driver &&
-                       !strcmp(aconfig->oss_in_device, aconfig->oss_duplex_device) &&
-                       aconfig->oss_in_bits == aconfig->oss_duplex_bits &&
-                       aconfig->oss_in_channels == aconfig->oss_duplex_channels)
-               {
-//                     adevice->open_duplex(mwindow->preferences->aconfig, 
-//                                             record->get_samplerate(), 
-//                                             get_in_length());
-                       audio_opened = 1;
-               }
-               else
-// two separate devices
-               {
-//                     adevice->open_output(mwindow->preferences->aconfig, 
-//                                     record->get_samplerate(), 
-//                                     record->get_out_length());
-               }
-       }
-
-       if(record->do_audio && !audio_opened)
-       {
-//             adevice->open_input(mwindow->preferences->aconfig, 
-//                             record->get_samplerate(), 
-//                             get_in_length());
-       }
-
-// Initialize video
-       if(record->do_video)
-       {
-//             vdevice->open_input(mwindow->preferences->vconfig, 
-//                     record->frame_w, 
-//                     record->frame_h,
-//                     record->video_x, 
-//                     record->video_y, 
-//                     record->video_zoom,
-//                     get_frame_rate());
-//             vdevice->set_field_order(record->reverse_interlace);
-//             if(record->get_current_channel())
-//                     vdevice->set_channel(record->get_current_channel());
-//             set_video_picture();
-       }
-
-       return 0;
-}
-
-
-int RecordEngine::close_input_devices()
-{
-       if(record->do_audio)
-               adevice->close_all();
-       if(record->do_video)
-               vdevice->close_all();
-
-       return 0;
-}
-
-int RecordEngine::start_monitor()
-{
-       monitor_timer.update();
-       open_input_devices(0);
-       monitor_thread->start_recording(0, 0);
-       is_monitoring = 1;
-       return 0;
-}
-
-int RecordEngine::stop_monitor()
-{
-//     if(is_monitoring)
-//     {
-//             is_monitoring = 0;
-//             monitor_thread->stop_recording();
-//     }
-       return 0;
-}
-
-int RecordEngine::pause_monitor()
-{
-       if(is_monitoring)
-       {
-               is_monitoring = 0;
-               monitor_thread->pause_recording();
-       }
-       return 0;
-}
-
-int RecordEngine::resume_monitor()
-{
-       if(!is_monitoring)
-       {
-               is_monitoring = 1;
-               monitor_timer.update();
-               open_input_devices(0);
-               monitor_thread->resume_recording();
-       }
-       return 0;
-}
-
-int RecordEngine::start_saving(int duplex)
-{
-       if(!is_saving)
-       {
-               pause_monitor();
-               record_timer.update();
-               open_input_devices(duplex);
-
-               duplex = record->enable_duplex() && duplex;
-
-// start the duplex engine if necessary
-// OSS < 3.9 crashes if recording starts before playback
-// OSS >= 3.9 crashes if playback starts before recording
-               if(duplex)
-               {
-                       long start, end;
-                       record->get_duplex_range(&start, &end);
-                       duplex_thread->reset_parameters();
-                       duplex_thread->arm_playback(0, 0, 1, adevice);
-                       duplex_thread->start_playback();
-                       is_duplexing = 1;
-               }
-
-//             record_thread->start_recording();
-
-               is_saving = 1;
-       }
-       return 0;
-}
-
-int RecordEngine::save_frame()
-{
-       if(!is_saving)
-       {
-               pause_monitor();
-               record_timer.update();
-               record->do_audio = 0;
-               open_input_devices(0);
-
-// start the duplex engine if necessary
-               record_thread->start_recording(0, 0);
-               is_saving = 1;
-       }
-       return 0;
-}
-
-int RecordEngine::stop_saving(int no_monitor)
-{
-       if(is_saving)
-       {
-// automatically stops duplex here and resumes monitor
-               record_thread->stop_recording(no_monitor); 
-       }
-       return 0;
-}
-
-int RecordEngine::stop_duplex()
-{
-       if(is_duplexing)
-       {
-               is_duplexing = 0;
-               duplex_thread->stop_playback(0);
-// OSS can't resume recording if buffers underrun
-// so stop playback first
-       }
-       return 0;
-}
-
-int RecordEngine::start_preview()
-{
-       if(!is_previewing)
-       {
-               stop_operation();
-               pause_monitor();
-
-               preview_timer.update();
-               open_output_devices();
-               preview_thread->start_preview(current_position, file);
-
-               is_previewing = 1;
-       }
-       return 0;
-}
-
-int RecordEngine::stop_preview(int no_monitor)
-{
-       if(is_previewing)
-       {
-               preview_thread->stop_preview(no_monitor);
-// preview engine automatically triggers monitor when finished
-       }
-       return 0;
-}
-
-int RecordEngine::stop_operation(int no_monitor)
-{
-// Resumes monitoring after stopping
-       if(is_saving) stop_saving(no_monitor);
-       else
-       if(is_previewing) stop_preview(no_monitor);
-       return 0;
-}
-
-int RecordEngine::set_video_picture()
-{
-       if(record->do_video && vdevice) 
-               vdevice->set_picture(record->video_brightness,
-                       record->video_hue,
-                       record->video_color,
-                       record->video_contrast,
-                       record->video_whiteness);
-       return 0;
-}
-
-int RecordEngine::open_output_devices()
-{
-       if(record->do_audio)
-       {
-//             adevice->open_output(mwindow->preferences->aconfig, 
-//                             record->get_samplerate(), 
-//                             record->get_out_length());
-               if(record->get_software_positioning()) adevice->set_software_positioning();
-       }
-
-// Video is already open for monitoring
-       return 0;
-}
-
-int RecordEngine::close_output_devices()
-{
-       if(record->do_audio)
-               adevice->close_all();
-// Video is already open for monitoring
-       return 0;
-}
-
-
-
-int RecordEngine::lock_window()
-{
-       gui->lock_window();
-}
-
-int RecordEngine::unlock_window()
-{
-       gui->unlock_window();
-}
-
-int RecordEngine::update_position(long new_position)
-{
-       if(new_position < 0) new_position = 0;      // fread error in filepcm
-       current_position = new_position;
-       
-       gui->update_position(new_position);
-
-       if(new_position > total_length) 
-       {
-               total_length = new_position;
-//             gui->update_total_length(new_position);
-       }
-       
-       if(prev_label != labels->get_prev_label(new_position))
-       {
-               prev_label = labels->get_prev_label(new_position);
-               gui->update_prev_label(prev_label);
-       }
-       
-       if(next_label != labels->get_next_label(new_position))
-       {
-               next_label = labels->get_next_label(new_position);
-
-               gui->update_next_label(next_label);
-       }
-}
-
-int RecordEngine::goto_prev_label()
-{
-       if(!is_saving)
-       {
-               stop_operation();
-               long new_position;
-
-               new_position = labels->goto_prev_label(current_position);
-               if(new_position != -1)
-               {
-//                     if(record->do_audio) file->set_audio_position(new_position);
-                       if(record->do_video) file->set_video_position(Units::toframes(new_position, record->get_samplerate(), record->get_framerate()), record->get_framerate());
-                       update_position(new_position);
-               }
-       }
-}
-
-int RecordEngine::goto_next_label()
-{
-       if(!is_saving)
-       {
-               stop_operation();
-               long new_position;
-
-               new_position = labels->goto_next_label(current_position);
-               if(new_position != -1 && new_position <= total_length)
-               {
-//                     if(record->do_audio) file->set_audio_position(new_position);
-                       if(record->do_video) file->set_video_position(Units::toframes(new_position, record->get_samplerate(), record->get_framerate()), record->get_framerate());
-                       update_position(new_position);
-               }
-       }
-       return 0;
-}
-
-int RecordEngine::toggle_label()
-{
-       labels->toggle_label(current_position);
-       update_position(current_position);
-       return 0;
-}
-
-int RecordEngine::calibrate_dc_offset()
-{
-       if(record->do_audio)
-       {
-               get_dc_offset(record->dc_offset, gui->dc_offset_text);
-       }
-       return 0;
-}
-
-int RecordEngine::calibrate_dc_offset(long new_value, int channel)
-{
-       if(record->do_audio)
-       {
-               set_dc_offset(new_value, channel);
-               record->dc_offset[channel] = new_value;
-       }
-       return 0;
-}
-
-int RecordEngine::reset_over()
-{
-}
-
-int RecordEngine::set_done(int value)
-{
-       stop_operation(1);
-       stop_monitor();
-       gui->set_done(value);
-}
-
-int RecordEngine::start_over()
-{
-       if((record->do_audio && file->get_audio_length() > 0) ||
-               (record->do_video && file->get_video_length(record->get_framerate()) > 0))
-       {
-               RecConfirmDelete dialog(mwindow);
-               dialog.create_objects(_("start over"));
-               int result = dialog.run_window();
-               if(!result)
-               {
-                       stop_operation();
-// remove file
-                       file->close_file();
-                       remove(asset->path);
-
-
-// start the engine over
-                       labels->delete_new_labels();
-                       update_position(0);
-                       total_length = 0;
-//                     gui->update_total_length(0);
-
-                       record->startsource_sample = 0;
-                       record->startsource_frame = 0;
-               }
-       }
-}
-
-int RecordEngine::change_channel(Channel *channel)
-{
-       if(record->do_video && vdevice) 
-               return vdevice->set_channel(channel);
-       else
-               return 0;
-}
-
-ArrayList<char*>* RecordEngine::get_video_inputs() 
-{ 
-       if(record->do_video && vdevice) 
-               return vdevice->get_inputs();
-       else
-               return 0;
-}
-
-int RecordEngine::get_vu_format() { return record->get_vu_format(); }
-int RecordEngine::get_dither() { return record->default_asset->dither * record->default_asset->bits; }
-int RecordEngine::get_input_channels() { return asset->channels; }
-int RecordEngine::get_format(char *string)
-{
-       File file;
-       strcpy(string, file.formattostr(mwindow->plugindb, asset->format)); 
-}
-int RecordEngine::get_samplerate() { return asset->rate; }
-int RecordEngine::get_bits() { return asset->bits; }
-int RecordEngine::get_time_format() { return record->get_time_format(); }
-float RecordEngine::get_frame_rate() { return record->get_frame_rate(); }
-int RecordEngine::get_loop_hr() { return record->loop_duration / asset->rate / 3600; }
-int RecordEngine::get_loop_min() { return record->loop_duration / asset->rate / 60 - (long)get_loop_hr() * 60; }
-int RecordEngine::get_loop_sec() { return record->loop_duration / asset->rate - (long)get_loop_hr() * 3600 - (long)get_loop_min() * 60; }
-long RecordEngine::get_loop_duration() { return record->loop_duration; }
-float RecordEngine::get_min_db() { return record->get_min_db(); }
-int RecordEngine::get_meter_over_hold(int divisions) { return divisions * 15; }
-int RecordEngine::get_meter_peak_hold(int divisions) { return divisions * 2; }
-int RecordEngine::get_meter_speed() { return record->get_meter_speed(); }
-float RecordEngine::get_frames_per_foot() { /* return mwindow->preferences->frames_per_foot; */ }
-
-int RecordEngine::set_monitor_video(int value)
-{
-}
-
-int RecordEngine::set_monitor_audio(int value)
-{
-}
-
-int RecordEngine::set_record_mode(char *text)
-{
-       record->record_mode = text_to_mode(text);
-}
-
-int RecordEngine::get_record_mode(char *text)
-{
-       mode_to_text(text, record->record_mode);
-}
-
-int RecordEngine::get_record_mode()
-{
-       return record->record_mode;
-}
-
-int RecordEngine::mode_to_text(char *string, int mode)
-{
-       switch(mode)
-       {
-               case 0:        sprintf(string, _("Untimed"));       break;
-               case 1:        sprintf(string, _("Timed"));         break;
-               case 2:        sprintf(string, _("Loop"));          break;
-       }
-}
-
-int RecordEngine::text_to_mode(char *string)
-{
-       if(!strcasecmp(string, _("Untimed"))) return 0;
-       if(!strcasecmp(string, _("Timed")))   return 1;
-       if(!strcasecmp(string, _("Loop")))    return 2;
-}
-
-long RecordEngine::get_current_delay()
-{
-       if(current_jump_jump > 0) current_jump_jump--;
-       if(current_jump_jump == 0 && current_jump_delay < /*JUMP_DELAYS*/ 1)
-       {
-               current_jump_delay++;
-               current_jump_jump = current_jump_jumps[current_jump_delay];
-       }
-       return jump_delay[current_jump_delay];
-}
-
-int RecordEngine::reset_current_delay()
-{
-       current_jump_delay = 0;
-       current_jump_jump = current_jump_jumps[current_jump_delay];
-}
-
-int RecordEngine::set_loop_duration() 
-{
-       record->set_loop_duration((long)record->get_samplerate() * (atol(gui->loop_sec->get_text()) + atol(gui->loop_min->get_text()) * 60 + atol(gui->loop_hr->get_text()) * 3600)); 
-}
-
-
-// Remember to change meters if you change this.
-// Return the size of the fragments to read from the audio device.
-int RecordEngine::get_in_length() 
-{
-       long fragment_size = 1;
-       while(fragment_size < asset->rate / record->get_meter_speed()) fragment_size *= 2;
-       fragment_size /= 2;
-       return fragment_size;
-}
-
-// Different absolute positions are defined for each operation so threads
-// can end at different times without screwing up the frame synchronization.
-long RecordEngine::absolute_monitor_position()
-{
-       if(is_monitoring)
-       {
-               if(record->do_audio)
-               {
-//                     return monitor_thread->absolute_position();
-               }
-               else
-               {
-                       return (long)((float)monitor_timer.get_difference() / 1000 * record->get_samplerate());
-               }
-       }
-       else
-       return -1;
-}
-
-long RecordEngine::absolute_preview_position()
-{
-       if(is_previewing)
-       {
-               if(record->do_audio)
-               {
-                       return preview_thread->absolute_position();
-               }
-               else
-               {
-                       return (long)((float)preview_timer.get_difference() / 1000 * record->get_samplerate());
-               }
-       }
-       else
-       return -1;
-}
-
-long RecordEngine::absolute_record_position()
-{
-       if(is_saving)
-       {
-               if(record->do_audio)
-               {
-//                     return record_thread->absolute_position();
-               }
-               else
-               {
-                       return (long)((float)record_timer.get_difference() / 1000 * record->get_samplerate());
-               }
-       }
-       else
-       return -1;
-}
-