And back again.
[ardour.git] / gtk2_ardour / sfdb_ui.cc
1 /*
2     Copyright (C) 2005 Paul Davis 
3     Written by Taybin Rutkin
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19
20 */
21
22 #include <gtkmm/box.h>
23 #include <gtkmm/stock.h>
24
25 #include <ardour/audio_library.h>
26 #include <ardour/sndfile_helpers.h>
27
28 #include "sfdb_ui.h"
29
30 #include "i18n.h"
31
32 std::string length2string (const int32_t frames, const int32_t sample_rate);
33
34 SoundFileBox::SoundFileBox (ARDOUR::Session* session)
35         :
36         current_pid(0),
37         fields(Gtk::ListStore::create(label_columns)),
38         main_box (false, 3),
39         top_box (true, 4),
40         bottom_box (true, 4),
41         play_btn(_("Play")),
42         stop_btn(_("Stop")),
43         add_field_btn(_("Add Field...")),
44         remove_field_btn(_("Remove Field"))
45 {
46         set_name (X_("SoundFileBox"));
47         border_frame.set_label (_("Soundfile Info"));
48         border_frame.add (main_box);
49
50         pack_start (border_frame);
51         set_border_width (4);
52
53         path_box.set_spacing (4);
54         path_box.pack_start (path, false, false);
55         path_box.pack_start (path_entry, true, true);
56
57         main_box.set_border_width (4);
58
59         main_box.pack_start(label, false, false);
60         main_box.pack_start(path_box, false, false);
61         main_box.pack_start(length, false, false);
62         main_box.pack_start(format, false, false);
63         main_box.pack_start(channels, false, false);
64         main_box.pack_start(samplerate, false, false);
65         main_box.pack_start(field_view, true, true);
66         main_box.pack_start(top_box, false, false);
67         main_box.pack_start(bottom_box, false, false);
68
69         field_view.set_size_request(200, 150);
70         top_box.set_homogeneous(true);
71         top_box.pack_start(add_field_btn);
72         top_box.pack_start(remove_field_btn);
73
74         remove_field_btn.set_sensitive(false);
75
76         bottom_box.set_homogeneous(true);
77         bottom_box.pack_start(play_btn);
78         bottom_box.pack_start(stop_btn);
79
80         play_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::play_btn_clicked));
81         stop_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::stop_btn_clicked));
82
83         if (!session) {
84                 play_btn.set_sensitive(false);
85         } else {
86                 session->AuditionActive.connect(mem_fun (*this, &SoundFileBox::audition_status_changed));
87         }
88
89         add_field_btn.signal_clicked().connect
90                         (mem_fun (*this, &SoundFileBox::add_field_clicked));
91         remove_field_btn.signal_clicked().connect
92                         (mem_fun (*this, &SoundFileBox::remove_field_clicked));
93
94         field_view.get_selection()->signal_changed().connect (mem_fun (*this, &SoundFileBox::field_selected));
95         ARDOUR::Library->fields_changed.connect (mem_fun (*this, &SoundFileBox::setup_fields));
96
97         show_all();
98         stop_btn.hide();
99 }
100
101 int
102 SoundFileBox::setup_labels (string filename) 
103 {
104     SNDFILE *sf;
105
106     if ((sf = sf_open ((char *) filename.c_str(), SFM_READ, &sf_info)) < 0) {
107         error << string_compose(_("file \"%1\" could not be opened"), filename) << endmsg;
108         return -1;
109     }
110
111     if (sf_info.frames == 0 && sf_info.channels == 0 &&
112                 sf_info.samplerate == 0 && sf_info.format == 0 &&
113                 sf_info.sections == 0) {
114                 /* .. ok, its not a sound file */
115             error << string_compose(_("file \"%1\" appears not to be an audio file"), filename) << endmsg;
116             return -1;
117         }
118
119         label.set_alignment (0.0f, 0.0f);
120     label.set_text ("Label: " + ARDOUR::Library->get_label(filename));
121
122         path.set_text ("Path: ");
123         path_entry.set_text (filename);
124         path_entry.set_position (-1);
125
126         length.set_alignment (0.0f, 0.0f);
127         length.set_text (string_compose("Length: %1", length2string(sf_info.frames, sf_info.samplerate)));
128
129         format.set_alignment (0.0f, 0.0f);
130         format.set_text (string_compose("Format: %1, %2", 
131                                 sndfile_major_format(sf_info.format),
132                                 sndfile_minor_format(sf_info.format)));
133
134         channels.set_alignment (0.0f, 0.0f);
135         channels.set_text (string_compose("Channels: %1", sf_info.channels));
136
137         samplerate.set_alignment (0.0f, 0.0f);
138         samplerate.set_text (string_compose("Samplerate: %1", sf_info.samplerate));
139
140         return 0;
141 }
142
143 void
144 SoundFileBox::setup_fields ()
145 {}
146
147 void
148 SoundFileBox::play_btn_clicked ()
149 {}
150
151 void
152 SoundFileBox::stop_btn_clicked ()
153 {}
154
155 void
156 SoundFileBox::add_field_clicked ()
157 {}
158
159 void
160 SoundFileBox::remove_field_clicked ()
161 {}
162
163 void
164 SoundFileBox::audition_status_changed (bool state)
165 {}
166
167 void
168 SoundFileBox::field_selected ()
169 {}
170
171 bool
172 SoundFileBox::update (std::string filename)
173 {
174         return true;
175 }
176
177 SoundFileBrowser::SoundFileBrowser (std::string title)
178         :
179         ArdourDialog(title),
180         chooser(Gtk::FILE_CHOOSER_ACTION_OPEN),
181         preview(session)
182 {
183         get_vbox()->pack_start(chooser);
184         chooser.set_preview_widget(preview);
185
186         chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview));
187
188         show_all();
189 }
190
191 void
192 SoundFileBrowser::update_preview ()
193 {
194         chooser.set_preview_widget_active(preview.update(chooser.get_filename()));
195 }
196
197 SoundFileChooser::SoundFileChooser (std::string title)
198         :
199         SoundFileBrowser(title)
200 {
201         add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
202         add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
203
204         show_all();
205 }
206
207 SoundFileOmega::SoundFileOmega (std::string title)
208         :
209         SoundFileBrowser(title),
210         embed_btn (_("Embed")),
211         import_btn (_("Import")),
212         split_check (_("Split Channels"))
213 {
214         get_action_area()->pack_start(embed_btn);
215         get_action_area()->pack_start(import_btn);
216         add_button (Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
217
218         chooser.set_extra_widget(split_check);
219
220         embed_btn.signal_clicked().connect (mem_fun (*this, &SoundFileOmega::embed_clicked));
221         import_btn.signal_clicked().connect (mem_fun (*this, &SoundFileOmega::import_clicked));
222
223         show_all();
224 }
225
226 void
227 SoundFileOmega::embed_clicked ()
228 {
229         Embedded (chooser.get_filenames(), split_check.get_active());
230 }
231
232 void
233 SoundFileOmega::import_clicked ()
234 {
235         Imported (chooser.get_filenames(), split_check.get_active());
236 }
237
238 std::string
239 length2string (const int32_t frames, const int32_t sample_rate)
240 {
241     int secs = (int) (frames / (float) sample_rate);
242     int hrs =  secs / 3600;
243     secs -= (hrs * 3600);
244     int mins = secs / 60;
245     secs -= (mins * 60);
246
247     int total_secs = (hrs * 3600) + (mins * 60) + secs;
248     int frames_remaining = frames - (total_secs * sample_rate);
249     float fractional_secs = (float) frames_remaining / sample_rate;
250
251     char duration_str[32];
252     sprintf (duration_str, "%02d:%02d:%05.2f", hrs, mins, (float) secs + fractional_secs);
253
254     return duration_str;
255 }
256