You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3414 lines
89 KiB

15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
  1. /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
  2. /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
  3. Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
  4. Provided under GPL version 2 or later.
  5. */
  6. #ifdef HAVE_CONFIG_H
  7. #include "../config.h"
  8. #endif
  9. #include <unistd.h>
  10. #include <signal.h>
  11. /* ts A61009 */
  12. /* #include <a ssert.h> */
  13. /* ts A61106 : Deliberate defect provocation macros
  14. DO NOT DEFINE THESE IF YOU WANT SUCCESSFUL TAO !
  15. #define Libburn_experimental_no_close_tracK 1
  16. #define Libburn_experimental_no_close_sessioN 1
  17. */
  18. /* ts A61114 : Highly experimental : try to achieve SAO on appendables
  19. THIS DOES NOT WORK YET !
  20. #define Libburn_sao_can_appenD 1
  21. */
  22. #include <sys/types.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include <stdlib.h>
  27. #include <fcntl.h>
  28. #include <errno.h>
  29. #include <sys/stat.h>
  30. #include <sys/time.h>
  31. /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
  32. #ifndef O_BINARY
  33. #define O_BINARY 0
  34. #endif
  35. #include "error.h"
  36. #include "sector.h"
  37. #include "libburn.h"
  38. #include "drive.h"
  39. #include "transport.h"
  40. #include "debug.h"
  41. #include "init.h"
  42. #include "toc.h"
  43. #include "util.h"
  44. #include "sg.h"
  45. #include "write.h"
  46. #include "options.h"
  47. #include "structure.h"
  48. #include "source.h"
  49. #include "mmc.h"
  50. #include "spc.h"
  51. #include "libdax_msgs.h"
  52. extern struct libdax_msgs *libdax_messenger;
  53. /* ts A91120 : <<< experimental */
  54. #ifdef Libburn_mmap_write_buffeR
  55. #include <sys/mman.h>
  56. #endif
  57. /* The maximum output size to be used with CD media. This is also curbed
  58. by BURN_OS_TRANSPORT_BUFFER_SIZE. The smaller number gets into effect.
  59. */
  60. #define Libburn_cd_obS (32 * 1024)
  61. /* The size to be used with DVD media.
  62. */
  63. #define Libburn_dvd_obS (32 * 1024)
  64. /* The size to be used with BD-RE media in normal, not streamed mode.
  65. */
  66. #define Libburn_bd_re_obS (64 * 1024)
  67. /* The size to be used with BD-R media in normal, not streamed mode.
  68. */
  69. #define Libburn_bd_r_obS (64 * 1024)
  70. /* The size to be used with BD-RE and BD-R media in streamed mode.
  71. */
  72. #define Libburn_bd_streamed_obS (64 * 1024)
  73. /* The number of retries if write(2) returns a short, non-negative write count.
  74. */
  75. #define Libburn_stdio_write_retrieS 16
  76. static int type_to_ctrl(int mode)
  77. {
  78. int ctrl = 0;
  79. int data = BURN_MODE2 | BURN_MODE1 | BURN_MODE0;
  80. if (mode & data) {
  81. ctrl |= 4;
  82. } else if (mode & BURN_AUDIO) {
  83. if (mode & BURN_4CH)
  84. ctrl |= 8;
  85. if (mode & BURN_PREEMPHASIS)
  86. ctrl |= 1;
  87. } else
  88. /* ts A61008 */
  89. /* a ssert(0); */
  90. return -1;
  91. if (mode & BURN_COPY)
  92. ctrl |= 2;
  93. return ctrl;
  94. }
  95. /* only the ctrl nibble is set here (not adr) */
  96. /* ts A61009 : removed "static" , reacted on type_to_ctrl() == -1
  97. preserved ignorance towards unknown modes (for now) */
  98. void type_to_form(int mode, unsigned char *ctladr, int *form)
  99. {
  100. int ret;
  101. ret = type_to_ctrl(mode) << 4;
  102. if (ret == -1) {
  103. *ctladr = 0xff;
  104. *form = -1;
  105. return;
  106. }
  107. *ctladr = ret;
  108. if (mode & BURN_AUDIO)
  109. *form = 0;
  110. if (mode & BURN_MODE0) {
  111. /* ts A61009 */
  112. /* a ssert(0); */
  113. *form = -1;
  114. return;
  115. }
  116. if (mode & BURN_MODE1)
  117. *form = 0x10;
  118. if (mode & BURN_MODE2) {
  119. /* ts A61009 */
  120. /* a ssert(0); */ /* XXX someone's gonna want this sometime */
  121. *form = -1;
  122. return;
  123. }
  124. if (mode & BURN_MODE_RAW)
  125. *form = 0;
  126. if (mode & BURN_SUBCODE_P16) /* must be expanded to R96 */
  127. *form |= 0x40;
  128. if (mode & BURN_SUBCODE_P96)
  129. *form |= 0xC0;
  130. if (mode & BURN_SUBCODE_R96)
  131. *form |= 0x40;
  132. }
  133. /* ts A71002 : outsourced from burn_write_flush() : no sync cache here */
  134. int burn_write_flush_buffer(struct burn_write_opts *o,struct burn_track *track)
  135. {
  136. struct burn_drive *d = o->drive;
  137. if (d->buffer->bytes && !d->cancel) {
  138. int err;
  139. err = d->write(d, d->nwa, d->buffer);
  140. if (err == BE_CANCELLED)
  141. return 0;
  142. /* A61101 */
  143. if(track != NULL) {
  144. track->writecount += d->buffer->bytes;
  145. track->written_sectors += d->buffer->sectors;
  146. }
  147. /* ts A61119 */
  148. d->progress.buffered_bytes += d->buffer->bytes;
  149. d->nwa += d->buffer->sectors;
  150. d->buffer->bytes = 0;
  151. d->buffer->sectors = 0;
  152. }
  153. return 1;
  154. }
  155. int burn_write_flush(struct burn_write_opts *o, struct burn_track *track)
  156. {
  157. int ret;
  158. struct burn_drive *d = o->drive;
  159. ret = burn_write_flush_buffer(o, track);
  160. if (ret <= 0)
  161. return ret;
  162. d->sync_cache(d);
  163. return 1;
  164. }
  165. /* ts A71002 : outsourced from burn_write_close_track() */
  166. int burn_write_track_minsize(struct burn_write_opts *o, struct burn_session *s,
  167. int tnum)
  168. {
  169. char msg[81];
  170. struct burn_drive *d;
  171. struct burn_track *t;
  172. int todo, step, cancelled, seclen;
  173. d = o->drive;
  174. t = s->track[tnum];
  175. /* ts A61103 : pad up track to minimum size of 600 sectors */
  176. if (t->written_sectors < 300) {
  177. todo = 300 - t->written_sectors;
  178. sprintf(msg,"Padding up track to minimum size (+ %d sectors)",
  179. todo);
  180. libdax_msgs_submit(libdax_messenger, o->drive->global_index,
  181. 0x0002011a,
  182. LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
  183. step = BUFFER_SIZE / 4096; /* shall fit any sector size */
  184. seclen = burn_sector_length(t->mode);
  185. if (seclen <= 0)
  186. seclen = 2048;
  187. memset(d->buffer, 0, sizeof(struct buffer));
  188. cancelled = d->cancel;
  189. for (; todo > 0; todo -= step) {
  190. if (step > todo)
  191. step = todo;
  192. d->buffer->bytes = step*seclen;
  193. d->buffer->sectors = step;
  194. d->cancel = 0;
  195. d->write(d, d->nwa, d->buffer);
  196. d->nwa += d->buffer->sectors;
  197. t->writecount += d->buffer->bytes;
  198. t->written_sectors += d->buffer->sectors;
  199. d->progress.buffered_bytes += d->buffer->bytes;
  200. }
  201. d->cancel = cancelled;
  202. }
  203. return 1;
  204. }
  205. /* ts A61030 */
  206. int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
  207. int tnum)
  208. {
  209. char msg[81];
  210. struct burn_drive *d;
  211. /* ts A61106 */
  212. #ifdef Libburn_experimental_no_close_tracK
  213. return 1;
  214. #endif
  215. d = o->drive;
  216. d->busy = BURN_DRIVE_CLOSING_TRACK;
  217. sprintf(msg, "Closing track %2.2d", tnum+1);
  218. libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119,
  219. LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
  220. /* MMC-1 mentions track number 0xFF for "the incomplete track",
  221. MMC-3 does not. I tried both. 0xFF was in effect when other
  222. bugs finally gave up and made way for readable tracks. */
  223. /* ts A70129
  224. Probably the right value for appendables is d->last_track_no
  225. */
  226. d->close_track_session(o->drive, 0, 0xff);
  227. d->busy = BURN_DRIVE_WRITING;
  228. return 1;
  229. }
  230. /* ts A61030 */
  231. int burn_write_close_session(struct burn_write_opts *o)
  232. {
  233. /* ts A61106 */
  234. #ifdef Libburn_experimental_no_close_sessioN
  235. return 1;
  236. #endif
  237. libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119,
  238. LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
  239. "Closing session", 0, 0);
  240. /* ts A61102 */
  241. o->drive->busy = BURN_DRIVE_CLOSING_SESSION;
  242. o->drive->close_track_session(o->drive, 1, 0);
  243. /* ts A61102 */
  244. o->drive->busy = BURN_DRIVE_WRITING;
  245. return 1;
  246. }
  247. /* ts A60819, B20101:
  248. This is useful only when changes about CD SAO get tested.
  249. # define Libburn_write_with_function_print_cuE yes
  250. */
  251. #ifdef Libburn_write_with_function_print_cuE
  252. static char cue_printify(char c)
  253. {
  254. if (c >= 32 && c < 127)
  255. return c;
  256. return '#';
  257. }
  258. static void print_cue(struct cue_sheet *sheet)
  259. {
  260. int i;
  261. unsigned char *unit;
  262. printf("\n");
  263. printf("ctladr|trno|indx|form|scms| msf | text\n");
  264. printf("------+----+----+----+----+----------+--------\n");
  265. for (i = 0; i < sheet->count; i++) {
  266. unit = sheet->data + 8 * i;
  267. if ((unit[0] & 0xf) == 2) {
  268. printf(
  269. " %1X %1X | | | | | | %c%c%c%c%c%c%c\n",
  270. (unit[0] & 0xf0) >> 4, unit[0] & 0xf,
  271. cue_printify(unit[1]), cue_printify(unit[2]),
  272. cue_printify(unit[3]), cue_printify(unit[4]),
  273. cue_printify(unit[5]), cue_printify(unit[6]),
  274. unit[7] == 0 ? ' ' : cue_printify(unit[7]));
  275. } else if ((unit[0] & 0xf) == 3) {
  276. printf(
  277. " %1X %1X | %2d | | | | | %c%c%c%c%c%c\n",
  278. (unit[0] & 0xf0) >> 4, unit[0] & 0xf,
  279. unit[1], cue_printify(unit[2]),
  280. cue_printify(unit[3]), cue_printify(unit[4]),
  281. cue_printify(unit[5]), cue_printify(unit[6]),
  282. cue_printify(unit[7]));
  283. } else if (unit[1] > 99) {
  284. printf(" %1X %1X |0x%02X| %2d | %02X | %02X |",
  285. (unit[0] & 0xf0) >> 4, unit[0] & 0xf,
  286. unit[1], unit[2], unit[3], unit[4]);
  287. printf(" %02d:%02d:%02d |\n",
  288. unit[5], unit[6], unit[7]);
  289. } else {
  290. printf(" %1X %1X | %2d | %2d | %02X | %02X |",
  291. (unit[0] & 0xf0) >> 4, unit[0] & 0xf,
  292. unit[1], unit[2], unit[3], unit[4]);
  293. printf(" %02d:%02d:%02d |\n",
  294. unit[5], unit[6], unit[7]);
  295. }
  296. }
  297. fflush(stdout);
  298. }
  299. #endif /* Libburn_write_with_print_cuE */
  300. /* ts B11226 */
  301. static int new_cue(struct cue_sheet *sheet, int number, int flag)
  302. {
  303. unsigned char *ptr;
  304. ptr = realloc(sheet->data, (sheet->count + number) * 8);
  305. if (ptr == NULL) {
  306. libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
  307. LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
  308. "Could not allocate new auxiliary object (cue_sheet->data)",
  309. 0, 0);
  310. return -1;
  311. }
  312. sheet->data = ptr;
  313. sheet->count += number;
  314. return 1;
  315. }
  316. /* ts B11226 : outsourced new_cue() */
  317. /** @return 1 = success , <=0 failure */
  318. static int add_cue(struct cue_sheet *sheet, unsigned char ctladr,
  319. unsigned char tno, unsigned char indx,
  320. unsigned char form, unsigned char scms, int lba)
  321. {
  322. unsigned char *unit;
  323. int m, s, f, ret;
  324. burn_lba_to_msf(lba, &m, &s, &f);
  325. ret = new_cue(sheet, 1, 0);
  326. if (ret <= 0)
  327. return -1;
  328. unit = sheet->data + (sheet->count - 1) * 8;
  329. unit[0] = ctladr;
  330. unit[1] = tno;
  331. unit[2] = indx;
  332. unit[3] = form;
  333. unit[4] = scms;
  334. unit[5] = m;
  335. unit[6] = s;
  336. unit[7] = f;
  337. return 1;
  338. }
  339. /* ts B11226 */
  340. static int add_catalog_cue(struct cue_sheet *sheet, unsigned char catalog[13])
  341. {
  342. unsigned char *unit;
  343. int i, ret;
  344. ret = new_cue(sheet, 2, 0);
  345. if (ret <= 0)
  346. return -1;
  347. unit = sheet->data + (sheet->count - 2) * 8;
  348. unit[0] = unit[8] = 0x02;
  349. for (i = 0; i < 13; i++)
  350. unit[1 + (i >= 7) * 8 + (i % 7)] = catalog[i];
  351. unit[15] = 0x00;
  352. return 1;
  353. }
  354. /* ts B11226 */
  355. static int add_isrc_cue(struct cue_sheet *sheet, unsigned char ctladr, int tno,
  356. struct isrc *isrc)
  357. {
  358. unsigned char *unit;
  359. int i, ret;
  360. char text[8];
  361. ret = new_cue(sheet, 2, 0);
  362. if (ret <= 0)
  363. return -1;
  364. unit = sheet->data + (sheet->count - 2) * 8;
  365. unit[0] = unit[8] = (ctladr & 0xf0) | 0x03;
  366. unit[1] = unit[9] = tno;
  367. unit[2] = isrc->country[0];
  368. unit[3] = isrc->country[1];
  369. unit[4] = isrc->owner[0];
  370. unit[5] = isrc->owner[1];
  371. unit[6] = isrc->owner[2];
  372. sprintf(text, "%-2.2u%-5.5u", (unsigned int) isrc->year, isrc->serial);
  373. unit[7] = text[0];
  374. for (i = 1; i < 7; i++)
  375. unit[9 + i] = text[i];
  376. return 1;
  377. }
  378. /* ts A61114: added parameter nwa */
  379. struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
  380. struct burn_session *session,
  381. int nwa)
  382. {
  383. int i, m, s, f, form, runtime = -150, ret, track_length;
  384. int leadin_form, leadin_start, pregap = 150, postgap;
  385. unsigned char ctladr, scms;
  386. struct burn_drive *d;
  387. struct burn_toc_entry *e;
  388. struct cue_sheet *sheet;
  389. struct burn_track **tar = session->track;
  390. int ntr = session->tracks;
  391. int rem = 0;
  392. #define Libburn_track_multi_indeX yes
  393. #ifdef Libburn_track_multi_indeX
  394. int j;
  395. #else
  396. int pform;
  397. #endif
  398. if (ntr < 1) {
  399. libdax_msgs_submit(libdax_messenger, -1, 0x0002019c,
  400. LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
  401. "Session has no defined tracks", 0, 0);
  402. return NULL;
  403. }
  404. d = o->drive;
  405. #ifdef Libburn_sao_can_appenD
  406. if (d->status == BURN_DISC_APPENDABLE)
  407. runtime = nwa-150;
  408. #endif
  409. sheet = calloc(1, sizeof(struct cue_sheet));
  410. /* ts A61009 : react on failures of calloc(), add_cue_sheet()
  411. type_to_form() */
  412. if (sheet == NULL) {
  413. libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
  414. LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
  415. "Could not allocate new auxiliary object (cue_sheet)",
  416. 0, 0);
  417. return NULL;
  418. }
  419. sheet->data = NULL;
  420. sheet->count = 0;
  421. type_to_form(tar[0]->mode, &ctladr, &form);
  422. if (form == -1) {
  423. libdax_msgs_submit(libdax_messenger, -1, 0x00020116,
  424. LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
  425. "Track mode has unusable value", 0, 0);
  426. goto failed;
  427. }
  428. if (tar[0]->mode & BURN_AUDIO)
  429. leadin_form = 0x01;
  430. else
  431. leadin_form = 0x14;
  432. if (o->num_text_packs > 0) {
  433. leadin_form |= 0x40;
  434. } else {
  435. /* Check for CD-TEXT in session. Not the final creation,
  436. because the cue sheet content might be needed for CD-TEXT
  437. pack type 0x88 "TOC".
  438. */
  439. if (o->text_packs == NULL) {
  440. ret = burn_cdtext_from_session(session, NULL, NULL, 1);
  441. if (ret < 0)
  442. goto failed;
  443. else if (ret > 0)
  444. leadin_form |= 0x40;
  445. }
  446. }
  447. if (o->has_mediacatalog)
  448. ret = add_catalog_cue(sheet, o->mediacatalog);
  449. else if (session->mediacatalog[0])
  450. ret = add_catalog_cue(sheet, session->mediacatalog);
  451. else
  452. ret = 1;
  453. if (ret <= 0)
  454. goto failed;
  455. /* ts B11225
  456. MMC-5 6.33.3.15 Data Form of Sub-channel
  457. seems to indicate that for leadin_form 0x41 one should announce
  458. d->start_lba as start of the leadin (e.g. -12490) and that data
  459. block type should 2 or 3 with mode page 05h. But my drives refuse
  460. on that.
  461. It works with LBA -150 and data block type 0. Shrug.
  462. */
  463. leadin_start = runtime;
  464. ret = add_cue(sheet, (ctladr & 64) | 1, 0, 0, leadin_form, 0,
  465. leadin_start);
  466. if (ret <= 0)
  467. goto failed;
  468. d->toc_entries = ntr + 3;
  469. /* ts A61009 */
  470. /* a ssert(d->toc_entry == NULL); */
  471. if (d->toc_entry != NULL) {
  472. /* ts A61109 : this happens with appendable CDs
  473. >>> Open question: is the existing TOC needed ? */
  474. /* ts A61109 : for non-SAO, this sheet is thrown away later */
  475. free((char *) d->toc_entry);
  476. /*
  477. libdax_msgs_submit(libdax_messenger,
  478. d->global_index, 0x00020117,
  479. LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
  480. "toc_entry of drive is already in use", 0, 0);
  481. goto failed;
  482. */
  483. }
  484. if (session->firsttrack + ntr - 1 > 99) {
  485. libdax_msgs_submit(libdax_messenger, -1, 0x0002019b,
  486. LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
  487. "CD track number exceeds 99", 0, 0);
  488. goto failed;
  489. }
  490. session->lasttrack = session->firsttrack + ntr - 1;
  491. d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry));
  492. e = d->toc_entry;
  493. e[0].point = 0xA0;
  494. if (tar[0]->mode & BURN_AUDIO)
  495. e[0].control = TOC_CONTROL_AUDIO;
  496. else
  497. e[0].control = TOC_CONTROL_DATA;
  498. e[0].pmin = session->firsttrack;
  499. e[0].psec = o->format;
  500. e[0].adr = 1;
  501. e[1].point = 0xA1;
  502. e[1].pmin = session->lasttrack;
  503. e[1].adr = 1;
  504. if (tar[ntr - 1]->mode & BURN_AUDIO)
  505. e[1].control = TOC_CONTROL_AUDIO;
  506. else
  507. e[1].control = TOC_CONTROL_DATA;
  508. e[2].point = 0xA2;
  509. e[2].control = e[1].control;
  510. e[2].adr = 1;
  511. tar[0]->pregap2 = 1;
  512. if (tar[0]->pregap2_size < 150)
  513. tar[0]->pregap2_size = 150;
  514. #ifndef Libburn_track_multi_indeX
  515. pform = form;
  516. #endif
  517. for (i = 0; i < ntr; i++) {
  518. /* ts A70125 :
  519. Still not understanding the sense behind linking tracks,
  520. i decided to at least enforce the MMC specs' minimum
  521. track length.
  522. */
  523. track_length = burn_track_get_sectors_2(tar[i], 1);
  524. if (track_length < 300 && !burn_track_is_open_ended(tar[i])) {
  525. track_length = 300;
  526. if (!tar[i]->pad)
  527. tar[i]->pad = 1;
  528. burn_track_set_sectors(tar[i], track_length);
  529. }
  530. type_to_form(tar[i]->mode, &ctladr, &form);
  531. if (tar[i]->mode & BURN_SCMS)
  532. scms = 0x80;
  533. else
  534. scms = 0;
  535. if (tar[i]->isrc.has_isrc) {
  536. ret = add_isrc_cue(sheet, ctladr,
  537. i + session->firsttrack, &(tar[i]->isrc));
  538. if (ret <= 0)
  539. goto failed;
  540. }
  541. pregap = 0;
  542. if (tar[i]->pregap2)
  543. pregap = tar[i]->pregap2_size;
  544. postgap = 0;
  545. if (tar[i]->postgap) {
  546. if (tar[i]->indices >= 99) {
  547. libdax_msgs_submit(libdax_messenger, -1,
  548. 0x0002019a, LIBDAX_MSGS_SEV_SORRY,
  549. LIBDAX_MSGS_PRIO_HIGH,
  550. "Post-gap index number exceeds 99",
  551. 0, 0);
  552. goto failed;
  553. }
  554. if (tar[i]->indices < 2)
  555. tar[i]->indices = 2;
  556. tar[i]->index[tar[i]->indices] = track_length;
  557. postgap = tar[i]->postgap_size;
  558. }
  559. #ifdef Libburn_track_multi_indeX
  560. for(j = 0; j < (tar[i]->indices + !!tar[i]->postgap) || j < 2;
  561. j++) {
  562. if(tar[i]->index[j] == 0x7fffffff) {
  563. if (j > 1)
  564. break;
  565. if (j == 0 && pregap <= 0)
  566. continue;
  567. /* force existence of mandatory index */
  568. tar[i]->index[j] = 0;
  569. } else if (j == 0) {
  570. tar[i]->index[j] = 0;
  571. } else if (j == 1 && tar[i]->index[0] == 0x7fffffff) {
  572. tar[i]->index[j] = 0;
  573. }
  574. if (j == 1) {
  575. tar[i]->entry = &e[3 + i];
  576. e[3 + i].point = i + session->firsttrack;
  577. burn_lba_to_msf(runtime, &m, &s, &f);
  578. e[3 + i].pmin = m;
  579. e[3 + i].psec = s;
  580. e[3 + i].pframe = f;
  581. e[3 + i].adr = 1;
  582. e[3 + i].control = type_to_ctrl(tar[i]->mode);
  583. }
  584. /* >>> ??? else if j == 0 && mode change to -data :
  585. Extended pregap */;
  586. /* >>> check index with track size */;
  587. tar[i]->index[j] += runtime;
  588. ret = add_cue(sheet, ctladr | 1,
  589. i + session->firsttrack, j, form, scms,
  590. tar[i]->index[j]);
  591. if (ret <= 0)
  592. goto failed;
  593. runtime += pregap;
  594. pregap = 0;
  595. }
  596. runtime += track_length + postgap;
  597. #else /* Libburn_track_multi_indeX */
  598. if (i == 0) {
  599. ret = add_cue(sheet, ctladr | 1, session->firsttrack,
  600. 0, form, 0, runtime);
  601. if (ret <= 0)
  602. goto failed;
  603. runtime += 150;
  604. } else if (pform != form) {
  605. /* ts A70121 : This seems to be thw wrong test. Correct would
  606. be to compare tar[]->mode or bit2 of ctladr.
  607. */
  608. ret = add_cue(sheet, ctladr | 1,
  609. i + session->firsttrack, 0, form, scms,
  610. runtime);
  611. if (ret <= 0)
  612. goto failed;
  613. runtime += 150;
  614. /* XXX fix pregap interval 1 for data tracks */
  615. /* ts A60813 silence righteous compiler warning about C++ style comments
  616. This is possibly not a comment but rather a trace of Derek Foreman
  617. experiments. Thus not to be beautified - but to be preserved rectified.
  618. / / if (!(form & BURN_AUDIO))
  619. / / tar[i]->pregap1 = 1;
  620. */
  621. /* ts A70121 : it is unclear why (form & BURN_AUDIO) should prevent pregap1.
  622. I believe, correct would be:
  623. runtime += 75;
  624. tar[i]->pregap1 = 1;
  625. The test for pform != form is wrong anyway.
  626. Next one has to care for Post-gap: table 555 in mmc5r03c.pdf does not
  627. show any although 6.33.3.19 would prescribe some.
  628. ts B20111: Table 1 of MMC-1 shows two post-gaps. The first matches the
  629. precriptions with SEND CUE SHEET. The second one is riddling.
  630. Both are part of a track and occupy the range of the last index
  631. of the track. Length is 2 seconds for each.
  632. Nobody seems to have ever tested this situation, up to now.
  633. It is banned for now in burn_disc_write().
  634. Warning have been placed in libburn.h .
  635. */
  636. tar[i]->pregap2 = 1;
  637. }
  638. /* XXX HERE IS WHERE WE DO INDICES IN THE CUE SHEET */
  639. /* XXX and we should make sure the gaps conform to ecma-130... */
  640. tar[i]->entry = &e[3 + i];
  641. e[3 + i].point = i + session->firsttrack;
  642. burn_lba_to_msf(runtime, &m, &s, &f);
  643. e[3 + i].pmin = m;
  644. e[3 + i].psec = s;
  645. e[3 + i].pframe = f;
  646. e[3 + i].adr = 1;
  647. e[3 + i].control = type_to_ctrl(tar[i]->mode);
  648. ret = add_cue(sheet, ctladr | 1, i + session->firsttrack,
  649. 1, form, scms, runtime);
  650. if (ret <= 0)
  651. goto failed;
  652. runtime += track_length;
  653. #endif /* ! Libburn_track_multi_indeX */
  654. /* if we're padding, we'll clear any current shortage.
  655. if we're not, we'll slip toc entries by a sector every time our
  656. shortage is more than a sector
  657. XXX this is untested :)
  658. */
  659. if (!tar[i]->pad) {
  660. rem += burn_track_get_shortage(tar[i]);
  661. /* ts A61101 : I doubt that linking would yield a
  662. desirable effect. With TAO it is
  663. counterproductive in any way.
  664. */
  665. if (o->write_type == BURN_WRITE_TAO)
  666. tar[i]->source->next = NULL;
  667. else
  668. if (i +1 != ntr)
  669. tar[i]->source->next = tar[i+1]->source;
  670. } else if (rem) {
  671. rem = 0;
  672. runtime++;
  673. }
  674. if (rem > burn_sector_length(tar[i]->mode)) {
  675. rem -= burn_sector_length(tar[i]->mode);
  676. runtime--;
  677. }
  678. #ifndef Libburn_track_multi_indeX
  679. pform = form;
  680. #endif
  681. }
  682. burn_lba_to_msf(runtime, &m, &s, &f);
  683. e[2].pmin = m;
  684. e[2].psec = s;
  685. e[2].pframe = f;
  686. ret = add_cue(sheet, ctladr | 1, 0xAA, 1, leadin_form & 0x3f,
  687. 0, runtime);
  688. if (ret <= 0)
  689. goto failed;
  690. return sheet;
  691. failed:;
  692. if (sheet != NULL)
  693. free((char *) sheet);
  694. return NULL;
  695. }
  696. int burn_sector_length(int tracktype)
  697. {
  698. if (tracktype & BURN_AUDIO)
  699. return 2352;
  700. if (tracktype & BURN_MODE_RAW)
  701. return 2352;
  702. if (tracktype & BURN_MODE1)
  703. return 2048;
  704. /* ts A61009 */
  705. /* a ssert(0); */
  706. return -1;
  707. }
  708. int burn_subcode_length(int tracktype)
  709. {
  710. if (tracktype & BURN_SUBCODE_P16)
  711. return 16;
  712. if ((tracktype & BURN_SUBCODE_P96) || (tracktype & BURN_SUBCODE_R96))
  713. return 96;
  714. return 0;
  715. }
  716. int burn_write_leadin(struct burn_write_opts *o,
  717. struct burn_session *s, int first)
  718. {
  719. struct burn_drive *d = o->drive;
  720. int count;
  721. d->busy = BURN_DRIVE_WRITING_LEADIN;
  722. if (first)
  723. count = 0 - d->alba - 150;
  724. else
  725. count = 4500;
  726. d->progress.start_sector = d->alba;
  727. d->progress.sectors = count;
  728. d->progress.sector = 0;
  729. while (count != 0) {
  730. if (!sector_toc(o, s->track[0]->mode))
  731. return 0;
  732. count--;
  733. d->progress.sector++;
  734. }
  735. d->busy = BURN_DRIVE_WRITING;
  736. return 1;
  737. }
  738. int burn_write_leadout(struct burn_write_opts *o,
  739. int first, unsigned char control, int mode)
  740. {
  741. struct burn_drive *d = o->drive;
  742. int count