Initial commit
[fillmore] / src / fillmore / audio_project.vala
diff --git a/src/fillmore/audio_project.vala b/src/fillmore/audio_project.vala
new file mode 100644 (file)
index 0000000..ac567ca
--- /dev/null
@@ -0,0 +1,153 @@
+/* Copyright 2009-2010 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later).  See the COPYING file in this distribution. 
+ */
+
+using Logging;
+namespace Model {
+
+class RecordFetcherCompletion : FetcherCompletion {
+    Track track;
+    Project project;
+    int64 position;
+
+    public RecordFetcherCompletion(Project project, Track track, int64 position) {
+        base();
+        this.track = track;
+        this.project = project;
+        this.position = position;
+    }
+
+    public override void complete(Fetcher fetch) {
+        base.complete(fetch);
+        Clip the_clip = new Clip(fetch.clipfile, MediaType.AUDIO, 
+            isolate_filename(fetch.clipfile.filename), 0, 0, fetch.clipfile.length, false);
+        project.undo_manager.start_transaction("Record");
+        track.append_at_time(the_clip, position, true);
+        project.undo_manager.end_transaction("Record");
+    }
+}
+
+class AudioProject : Project {
+    bool has_been_saved;
+
+    public AudioProject(string? filename) throws Error {
+        base(filename, false);
+        // TODO: When vala supports throwing from base, remove this check
+        if (this != null) {
+            has_been_saved = filename != null;
+            if (!has_been_saved) {
+                project_file = generate_filename();
+            }
+            media_engine.callback_pulse.connect(media_engine.on_callback_pulse);
+            media_engine.record_completed.connect(on_record_completed);
+        }
+    }
+
+    public override TimeCode get_clip_time(ClipFile f) {
+        TimeCode t = {};
+        
+        t.get_from_length(f.length);
+        return t;
+    }
+
+    public override string? get_project_file() {
+        if (!has_been_saved) {
+            return null;
+        } else {
+            return base.get_project_file();
+        }
+    }
+
+    string generate_filename() {
+        Time now = Time.local(time_t());
+        string timestring = now.to_string();
+        timestring = timestring.replace(":", "_");
+        string pathname = Path.build_filename(GLib.Environment.get_home_dir(), ".fillmore", 
+            timestring);
+        GLib.DirUtils.create(pathname, 0777);
+        string filename = "%s.%s".printf(timestring, "fill");
+        return Path.build_filename(pathname, filename);
+    }
+
+    public override string get_app_name() {
+        return Recorder.NAME;
+    }
+
+    public override void add_track(Track track) {
+        if (track.media_type() == MediaType.VIDEO) {
+            track.hide();
+            inactive_tracks.add(track);
+            return;
+        }
+        
+        base.add_track(track);
+    }
+    
+    public void record(AudioTrack track) {
+        media_engine.record(track);
+    }
+
+    public void on_record_completed() {
+        emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_record_completed");
+        try {
+            create_clip_fetcher(new Model.RecordFetcherCompletion(this, media_engine.record_track,
+                media_engine.record_region.start), media_engine.record_region.clipfile.filename);
+        } catch (Error e) {
+            error_occurred("Could not complete recording", e.message);
+        }
+    }
+
+    public override void load(string? filename) {
+        has_been_saved = filename != null;
+        if (!has_been_saved) {
+            project_file = generate_filename();
+        }
+        base.load(filename);
+    }
+
+    public override void save(string? filename) {
+        if (!has_been_saved && filename != null) {
+            move_audio_files(filename);
+            GLib.FileUtils.remove(project_file);
+            GLib.DirUtils.remove(Path.get_dirname(project_file));
+        }
+
+        base.save(filename);
+        has_been_saved = true;
+    }
+
+    void move_audio_files(string filename) {
+        string audio_path = get_audio_path();
+        string destination_path = Path.build_filename(Path.get_dirname(filename), "audio files");
+        GLib.DirUtils.create(destination_path, 0777);
+        GLib.Dir dir;
+        try {
+            dir = Dir.open(audio_path);
+        } catch (FileError e) {
+            return;
+        }
+
+        // First, move all of the files over, even if they aren't currently in the project
+        weak string? base_name = null;
+        do {
+            base_name = dir.read_name();
+            string destination = Path.build_filename(destination_path, base_name);
+            FileUtils.rename(Path.build_filename(audio_path, base_name), destination);
+        } while (base_name != null);
+
+        // Next, update the model so that the project file is saved properly
+        foreach (ClipFile clip_file in clipfiles) {
+            if (Path.get_dirname(clip_file.filename) == audio_path) {
+                string file_name = Path.get_basename(clip_file.filename);
+                string destination = Path.build_filename(destination_path, file_name);
+                clip_file.filename = destination;
+            }
+        }
+
+        GLib.DirUtils.remove(audio_path);
+    }
+
+}
+}