r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / plugins / cdripper / cdripper.C
blob2b087d4fcf3204793a746d69a75fb8d113d80583
1 #include "errorbox.h"
2 #include "bcdisplayinfo.h"
3 #include "cdripper.h"
4 #include "cdripwindow.h"
5 #include "defaults.h"
6 #include "mainprogress.h"
7 #include "mwindow.inc"
9 #include <fcntl.h>
10 #include <sys/ioctl.h>
11 #include <sys/types.h>
12 #include <unistd.h>
14 #include <libintl.h>
15 #define _(String) gettext(String)
16 #define gettext_noop(String) String
17 #define N_(String) gettext_noop (String)
19 PluginClient* new_plugin(PluginServer *server)
21         return new CDRipMain(server);
25 CDRipMain::CDRipMain(PluginServer *server)
26  : PluginAClient(server)
28         load_defaults();
31 CDRipMain::~CDRipMain()
33         save_defaults();
34         delete defaults;
37 char* CDRipMain::plugin_title() { return _("CD Ripper"); }
39 int CDRipMain::is_realtime() { return 0; }
41 int CDRipMain::is_multichannel() { return 1; }
43 int CDRipMain::load_defaults()
45 // set the default directory
46         char directory[1024];
47         sprintf(directory, "%scdripper.rc", BCASTDIR);
49 // load the defaults
50         defaults = new Defaults(directory);
51         defaults->load();
53         track1 = defaults->get("TRACK1", 1);
54         min1 = defaults->get("MIN1", 0);
55         sec1 = defaults->get("SEC1", 0);
56         track2 = defaults->get("TRACK2", 2);
57         min2 = defaults->get("MIN2", 0);
58         sec2 = defaults->get("SEC2", 0);
59         sprintf(device, "/dev/cdrom");
60         defaults->get("DEVICE", device);
61         startlba = defaults->get("STARTLBA", 0);
62         endlba = defaults->get("ENDLBA", 0);
63         return 0;
66 int CDRipMain::save_defaults()
68         defaults->update("TRACK1", track1);
69         defaults->update("MIN1", min1);
70         defaults->update("SEC1", sec1);
71         defaults->update("TRACK2", track2);
72         defaults->update("MIN2", min2);
73         defaults->update("SEC2", sec2);
74         defaults->update("DEVICE", device);
75         defaults->update("STARTLBA", startlba);
76         defaults->update("ENDLBA", endlba);
77         defaults->save();
78         return 0;
81 int CDRipMain::get_parameters()
83         int result, result2;
85         result = 0;
86         result2 = 1;
88         while(result2 && !result)
89         {
90                 {
91                         BC_DisplayInfo info;
92 //printf("CDRipMain::get_parameters 1\n");
93                         CDRipWindow window(this, info.get_abs_cursor_x(), info.get_abs_cursor_y());
94 //printf("CDRipMain::get_parameters 2\n");
95                         window.create_objects();
96 //printf("CDRipMain::get_parameters 3\n");
97                         result = window.run_window();
98 //printf("CDRipMain::get_parameters 4\n");
99                 }
100                 if(!result) result2 = get_toc();
101 //printf("CDRipMain::get_parameters 5 %d\n", result);
102         }
103         PluginClient::sample_rate = 44100;
104         return result;
107 int CDRipMain::open_drive()
109         if((cdrom = open(device, O_RDONLY)) < 0)
110         {
111                 BC_DisplayInfo info;
112                 ErrorBox window(PROGRAM_NAME ": CD Ripper",
113                         info.get_abs_cursor_x(), 
114                         info.get_abs_cursor_y());
115                 window.create_objects(_("Can't open cdrom drive."));
116                 window.run_window();
117                 return 1;
118         }
120         ioctl(cdrom, CDROMSTART);         // start motor
121         return 0;
124 int CDRipMain::close_drive()
126         ioctl(cdrom, CDROMSTOP);
127         close(cdrom);
128         return 0;
131 int CDRipMain::get_toc()
133 // test CD
134         int result = 0, i, tracks;
135         struct cdrom_tochdr hdr;
136         struct cdrom_tocentry entry[100];
137         BC_DisplayInfo info;
138         
139         result = open_drive();
140         
141         if(ioctl(cdrom, CDROMREADTOCHDR, &hdr) < 0)
142         {
143                 close(cdrom);
144                 ErrorBox window(PROGRAM_NAME ": CD Ripper",
145                         info.get_abs_cursor_x(), 
146                         info.get_abs_cursor_y());
147                 window.create_objects(_("Can't get total from table of contents."));
148                 window.run_window();
149                 result = 1;
150         }
152         for(i = 0; i < hdr.cdth_trk1; i++)
153         {
154                 entry[i].cdte_track = 1 + i;
155                 entry[i].cdte_format = CDROM_LBA;
156                 if(ioctl(cdrom, CDROMREADTOCENTRY, &entry[i]) < 0)
157                 {
158                         ioctl(cdrom, CDROMSTOP);
159                         close(cdrom);
160                         ErrorBox window(PROGRAM_NAME ": CD Ripper",
161                                 info.get_abs_cursor_x(), 
162                                 info.get_abs_cursor_y());
163                         window.create_objects(_("Can't get table of contents entry."));
164                         window.run_window();
165                         result = 1;
166                         break;
167                 }
168         }
170         entry[i].cdte_track = CDROM_LEADOUT;
171         entry[i].cdte_format = CDROM_LBA;
172         if(ioctl(cdrom, CDROMREADTOCENTRY, &entry[i]) < 0)
173         {
174                 ioctl(cdrom, CDROMSTOP);
175                 close(cdrom);
176                 ErrorBox window(PROGRAM_NAME ": CD Ripper",
177                         info.get_abs_cursor_x(), 
178                         info.get_abs_cursor_y());
179                 window.create_objects(_("Can't get table of contents leadout."));
180                 window.run_window();
181                 result = 1;
182         }
183                         
184                         
185         tracks = hdr.cdth_trk1+1;
187         if(track1 <= 0 || track1 > tracks)
188         {
189                 ioctl(cdrom, CDROMSTOP);
190                 close(cdrom);
191                 ErrorBox window(PROGRAM_NAME ": CD Ripper",
192                         info.get_abs_cursor_x(), 
193                         info.get_abs_cursor_y());
194                 window.create_objects(_("Start track is out of range."));
195                 window.run_window();
196                 result = 1;
197         }
198         
199         if(track2 < track1 || track2 <= 0 || track2 > tracks)
200         {
201                 ioctl(cdrom, CDROMSTOP);
202                 close(cdrom);
203                 ErrorBox window(PROGRAM_NAME ": CD Ripper",
204                         info.get_abs_cursor_x(), 
205                         info.get_abs_cursor_y());
206                 window.create_objects(_("End track is out of range."));
207                 window.run_window();
208                 result = 1;
209         }
210         
211         if(track1 == track2 && min2 == 0 && sec2 == 0)
212         {
213                 ioctl(cdrom, CDROMSTOP);
214                 close(cdrom);
215                 ErrorBox window(PROGRAM_NAME ": CD Ripper",
216                         info.get_abs_cursor_x(), 
217                         info.get_abs_cursor_y());
218                 window.create_objects(_("End position is out of range."));
219                 window.run_window();
220                 result = 1;
221         }
223         startlba = endlba = 0;
224         if(!result)
225         {
226                 startlba = entry[track1 - 1].cdte_addr.lba;
227                 startlba += (min1 * 44100 * 4 * 60 + sec1 * 44100 * 4) / FRAMESIZE;
229                 endlba = entry[track2 - 1].cdte_addr.lba;
230                 if(track2 < tracks)
231                 {
232                         endlba += (min2 * 44100 * 4 * 60 + sec2 * 44100 * 4) / FRAMESIZE;
233                 }
234         }
236 //printf("CDRipMain::get_toc %ld %ld\n", startlba, endlba);
237         close_drive();
238         return result;
241 int CDRipMain::start_loop()
243 // get CD parameters
244         int result = 0;
246 //printf("CDRipMain::start_loop 1\n");
247         result = get_toc();
248         FRAME = 4;    // 2 bytes 2 channels
249         previewing = 3;     // defeat bug in hardware
250         fragment_length = PluginClient::in_buffer_size * FRAME;
251         fragment_length /= NFRAMES * FRAMESIZE;
252         fragment_length *= NFRAMES * FRAMESIZE;
253         total_length = (endlba - startlba) * FRAMESIZE / fragment_length + previewing + 1;
254         result = open_drive();
255 //printf("CDRipMain::start_loop 1 %d\n", interactive);
257 // thread out progress
258         if(interactive)
259         {
260                 char string[BCTEXTLEN];
261                 sprintf(string, "%s...", plugin_title());
262                 progress = start_progress(string, total_length);
263         }
264 //printf("CDRipMain::start_loop 1\n");
266 // get still more CD parameters
267         endofselection = 0;
268         currentlength = 0;
269         startlba_fragment = startlba - fragment_length * previewing / FRAMESIZE;
270         buffer = new char[fragment_length];
271         arg.addr.lba = startlba_fragment;
272         arg.addr_format = CDROM_LBA;
273         arg.nframes = NFRAMES;
274 //printf("CDRipMain::start_loop 2\n");
276         return result;
280 int CDRipMain::stop_loop()
282         if(interactive)
283         {
284                 progress->stop_progress();
285                 delete progress;
286         }
288         delete buffer;
289         close_drive();
290         return 0;
293 int CDRipMain::process_loop(double **plugin_buffer, int64_t &write_length)
295         int result = 0;
296 //printf("CDRipMain::process_loop 1\n");
298 // render it
299         if(arg.addr.lba < endlba && !endofselection)
300         {
301                 if(arg.addr.lba + fragment_length / FRAMESIZE > endlba)
302                 {
303                         fragment_length = (endlba - arg.addr.lba) / NFRAMES;
304                         fragment_length *= NFRAMES * FRAMESIZE;
305                         endofselection = 1;
306                 }
307 //printf("CDRipMain::process_loop 2 %d %d\n", arg.addr.lba, endlba);
309                 for(i = 0; i < fragment_length; 
310                         i += NFRAMES * FRAMESIZE,
311                         arg.addr.lba += NFRAMES)
312                 {
313                         arg.buf = (unsigned char*)&buffer[i];
314                         for(attempts = 0; attempts < 3; attempts++)
315                         {
316                                 if(!(ioctl(cdrom, CDROMREADAUDIO, &arg)))
317                                 {
318                                         attempts = 3;
319                                 }
320                                 else
321                                 if(attempts == 2 && !previewing) printf("Can't read CD audio.\n");
322                         }
323                 }
324 //printf("CDRipMain::process_loop 3\n");
326                 if(arg.addr.lba > startlba)
327                 {
328 // convert to doubles
329                         fragment_samples = fragment_length / FRAME;
330                         for(j = 0; j < 2 && j < PluginClient::total_in_buffers; j++)
331                         {
332                                 buffer_channel = (int16_t*)buffer + j;
333                                 output_buffer = plugin_buffer[j];
334                                 for(k = 0, l = 0; l < fragment_samples; k += 2, l++)
335                                 {
336                                         output_buffer[l] = buffer_channel[k];
337                                         output_buffer[l] /= 0x7fff;
338                                 }
339                         }
341                         write_length = fragment_samples;
342                 }
343 //printf("CDRipMain::process_loop 5 %d\n", interactive);
345                 currentlength++;
346                 if(interactive)
347                 {
348                         if(!result) result = progress->update(currentlength);
349                 }
350 //printf("CDRipMain::process_loop 6\n");
351         }
352         else
353         {
354 //printf("CDRipMain::process_loop 7\n");
355                 endofselection = 1;
356                 write_length = 0;
357         }
359 //printf("CDRipMain::process_loop 8 %d %d\n", endofselection, result);
360         return endofselection || result;