2 #include "bcdisplayinfo.h"
4 #include "cdripwindow.h"
6 #include "mainprogress.h"
10 #include <sys/ioctl.h>
11 #include <sys/types.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)
31 CDRipMain::~CDRipMain()
37 char* CDRipMain::plugin_title() { return N_("CD Ripper"); }
38 int CDRipMain::is_realtime() { return 0; }
39 int CDRipMain::is_multichannel() { return 1; }
42 int CDRipMain::load_defaults()
44 // set the default directory
46 sprintf(directory, "%scdripper.rc", BCASTDIR);
49 defaults = new BC_Hash(directory);
52 track1 = defaults->get("TRACK1", 1);
53 min1 = defaults->get("MIN1", 0);
54 sec1 = defaults->get("SEC1", 0);
55 track2 = defaults->get("TRACK2", 2);
56 min2 = defaults->get("MIN2", 0);
57 sec2 = defaults->get("SEC2", 0);
58 sprintf(device, "/dev/cdrom");
59 defaults->get("DEVICE", device);
60 startlba = defaults->get("STARTLBA", 0);
61 endlba = defaults->get("ENDLBA", 0);
65 int CDRipMain::save_defaults()
67 defaults->update("TRACK1", track1);
68 defaults->update("MIN1", min1);
69 defaults->update("SEC1", sec1);
70 defaults->update("TRACK2", track2);
71 defaults->update("MIN2", min2);
72 defaults->update("SEC2", sec2);
73 defaults->update("DEVICE", device);
74 defaults->update("STARTLBA", startlba);
75 defaults->update("ENDLBA", endlba);
80 int CDRipMain::get_parameters()
87 while(result2 && !result)
91 //printf("CDRipMain::get_parameters 1\n");
92 CDRipWindow window(this, info.get_abs_cursor_x(), info.get_abs_cursor_y());
93 //printf("CDRipMain::get_parameters 2\n");
94 window.create_objects();
95 //printf("CDRipMain::get_parameters 3\n");
96 result = window.run_window();
97 //printf("CDRipMain::get_parameters 4\n");
99 if(!result) result2 = get_toc();
100 //printf("CDRipMain::get_parameters 5 %d\n", result);
102 PluginAClient::sample_rate = 44100;
106 int CDRipMain::open_drive()
108 if((cdrom = open(device, O_RDONLY)) < 0)
111 ErrorBox window(PROGRAM_NAME ": CD Ripper",
112 info.get_abs_cursor_x(),
113 info.get_abs_cursor_y());
114 window.create_objects(_("Can't open cdrom drive."));
119 ioctl(cdrom, CDROMSTART); // start motor
123 int CDRipMain::close_drive()
125 ioctl(cdrom, CDROMSTOP);
130 int CDRipMain::get_toc()
133 int result = 0, i, tracks;
134 struct cdrom_tochdr hdr;
135 struct cdrom_tocentry entry[100];
138 result = open_drive();
140 if(ioctl(cdrom, CDROMREADTOCHDR, &hdr) < 0)
143 ErrorBox window(PROGRAM_NAME ": CD Ripper",
144 info.get_abs_cursor_x(),
145 info.get_abs_cursor_y());
146 window.create_objects(_("Can't get total from table of contents."));
151 for(i = 0; i < hdr.cdth_trk1; i++)
153 entry[i].cdte_track = 1 + i;
154 entry[i].cdte_format = CDROM_LBA;
155 if(ioctl(cdrom, CDROMREADTOCENTRY, &entry[i]) < 0)
157 ioctl(cdrom, CDROMSTOP);
159 ErrorBox window(PROGRAM_NAME ": CD Ripper",
160 info.get_abs_cursor_x(),
161 info.get_abs_cursor_y());
162 window.create_objects(_("Can't get table of contents entry."));
169 entry[i].cdte_track = CDROM_LEADOUT;
170 entry[i].cdte_format = CDROM_LBA;
171 if(ioctl(cdrom, CDROMREADTOCENTRY, &entry[i]) < 0)
173 ioctl(cdrom, CDROMSTOP);
175 ErrorBox window(PROGRAM_NAME ": CD Ripper",
176 info.get_abs_cursor_x(),
177 info.get_abs_cursor_y());
178 window.create_objects(_("Can't get table of contents leadout."));
184 tracks = hdr.cdth_trk1+1;
186 if(track1 <= 0 || track1 > tracks)
188 ioctl(cdrom, CDROMSTOP);
190 ErrorBox window(PROGRAM_NAME ": CD Ripper",
191 info.get_abs_cursor_x(),
192 info.get_abs_cursor_y());
193 window.create_objects(_("Start track is out of range."));
198 // Clamp to highest track
204 if(track2 < track1 || track2 <= 0)
206 ioctl(cdrom, CDROMSTOP);
208 ErrorBox window(PROGRAM_NAME ": CD Ripper",
209 info.get_abs_cursor_x(),
210 info.get_abs_cursor_y());
211 window.create_objects(_("End track is out of range."));
216 if(track1 == track2 && min2 == 0 && sec2 == 0)
218 ioctl(cdrom, CDROMSTOP);
220 ErrorBox window(PROGRAM_NAME ": CD Ripper",
221 info.get_abs_cursor_x(),
222 info.get_abs_cursor_y());
223 window.create_objects(_("End position is out of range."));
228 startlba = endlba = 0;
231 startlba = entry[track1 - 1].cdte_addr.lba;
232 startlba += (min1 * 44100 * 4 * 60 + sec1 * 44100 * 4) / FRAMESIZE;
234 endlba = entry[track2 - 1].cdte_addr.lba;
237 endlba += (min2 * 44100 * 4 * 60 + sec2 * 44100 * 4) / FRAMESIZE;
241 //printf("CDRipMain::get_toc %ld %ld\n", startlba, endlba);
246 int CDRipMain::start_loop()
251 //printf("CDRipMain::start_loop 1\n");
253 FRAME = 4; // 2 bytes 2 channels
254 previewing = 3; // defeat bug in hardware
255 fragment_length = PluginClient::in_buffer_size * FRAME;
256 fragment_length /= NFRAMES * FRAMESIZE;
257 fragment_length *= NFRAMES * FRAMESIZE;
258 total_length = (endlba - startlba) * FRAMESIZE / fragment_length + previewing + 1;
259 result = open_drive();
260 //printf("CDRipMain::start_loop 1 %d\n", interactive);
262 // thread out progress
265 char string[BCTEXTLEN];
266 sprintf(string, "%s...", plugin_title());
267 progress = start_progress(string, total_length);
269 //printf("CDRipMain::start_loop 1\n");
271 // get still more CD parameters
274 startlba_fragment = startlba - fragment_length * previewing / FRAMESIZE;
275 buffer = new char[fragment_length];
276 arg.addr.lba = startlba_fragment;
277 arg.addr_format = CDROM_LBA;
278 arg.nframes = NFRAMES;
279 //printf("CDRipMain::start_loop 2\n");
285 int CDRipMain::stop_loop()
289 progress->stop_progress();
298 int CDRipMain::process_loop(double **plugin_buffer, int64_t &write_length)
301 //printf("CDRipMain::process_loop 1\n");
304 if(arg.addr.lba < endlba && !endofselection)
306 if(arg.addr.lba + fragment_length / FRAMESIZE > endlba)
308 fragment_length = (endlba - arg.addr.lba) / NFRAMES;
309 fragment_length *= NFRAMES * FRAMESIZE;
312 //printf("CDRipMain::process_loop 2 %d %d\n", arg.addr.lba, endlba);
314 for(i = 0; i < fragment_length;
315 i += NFRAMES * FRAMESIZE,
316 arg.addr.lba += NFRAMES)
318 arg.buf = (unsigned char*)&buffer[i];
319 for(attempts = 0; attempts < 3; attempts++)
321 if(!(ioctl(cdrom, CDROMREADAUDIO, &arg)))
326 if(attempts == 2 && !previewing) printf("Can't read CD audio.\n");
329 //printf("CDRipMain::process_loop 3\n");
331 if(arg.addr.lba > startlba)
333 // convert to doubles
334 fragment_samples = fragment_length / FRAME;
335 for(j = 0; j < 2 && j < PluginClient::total_in_buffers; j++)
337 buffer_channel = (int16_t*)buffer + j;
338 output_buffer = plugin_buffer[j];
339 for(k = 0, l = 0; l < fragment_samples; k += 2, l++)
341 output_buffer[l] = buffer_channel[k];
342 output_buffer[l] /= 0x7fff;
346 write_length = fragment_samples;
348 //printf("CDRipMain::process_loop 5 %d\n", interactive);
353 if(!result) result = progress->update(currentlength);
355 //printf("CDRipMain::process_loop 6\n");
359 //printf("CDRipMain::process_loop 7\n");
364 //printf("CDRipMain::process_loop 8 %d %d\n", endofselection, result);
365 return endofselection || result;