Compare commits

...

124 Commits
1.1.8 ... 1.2.0

Author SHA1 Message Date
b69baec77a Updated change log 2012-01-27 11:43:11 +00:00
516e509198 Updated cdrskin tarball generator 2012-01-27 11:41:06 +00:00
9736695026 Made number transition to 1.2.0 2012-01-27 11:39:50 +00:00
e2295ddbf8 Branching for libburn release 1.2.0 2012-01-27 10:23:19 +00:00
bfb798b51b Removed overdone part of rev 4593 2012-01-25 09:26:55 +00:00
72645c8fba Fixed an endless loop with cdrskin signal handling 2012-01-23 16:43:52 +00:00
f338575f41 Updated cdrskin wiki text 2012-01-23 12:54:57 +00:00
cc3ff147fe Updated change log 2012-01-23 12:53:26 +00:00
dcd1eab82d Updated change log 2012-01-23 11:59:40 +00:00
3ea4892040 Corrected some minor differences between SVN and local development tree 2012-01-23 10:27:13 +00:00
e0d7eb4820 Bug fix: cdrskin produced a memory fault if interupted before writing began 2012-01-23 10:17:26 +00:00
daf744276e Disabled dangerous abort handler actions while BURN_DRIVE_GRABBING 2012-01-23 10:15:01 +00:00
8963905bbc Improved reaction time on interrupt during writing of lead-in 2012-01-23 10:13:08 +00:00
88da4e9ead Prevented SIGSEGV with testing drive for being prepared for writing 2012-01-23 10:10:19 +00:00
cc9ec8666c Revoked an aspect of rev 4465 which aborted operation before drive is ready 2012-01-23 10:09:04 +00:00
7ce13c6dd3 Allowing SCSI read operations > 32 kB 2012-01-23 10:06:52 +00:00
6549072dcd Introduced burn_offst_source_new() flag bit0 which bans size changes 2012-01-23 09:56:53 +00:00
a88039e222 Counting post-gap as part of track with burn_track_get_sectors() 2012-01-23 09:54:20 +00:00
a75a838af9 Introduced burn_offst_source_new() flag bit0 which bans size changes 2012-01-23 09:36:47 +00:00
024701c220 Counting post-gap as part of track with burn_track_get_sectors() 2012-01-23 09:30:48 +00:00
72c31e89b2 Made conversion of ASC ASCQ to text independent of key and its text 2012-01-18 14:20:25 +00:00
2f548e046d Detecting address sequence errors with .cue command INDEX 2012-01-18 12:04:30 +00:00
9f8e4fb36b Preventing CD-TEXT with sessions that are not pure audio 2012-01-16 11:23:04 +00:00
645d41fdd2 Corrected a comment 2012-01-16 11:20:49 +00:00
853928815a Updated SAO cookbook about indice, pre-gap, post-gap 2012-01-15 09:09:37 +00:00
38bbbf2496 Implemented index reporting for struct burn_progress 2012-01-13 17:10:06 +00:00
6a13187e03 Corrected total size summary of cdrskin before burn start 2012-01-13 15:11:24 +00:00
ce0f35831b Removed development macro which sneaked in with previous revision 2012-01-13 15:09:47 +00:00
0e9a79e352 Corrected write count for tracks with post-gap 2012-01-13 14:27:21 +00:00
0c01912143 Corrected type and sector size for .cue generated tracks 2012-01-13 14:15:20 +00:00
66639c6e11 Flushing buffer to MMC before a new track begins 2012-01-13 12:22:07 +00:00
a0540651eb Avoided display of negative speed numbers at track change 2012-01-13 10:18:52 +00:00
34195c3037 New cdrskin options sao_pregap=, sao_postgap= 2012-01-12 19:12:10 +00:00
9623a04ce9 Interpreting .cue file command POSTGAP 2012-01-12 12:03:47 +00:00
ef7999342b New API call burn_track_set_postgap_size() 2012-01-12 08:44:34 +00:00
cb8c85579d Clarified meaning of parameter trackno with call burn_disc_track_lba_nwa() 2012-01-11 13:29:46 +00:00
ebf2fe5c28 Corrected track number of blank track reported by cdrskin -minfo 2012-01-11 13:29:13 +00:00
66eba145d3 Obtaining more accurate track sizes for CD with pre-gap 2012-01-11 12:25:06 +00:00
5cd7b09d5c Interpreting .cue file command PREGAP 2012-01-11 12:22:52 +00:00
ac7f4e90a4 Reacted on compiler warning 2012-01-11 12:20:35 +00:00
2c10b444a1 Enabled pre-gap size for tracks other than the first one 2012-01-11 11:16:18 +00:00
ea1160f077 Removed a development test contraption introduced by previous revision 2012-01-10 12:49:34 +00:00
d4c4430a40 New API call burn_track_set_pregap_size() 2012-01-10 12:20:23 +00:00
a2493b97e4 New cdrskin option cd_start_tno= 2012-01-08 19:14:42 +00:00
4d70043e78 Corrected display of track number offset with -toc and -minfo 2012-01-08 15:48:47 +00:00
c9a44d0128 While writing: Reporting track numbers with correct start number offset 2012-01-08 14:11:11 +00:00
a9b400833c New API call burn_session_get_start_tno() 2012-01-08 14:10:24 +00:00
0446226aa6 Implemented track number starts > 1 with .cue and v07t.txt files 2012-01-08 13:23:16 +00:00
18efcd6299 New API call burn_session_set_start_tno() 2012-01-07 19:09:15 +00:00
775eb175b6 Implemented data extraction from cue sheet FILE type WAVE 2012-01-06 12:59:20 +00:00
b8b6734cd1 Reacted on compiler warning about rev 4519 2012-01-05 14:09:35 +00:00
688a6fccca Updated change log and web page 2012-01-05 12:31:30 +00:00
792a5896e7 Reacted on compiler warnings about rev 4535 2012-01-05 12:02:44 +00:00
c1bd3ced61 Bug fix: Progress report with blanking and formatting could be bogus 2012-01-05 11:55:22 +00:00
dcb6f8344b Implemented option index= 2012-01-04 13:18:11 +00:00
83fa2ce51b New API calls burn_track_set_index(), burn_track_clear_indice() 2012-01-03 19:43:26 +00:00
b8eb8b35d9 Changed debug messages about CUE SHEET MSF from hex to decimal 2012-01-02 16:41:15 +00:00
c851520684 Reporting line number in case of cue sheet file problems 2012-01-02 14:37:35 +00:00
4c9783d7ae Implemented cue sheet file commands ARRANGER, COMPOSER, MESSAGE 2012-01-01 17:35:20 +00:00
8ac3ee15f1 New cdrskin options --four_channel --two_channel 2012-01-01 13:50:26 +00:00
e5742f724a Implemented options -scms -copy -nocopy -preemp -nopreemp 2012-01-01 12:55:41 +00:00
0c3fa9b341 Interpreting CDRWIN command FLAGS 2012-01-01 12:46:50 +00:00
a1f18ad44e Fixed a wrong assumption about track.mode 2012-01-01 12:44:25 +00:00
3845e1af05 Writing SCMS into mode page 5 if TAO 2012-01-01 12:43:36 +00:00
23d7867331 Corrected CTL of lead-in CUE SHEET entry 2012-01-01 12:41:24 +00:00
38aaa2f8aa New track mode modifier BURN_SCMS 2011-12-31 12:00:14 +00:00
ce29b4b38c Corrected precedence of media catalog and ISRC options 2011-12-30 17:44:19 +00:00
f1ae493c57 Coordinated option cuefile= with option input_sheet_v07t= 2011-12-30 16:47:57 +00:00
4afaaf3fb6 Reduced waiting time between retries of WRITE commands 2011-12-30 14:27:45 +00:00
8f725bab11 Improved reaction on failure of SEND CUE SHEET 2011-12-28 15:23:24 +00:00
7b5040af17 Implemented options mcn= and isrc= 2011-12-28 10:45:38 +00:00
47e5ce5da2 Transmitting CATALOG by mode page 5. ISRC too, if TAO. 2011-12-28 10:41:05 +00:00
cdaa2971db Writing CATALOG and ISRC into Q sub-channel of CD SAO sessions 2011-12-27 13:38:39 +00:00
67ae1413e3 New API call burn_track_set_isrc_string() 2011-12-27 11:56:54 +00:00
6716f7041d Updated doc/cdtext.txt 2011-12-26 09:57:02 +00:00
94c50a0145 Reacted on compiler warnings about uninitialized variables 2011-12-25 11:04:44 +00:00
74fa33bc42 Partly implemented options cuefile= and -text 2011-12-25 10:51:01 +00:00
8cdba24ff9 New API calls burn_cdtext_from_packfile() and burn_session_by_cue_file() 2011-12-25 10:39:05 +00:00
c8debb85a3 Changed libburn print threshold of cdrskin -v to severity NOTE 2011-12-22 11:21:50 +00:00
eeef039aab New options --cdtext_dummy and --cdtext_verbose 2011-12-18 16:11:47 +00:00
1cc7c7f8b2 Moved a function from cdtext.c to util.c 2011-12-16 11:13:11 +00:00
8f40e66fa4 Moved a function from cdtext.c to util.c 2011-12-16 10:53:43 +00:00
a34596d7b7 Moved burn_cdtext_from_session() from write.c to cdtext.c 2011-12-15 17:49:29 +00:00
e15e949a20 Documented new API call 2011-12-15 16:14:12 +00:00
8e8ed3e682 Moved reading of Sony Input Sheet v07 from cdrskin to libburn 2011-12-15 15:56:49 +00:00
52798b0b4a New API call burn_session_input_sheet_v07t() 2011-12-15 15:48:27 +00:00
de6d193eec Refusing to burn CD-TEXT if non-audio tracks are present 2011-12-15 10:43:07 +00:00
d774aa0b35 Included doc/cdtext.txt in libburn tarball 2011-12-15 09:15:11 +00:00
350971a34e Improved cdrskin man page and web page 2011-12-14 14:27:27 +00:00
64b90c1da6 Updated change log 2011-12-14 13:39:43 +00:00
398ee89348 New option input_sheet_v07t= 2011-12-14 13:26:06 +00:00
c3a02f8631 Changed default CD-TEXT for tracks from track number text to empty text 2011-12-14 12:49:16 +00:00
89e5450fb8 More macros for CD-TEXT genre and language names 2011-12-13 16:43:46 +00:00
e05285e246 Enabled repetition of track texts by TAB character 2011-12-12 18:14:16 +00:00
9ab0edae71 New macros for CD-TEXT genre and language names 2011-12-12 16:45:10 +00:00
8a9c6176c2 not needed since:
we would be better off building on the given OS/arch instead of playing with preprocessor directives;
all releng tests are gathered in libisoburn tree
2011-12-12 12:58:08 +00:00
620871c91d New API calls for composing CD-TEXT 2011-12-12 09:26:41 +00:00
2063dc2ca7 Pointing from man cdrskin to doc/cdtext.txt for CD-TEXT details 2011-12-12 09:13:27 +00:00
358ebaf458 Outsourced cdtext.txt from cookbook.txt 2011-12-12 08:52:40 +00:00
38387c0cb0 Some polishing in cookbook 2011-12-10 13:23:38 +00:00
f594e30f39 Updated documentation of CD-TEXT pack types 0x88 and 0x89 2011-12-10 12:38:27 +00:00
39bdf8c725 Tolerating trailing zero of Sony CDTEXT files 2011-12-09 09:22:02 +00:00
8a8a84b0f6 Updated documentation of CD-TEXT pack types 0x86, 0x8d, 0x8e 2011-12-08 19:49:45 +00:00
3b0f6b742f Updated documentation of CD-TEXT pack types 0x87 and 0x8f 2011-12-08 12:46:30 +00:00
0e5149d716 Removed version.h from list of source files because generated by configure 2011-12-07 07:50:45 +00:00
c085581224 Documented CD-TEXT pack type 0x8f 2011-12-06 14:00:32 +00:00
c84ba30220 Reacted on compiler warning about uninitialized variable in rev 4476 2011-12-06 13:47:52 +00:00
7b0a23d553 Implemented cdrskin option textfile= 2011-12-05 20:38:36 +00:00
7be652ac6b New API call burn_write_opts_set_leadin_text() 2011-12-05 20:36:31 +00:00
b385a3863e Added ./bootstrap script to release tarball 2011-12-03 12:11:59 +00:00
25d61ceba0 Removing cdrskin/.libs and test/.libs witch make clean 2011-12-03 12:11:04 +00:00
9aa23d6695 Corrected a style deviation in code of mmc.c 2011-12-03 11:33:59 +00:00
94a66f72d4 Clarified meaning of Character Position byte of burn_disc_get_leadin_text() 2011-12-02 20:45:24 +00:00
48e6a5975c Storing CD-TEXT as cdtext.dat with cdrskin option -toc -vv, reporting with -vvv 2011-12-02 17:17:28 +00:00
1d5ee82c16 New API call burn_disc_get_leadin_text() 2011-12-02 17:15:14 +00:00
56c02fa394 Bug fix: Interrupting libburn while drive tray is loading led to endless loop 2011-12-02 10:02:25 +00:00
7a5f1ab35c Improved debugging of drive feature list 2011-11-30 13:16:38 +00:00
6b7e0f134a Made SCSI timeout settable at level of SPC, SBC, MMC functions 2011-11-30 08:11:52 +00:00
417a4cc0bf Bug fix: Solaris adapter mishandled write commands which failed on first try 2011-11-26 15:32:03 +00:00
041f0e357e Reporting about failure to open existing /dev/sr or /dev/scd on Linux 2011-11-23 10:50:05 +00:00
6629d05eea Reacted on compiler warning of Debian buildd 2011-11-22 19:16:59 +00:00
8d6c28b6c5 Updated change log 2011-11-20 21:59:53 +00:00
4814e8c13a Updated cdrskin tarball generator 2011-11-20 21:57:15 +00:00
2718016de6 Made number transition to 1.1.9 2011-11-20 21:56:13 +00:00
51 changed files with 7998 additions and 707 deletions

View File

@ -1,8 +1,36 @@
SVN trunk (to become libburn-1.1.8.tar.gz or higher)
SVN trunk (to become libburn-1.2.0.tar.gz or higher)
===============================================================================
- no novelties yet
* Bug fix: cdrskin produced a memory fault if interupted before writing began
* Bug fix: Solaris adapter mishandled write commands which failed on first try
* Bug fix: Interrupting libburn while drive tray is loading led to endless loop
* Bug fix: Progress report with blanking and formatting could be bogus
* New API calls burn_disc_get_leadin_text(), burn_write_opts_set_leadin_text()
* New API calls for composing CD-TEXT, see doc/cdtext.txt
* New API call burn_session_by_cue_file() for reading CDRWIN .cue files
* New API call burn_track_set_isrc_string()
* New API calls burn_track_set_index(), burn_track_clear_indice()
* New API calls burn_session_set_start_tno(), burn_session_get_start_tno()
* New API calls burn_track_set_pregap_size(), burn_track_set_postgap_size()
* Implemented cdrskin option textfile=
* Implemented cdrskin option combination -vv -toc for cdtext.dat production
* Implemented cdrskin options mcn= and isrc=
* Implemented cdrskin options -scms -copy -nocopy -preemp -nopreemp
* Implemented cdrskin option index=
* Partly implemented cdrskin options cuefile= and -text
* New cdrskin option input_sheet_v07t= for CD-TEXT definition
* New cdrskin options --cdtext_dummy and --cdtext_verbose
* New cdrskin options --four_channel --two_channel
* New cdrskin option cd_start_tno=
* New cdrskin options sao_pregap=, sao_postgap=
libburn-1.1.8.tar.gz Mon Nov 21 2011
===============================================================================
* Bug fix: Misinterpreted mode page 2A if block descriptors are present
* Enabled recognition of QEMU DVD-ROM 0.12
* Avoiding to intermediately close and open drive device file
* New API call burn_drive_re_assess()
libburn-1.1.6.tar.gz Tue Sep 27 2011
===============================================================================
* Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover

View File

@ -21,6 +21,7 @@ libburn_libburn_la_SOURCES = \
libburn/async.c \
libburn/async.h \
libburn/back_hacks.h \
libburn/cdtext.c \
libburn/cleanup.c \
libburn/cleanup.h \
libburn/crc.c \
@ -68,8 +69,7 @@ libburn_libburn_la_SOURCES = \
libburn/util.c \
libburn/util.h \
libburn/write.c \
libburn/write.h \
version.h
libburn/write.h
## libburn/sg-@ARCH@.c \
@ -120,7 +120,7 @@ test_structest_SOURCES = test/structest.c
## cdrskin construction site - ts A60816 - B10808
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_1_7
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_2_0
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
@ -131,6 +131,11 @@ cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h
## Open questions: how to compute $timestamp and express -DX="$timestamp"
##
# "make clean" shall remove a few stubborn .libs directories
# which George Danchev reported Dec 03 2011.
# Learned from: http://www.gnu.org/software/automake/manual/automake.html#Clean
clean-local:
-rm -rf cdrskin/.libs test/.libs
## ========================================================================= ##
@ -193,12 +198,14 @@ nodist_pkgconfig_DATA = \
man_MANS = cdrskin/cdrskin.1
EXTRA_DIST = \
bootstrap \
libburn-1.pc.in \
version.h.in \
doc/comments \
doc/doxygen.conf.in \
doc/cookbook.txt \
doc/mediainfo.txt \
doc/cdtext.txt \
README \
AUTHORS \
CONTRIBUTORS \

21
README
View File

@ -6,12 +6,12 @@ This all is under GPL.
------------------------------------------------------------------------------
libburn-project.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2011 Mario Danic, Thomas Schmitt
Copyright (C) 2006-2012 Mario Danic, Thomas Schmitt
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
and Ben Jansens <xor@orodu.net>
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
http://files.libburnia-project.org/releases/libburn-1.1.6.tar.gz
http://files.libburnia-project.org/releases/libburn-1.2.0.tar.gz
------------------------------------------------------------------------------
@ -19,10 +19,10 @@ Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
From tarball
Obtain libburn-1.1.6.tar.gz, take it to a directory of your choice and do:
Obtain libburn-1.2.0.tar.gz, take it to a directory of your choice and do:
tar xzf libburn-1.1.6.tar.gz
cd libburn-1.1.6
tar xzf libburn-1.2.0.tar.gz
cd libburn-1.2.0
./configure --prefix=/usr
make
@ -661,6 +661,17 @@ Project history as far as known to me:
in several rarely used features. Processing of ACL and extattr was enabled
on FreeBSD. Workarounds try to cope with vanishing udev links on GNU/Linux.
- Mon Nov 21 2011 release libburn-1.1.8 and libisoburn-1.1.8:
libburn avoids to close and open drive device files while operating on them.
xorriso emulation mode xorrecord now has an own manual. libburn and xorriso
were prepared to operate on qemu virtio-blk-pci devices.
- Sat Jan 28 2012 release 1.2.0:
libburn has learned to read and write CD-TEXT with CD SAO audio sessions.
It can now read CDRWIN .cue files which define pure audio or pure data
sessions. libisofs and libisoburn improved timestamp handling. Several
minor bugs were fixed.
------------------------------------------------------------------------------

View File

@ -4,7 +4,7 @@
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
Integrated sub project of libburnia-project.org but also published via:
http://scdbackup.sourceforge.net/cdrskin_eng.html
http://scdbackup.sourceforge.net/cdrskin-1.1.7.tar.gz
http://scdbackup.sourceforge.net/cdrskin-1.2.0.tar.gz
Copyright (C) 2006-2011 Thomas Schmitt, provided under GPL version 2 or later.
------------------------------------------------------------------------------
@ -26,10 +26,10 @@ By using this software you agree to the disclaimer at the end of this text
Compilation, First Glimpse, Installation
Obtain cdrskin-1.1.7.tar.gz, take it to a directory of your choice and do:
Obtain cdrskin-1.2.0.tar.gz, take it to a directory of your choice and do:
tar xzf cdrskin-1.1.7.tar.gz
cd cdrskin-1.1.7
tar xzf cdrskin-1.2.0.tar.gz
cd cdrskin-1.2.0
Within that directory execute:

View File

@ -38,7 +38,7 @@ original="./libburn_svn_release.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-release"
skin_release="1.1.6"
skin_release="1.2.0"
patch_level=""
# patch_level=".pl00"
skin_rev="$skin_release""$patch_level"

View File

@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-develop"
skin_release="1.1.7"
skin_release="1.2.1"
patch_level=""
skin_rev="$skin_release""$patch_level"

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "Jul 28, 2011"
.TH CDRSKIN 1 "Jan 12, 2012"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -80,15 +80,19 @@ Emulated drives
The input-output entities which get processed are called tracks.
A \fBtrack\fP stores a stream of bytes.
.br
Each track is initiated by one track source address argument, which may either
be "-" for standard input or the address of a readable file. If no write mode
is given explicitly then one will be chosen which matches the peculiarities
of track sources and the state of the output media.
.PP
More than one track can be burned by a single run of cdrskin.
In the terms of the MMC standard all tracks written by the same run constitute
a \fBsession\fP.
.br
Normally, each track is initiated by one track source address argument,
which may either be "-" for standard input or the address of a readable file.
Alternatively, option cuefile= may be used to read a session description
from a text file and to read the session content from a single data file.
.br
If no write mode
is given explicitly then one will be chosen which matches the peculiarities
of track sources and the state of the output media.
.PP
Some media types can be kept appendable so that further tracks can
be written to them in subsequent runs of cdrskin (see option -multi).
Info about the addresses of burned tracks is kept in a table of
@ -130,8 +134,8 @@ eventual multi-session capabilities.
A more restrictive mode
.B -sao
(alias -dao) which usually demands a predictable track size and is not
necessarily capable of multi-session. It may have advantages for some
readers resp. players of the recorded tracks.
necessarily capable of multi-session. It can be used to write CD-TEXT and
it is the only one that works with option cuefile=.
.br
If none of the options -dao, -tao or -sao is given then the program will
try to choose a write mode which matches the defined recording job,
@ -494,6 +498,27 @@ Print this list of blanking types.
Retrieve some info about the addressed drive and then exit.
Exits with non-zero value if the drive cannot be found and opened.
.TP
.BI \-copy
Create the subsequent tracks with permission for an unlimited number of copies.
.TP
.BI cuefile= path
Read a session description from a cue sheet file in CDRWIN format.
Base the tracks on a single file which is given in the sheet by command FILE.
To enable CD-TEXT from the cue sheet file, cdrskin option -text has to be
present.
.br
cdrskin currently supports TRACK datatypes AUDIO and MODE1/2048 which may
not be mixed.
Data source may be of FILE type BINARY, MOTOROLA, or WAVE.
.br
Non-CDRWIN commands ARRANGER, COMPOSER, MESSAGE are supported.
.br
Cue sheet file commands CATALOG and ISRC may be overridden by option mcn=
and by input_sheet_v07t= purpose specifiers "UPC / EAN" and "ISRC".
This does not affect their appearance in CD-TEXT, but only on Q sub-channel.
.br
The track numbers may be overridden by option cd_start_tno=.
.TP
.BI \-dao
Alias for option -sao. Write CD in Session at Once mode
or DVD-R[W] in Disc-at-once mode.
@ -592,6 +617,20 @@ long running drive commands asynchronous and thus eases the load on some
wiring hardware types. Regardless of option -immed, cdrskin uses asynchronous
commands where possible and appropriate.
.TP
.BI index= list
Set a comma separated list of index start address numbers for the next track.
This applies to CD SAO sessions only.
.br
The addresses count sectors from the start of the next track. The first number
is for index 1 and must be 0. The following numbers have to be larger than
their respective predecessors. Up to 99 numbers are allowed.
.br
Sector numbers are computed from Min:Sec:Frame addresses by
.br
Sector = ((Min*60)+Sec)*75+Frame
.br
E.g.: "0,7512,20408" sets index 2 to 01:40:12 and index 3 to 04:32:08.
.TP
.BI -inq
Print the identification of the drive and then exit.
.TP
@ -611,6 +650,16 @@ This option can be performed on track sources which are regular files or block
devices. For the first track of the session it can be performed on any type
of source if there is a fifo of at least 64 kiB. See option fs= .
.TP
.BI isrc= text
Set the ISRC for the next track source to the given text, which must be exactly
13 characters long. It must comply to the format CCOOOYYSSSSS.
.br
CC is the country code. OOO is the owner code. Both may consist of capital
letters A to Z and of decimal digits 0 to 9. YY depicts the year (00 to 99).
SSSSS is the serial number (00000 to 99999).
.br
This option does not affect CD-TEXT but only the Q sub-channel.
.TP
.BI -load
Load the media and exit. Exit value is 0 if any kind of media was found, non
zero else. Note: Option -eject will unload the media even if -load is given.
@ -623,6 +672,12 @@ Use program "eject" or cdrskin -eject to get the tray out of the drive.
Runs of programs like cdrecord, growisofs, wodim, cdrskin will not be hampered
and normally enable the drive's eject button when they are done.
.TP
.BI mcn= text
Set the CD Media Catalog Number to text, which must be exactly 13 characters
long and should consist of decimal digits.
.br
This option does not affect CD-TEXT but only the Q sub-channel.
.TP
.BI minbuf= percentage
Equivalent to:
.br
@ -684,11 +739,19 @@ for lifting the ban on -multi.
.br
Note: -multi might make DVD media unreadable in some DVD-ROM drives.
.TP
.BI \-nocopy
Create subsequent tracks with permission for a single level of copies.
I.e. those copies would then be marked by -scms as offering no permission
for further copies.
.TP
.BI \-nopad
Do not add trailing zeros to the data stream. Nevertheless, since there seems
to be no use for audio tracks with incomplete last sector, this option applies
only to data tracks. There it is default.
.TP
.BI \-nopreemp
Indicate for subsequent tracks that they were mastered without pre-emphasis.
.TP
.BI \-pad
Add 30 kiB of trailing zeros to each data track. (This is not sufficient to
avoid problems with various CD-ROM read drivers.)
@ -698,6 +761,9 @@ Add the given amount of trailing zeros to the next data track. This option
gets reset to padsize=0 after that next track is written. It may be set
again before the next track argument. About size specifiers, see option fs=.
.TP
.BI \-preemp
Indicate for subsequent tracks that they were mastered with pre-emphasis.
.TP
.BI \-sao
Write CD in Session At Once mode or sequential DVD-R[W] in Disc-at-once
(DAO) mode.
@ -730,6 +796,14 @@ The useful fields in a result line are:
.br
Bus,Target,Lun Number) 'Vendor' 'Mode' 'Revision'
.TP
.BI \-scms
Create subsequent tracks without permission for being copied. This is usually
done for tracks which are copies of tracks that were marked with -nocopy
(but not yet with -scms). So copies of copies are prohibited.
.br
This option gets reset by option -copy. Thus the combination -copy -nocopy
means -nocopy surely without -scms.
.TP
.BI speed= number
Set speed of drive. With data CD, 1x speed corresponds to a throughput of
150,000 bytes/second. With DVD, 1x = 1,385,000 bytes/second.
@ -760,12 +834,57 @@ the only mode which allows -multi.
.br
Mode -tao is not usable for minimally blanked DVD-RW and for DVD-R DL.
.TP
.BI \-text
Enable writing of CD-TEXT attributes read by option cuefile=.
Without option -text, cue sheet file command CDTEXTFILE will be ignored and
no CD-TEXT attributes will be read from the file. Nevertheless, CATALOG and
ISRC will have the same effect as options mcn= and isrc=.
.TP
.BI textfile= path
Read CD-TEXT packs from the file depicted by path and put them into the
Lead-in of the emerging session. This session has to be done by Session At Once
(SAO) mode and may only contain audio tracks.
.br
path must lead to a regular file, which consists of an optional header of four
bytes and one or more text packs of 18 bytes each. Suitable would be the
file 'cdtext.dat' which gets extracted from CD media by options -vv -toc
and shown in human readable form by -vvv -toc.
.br
The header, if present, must tell the file size minus 2, encoded as big-endian
16 bit word. The other two bytes must be 0.
.br
If there is no 4-byte header, then a trailing 0-byte, as of Sony specification,
is tolerated and ignored.
.br
A text pack consists of a pack type byte, a track number byte, a counter byte,
a Block Number and Character Indicator byte, 12 text characters or data bytes,
two optional CRC bytes. For details see libburn documentation file
doc/cdtext.txt.
.br
By default, the input file is checked for correct CRC bytes. If all CRC bytes
are 0, then the correct values get silently inserted. If there are non-zero
CRC bytes, then a mismatch causes the abort of the burn run.
This check can be disabled by option -force.
.br
Note that this option overrides option input_sheet_v07t= .
.TP
.BI \-toc
Print the table of content (TOC) which describes the tracks recorded on disc.
The output contains all info from option -atip plus lines which begin with
"track:", the track number, the word "lba:" and a number which gives the
start address of the track. Addresses are counted in CD sectors which with
SAO or TAO data tracks hold 2048 bytes each.
.br
If verbosity is set to level 2 (-v -v) then the CD-TEXT packs from the lead-in
of an audio CD get extracted and written into file 'cdtext.dat', if that file
does not yet exist. Prepended is a 4 byte header, followed by one or more
packs of 18 bytes each.
.br
Verbosity level 3 causes the CD-TEXT packs to be printed as hex numbers to
standard output. Bytes 4 to 15 of certain pack types are printed as ASCII
characters if they have values in the range of 32 to 126.
.br
See option textfile= for more information about the text pack format.
.RS
.TP
Example. Retrieve an afio archive from track number 2:
@ -798,7 +917,7 @@ then the track on media gets truncated to the predicted size and cdrskin exits
with non-zero value.
.TP
.BI \-v
Increment verbose level by one. Startlevel is 0 with only few messages.
Increment verbosity level by one. Startlevel is 0 with only few messages.
Level 1 prints progress report with long running operations and also causes
some extra lines to be put out with info retrieval options.
Level 2 additionally reports about option settings derived from arguments or
@ -865,6 +984,16 @@ taken as plain block number with block size 2048 byte.
(E.g ...=1000 or ...=1000s means block 1000, ...=1m means block
512, ...=4096b means block number 2)
.TP
.BI cd_start_tno= number
Set the number which shall be written as CD track number with the first
track of the session. The following tracks will then get written with
consecutive CD track numbers. The resulting number of the last track
must not exceed 99. The lowest possible start number is 1, which is also
the default.
.br
This setting applies only to CD SAO writing. It overrides the track number
settings caused by options cuefile= or input_sheet_v07t=.
.TP
.BI \--demand_a_drive
Exit with a nonzero value if no drive can be found during a bus scan.
.TP
@ -953,6 +1082,9 @@ implies fallback_program=cdrecord
.br
.B codim
implies fallback_program=wodim
.TP
.BI --four_channel
Indicate for subsequent tracks that they were mastered with four channels.
.TP
.BI fifo_start_at= size
Do not wait for full fifo but start burning as soon as the given number
@ -1004,6 +1136,97 @@ With multi-session DVD, blank=fast will act like dvd+rw-format -blank=full .
.br
growisofs -dvd-compat is roughly equivalent to cdrskin without option -multi.
.TP
.BI input_sheet_v07t= path
Read CD-TEXT definitions from a Sony Input Sheet version 0.7T. Up to eight
or seven such sheets can be read by multiple input_sheet_v07t= options.
Each will define a CD-TEXT language block.
.br
The information in such a sheet is given by text lines of the following form:
.br
purpose specifier [whitespace] = [whitespace] content text
.br
[whitespace] is zero or more ASCII 32 (space) or ASCII 9 (tab) characters.
The purpose specifier tells the meaning of the content text.
Empty content text does not cause a CD-TEXT attribute to be attached.
.br
The following purpose specifiers apply to the session as a whole:
.br
Purpose specifier | Content example
.br
-------------------------------------------------------------
.br
Text Code = 8859
.br
Language Code = English
.br
Album Title = Joyful Nights
.br
Artist Name = United Cat Orchestra
.br
Songwriter = Various Songwriters
.br
Composer = Various Composers
.br
Arranger = Tom Cat
.br
Album Message = For all our fans
.br
Catalog Number = 1234567890
.br
Genre Code = Classical
.br
Genre Information = Feline classic music
.br
Closed Information = This is not to be shown by CD players
.br
UPC / EAN = 1234567890123
.br
Text Data Copy Protection = OFF
.br
First Track Number = 1
.br
Last Track Number = 3
.br
The following purpose specifiers apply to particular tracks:
.br
Purpose specifier | Content example
.br
-------------------------------------------------------------
.br
Track 01 Title = Song of Joy
.br
Track 01 Artist = Felix and The Purrs
.br
Track 01 Songwriter = Friedrich Schiller
.br
Track 01 Composer = Ludwig van Beethoven
.br
Track 01 Arranger = Tom Cat
.br
Track 01 Message = Fritz and Louie once were punks
.br
ISRC 01 = XYCRR1101234
.br
Track numbers are decimal despite the leading 0. There should be as many track
definitions as there are track source files given.
.br
See libburn's doc/cdtext.txt for a detailed definition of 0.7T and the
possible values for Text Code, Language Code, Genre Code, Text Data Copy
Protection.
.br
The Q sub-channel settings by "UPC / EAN" and "ISRC" may be overridden by
options mcn= and isrc=. This will not affect their appearance as CD-TEXT.
They may override cuefile= commands CATALOG and ISRC in the same way.
.br
If options -text cuefile= are given and if the cue sheet file defines CD-TEXT,
then only seven input_sheet_v07t= options may be given. They will then be
used as CD-TEXT language blocks 1 to 7.
.br
This option will get into effect only if no option textfile= is given.
The write mode must be SAO on CD. All tracks must be -audio tracks.
.br
The track numbers may be overridden by option cd_start_tno=.
.TP
.BI \--list_formats
List the available format descriptors as reported by the drive for the
loaded media. Each descriptor line begins with "Format idx" and the
@ -1089,6 +1312,9 @@ is possible with the given options.
This option redirects to stderr all message output except its own result
string and eventual output of -msinfo.
.TP
.BI --two_channel
Indicate for subsequent tracks that they were mastered with two channels.
.TP
.BI write_start_address= byte_offset
Set the address on media where to start writing the track. With DVD+RW, DVD-RAM
or BD-RE byte_offset must be aligned to 2 kiB blocks, but better is 32 kiB.
@ -1113,6 +1339,20 @@ under test reservation.
(If you really test experimental media, then please report the outcome on
libburn-hackers@pykix.org)
.TP
.BI \--cdtext_dummy
Prepare a burn run, report the effective array of CD-TEXT packs to stdout,
and then end the program run without starting to burn the session.
A blank CD-R or CD-RW has to be present in the drive, nevertheless.
.br
The output is formatted in lines which describe 18 bytes as 2-digit hex
numbers or as single printable characters.
See libburn document doc/cdtext.txt about the format of these records.
.TP
.BI \--cdtext_verbose
Like --cdtext_dummy but without preventing the burn run. Combinable with
option -dummy to exercise a CD burn run with no persistent impact on the
medium.
.TP
.BI dev_translation= <sep><from><sep><to>
Set drive address alias. This was necessary before cdrskin-0.2.4 to manually
translate cdrecord addresses into cdrskin addresses.
@ -1242,6 +1482,26 @@ Linux specific:
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
pseudo ATA addresses. This method is outdated and was never compatible with
original cdrecord.
.TP
.BI sao_postgap= off|number
Define whether a post-gap shall be written at the end of the track and
how many sectors this gap shall have. A post-gap occupies the range of
an additional index of the track. It contains zeros. No bytes from the
track source will be read for writing the post-gap.
.br
This setting affects only CD SAO write runs.
.TP
.BI sao_pregap= off|number
Define whether a pre-gap shall be written before the track and how many
sectors this pre-gap shall have. A pre-gap is written in the range of track
index 0 and contains zeros resp. silence. No bytes from the track source
will be read for writing the pre-gap.
.br
This setting affects only CD SAO write runs.
.br
The first track automatically gets a pre-gap of at least 150 sectors. Its
size can only be enlarged by this call.
.TP
.BI --xa1-ignore
Silently interpret option -xa1 as -data. This may be necessary if a frontent
does not prepare -xa1 block headers but insists in using option -xa1.

File diff suppressed because it is too large Load Diff

View File

@ -65,7 +65,7 @@ connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
GPL software included:<BR>
</H2>
<DL>
<DT>libburn-1.1.6</DT>
<DT>libburn-1.2.0</DT>
<DD>(founded by Derek Foreman and Ben Jansens,
developed and maintained since August 2006 by
Thomas Schmitt from team of libburnia-project.org)
@ -200,13 +200,13 @@ Standalone ISO 9660 multi-session CD/DVD/BD tool
<P>
<DL>
<DT>Download as source code (see README):</DT>
<DD><A HREF="cdrskin-1.1.6.tar.gz">cdrskin-1.1.6.tar.gz</A>
(870 KB).
<DD><A HREF="cdrskin-1.2.0.tar.gz">cdrskin-1.2.0.tar.gz</A>
(930 KB).
</DD>
<DD><A HREF="cdrskin-1.1.6.tar.gz.sig">cdrskin-1.1.6.tar.gz.sig</A></DD>
<DD><A HREF="cdrskin-1.2.0.tar.gz.sig">cdrskin-1.2.0.tar.gz.sig</A></DD>
<DD>
(detached GPG signature for verification by
<KBD>gpg --verify cdrskin-1.1.6.tar.gz.sig cdrskin-1.1.6.tar.gz</KBD>
<KBD>gpg --verify cdrskin-1.2.0.tar.gz.sig cdrskin-1.2.0.tar.gz</KBD>
<BR>
after <KBD>gpg --keyserver keys.gnupg.net --recv-keys ABC0A854</KBD>).
</DD>
@ -257,21 +257,31 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
<HR>
<P>
Enhancements towards previous stable version cdrskin-1.1.4:
Enhancements towards previous stable version cdrskin-1.1.8:
<UL>
<LI>
Worked around a collision with Linux udev which lets links vanish
<LI>Implemented option textfile=</LI>
<LI>Implemented option combination -vv -toc for cdtext.dat production
<LI>Implemented options mcn= and isrc=</LI>
<LI>Implemented options -scms -copy -nocopy -preemp -nopreemp</LI>
<LI>Implemented option index=</LI>
<LI>Partly implemented options cuefile= and -text</LI>
<LI>New option input_sheet_v07t= for CD-TEXT definition</LI>
<LI>New options --cdtext_dummy and --cdtext_verbose</LI>
<LI>New options --four_channel --two_channel</LI>
<LI>New option cd_start_tno=</LI>
<LI>New options sao_pregap=, sao_postgap=</LI>
</LI>
<!--
<LI>none</LI>
-->
</UL>
Bug fixes towards cdrskin-1.1.4:
Bug fixes towards cdrskin-1.1.8:
<UL>
<LI>
stdio sizes > 4 TB - 32 kB caused integer rollover
</LI>
<LI>Memory fault if interupted before writing began</LI>
<LI>Solaris adapter mishandled write commands which failed on first try</LI>
<LI>Interrupting libburn while drive tray is loading led to endless loop</LI>
<LI>Progress report with blanking and formatting could be bogus</LI>
<!--
<LI>none</LI>
-->
@ -281,8 +291,8 @@ stdio sizes > 4 TB - 32 kB caused integer rollover
<P>
<DL>
<DT><H3>Development snapshot, version 1.1.7 :</H3></DT>
<DD>Enhancements towards current stable version 1.1.6:
<DT><H3>Development snapshot, version 1.2.1 :</H3></DT>
<DD>Enhancements towards current stable version 1.2.0:
<UL>
<LI>none yet</LI>
<!--
@ -292,20 +302,19 @@ stdio sizes > 4 TB - 32 kB caused integer rollover
</UL>
</DD>
<DD>Bug fixes towards cdrskin-1.1.6:
<DD>Bug fixes towards cdrskin-1.2.0:
<UL>
<LI>none yet</LI>
<!--
<LI>none yet</LI>
-->
</UL>
</DD>
<DD>&nbsp;</DD>
<DD><A HREF="README_cdrskin_devel">README 1.1.7</A>
<DD><A HREF="cdrskin__help_devel">cdrskin-1.1.7 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin-1.1.7 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.1.7)</A></DD>
<DD><A HREF="README_cdrskin_devel">README 1.2.1</A>
<DD><A HREF="cdrskin__help_devel">cdrskin-1.2.1 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin-1.2.1 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.2.1)</A></DD>
<DD>&nbsp;</DD>
<DT>Maintainers of cdrskin unstable packages please use SVN of
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
@ -325,8 +334,8 @@ admins with full system souvereignty.</DT>
<A HREF="README_cdrskin_devel">upcoming README</A> ):
</DD>
<DD>
<A HREF="cdrskin-1.1.7.tar.gz">cdrskin-1.1.7.tar.gz</A>
(870 KB).
<A HREF="cdrskin-1.2.1.tar.gz">cdrskin-1.2.1.tar.gz</A>
(930 KB).
</DD>
<!-- This is not offered any more since spring 2008

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2011.11.18.155410"
#define Cdrskin_timestamP "2012.01.27.103001"

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
#!/bin/sh
# compile_cdrskin.sh
# Copyright 2005 - 2011 Thomas Schmitt, scdbackup@gmx.net, GPL
# Copyright 2005 - 2012 Thomas Schmitt, scdbackup@gmx.net, GPL
# to be executed within ./libburn-* resp ./cdrskin-*
debug_opts="-O2"
def_opts=
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
fifo_opts=""
libvers="-DCdrskin_libburn_1_1_7"
libvers="-DCdrskin_libburn_1_2_0"
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
# burn="libburn/libburn_libburn_la-"
@ -41,15 +41,15 @@ do
elif test "$i" = "-compile_dewav"
then
compile_dewav=1
elif test "$i" = "-libburn_1_1_6"
elif test "$i" = "-libburn_1_2_0"
then
libvers="-DCdrskin_libburn_1_1_6"
libvers="-DCdrskin_libburn_1_2_0"
libdax_audioxtr_o="$burn"libdax_audioxtr.o
libdax_msgs_o="$burn"libdax_msgs.o
cleanup_src_or_obj="$burn"cleanup.o
elif test "$i" = "-libburn_svn"
then
libvers="-DCdrskin_libburn_1_1_7"
libvers="-DCdrskin_libburn_1_2_1"
libdax_audioxtr_o="$burn"libdax_audioxtr.o
libdax_msgs_o="$burn"libdax_msgs.o
cleanup_src_or_obj="$burn"cleanup.o
@ -99,7 +99,7 @@ do
echo "Options:"
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
echo " -compile_dewav compile program test/dewav without libburn."
echo " -libburn_1_1_6 set macro to match libburn-1.1.6"
echo " -libburn_1_2_0 set macro to match libburn-1.2.0"
echo " -libburn_svn set macro to match current libburn-SVN."
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
echo " -use_libcdio link with -lcdio because libburn uses it."
@ -145,6 +145,7 @@ then
$cleanup_src_or_obj \
\
"$burn"async.o \
"$burn"cdtext.o \
"$burn"debug.o \
"$burn"drive.o \
"$burn"file.o \

View File

@ -19,7 +19,7 @@ Many bytes have been copied from the message output of cdrecord
runs, though. The most comprehensive technical overview of cdrskin
can be found in [http://libburnia-project.org/browser/libburn/trunk/cdrskin/README?format=txt cdrskin/README].
About libburn API for burning CD and DVD: http://api.libburnia-project.org
About libburn API for burning CD, DVD, and BD: http://api.libburnia-project.org
--------------------------------------------------------------------------
@ -279,23 +279,7 @@ for an illustrated example with K3b 0.10 .
--------------------------------------------------------------------------
DVD advise:
For burning of DVD/BD media other than DVD-RAM, DVD+RW, DVD+R, DVD+R DL,
DVD-RW, DVD-R, BD-RE, the cdrskin project currently advises to use
Andy Polyakov's dvd+rw-tools which despite their historic name are
capable of all the media above and more, including BD discs.
http://fy.chalmers.se/~appro/linux/DVD+RW/tools
They are not compatible or related to cdrecord resp. cdrecord-ProDVD
(now obsoleted by original source cdrtools cdrecord with identical
capabilities besides the license key).
--------------------------------------------------------------------------
Advanced multi-session use cases:
Advanced multi-session use cases as of dvd+rw-tools:
A special feature of dvd+rw-tools is growing of ISO-9660 filesystems on
overwriteable media. This is not the same as multi-session writing of cdrskin

View File

@ -1,4 +1,4 @@
AC_INIT([libburn], [1.1.7], [http://libburnia-project.org])
AC_INIT([libburn], [1.2.0], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -10,7 +10,7 @@ LIBBURNIA_SET_FLAGS
AM_INIT_AUTOMAKE([subdir-objects])
AC_CONFIG_MACRO_DIR([./])
dnl Notes by ts A71207 - B10409 :
dnl Notes about version numbers and .so numbers:
dnl
dnl Regrettably the meaning of the various version types was misunderstood
dnl before version 0.4.1.
@ -94,6 +94,8 @@ dnl 1.0.6 = libburn.so.4.63.0
dnl 1.1.0 = libburn.so.4.65.0
dnl 1.1.4 = libburn.so.4.67.0
dnl 1.1.6 = libburn.so.4.69.0
dnl 1.1.8 = libburn.so.4.71.0
dnl 1.2.0 = libburn.so.4.73.0
dnl
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
@ -118,8 +120,8 @@ dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
BURN_MAJOR_VERSION=1
BURN_MINOR_VERSION=1
BURN_MICRO_VERSION=7
BURN_MINOR_VERSION=2
BURN_MICRO_VERSION=0
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
AC_SUBST(BURN_MAJOR_VERSION)
@ -130,14 +132,14 @@ AC_SUBST(BURN_VERSION)
dnl Libtool versioning
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
dnl
dnl ### This is the release version libburn-1.1.6
dnl This is the development version after above release version
dnl This is the release version libburn-1.2.0
dnl ### This is the development version after above release version
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
dnl
dnl SONAME = 73 - 69 = 4 . Linux library name = libburn.so.4.69.0
LT_CURRENT=73
LT_AGE=69
dnl SONAME = 77 - 73 = 4 . Linux library name = libburn.so.4.73.0
LT_CURRENT=77
LT_AGE=73
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`

700
doc/cdtext.txt Normal file
View File

@ -0,0 +1,700 @@
Description of CD-TEXT
Guided by Leon Merten Lohse via libcdio-devel@gnu.org
by reading mmc3r10g.pdf from http://www.t10.org/ftp/t10/drafts/mmc3/
by docs and results of cdtext.zip from http://www.sonydadc.com/file/
by reading http://digitalx.org/cue-sheet/syntax
by reading source of libcdio from http://www.gnu.org/s/libcdio
which quotes source of cdrecord from ftp://ftp.berlios.de/pub/cdrecord/alpha
by reading cdrecord.1 from ftp://ftp.berlios.de/pub/cdrecord/alpha
Language codes were learned from http://tech.ebu.ch/docs/tech/tech3264.pdf
Genre codes were learned from libcdio and confirmed by
http://helpdesk.audiofile-engineering.com/index.php?pg=kb.page&id=123
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
Content:
- CD-TEXT from the view of the user
- Content specifications of particular pack types
- Format of a CD-TEXT packs array
- Overview of libburn API calls for CD-TEXT
- Sony Text File Format (Input Sheet Version 0.7T)
- CDRWIN cue sheet files
-------------------------------------------------------------------------------
CD-TEXT from the view of the user:
CD-TEXT records attributes of disc and tracks on audio CD.
The attributes are grouped into blocks which represent particular languages.
Up to 8 blocks are possible.
There are 13 defined attribute categories, which are called Pack Types and are
identified by a single-byte code:
0x80 = Title
0x81 = Names of Performers
0x82 = Names of Songwriters
0x83 = Names of Composers
0x84 = Names of Arrangers
0x85 = Messages
0x86 = text-and-binary: Disc Identification
0x87 = text-and-binary: Genre Identification
0x88 = binary: Table of Content information
0x89 = binary: Second Table of Content information
(0x8a to 0x8c are reserved.)
0x8d = Closed Information
0x8e = UPC/EAN code of the album and ISRC code of each track
0x8f = binary: Size Information of the Block
Some of these categories apply to the whole disc only:
0x86, 0x87, 0x88, 0x89, 0x8d
Some have to be additionally attributed to each track, if they are present for
the whole disc:
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x8e
One describes the overall content of a block and in part of all other blocks:
0x8f
The total size of a block's attribute set is restricted by the fact that it
has to be stored in at most 253 records with 12 bytes of payload. These records
are called Text Packs.
A shortcut for repeated identical track texts is provided, so that a text
that is identical to the one of the previous track occupies only 2 or 4 bytes.
-------------------------------------------------------------------------------
Content specification of particular pack types:
Pack types 0x80 to 0x85 and 0x8e contain 0-terminated cleartext. If double byte
characters are used, then two 0-bytes terminate the cleartext.
The meaning of 0x80 to 0x85 should be clear by above list. They are encoded
according to the Character Code of their block. Either as ISO-8859-1 single
byte characters, or as 7-bit ASCII single byte characters, or as MS-JIS double
byte characters.
More info to 0x8e is given below.
Pack type 0x86 (Disc Identification) is documented by Sony as "Catalog Number:
(use ASCII Code) Catalog Number of the album". So it is not really binary
but might be non-printable, and should contain only bytes with bit7 = 0.
Pack type 0x87 contains 2 binary bytes, followed by 0-terminated cleartext.
The two binary bytes form a big-endian index to the following list.
0x0000 = "Not Used" (Sony prescribes to use this if no genre applies)
0x0001 = "Not Defined"
0x0002 = "Adult Contemporary"
0x0003 = "Alternative Rock"
0x0004 = "Childrens Music"
0x0005 = "Classical"
0x0006 = "Contemporary Christian"
0x0007 = "Country"
0x0008 = "Dance"
0x0009 = "Easy Listening"
0x000a = "Erotic"
0x000b = "Folk"
0x000c = "Gospel"
0x000d = "Hip Hop"
0x000e = "Jazz"
0x000f = "Latin"
0x0010 = "Musical"
0x0011 = "New Age"
0x0012 = "Opera"
0x0013 = "Operetta"
0x0014 = "Pop Music"
0x0015 = "Rap"
0x0016 = "Reggae"
0x0017 = "Rock Music"
0x0018 = "Rhythm & Blues"
0x0019 = "Sound Effects"
0x001a = "Spoken Word"
0x001b = "World Music"
Sony documents the cleartext part as "Genre information that would supplement
the Genre Code, such as 'USA Rock music in the 60s'". Always ASCII encoded.
Pack type 0x88 records information from the CD's Table of Content, as of
READ PMA/TOC/ATIP Format 0010b (mmc5r03c.pdf, table 490 TOC Track Descriptor
Format, Q Sub-channel).
See below, Format of CD-TEXT packs, for more details about the content of
pack type 0x88.
Pack type 0x89 is yet quite unclear. It might be a representation of Playback
Skip Interval, Mode-5 Q sub-channel, POINT 01 to 40 (mmc5r03.pdf 4.2.3.7.4).
If so, then this seems not to apply to write type SAO, because the CUE SHEET
format offers no way to express Mode-5 Q.
See below, Format of CD-TEXT packs, for an example of this pack type.
Pack type 0x8d is documented by Sony as "Closed Information: (use 8859-1 Code)
Any information can be recorded on disc as memorandum. Information in this
field will not be read by CD TEXT players available to the public."
Always ISO-8859-1 encoded.
Pack type 0x8e is documented by Sony as "UPC/EAN Code (POS Code) of the album.
This field typically consists of 13 characters." Always ASCII encoded.
It applies to tracks as "ISRC code [which] typically consists of 12 characters"
and is always ISO-8859-1 encoded.
MMC calls these information entities Media Catalog Number and ISRC.
The catalog number consists of 13 decimal digits.
ISRC consists of 12 characters: 2 country code [0-9A-Z], 3 owner code [0-9A-Z],
2 year digits (00 to 99), 5 serial number digits (00000 to 99999).
Pack type 0x8f summarizes the whole list of text packs of a block.
See below, Format of CD-TEXT packs, for details.
-------------------------------------------------------------------------------
Format of a CD-TEXT packs array:
The attributes are represented on CD as Text Packs in the sub-channel of
the Lead-in of the disc. See doc/cookbook.txt for a description how to write
the readily formatted CD-TEXT pack array to CD, and how to read CD-TEXT packs
from CD.
The format is explained in part in MMC-3 (mmc3r10g.pdf, Annex J) and in part by
the documentation in Sony's cdtext.zip :
Each pack consists of a 4-byte header, 12 bytes of payload, and 2 bytes of CRC.
The first byte of each pack tells the pack type. See above for a list of types.
The second byte tells the track number to which the first text piece in
a pack is associated. Number 0 means the whole album. Higher numbers are
valid for types 0x80 to 0x85, and 0x8e. With these types, there should be
one text for the disc and one for each track.
With types 0x88 and 0x89, the second byte bears a track number, too.
With type 0x8f, the second byte counts the record parts from 0 to 2.
The third byte is a sequential counter.
The fourth byte is the Block Number and Character Position Indicator.
It consists of three bit fields:
bit7 = Double Bytes Character Code (0= single byte characters)
bit4-6 = Block Number (groups text packs in language blocks)
bit0-3 = Character position. Either the number of characters which
the current text inherited from the previous pack, or
15 if the current text started before the previous pack.
The 12 payload bytes contain pieces of 0-terminated texts or binary data.
A text may span over several packs. Unused characters in a pack are used for
the next text of the same pack type. If no text of the same type follows,
then the remaining text bytes are set to 0.
The CRC algorithm uses divisor 0x11021. The resulting 16-bit residue of the
polynomial division gets exored with 0xffff and written as big-endian
number to bytes 16 and 17 of the pack.
The text packs are grouped in up to 8 blocks of at most 256 packs. Each block
is in charge for one language. Sequence numbers of each block are counted
separately. All packs of block 0 come before the packs of block 1.
The limitation of block number and sequence numbers imply that there are at
most 2048 text packs possible. (READ TOC/PMS/ATIP could retrieve 3640 packs,
as it is limited to 64 kB - 2.)
If a text of a track (pack types 0x80 to 0x85 and 0x8e) repeats identically
for the next track, then it may be represented by a TAB character (ASCII 9)
for single byte texts, resp. two TAB characters for double byte texts.
(This should be used because 256 * 12 bytes is few space for 99 tracks.)
The two binary bytes of pack type 0x87 are written to the first 0x87 pack of
a block. They may or may not be repeated at the start of the follow-up packs
of type 0x87.
The first pack of type 0x88 in a block records in its payload bytes:
0 : PMIN of POINT A1 = First Track Number
1 : PMIN of POINT A2 = Last Track Number
2 : unknown, 0 in Sony example
3 : PMIN of POINT A2 = Start position of Lead-Out
4 : PSEC of POINT A2 = Start position of Lead-Out
5 : PFRAME of POINT A2 = Start position of Lead-Out
6 to 11 : unknown, 0 in Sony example
The following packs record PMIN, PSEC, PFRAME of the POINTs between the
lowest track number (min 01h) and the highest track number (max 63h).
The payload of the last pack is padded by 0s.
The Sony .TOC example:
A0 01
A1 14
A2 63:02:18
01 00:02:00
02 04:11:25
03 08:02:50
04 11:47:62
...
13 53:24:25
14 57:03:25
yields
88 00 23 00 01 0e 00 3f 02 12 00 00 00 00 00 00 12 00
88 01 24 00 00 02 00 04 0b 19 08 02 32 0b 2f 3e 67 2d
...
88 0d 27 00 35 18 19 39 03 19 00 00 00 00 00 00 ea af
Pack type 0x89 is yet quite unclear. Especially what the information shall
mean to the user of the CD. The time points in the Sony example are in the
time range of the tracks numbers that are given before the time points:
01 02:41:48 01 02:52:58
06 23:14:25 06 23:29:60
07 28:30:39 07 28:42:30
13 55:13:26 13 55:31:50
yields
89 01 28 00 01 04 00 00 00 00 02 29 30 02 34 3a f3 0c
89 06 29 00 02 04 00 00 00 00 17 0e 19 17 1d 3c 73 92
89 07 2a 00 03 04 00 00 00 00 1c 1e 27 1c 2a 1e 72 20
89 0d 2b 00 04 04 00 00 00 00 37 0d 1a 37 1f 32 0b 62
The track numbers are stored in the track number byte of the packs. The two
time points are stored in byte 6 to 11 of the payload. Byte 0 of the payload
seems to be a sequential counter. Byte 1 always 4 ? Byte 2 to 5 always 0 ?
Pack type 0x8f summarizes the whole list of text packs of a block.
So there is one group of three 0x8f packs per block.
Nevertheless each 0x8f group tells the highest sequence number and the
language code of all blocks.
The payload bytes of three 0x8f packs form a 36 byte record. The track number
bytes of the three packs have the values 0, 1, 2.
Byte :
0 : Character code for pack types 0x80 to 0x85:
0x00 = ISO-8859-1
0x01 = 7 bit ASCII
0x80 = MS-JIS (japanese Kanji, double byte characters)
1 : Number of first track
2 : Number of last track
3 : libcdio source states: "cd-text information copyright byte"
Probably 3 means "copyrighted", 0 means "not copyrighted".
4 - 19 : Pack count of the various types 0x80 to 0x8f.
Byte number N tells the count of packs of type 0x80 + (N - 4).
I.e. the first byte in this field of 16 counts packs of type 0x80.
20 - 27 : Highest sequence byte number of blocks 0 to 7.
28 - 36 : Language code for blocks 0 to 7 (tech3264.pdf appendix 3)
Not all of these Codes have ever been seen with CD-TEXT, though.
0x00 = Unknown
0x01 = Albanian
0x02 = Breton
0x03 = Catalan
0x04 = Croatian
0x05 = Welsh
0x06 = Czech
0x07 = Danish
0x08 = German
0x09 = English
0x0a = Spanish
0x0b = Esperanto
0x0c = Estonian
0x0d = Basque
0x0e = Faroese
0x0f = French
0x10 = Frisian
0x11 = Irish
0x12 = Gaelic
0x13 = Galician
0x14 = Icelandic
0x15 = Italian
0x16 = Lappish
0x17 = Latin
0x18 = Latvian
0x19 = Luxembourgian
0x1a = Lithuanian
0x1b = Hungarian
0x1c = Maltese
0x1d = Dutch
0x1e = Norwegian
0x1f = Occitan
0x20 = Polish
0x21 = Portuguese
0x22 = Romanian
0x23 = Romansh
0x24 = Serbian
0x25 = Slovak
0x26 = Slovenian
0x27 = Finnish
0x28 = Swedish
0x29 = Turkish
0x2a = Flemish
0x2b = Wallon
0x45 = Zulu
0x46 = Vietnamese
0x47 = Uzbek
0x48 = Urdu
0x49 = Ukrainian
0x4a = Thai
0x4b = Telugu
0x4c = Tatar
0x4d = Tamil
0x4e = Tadzhik
0x4f = Swahili
0x50 = Sranan Tongo
0x51 = Somali
0x52 = Sinhalese
0x53 = Shona
0x54 = Serbo-croat
0x55 = Ruthenian
0x56 = Russian
0x57 = Quechua
0x58 = Pushtu
0x59 = Punjabi
0x5a = Persian
0x5b = Papamiento
0x5c = Oriya
0x5d = Nepali
0x5e = Ndebele
0x5f = Marathi
0x60 = Moldavian
0x61 = Malaysian
0x62 = Malagasay
0x63 = Macedonian
0x64 = Laotian
0x65 = Korean
0x66 = Khmer
0x67 = Kazakh
0x68 = Kannada
0x69 = Japanese
0x6a = Indonesian
0x6b = Hindi
0x6c = Hebrew
0x6d = Hausa
0x6e = Gurani
0x6f = Gujurati
0x70 = Greek
0x71 = Georgian
0x72 = Fulani
0x73 = Dari
0x74 = Churash
0x75 = Chinese
0x76 = Burmese
0x77 = Bulgarian
0x78 = Bengali
0x79 = Bielorussian
0x7a = Bambora
0x7b = Azerbaijani
0x7c = Assamese
0x7d = Armenian
0x7e = Arabic
0x7f = Amharic
E.g. these three packs
42 : 8f 00 2a 00 01 01 03 00 06 05 04 05 07 06 01 02 48 65
43 : 8f 01 2b 00 00 00 00 00 00 00 06 03 2c 00 00 00 c0 20
44 : 8f 02 2c 00 00 00 00 00 09 00 00 00 00 00 00 00 11 45
decode to
Byte :Value Meaning
0 : 01 = ASCII 7-bit
1 : 01 = first track is 1
2 : 03 = last track is 3
3 : 00 = copyright (0 = public domain, 3 = copyrighted ?)
4 : 06 = 6 packs of type 0x80
5 : 05 = 5 packs of type 0x81
6 : 04 = 4 packs of type 0x82
7 : 05 = 5 packs of type 0x83
8 : 07 = 7 packs of type 0x84
9 : 06 = 6 packs of type 0x85
10 : 01 = 1 pack of type 0x86
11 : 02 = 2 packs of type 0x87
12 : 00 = 0 packs of type 0x88
13 : 00 = 0 packs of type 0x89
14 : 00 00 00 00 = 0 packs of types 0x8a to 0x8d
18 : 06 = 6 packs of type 0x8e
19 : 03 = 3 packs of type 0x8f
20 : 2c = last sequence for block 0
This matches the sequence number of the last text pack (0x2c = 44)
21 : 00 00 00 00 00 00 00 = last sequence numbers for block 1..7 (none)
28 : 09 = language code for block 0: English
29 : 00 00 00 00 00 00 00 = language codes for block 1..7 (none)
-------------------------------------------------------------------------------
libburn API calls for CD-TEXT (see libburn/libburn.h for details):
libburn can retrieve the set of text packs from a CD:
int burn_disc_get_leadin_text(struct burn_drive *d,
unsigned char **text_packs, int *num_packs,
int flag);
It can write a text pack set with a CD SAO session.
This set may be attached as array of readily formatted text packs by:
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
unsigned char *text_packs,
int num_packs, int flag);
The array may be read from a file by
int burn_cdtext_from_packfile(char *path, unsigned char **text_packs,
int *num_packs, int flag);
Alternatively the pack set may be defined by attaching CD-TEXT attributes
to burn_session and burn_track:
int burn_session_set_cdtext_par(struct burn_session *s,
int char_codes[8], int copyrights[8],
int languages[8], int flag);
int burn_session_set_cdtext(struct burn_session *s, int block,
int pack_type, char *pack_type_name,
unsigned char *payload, int length, int flag);
int burn_track_set_cdtext(struct burn_track *t, int block,
int pack_type, char *pack_type_name,
unsigned char *payload, int length, int flag);
Macros list the texts for genre and language codes:
BURN_CDTEXT_LANGUAGES_0X00
BURN_CDTEXT_FILLER
BURN_CDTEXT_LANGUAGES_0X45
BURN_CDTEXT_GENRE_LIST
BURN_CDTEXT_NUM_GENRES
There is a reader for Sony Input Sheet Version 0.7T:
int burn_session_input_sheet_v07t(struct burn_session *session,
char *path, int block, int flag);
CD-TEXT can be read from a CDRWIN cue sheet file which defines the tracks
of a session
int burn_session_by_cue_file(struct burn_session *session,
char *path, int fifo_size, struct burn_source **fifo,
unsigned char **text_packs, int *num_packs, int flag);
The session and track attributes can then be converted into an array of
text packs by:
int burn_cdtext_from_session(struct burn_session *s,
unsigned char **text_packs, int *num_packs,
int flag);
or they can be written as array of text packs to CD when burning begins and
no array of pre-formatted packs was attached to the write options by
burn_write_opts_set_leadin_text().
There are calls for inspecting the attached attributes:
int burn_session_get_cdtext_par(struct burn_session *s,
int char_codes[8], int copyrights[8],
int block_languages[8], int flag);
int burn_session_get_cdtext(struct burn_session *s, int block,
int pack_type, char *pack_type_name,
unsigned char **payload, int *length, int flag);
int burn_track_get_cdtext(struct burn_track *t, int block,
int pack_type, char *pack_type_name,
unsigned char **payload, int *length, int flag);
and for removing attached attributes:
int burn_session_dispose_cdtext(struct burn_session *s, int block);
int burn_track_dispose_cdtext(struct burn_track *t, int block);
UPC/EAN and ISRC not only affect CD-TEXT but also information that is written
along with the tracks in Q sub-channel. These can be influenced by
burn_session_input_sheet_v07t(), burn_session_by_cue_file() and by
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
unsigned char mediacatalog[13]);
void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
int has_mediacatalog);
void burn_track_set_isrc(struct burn_track *t, char *country, char *owner,
unsigned char year, unsigned int serial);
int burn_track_set_isrc_string(struct burn_track *t, char isrc[13],
int flag);
-------------------------------------------------------------------------------
Sony Text File Format (Input Sheet Version 0.7T):
This text file format provides comprehensive means to define the text
attributes of session and tracks for a single block. More than one
such file has to be read to form an attribute set with multiple blocks.
The information is given by text lines of the following form:
purpose specifier [whitespace] = [whitespace] content text
[whitespace] is zero or more ASCII 32 (space) or ASCII 9 (tab) characters.
The purpose specifier tells the meaning of the content text.
Empty content text does not cause a CD-TEXT attribute to be attached.
The following purpose specifiers apply to the session as a whole:
Specifier = Meaning
-------------------------------------------------------------------------
Text Code = Character code for pack type 0x8f
"ASCII", "8859"
Language Code = One of the language names for pack type 0x8f
Album Title = Content of pack type 0x80
Artist Name = Content of pack type 0x81
Songwriter = Content of pack type 0x82
Composer = Content of pack type 0x83
Arranger = Content of pack type 0x84
Album Message = Content of pack type 0x85
Catalog Number = Content of pack type 0x86
Genre Code = One of the genre names for pack type 0x87
Genre Information = Cleartext part of pack type 0x87
Closed Information = Content of pack type 0x8d
UPC / EAN = Content of pack type 0x8e
Text Data Copy Protection = Copyright value for pack type 0x8f
"ON" = 0x03, "OFF" = 0x00
First Track Number = The lowest track number used in the file
Last Track Number = The highest track number used in the file
The following purpose specifiers apply to particular tracks:
Track NN Title = Content of pack type 0x80
Track NN Artist = Content of pack type 0x81
Track NN Songwriter = Content of pack type 0x82
Track NN Composer = Content of pack type 0x83
Track NN Arranger = Content of pack type 0x84
Track NN Message = Content of pack type 0x85
ISRC NN = Content of pack type 0x8e
The following purpose specifiers have no effect on CD-TEXT:
Remarks = Comments with no influence on CD-TEXT
Disc Information NN = Supplementary information for use by record companies.
ISO-8859-1 encoded. NN ranges from 01 to 04.
Input Sheet Version = "0.7T"
libburn peculiarties:
libburn may read files of the described format by
burn_session_input_sheet_v07t()
after the burn_session has been establiched and all burn_track objects have
been added.
The following purpose specifiers accept byte values of the form 0xXY.
Text Code , Language Code , Genre Code , Text Data Copy Protection
E.g. to indicate MS-JIS character code (of which the exact name is unknown):
Text Code = 0x80
Genre Code is settable by 0xXY or 0xXYZT or 0xXY 0xZT.
Genre Code = 0x001b
Purpose specifiers which have the meaning "Content of pack type 0xXY"
may be replaced by the pack type codes. E.g.:
0x80 = Session content of pack type 0x80
Track 02 0x80 = Track content of pack type 0x80 for track 2.
Applicable are pack types 0x80 to 0x86, 0x8d, 0x8e.
Text Code may be specified only once. It gets speficied to "ISO-8850-1"
automatically as soon as content is defined which depends on the text
encoding of the block. I.e with pack types 0x80 to 0x85.
If a track attribute is set, but the corresponding session attribute is not
defined or defined with empty text, then the session attribute gets attached
as empty test. (Normally empty content is ignored.)
Example cdrskin run with three tracks:
$ cdrskin dev=/dev/sr0 -v input_sheet_v07t=NIGHTCATS.TXT \
-audio track_source_1 track_source_2 track_source_3
----------------------------------------------------------
Content of file NIGHTCATS.TXT :
----------------------------------------------------------
Input Sheet Version = 0.7T
Text Code = 8859
Language Code = English
Album Title = Joyful Nights
Artist Name = United Cat Orchestra
Songwriter = Various Songwriters
Composer = Various Composers
Arranger = Tom Cat
Album Message = For all our fans
Catalog Number = 1234567890
Genre Code = Classical
Genre Information = Feline classic music
Closed Information = This is not to be shown by CD players
UPC / EAN = 1234567890123
Text Data Copy Protection = OFF
First Track Number = 1
Last Track Number = 3
Track 01 Title = Song of Joy
Track 01 Artist = Felix and The Purrs
Track 01 Songwriter = Friedrich Schiller
Track 01 Composer = Ludwig van Beethoven
Track 01 Arranger = Tom Cat
Track 01 Message = Fritz and Louie once were punks
ISRC 01 = XYBLG1101234
Track 02 Title = Humpty Dumpty
Track 02 Artist = Catwalk Beauties
Track 02 Songwriter = Mother Goose
Track 02 Composer = unknown
Track 02 Arranger = Tom Cat
Track 02 Message = Pluck the goose
ISRC 02 = XYBLG1100005
Track 03 Title = Mee Owwww
Track 03 Artist = Mia Kitten
Track 03 Songwriter = Mia Kitten
Track 03 Composer = Mia Kitten
Track 03 Arranger = Mia Kitten
Track 03 Message =
ISRC 03 = XYBLG1100006
----------------------------------------------------------
-------------------------------------------------------------------------------
CDRWIN cue sheet files:
A CDRWIN cue sheet file defines the track data source (FILE), various text
attributes (CATALOG, TITLE, PERFORMER, SONGWRITER, ISRC), track block types
(TRACK), track start addresses (INDEX).
The rules for CDRWIN cue sheet files are described at
http://digitalx.org/cue-sheet/syntax/
There are three more text attributes mentioned in man cdrecord for defining
the corresponding CD-TEXT attributes: ARRANGER, COMPOSER, MESSAGE.
--------------------------------------
Example of a CDRWIN cue sheet file :
--------------------------------------
CATALOG 1234567890123
FILE "cdtext.bin" BINARY
TITLE "Joyful Nights"
TRACK 01 AUDIO
FLAGS DCP
TITLE "Song of Joy"
PERFORMER "Felix and The Purrs"
SONGWRITER "Friedrich Schiller"
ISRC XYBLG1101234
INDEX 01 00:00:00
TRACK 02 AUDIO
FLAGS DCP
TITLE "Humpty Dumpty"
PERFORMER "Catwalk Beauties"
SONGWRITER "Mother Goose"
ISRC XYBLG1100005
INDEX 01 08:20:12
TRACK 03 AUDIO
FLAGS DCP
TITLE "Mee Owwww"
PERFORMER "Mia Kitten"
SONGWRITER "Mia Kitten"
ISRC XYBLG1100006
INDEX 01 13:20:33
--------------------------------------
Some restrictions apply in the libburn call burn_session_by_cue_file():
Only FILE types BINARY, MOTOROLA, WAVE are allowed.
Only TRACK datatypes AUDIO, MODE1/2048 are allowed. They may not be mixed in
the same session.
On the other hand, ARRANGER, COMPOSER, MESSAGE are supported unconditionally.
-------------------------------------------------------------------------------
This text is copyright 2011 - 2012 Thomas Schmitt <scdbackup@gmx.net>.
Permission is granted to copy, modify, and distribute it, as long as the
references to the original information sources are maintained.
There is NO WARRANTY, to the extent permitted by law.
-------------------------------------------------------------------------------

View File

@ -4,7 +4,7 @@ Note: This is about how libburn operates optical drives. Not about how to
operate libburn. The libburn API is described in libburn/libburn.h
-------------------------------------------------------------------------------
libburnia-project.org Optical Media Rotisserie Recipes as of January 2010
libburnia-project.org Optical Media Rotisserie Recipes as of December 2011
Content:
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
@ -94,10 +94,15 @@ parameters:
Write Type Packet/TAO/SAO/RAW 01h = TAO
Multi-session Whether to keep appendable 00b = finalize
11b = keep appendable
Copy Whether to deny copying 1 = deny by SCMS , 0 = allow
Track Mode Describes frame type 4 for data , 0 for audio
Data Block Type Layout of payload blocks 8 for 2048 byte data blocks
0 for 2352 byte audio blocks
Audio Pause Length 150 = 2 seconds
Media Catalog Number A property of the disc 0x80 if valid
13 decimal digits as ASCII
ISRC A property of the track 0x80 if valid
12 letters and digits, ASCII
Any other parameters may be set to 0.
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
@ -193,7 +198,9 @@ If POINT is >= 1 and <= 99 (63h) then the descriptor is about the track of
which POINT tells the number.
The start address of this track can be read from PMIN, PSEC, PFRAME where
it is encoded in MSF format:
blocks = frames - 150, 75 frames = 1 sec , 60 sec = 1 min.
If M is smaller than 90: LBA = (M * 60 + S) * 75 + F - 150
Else : LBA = (M * 60 + S) * 75 + F - 450150
The length of the track is given by MIN,SEC,FRAME in the same format.
If POINT = A0h then the descriptor tells in PMIN the first track number of its
@ -220,10 +227,12 @@ sync. libburn uses the info provided by 52h READ TRACK INFORMATION.
-------------------------------------------------------------------------------
SAO CD Cookbook
-------------------------------------------------------------------------------
Guided by reading libburn/* from http://icculus.org/burn
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
and by experiments with drives NEC ND-4570A, LG GSA-4082B, LITE-ON LTR48125S
which used in part code from http://icculus.org/burn.
Guided by reading libburn/* from http://icculus.org/burn
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
backed by reading scms.html from
http://www.barrel-of-monkeys.com/graphics/prod/dvdplayers/
and by experiments with drives NEC ND-4570A, LG GSA-4082B, LITE-ON LTR48125S,
Optiarc BD RW BD-5300S, LG BDDVDRW GGC-H20L
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
@ -260,38 +269,85 @@ Each entry of the sheet is of 8 bytes size. Its fields are named
CTL|ADR, TNO, INDEX, DATA FORM, SCMS, MIN, SEC, FRAME .
(mmc5r03c.pdf 6.33)
CTL is 40h for data and 00h for audio.
CTL is comprised of four bits:
bit4 = Pre-emphasis (audio only)
bit5 = Digital copy permission:
0 = prohibited (one-time copy is permitted if SCMS is 00h)
1 = permitted (unlimited)
bit6 = Data track indicator (bit4 and bit7 shall be 0)
bit7 = 4-channel audio
Usually CTL is 40h for data and 00h for audio.
(mmc5r03c.pdf 6.33.3.4)
ADR is always 01h.
TNO is the track number (1 to 99).
INDEX is a subaddress within tracks. This recipe uses only INDEX 01h within
tracks.
ADR is 01h for entries which define time points. It is 02h for media catalog
entries and it is 03h for track ISRC entries.
The bits of CTL and ADR are combined in the CTL|ADR byte.
TNO is the track number. The TNO of the first track may be chosen in the range
of 1 to 99. The TNO of following tracks must be the TNO of their predecessor
plus 1. The last track must not have a TNO larger than 99.
INDEX is a subaddress within tracks. INDEX 1 is mandatory and marks the start
of the payload area of a track. The range between INDEX 0 and 1 is called
pre-gap. It should contain zeros if it exists. Further cue sheet entries with
consecutive INDEX numbers mark ranges within the track. The range of the last
index may contain a post-gap with zeros.
(mmc5r03c.pdf 4.2.3.5.2)
DATA FORM is 00h for audio payload , 10h for data. (01h for audio pause is not
used in libburn).
A pre-gap of 2 seconds is mandatory only for the first track. Pre-gap and
post-gap may be needed with further tracks if they have neighbors with
different DATA FORM values. (Such mixing is not yet supported by libburn.)
DATA FORM is 00h for audio payload, 01h for audio pause, 10h for data,
41h for CD-TEXT in Lead-in.
(mmc5r03c.pdf 6.33.3.11 CD-DA Data Form, 6.33.3.12 CD-ROM mode 1 Form)
SCMS is always 00h.
SCMS value 80h in conjunction with bit5 of CTL is an indicator for exhausted
one-time-copy permission. If this permission is still intact, then SCMS is 00h.
MIN, SEC, FRAME give the MSF address where the described data entity starts.
LBA = frames - 150, 75 frames = 1 sec , 60 sec = 1 min.
This address must increase from entry to entry (or at least stay equal).
The first entry describes the Lead-in. Its content is
(CTL|ADR ,00h,00h,01h,00h,00h,00h,00h)
The first two entries in a Cue Sheet may describe the Media Catalog Number,
a string of 13 characters, also known with CD-TEXT as "UPC/EAN".
(02h, catalog characters 1 to 7)
(02h, catalog characters 8 to 13, 00h)
These two entries shall be omitted if no catalog number is given.
The next entry (eventually being the first one) describes the Lead-in.
Its content is
(CTL|ADR ,00h,00h, DATA FORM ,00h,00h,00h,00h)
With the CTL|ADR for the first track: 41h for data, 01h for audio.
DATA FORM is 41h if CD-TEXT shall be stored in Lean-in. Else it is 01h.
The LBA for the first write is negative: -150. This corresponds to MSF address
00h:00h:00h. All addresses are to be given in MSF format.
The first information track on disc is preceded by a pause encoding of 2 sec:
Each track may be preceded by two entries describing an ISRC string of 12
characters.
(CTL | 03h, TNO, characters 1 to 6)
(CTL | 03h, TNO, characters 7 to 12)
These entries shall be omitted if no ISRC is given for the track.
CTL shall be the same as with the track.
The first information track on disc is preceded by a pause encoding or pre-gap
of at least 2 seconds:
(CTL|ADR,01h,00h, DATA FORM ,00h,00h,00h,00h)
with DATA FORM = 00h for audio and 10h for data. By those 2 seconds the MSF
address increases to 00h:02h:00h = LBA 0.
address increases to 00h:02h:00h = LBA 0. Optional further sectors may occupy
addresses larger than 0. This entry has to come after ISRC, if ISRC is given
for the track. INDEX has to be 0.
Each track is represented by an entry
Each track is represented by one or more entries, with increasing index number.
At least the entry for INDEX 1 has to exist:
(CTL|ADR, TNO ,01h,DATA FORM,00h, MIN , SEC , FRAME)
TNO gives the track number. MIN, SEC, FRAME give the MSF address which becomes
the start address of the track. The MSF address is then increased by the size
of the track (to be used with next track or with lead-out).
There may be more entries with INDEX 2 to 99. Their MSF address tells the
sector where their range starts. This range ends at the MSF of the next entry
in the cue sheet. INDEX information is stored in the sub-channel of the sectors
but not in the Table-of-Content of the disc.
A track must at least contain 300 payload blocks: 4 seconds of audio or
600 KiB of data.
@ -312,6 +368,12 @@ next lower possible value by the drive. So it is helpful to add a few
kbytes/sec just in case the drive has rounding problems.
(mmc5r03c.pdf 6.37)
If CD-TEXT shall be written into Lead-in, then it is necessary to obtain the
Start Time of Lead-in by 43h READ TOC/PMA/ATIP Format 0100b. It is an MFS
address which varies from media manufacturer to media manufacturer.
Minute will be >= 90. Therefore this conversion applies:
LBA = (M * 60 + S) * 75 + F - 450150
A Write Parameters mode page 05h has to be composed and transmitted via
55h MODE SELECT. This page describes the following parameters:
BUFE Buffer Underrun protection 0=off, 1=on
@ -322,6 +384,10 @@ A Write Parameters mode page 05h has to be composed and transmitted via
Track Mode Describes frame type 0 (is ignored)
Data Block Type Layout of payload blocks 0 (is ignored)
Audio Pause Length 150 = 2 seconds (ignored ?)
Media Catalog Number 0x80 if valid
See also Cue Sheet ADR 02h 13 decimal digits as ASCII
(With SAO, ISRC is transmitted only by the Cue Sheet.)
Any other parameters may be set to 0.
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
@ -338,15 +404,32 @@ blocks written. I.e the Transfer Length of the previous 2Ah WRITE has to be
added to the Logical Block Address for the next 2Ah WRITE. Only full blocks
can be written.
(mmc5r03c.pdf, 6.44)
Writing begins at LBA -150 which is to be transmitted as 4-byte, Big-endian,
two's-complement. E.g: -150 = FFh FFh FFh 6Ah. This is the natural form found
with about any 32-bit processor, so only the endianness has to be taken into
respect when converting a 32-bit integer into a LBA for command 2Ah WRITE.
Block addresses may be negative for areas before the normally readable
data. Data representation of addresses is 4-byte, big-endian, two's-complement.
E.g: -150 = FFh FFh FFh 6Ah.
This is the natural form found with about any 32-bit processor, so only
the endianness has to be taken into respect when converting a 32-bit
integer into a LBA for command 2Ah WRITE.
If CD-TEXT shall be written into Lead-in, then writing begins at the start
address of Lead-in, which was obtained above.
The 18 bytes of each text pack have to be split up to 24 bytes with only the
lowest six bits used in each byte. E.g. text pack
8F 00 2A 00 01 01 03 00 06 05 04 05 07 06 01 02 48 65
becomes
23 30 00 2A 00 00 04 01 00 30 00 06 01 10 10 05 01 30 18 01 00 24 21 25
4 of these 24 byte packs form a block of DATA FORM 41h. I.e. only 96 bytes
payload per block. The whole range from Lead-in start to LBA -150 has to be
filled with blocks of this form. Therefore it is necessary to write the
list of given packs in repeated cycles.
A typical Lead-in start address is -11635 = FFh FFh D2h 8Dh.
A description of the CD-TEXT pack format is given in file doc/cdtext.txt .
At first the mandatory pause preceding the first track has to be written as
150 blocks of the matching sector size: 2048 for data, 2352 for audio.
By this, the LBA increases from -150 to 0.
Writing without CD-TEXT begins at LBA -150 = FFh FFh FFh 6Ah.
In both cases, the mandatory pause preceding the first track has to be
written as 150 blocks of the matching sector size: 2048 for data,
2352 for audio. By this, the LBA increases from -150 to 0.
Next the tracks' payload is sent. For each track exactly the number of blocks
has to be transmitted as is announced in the Cue Sheet by the difference
@ -370,6 +453,21 @@ to media by 35h SYNCHRONIZE CACHE.
No further finalization is necessary. (I.e. no 5Bh CLOSE TRACK SESSION.)
-------------------------------------------------------------------------------
Obtaining CD-TEXT from Lead-in :
Audio CDs may contain CD-TEXT information in their Lead-in. It is gained by
43h READ TOC/PMA/ATIP, Format 0101b. The reply consists of 4 bytes header,
of which the first two bytes give the number of following bytes as big-endian
16 bit number. The other two bytes are 0.
Following are text packs of 18 bytes each.
(mmc5r03c.pdf 6.26.3.7.1 table 495)
A description of CD-TEXT packs and of the applicable libburn API calls is
given in file doc/cdtext.txt .
----------------------------------------------------------------------------
What is known about mixed mode sessions :
@ -1405,5 +1503,11 @@ written as rLBA nor as vLBA yet. So one should begin the vLBA of new sessions
at the NWA of a sufficiently sized track.
(mmc5r03c.pdf 4.5.3.5.4.2 , 4.5.3.6.9)
-------------------------------------------------------------------------------
This text is copyright 2011 - 2012 Thomas Schmitt <scdbackup@gmx.net>.
Permission is granted to copy, modify, and distribute it, as long as the
references to the original information sources are maintained.
There is NO WARRANTY, to the extent permitted by law.
-------------------------------------------------------------------------------

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -587,6 +587,7 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
struct write_opts o;
char *reasons= NULL;
struct burn_drive *d;
int mvalid;
d = opts->drive;
@ -634,12 +635,18 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
}
/* ts A61007 : obsolete Assert in spc_select_write_params() */
if (d->drive_role == 1 && d->mdata->valid <= 0) {
libdax_msgs_submit(libdax_messenger,
if (d->drive_role == 1) {
mvalid = 0;
if (d->mdata != NULL)
if (d->mdata->valid > 0)
mvalid = 1;
if (!mvalid) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020113,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Drive capabilities not inquired yet", 0, 0);
return;
return;
}
}
/* ts A70219 : intended to replace all further tests here and many

1111
libburn/cdtext.c Executable file

File diff suppressed because it is too large Load Diff

View File

@ -116,6 +116,9 @@ unsigned long crc32_table[256] = {
Use in libburn for raw write modes in sector.c.
There is also disabled code in read.c which would use it.
ts B11222:
libburn/cdtext.c uses a simple bit shifting function : crc_11021()
*/
unsigned short crc_ccitt(unsigned char *q, int len)
{

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -187,7 +187,10 @@ int burn_drive_is_occupied(struct burn_drive *d)
if(d->busy == BURN_DRIVE_READING_SYNC ||
d->busy == BURN_DRIVE_WRITING_SYNC)
return 2;
if(d->busy == BURN_DRIVE_WRITING) {
if(d->busy == BURN_DRIVE_WRITING ||
d->busy == BURN_DRIVE_WRITING_LEADIN ||
d->busy == BURN_DRIVE_WRITING_LEADOUT ||
d->busy == BURN_DRIVE_WRITING_PREGAP) {
/* ts A70928 */
/* >>> how do i learn whether the writer thread is still
@ -340,7 +343,7 @@ int burn_drive_send_default_page_05(struct burn_drive *d, int flag)
else
burn_write_opts_set_write_type(opts,
BURN_WRITE_SAO, BURN_BLOCK_SAO);
d->send_write_parameters(d, opts);
d->send_write_parameters(d, NULL, -1, opts);
burn_write_opts_free(opts);
d->sent_default_page_05 = 1;
return 1;
@ -483,9 +486,10 @@ int burn_drive_grab_stdio(struct burn_drive *d, int flag)
int burn_drive_grab(struct burn_drive *d, int le)
{
int errcode;
/* ts A61125 - B10314 */
int ret, sose;
/* ts A61125 - B20122 */
int ret, sose, signal_action_mem = -1;
sose = d->silent_on_scsi_error;
if (!d->released) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020189, LIBDAX_MSGS_SEV_FATAL,
@ -502,26 +506,40 @@ int burn_drive_grab(struct burn_drive *d, int le)
errcode = d->grab(d);
if (errcode == 0)
return 0;
burn_grab_prepare_sig_action(&signal_action_mem, 0);
d->busy = BURN_DRIVE_GRABBING;
if (le)
d->load(d);
if (d->cancel || burn_is_aborting(0))
{ret = 0; goto ex;}
d->lock(d);
if (d->cancel || burn_is_aborting(0))
{ret = 0; goto ex;}
/* ts A61118 */
d->start_unit(d);
if (d->cancel || burn_is_aborting(0))
{ret = 0; goto ex;}
/* ts A61202 : gave bit1 of le a meaning */
sose = d->silent_on_scsi_error;
if (!le)
d->silent_on_scsi_error = 1;
/* ts A61125 : outsourced media state inquiry aspects */
ret = burn_drive_inquire_media(d);
if (d->cancel || burn_is_aborting(0))
{ret = 0; goto ex;}
burn_drive_send_default_page_05(d, 0);
if (d->cancel || burn_is_aborting(0))
{ret = 0; goto ex;}
ex:;
d->silent_on_scsi_error = sose;
d->busy = BURN_DRIVE_IDLE;
burn_grab_restore_sig_action(signal_action_mem, 0);
return ret;
}
@ -745,7 +763,7 @@ void burn_drive_release(struct burn_drive *d, int le)
/* API */
int burn_drive_re_assess(struct burn_drive *d, int flag)
{
int ret;
int ret, signal_action_mem;
if (d->released) {
libdax_msgs_submit(libdax_messenger, d->global_index,
@ -762,10 +780,12 @@ int burn_drive_re_assess(struct burn_drive *d, int flag)
return ret;
}
burn_grab_prepare_sig_action(&signal_action_mem, 0);
d->busy = BURN_DRIVE_GRABBING;
ret = burn_drive_inquire_media(d);
burn_drive_send_default_page_05(d, 0);
d->busy = BURN_DRIVE_IDLE;
burn_grab_restore_sig_action(signal_action_mem, 0);
d->released = 0;
return ret;
}
@ -863,12 +883,34 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
d->erase(d, fast);
d->busy = BURN_DRIVE_ERASING;
#ifdef Libburn_old_progress_looP
/* read the initial 0 stage */
while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0)
sleep(1);
while ((d->progress.sector = d->get_erase_progress(d)) > 0 ||
!d->test_unit_ready(d))
sleep(1);
#else /* Libburn_old_progress_looP */
while (1) {
ret = d->get_erase_progress(d);
if (ret == -2 || ret > 0)
break;
sleep(1);
}
while (1) {
ret = d->get_erase_progress(d);
if(ret == -2)
break;
if (ret >= 0)
d->progress.sector = ret;
sleep(1);
}
#endif /* ! Libburn_old_progress_looP */
d->progress.sector = 0x10000;
/* ts A61125 : update media state records */
@ -913,6 +955,8 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
if (ret <= 0)
d->cancel = 1;
#ifdef Libburn_old_progress_looP
while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0)
sleep(1);
while ((pseudo_sector = d->get_erase_progress(d)) > 0 ||
@ -920,6 +964,26 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
d->progress.sector = pseudo_sector / stages;
sleep(1);
}
#else /* Libburn_old_progress_looP */
while (1) {
ret = d->get_erase_progress(d);
if (ret == -2 || ret > 0)
break;
sleep(1);
}
while (1) {
pseudo_sector = d->get_erase_progress(d);
if(pseudo_sector == -2)
break;
if (pseudo_sector >= 0)
d->progress.sector = pseudo_sector / stages;
sleep(1);
}
#endif /* ! Libburn_old_progress_looP */
d->sync_cache(d);
if (size <= 0)
@ -2318,12 +2382,14 @@ int burn_abort_5(int patience,
}
if(occup < 10) {
if (!drive_array[i].cancel)
burn_drive_cancel(&(drive_array[i]));
if (drive_array[i].drive_role != 1)
/* occup == -1 comes early */
usleep(1000000);
burn_drive_forget(&(drive_array[i]), 1);
} else if(occup <= 100) {
if(first_round)
if (!drive_array[i].cancel)
burn_drive_cancel(&(drive_array[i]));
still_not_done++;
} else if(occup <= 1000) {
@ -2469,7 +2535,7 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
if (d->drive_role != 1)
return 0;
if (o != NULL)
d->send_write_parameters(d, o);
d->send_write_parameters(d, NULL, -1, o);
ret = d->get_nwa(d, trackno, lba, nwa);
return ret;
}
@ -2522,7 +2588,7 @@ off_t burn_disc_available_space(struct burn_drive *d,
(off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
} else {
if (o != NULL)
d->send_write_parameters(d, o);
d->send_write_parameters(d, NULL, -1, o);
d->get_nwa(d, -1, &lba, &nwa);
}
if (o != NULL) {
@ -2971,11 +3037,12 @@ int burn_disc_get_write_mode_demands(struct burn_disc *disc,
last_track_is_unknown = 1;
} else
last_track_is_unknown = 0;
if (mode != track->mode)
if ((mode & BURN_MODE_BITS) !=
(track->mode & BURN_MODE_BITS))
result->mixed_mode = 1;
if (track->mode == BURN_MODE1) {
if (track->mode & BURN_MODE1) {
result->block_types |= BURN_BLOCK_MODE1;
} else if (track->mode == BURN_AUDIO) {
} else if (track->mode & BURN_AUDIO) {
result->audio = 1;
result->block_types |= BURN_BLOCK_RAW0;
result->exotic_track = 1;
@ -3309,3 +3376,16 @@ int burn_disc_next_track_is_damaged(struct burn_drive *d, int flag)
}
/* ts B11201 : API */
/* Read the CD-TEXT data from the Lead-in of an Audio CD
*/
int burn_disc_get_leadin_text(struct burn_drive *d,
unsigned char **text_packs, int *num_packs,
int flag)
{
int ret;
ret = mmc_get_leadin_text(d, text_packs, num_packs, 0);
return ret;
}

View File

@ -26,6 +26,7 @@
#include "libburn.h"
#include "file.h"
#include "async.h"
#include "init.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
@ -175,7 +176,7 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size)
if (datafd == -1)
return NULL;
fs = calloc(1, sizeof(struct burn_source_file));
fs = burn_alloc_mem(sizeof(struct burn_source_file), 1, 0);
if (fs == NULL) /* ts A70825 */
return NULL;
fs->datafd = datafd;
@ -510,7 +511,7 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
"Desired fifo buffer too small", 0, 0);
return NULL;
}
fs = calloc(1, sizeof(struct burn_source_fifo));
fs = burn_alloc_mem(sizeof(struct burn_source_fifo), 1, 0);
if (fs == NULL)
return NULL;
fs->is_started = 0;
@ -757,9 +758,12 @@ int burn_fifo_fill(struct burn_source *source, int bufsize, int flag)
static void offst_free(struct burn_source *source);
static struct burn_source_offst *offst_auth(struct burn_source *source)
/* @param flag bit0 = do not check for burn_source_offst, do not return NULL
*/
static struct burn_source_offst *offst_auth(struct burn_source *source,
int flag)
{
if (source->free_data != offst_free) {
if (source->free_data != offst_free && !(flag & 1)) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002017a,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Expected offset source object as parameter",
@ -773,18 +777,21 @@ static off_t offst_get_size(struct burn_source *source)
{
struct burn_source_offst *fs;
if ((fs = offst_auth(source)) == NULL)
if ((fs = offst_auth(source, 0)) == NULL)
return (off_t) 0;
return fs->size;
return fs->nominal_size;
}
static int offst_set_size(struct burn_source *source, off_t size)
{
struct burn_source_offst *fs;
if ((fs = offst_auth(source)) == NULL)
if ((fs = offst_auth(source, 0)) == NULL)
return 0;
fs->size = size;
fs->nominal_size = size;
if (fs->size <= 0 || fs->size_adjustable)
fs->size = size;
return 1;
}
@ -792,12 +799,12 @@ static void offst_free(struct burn_source *source)
{
struct burn_source_offst *fs;
if ((fs = offst_auth(source)) == NULL)
if ((fs = offst_auth(source, 0)) == NULL)
return;
if (fs->prev != NULL)
offst_auth(fs->prev)->next = fs->next;
offst_auth(fs->prev, 1)->next = fs->next;
if (fs->next != NULL)
offst_auth(fs->next)->prev = fs->prev;
offst_auth(fs->next, 1)->prev = fs->prev;
if (fs->inp != NULL)
burn_source_free(fs->inp); /* i.e. decrement refcount */
free(source->data);
@ -809,13 +816,13 @@ static int offst_read(struct burn_source *source, unsigned char *buffer,
int ret, to_read, todo;
struct burn_source_offst *fs;
if ((fs = offst_auth(source)) == NULL)
if ((fs = offst_auth(source, 0)) == NULL)
return -1;
/* Eventually skip bytes up to start position */;
if (!fs->running) {
if (fs->prev != NULL)
fs->pos = offst_auth(fs->prev)->pos;
fs->pos = offst_auth(fs->prev, 1)->pos;
fs->running= 1;
}
if(fs->pos < fs->start) {
@ -850,7 +857,7 @@ static int offst_cancel(struct burn_source *source)
int ret;
struct burn_source_offst *fs;
if ((fs = offst_auth(source)) == NULL)
if ((fs = offst_auth(source, 0)) == NULL)
return -1;
ret = burn_source_cancel(fs->inp);
return ret;
@ -864,7 +871,7 @@ struct burn_source *burn_offst_source_new(
struct burn_source_offst *fs, *prev_fs = NULL;
if (prev != NULL)
if ((prev_fs = offst_auth(prev)) == NULL)
if ((prev_fs = offst_auth(prev, 0)) == NULL)
return NULL; /* Not type burn_source_offst */
fs = calloc(1, sizeof(struct burn_source_offst));
@ -889,7 +896,7 @@ struct burn_source *burn_offst_source_new(
fs->next = NULL;
if (prev != NULL) {
if (prev_fs->next != NULL) {
offst_auth(prev_fs->next)->prev = src;
offst_auth(prev_fs->next, 1)->prev = src;
fs->next = prev_fs->next;
}
prev_fs->next = src;
@ -903,6 +910,8 @@ struct burn_source *burn_offst_source_new(
}
fs->start = start;
fs->size = size;
fs->size_adjustable = !(flag & 1);
fs->nominal_size = size;
fs->running = 0;
fs->pos = 0;
inp->refcount++; /* make sure inp lives longer than src */

View File

@ -82,6 +82,10 @@ struct burn_source_offst {
struct burn_source *prev;
off_t start;
off_t size;
int size_adjustable;
/* for set_size/get_size */
int nominal_size;
/* To help offst_free() */
struct burn_source *next;

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -362,6 +362,23 @@ char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80])
return text;
}
/* ts B20122 */
/* @param value 0=return rather than exit(value)
*/
int burn_abort_exit(int value)
{
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
fprintf(stderr,
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
abort_message_prefix);
if (value)
exit(value);
burn_global_abort_level = -2;
return(1);
}
int burn_builtin_abort_handler(void *handle, int signum, int flag)
{
@ -476,13 +493,9 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
"%sABORT : Wait the normal burning time before any kill -9\n",
abort_message_prefix);
close(0); /* somehow stdin as input blocks abort until EOF */
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
fprintf(stderr,
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
abort_message_prefix);
burn_global_abort_level = -2;
return(1);
burn_abort_exit(0);
return (1);
}
@ -550,6 +563,41 @@ int burn_init_catch_on_abort(int flag)
}
/* B20122 */
/* Temporarily disable builtin actions 0,1,2 to avoid that burn_abort()
waits for its own thread to end grabbing.
*/
int burn_grab_prepare_sig_action(int *signal_action_mem, int flag)
{
*signal_action_mem = -1;
if (burn_global_signal_handler == burn_builtin_abort_handler &&
burn_builtin_signal_action >= 0 &&
burn_builtin_signal_action <= 2) {
*signal_action_mem = burn_builtin_signal_action;
burn_builtin_signal_action = 3;
}
return 1;
}
/* B20122 */
/* Re-enable builtin actions 0,1,2 and perform delayed signal reactions
*/
int burn_grab_restore_sig_action(int signal_action_mem, int flag)
{
if (signal_action_mem >= 0)
burn_builtin_signal_action = signal_action_mem;
if (burn_is_aborting(0) && signal_action_mem >= 0) {
if (signal_action_mem == 0 || signal_action_mem == 1) {
burn_abort_exit(1); /* Never comes back */
} else if (signal_action_mem == 2) {
burn_builtin_triggered_action = signal_action_mem;
}
}
return 1;
}
/* ts A70223 : API */
void burn_allow_untested_profiles(int yes)
{
@ -589,7 +637,7 @@ void *burn_alloc_mem(size_t size, size_t count, int flag)
{
void *pt;
pt = calloc(size, count);
pt = calloc(count, size);
if(pt == NULL)
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,

View File

@ -48,4 +48,9 @@ void *burn_alloc_mem(size_t size, size_t count, int flag);
}
/* B20122 */
int burn_grab_prepare_sig_action(int *signal_action_mem, int flag);
int burn_grab_restore_sig_action(int signal_action_mem, int flag);
#endif /* BURN__INIT_H */

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
This is the official API definition of libburn.
@ -121,6 +121,15 @@ struct burn_write_opts;
/** Input mode modifier - subcodes present raw 96 */
#define BURN_SUBCODE_R96 (1 << 12)
/* ts B11230 */
/** Track mode modifier - Serial Copy Management System, SAO only
If this is set and BURN_COPY is not set, then copying the emerging
track will be forbidden.
@since 1.2.0
*/
#define BURN_SCMS (1 << 13)
/** Possible disc writing style/modes */
enum burn_write_types
{
@ -1290,6 +1299,30 @@ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
unsigned int *disc_id, char bar_code[9], int *app_code,
int *valid);
/* ts B11201 */
/** Read the array of CD-TEXT packs from the Lead-in of an audio CD.
Each pack consists of 18 bytes, of which 4 are header. 12 bytes are pieces
of 0-terminated texts or binary data. 2 bytes hold a CRC.
For a description of the format of the array, see file doc/cdtext.txt.
@param d The drive to query.
@param text_packs Will point to an allocated memory buffer with CD-TEXT.
It will only contain text packs, and not be prepended
by the TOC header of four bytes, which gets stored with
file cdtext.dat by cdrecord -vv -toc. (The first two of
these bytes are supposed to hold the number of CD-TEXT
bytes + 2. The other two bytes are supposed to be 0.)
Dispose this buffer by free(), when no longer needed.
@param num_packs Will tell the number of text packs, i.e. the number of
bytes in text_packs divided by 18.
@param flag Bitfield for control purposes,
Unused yet. Submit 0.
@return 1 success, 0= no CD-TEXT found, < 0 an error occured
@since 1.2.0
*/
int burn_disc_get_leadin_text(struct burn_drive *d,
unsigned char **text_packs, int *num_packs,
int flag);
/* ts B00924 */
/** Read the current usage of the eventual BD Spare Area. This area gets
reserved on BD media during formatting. During writing it is used to
@ -1338,6 +1371,9 @@ int burn_disc_get_phys_format_info(struct burn_drive *d, int *disk_category,
@param d The drive to query.
@param o If not NULL: write parameters to be set on drive before query
@param trackno 0=next track to come, >0 number of existing track
The first existing track on a CD may have a number higher
than 1. Use burn_session_get_start_tno() to inquire this
start number.
@param lba return value: start lba
@param nwa return value: Next Writeable Address
@return 1=nwa is valid , 0=nwa is not valid , -1=error
@ -1826,7 +1862,57 @@ int burn_disc_add_session(struct burn_disc *d, struct burn_session *s,
int burn_disc_remove_session(struct burn_disc *d, struct burn_session *s);
/** Create a track (for TAO recording, or to put in a session) */
/* ts B11219 */
/** Read a CDRWIN cue sheet file and equip the session object by tracks and
CD-TEXT according to the content of the file.
For a description of CDRWIN file format see
http://digitalx.org/cue-sheet/syntax/
Fully supported commands are:
CATALOG , CDTEXTFILE , FLAGS , INDEX , ISRC , PERFORMER ,
POSTGAP , PREGAP , REM , SONGWRITER , TITLE
Further supported commands introduced by cdrecord (usage like PERFORMER):
ARRANGER , COMPOSER , MESSAGE
Partly supported commands are:
FILE which supports only types BINARY , MOTOROLA , WAVE
TRACK which supports only datatypes AUDIO , MODE1/2048
Unsupported types of FILE or TRACK lead to failure of the call.
libburn does not yet support mixing of AUDIO and MODE1/2048. So this call
will fail if such a mix is found.
CD-TEXT information is allowed only if all tracks are of datatype AUDIO.
Empty lines and lines which start by '#' are ignored.
@param session Session where to attach tracks. It must not yet have
tracks or else this call will fail.
@param path Filesystem address of the CDRWIN cue sheet file.
Normally with suffix .cue
@param fifo_size Number of bytes in fifo. This will be rounded up by
the block size of the track mode. <= 0 means no fifo.
@param fifo Returns a reference to the burn_source object that
was installed as fifo between FILE and the track
burn sources. One may use this to inquire the fifo
state. Dispose it by burn_source_free() when no longer
needed. It is permissible to pass this parameter to
libburn as NULL, in order to immediately drop ownership
on the fifo.
@param text_packs Returns pre-formatted CD-TEXT packs resulting from
cue sheet command CDTEXTFILE. To be used with call
burn_write_opts_set_leadin_text().
It is permissible to pass this parameter to libburn
as NULL, in order to disable CDTEXTFILE.
@param num_packs Returns the number of 18 byte records in text_packs.
@param flag Bitfield for control purposes.
bit0= Do not attach CD-TEXT information to session and
tracks. Do not load text_packs.
bit1= Do not use media catalog string of session or ISRC
strings of tracks for writing to Q sub-channel.
@return > 0 indicates success, <= 0 indicates failure
@since 1.2.0
*/
int burn_session_by_cue_file(struct burn_session *session,
char *path, int fifo_size, struct burn_source **fifo,
unsigned char **text_packs, int *num_packs, int flag);
/** Create a track */
struct burn_track *burn_track_create(void);
/** Free a track
@ -1851,6 +1937,331 @@ int burn_session_add_track(struct burn_session *s, struct burn_track *t,
int burn_session_remove_track(struct burn_session *s, struct burn_track *t);
/* ts B20107 */
/** Set the number which shall be written as CD track number with the first
track of the session. The following tracks will then get written with
consecutive CD track numbers. The resulting number of the last track
must not exceed 99. The lowest possible start number is 1, which is also
the default. This setting applies only to CD SAO writing.
@param session The session to be manipulated
@param tno A number between 1 and 99
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return > 0 indicates success, <= 0 indicates failure
@since 1.2.0
*/
int burn_session_set_start_tno(struct burn_session *session, int tno,
int flag);
/* ts B20108 */
/** Inquire the CD track start number, as set by default ot by
burn_session_set_start_tno().
@param session The session to be inquired
@return > 0 is the currently set CD track start number
<= 0 indicates failure
@since 1.2.0
*/
int burn_session_get_start_tno(struct burn_session *session, int flag);
/* ts B11206 */
/** Set the Character Codes, the Copyright bytes, and the Language Codes
for CD-TEXT blocks 0 to 7. They will be used in the block summaries
of text packs which get generated from text or binary data submitted
by burn_session_set_cdtext() and burn_track_set_cdtext().
Character Code value can be
0x00 = ISO-8859-1
0x01 = 7 bit ASCII
0x80 = MS-JIS (japanesei Kanji, double byte characters)
Copyright byte value can be
0x00 = not copyrighted
0x03 = copyrighted
Language Code value will typically be 0x09 = English or 0x69 = Japanese.
See below macros BURN_CDTEXT_LANGUAGES_0X00 and BURN_CDTEXT_LANGUAGES_0X45,
but be aware that many of these codes have never been seen on CD, and that
many of them do not have a character representation among the above
Character Codes.
Default is 0x09 = English for block 0 and 0x00 = Unknown for block 1 to 7.
Copyright and Character Code are 0x00 for all blocks by default.
See also file doc/cdtext.txt, "Format of a CD-TEXT packs array",
"Pack type 0x8f".
Parameter value -1 leaves the current setting of the session parameter
unchanged.
@param s Session where to change settings
@param char_codes Character Codes for block 0 to 7
@param copyrights Copyright bytes for block 0 to 7
@param languages Language Codes for block 0 to 7
@param flag Bitfiled for control purposes. Unused yet. Submit 0.
@return <=0 failure, > 0 success
@since 1.2.0
*/
int burn_session_set_cdtext_par(struct burn_session *s,
int char_codes[8], int copyrights[8],
int languages[8], int flag);
/** This is the first list of languages sorted by their Language codes,
which start at 0x00. They stem from from EBU Tech 3264, appendix 3.
E.g. language 0x00 is "Unknown", 0x08 is "German", 0x10 is "Frisian",
0x18 is "Latvian", 0x20 is "Polish", 0x28 is "Swedish", 0x2b is "Wallon".
See also file doc/cdtext.txt.
@since 1.2.0
*/
#define BURN_CDTEXT_LANGUAGES_0X00 \
"Unknown", "Albanian", "Breton", "Catalan", \
"Croatian", "Welsh", "Czech", "Danish", \
"German", "English", "Spanish", "Esperanto", \
"Estonian", "Basque", "Faroese", "French", \
"Frisian", "Irish", "Gaelic", "Galician", \
"Icelandic", "Italian", "Lappish", "Latin", \
"Latvian", "Luxembourgian", "Lithuanian", "Hungarian", \
"Maltese", "Dutch", "Norwegian", "Occitan", \
"Polish", "Portuguese", "Romanian", "Romansh", \
"Serbian", "Slovak", "Slovenian", "Finnish", \
"Swedish", "Turkish", "Flemish", "Wallon"
/** This is the second list of languages sorted by their Language codes,
which start at 0x45. They stem from from EBU Tech 3264, appendix 3.
E.g. language 0x45 is "Zulu", 0x50 is "Sranan Tongo", 0x58 is "Pushtu",
0x60 is "Moldavian", 0x68 is "Kannada", 0x70 is "Greek", 0x78 is "Bengali",
0x7f is "Amharic".
See also file doc/cdtext.txt.
@since 1.2.0
*/
#define BURN_CDTEXT_LANGUAGES_0X45 \
"Zulu", "Vietnamese", "Uzbek", \
"Urdu", "Ukrainian", "Thai", "Telugu", \
"Tatar", "Tamil", "Tadzhik", "Swahili", \
"Sranan Tongo", "Somali", "Sinhalese", "Shona", \
"Serbo-croat", "Ruthenian", "Russian", "Quechua", \
"Pushtu", "Punjabi", "Persian", "Papamiento", \
"Oriya", "Nepali", "Ndebele", "Marathi", \
"Moldavian", "Malaysian", "Malagasay", "Macedonian", \
"Laotian", "Korean", "Khmer", "Kazakh", \
"Kannada", "Japanese", "Indonesian", "Hindi", \
"Hebrew", "Hausa", "Gurani", "Gujurati", \
"Greek", "Georgian", "Fulani", "Dari", \
"Churash", "Chinese", "Burmese", "Bulgarian", \
"Bengali", "Bielorussian", "Bambora", "Azerbaijani", \
"Assamese", "Armenian", "Arabic", "Amharic"
/* This is the list of empty languages names between 0x30 and 0x44.
Together the three macros fill an array of 128 char pointers.
static char *languages[] = {
BURN_CDTEXT_LANGUAGES_0X00,
BURN_CDTEXT_FILLER,
BURN_CDTEXT_LANGUAGES_0X45
};
*/
#define BURN_CDTEXT_FILLER \
"", "", "", "", \
"", "", "", "", \
"", "", "", "", \
"", "", "", "", \
"", "", "", "", \
"", "", "", "", \
""
/* ts B11206 */
/** Obtain the current settings as of burn_session_set_cdtext_par() resp.
by default.
@param s Session which to inquire
@param char_codes Will return Character Codes for block 0 to 7
@param copyrights Will return Copyright bytes for block 0 to 7
@param languages Will return Language Codes for block 0 to 7
@param flag Bitfiled for control purposes. Unused yet. Submit 0.
@return <=0 failure, reply invalid, > 0 success, reply valid
@since 1.2.0
*/
int burn_session_get_cdtext_par(struct burn_session *s,
int char_codes[8], int copyrights[8],
int block_languages[8], int flag);
/* ts B11206 */
/** Attach text or binary data as CD-TEXT attributes to a session.
They can be used to generate CD-TEXT packs by burn_cdtext_from_session()
or to write CD-TEXT packs into the lead-in of a CD SAO session.
The latter happens only if no array of CD-TEXT packs is attached to
the write options by burn_write_opts_set_leadin_text().
For details of the CD-TEXT format and of the payload content, see file
doc/cdtext.txt .
@param s Session where to attach CD-TEXT attribute
@param block Number of the language block in which the attribute
shall appear. Possible values: 0 to 7.
@param pack_type Pack type number. 0x80 to 0x8e. Used if pack_type_name
is NULL or empty text. Else submit 0 and a name.
Pack type 0x8f is generated automatically and may not
be set by applications.
@param pack_type_name The pack type by name. Defined names are:
0x80 = "TITLE" 0x81 = "PERFORMER"
0x82 = "SONGWRITER" 0x83 = "COMPOSER"
0x84 = "ARRANGER" 0x85 = "MESSAGE"
0x86 = "DISCID" 0x87 = "GENRE"
0x88 = "TOC" 0x89 = "TOC2"
0x8d = "CLOSED" 0x8e = "UPC_ISRC"
Names are recognized uppercase and lowercase.
@param payload Text or binary bytes. The data will be copied to
session-internal memory.
Pack types 0x80 to 0x85 contain 0-terminated cleartext
encoded according to the block's Character Code.
If double byte characters are used, then two 0-bytes
terminate the cleartext.
Pack type 0x86 is 0-terminated ASCII cleartext.
Pack type 0x87 consists of two byte big-endian
Genre code (see below BURN_CDTEXT_GENRE_LIST), and
0-terminated ASCII cleartext of genre description.
Pack type 0x88 mirrors the session table-of-content.
Pack type 0x89 is not understood yet.
Pack types 0x8a to 0x8c are reserved.
Pack type 0x8d contains ISO-8859-1 cleartext which is
not to be shown by commercial audio CD players.
Pack type 0x8e is ASCII cleartext with UPC/EAN code.
@pram length Number of bytes in payload. Including terminating
0-bytes.
@param flag Bitfield for control purposes.
bit0= payload contains double byte characters
(with character code 0x80 MS-JIS japanese Kanji)
@return > 0 indicates success , <= 0 is failure
@since 1.2.0
*/
int burn_session_set_cdtext(struct burn_session *s, int block,
int pack_type, char *pack_type_name,
unsigned char *payload, int length, int flag);
/** This is the list of Genres sorted by their Genre codes.
E.g. genre code 0x0000 is "No Used", 0x0008 is "Dance, 0x0010 is "Musical",
0x0018 is "Rhythm & Blues", 0x001b is "World Music".
See also file doc/cdtext.txt.
@since 1.2.0
*/
#define BURN_CDTEXT_GENRE_LIST \
"Not Used", "Not Defined", "Adult Contemporary", "Alternative Rock", \
"Childrens Music", "Classical", "Contemporary Christian", "Country", \
"Dance", "Easy Listening", "Erotic", "Folk", \
"Gospel", "Hip Hop", "Jazz", "Latin", \
"Musical", "New Age", "Opera", "Operetta", \
"Pop Music", "Rap", "Reggae", "Rock Music", \
"Rhythm & Blues", "Sound Effects", "Spoken Word", "World Music"
/* The number of genre names in BURN_CDTEXT_GENRE_LIST.
*/
#define BURN_CDTEXT_NUM_GENRES 28
/* ts B11206 */
/** Obtain a CD-TEXT attribute that was set by burn_session_set_cdtext()
@param s Session to inquire
@param block Number of the language block to inquire.
@param pack_type Pack type number to inquire. Used if pack_type_name
is NULL or empty text. Else submit 0 and a name.
Pack type 0x8f is generated automatically and may not
be inquire in advance. Use burn_cdtext_from_session()
to generate all packs including type 0x8f packs.
@param pack_type_name The pack type by name.
See above burn_session_set_cdtext().
@param payload Will return a pointer to text or binary bytes.
Not a copy of data. Do not free() this address.
If no text attribute is attached for pack type and
block, then payload is returned as NULL. The return
value will not indicate error in this case.
@pram length Will return the number of bytes pointed to by payload.
Including terminating 0-bytes.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return 1 single byte char, 2 double byte char, <=0 error
@since 1.2.0
*/
int burn_session_get_cdtext(struct burn_session *s, int block,
int pack_type, char *pack_type_name,
unsigned char **payload, int *length, int flag);
/* ts B11215 */
/** Read a Sony CD-TEXT Input Sheet Version 0.7T file and attach its text
attributes to the given session and its tracks for the given CD-TEXT
block number. This overrides previous settings made by
burn_session_set_cdtext(), burn_track_set_cdtext(), burn_track_set_isrc(),
burn_session_set_start_tno(). It can later be overridden by said function
calls.
The media catalog number from purpose specifier "UPC / EAN" gets into
effect only if burn_write_opts_set_has_mediacatalog() is set to 0.
The format of a v07t sheet file is documented in doc/cdtext.txt.
@param s Session where to attach CD-TEXT attributes
@param path Local filesystem address of the sheet file which
shall be read and interpreted.
@param block Number of the language block in which the attributes
shall appear. Possible values: 0 to 7.
@param flag Bitfield for control purposes.
bit1= Do not use media catalog string of session or ISRC
strings of tracks for writing to Q sub-channel.
@return > 0 indicates success , <= 0 is failure
@since 1.2.0
*/
int burn_session_input_sheet_v07t(struct burn_session *session,
char *path, int block, int flag);
/* ts B11210 */
/** Produce an array of CD-TEXT packs that could be submitted to
burn_write_opts_set_leadin_text() or stored as *.cdt file.
For a description of the format of the array, see file doc/cdtext.txt.
The input data stem from burn_session_set_cdtext_par(),
burn_session_set_cdtext(), and burn_track_set_cdtext().
@param s Session from which to produce CD-TEXT packs.
@param text_packs Will return the buffer with the CD-TEXT packs.
Dispose by free() when no longer needed.
@param num_packs Will return the number of 18 byte text packs.
@param flag Bitfield for control purposes.
bit0= do not return generated CD-TEXT packs,
but check whether production would work and
indicate the number of packs by the call return
value. This happens also if
(text_packs == NULL || num_packs == NULL).
@return Without flag bit0: > 0 is success, <= 0 failure
With flag bit0: > 0 is number of packs,
0 means no packs will be generated,
< 0 means failure
@since 1.2.0
*/
int burn_cdtext_from_session(struct burn_session *s,
unsigned char **text_packs, int *num_packs,
int flag);
/* ts B11206 */
/** Remove all CD-TEXT attributes of the given block from the session.
They were attached by burn_session_set_cdtext().
@param s Session where to remove the CD-TEXT attribute
@param block Number of the language block in which the attribute
shall appear. Possible values: 0 to 7.
-1 causes text packs of all blocks to be removed.
@return > 0 is success, <= 0 failure
@since 1.2.0
*/
int burn_session_dispose_cdtext(struct burn_session *s, int block);
/* ts B11221*/
/** Read an array of CD-TEXT packs from a file. This array should be suitable
for burn_write_opts_set_leadin_text().
The function tolerates and removes 4-byte headers as produced by
cdrecord -vv -toc, if this header tells the correct number of bytes which
matches the file size. If no 4-byte header is present, then the function
tolerates and removes a trailing 0-byte as of Sony specs.
@param path Filesystem address of the CD-TEXT pack file.
Normally with suffix .cdt or .dat
@param text_packs Will return the buffer with the CD-TEXT packs.
Dispose by free() when no longer needed.
@param num_packs Will return the number of 18 byte text packs.
@param flag Bitfield for control purposes. Unused yet.Submit 0.
@return 0 is success, <= 0 failure
@since 1.2.0
*/
int burn_cdtext_from_packfile(char *path, unsigned char **text_packs,
int *num_packs, int flag);
/** Define the data in a track
@param t the track to define
@param offset The lib will write this many 0s before start of data
@ -1864,14 +2275,76 @@ void burn_track_define_data(struct burn_track *t, int offset, int tail,
int pad, int mode);
/* ts A61024 */
/** Define whether a track shall swap bytes of its input stream.
@param t The track to change
@param swap_source_bytes 0=do not swap, 1=swap byte pairs
@return 1=success , 0=unacceptable value
@since 0.2.6
/* ts B11206 */
/** Attach text or binary data as CD-TEXT attributes to a track.
The payload will be used to generate CD-TEXT packs by
burn_cdtext_from_session() or to write CD-TEXT packs into the lead-in
of a CD SAO session. This happens if the CD-TEXT attribute of the session
gets generated, which has the same block number and pack type. In this
case, each track should have such a CD-TEXT attribute, too.
See burn_session_set_cdtext().
Be cautious not to exceed the maximum number of 253 payload packs per
language block. Use burn_cdtext_from_session() to learn whether a valid
array of CD-TEXT packs can be generated from your attributes.
@param t Track where to attach CD-TEXT attribute.
@param block Number of the language block in which the attribute
shall appear. Possible values: 0 to 7.
@param pack_type Pack type number. 0x80 to 0x85 or 0x8e. Used if
pack_type_name is NULL or empty text. Else submit 0
and a name.
@param pack_type_name The pack type by name. Applicable names are:
0x80 = "TITLE" 0x81 = "PERFORMER"
0x82 = "SONGWRITER" 0x83 = "COMPOSER"
0x84 = "ARRANGER" 0x85 = "MESSAGE"
0x8e = "UPC_ISRC"
@param payload 0-terminated cleartext. If double byte characters
are used, then two 0-bytes terminate the cleartext.
@pram length Number of bytes in payload. Including terminating
0-bytes.
@param flag Bitfield for control purposes.
bit0= payload contains double byte characters
(with character code 0x80 MS-JIS japanese Kanji)
@return > 0 indicates success , <= 0 is failure
@since 1.2.0
*/
int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes);
int burn_track_set_cdtext(struct burn_track *t, int block,
int pack_type, char *pack_type_name,
unsigned char *payload, int length, int flag);
/* ts B11206 */
/** Obtain a CD-TEXT attribute that was set by burn_track_set_cdtext().
@param t Track to inquire
@param block Number of the language block to inquire.
@param pack_type Pack type number to inquire. Used if pack_type_name
is NULL or empty text. Else submit 0 and a name.
@param pack_type_name The pack type by name.
See above burn_track_set_cdtext().
@param payload Will return a pointer to text bytes.
Not a copy of data. Do not free() this address.
If no text attribute is attached for pack type and
block, then payload is returned as NULL. The return
value will not indicate error in this case.
@pram length Will return the number of bytes pointed to by payload.
Including terminating 0-bytes.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return 1=single byte char , 2= double byte char , <=0 error
@since 1.2.0
*/
int burn_track_get_cdtext(struct burn_track *t, int block,
int pack_type, char *pack_type_name,
unsigned char **payload, int *length, int flag);
/* ts B11206 */
/** Remove all CD-TEXT attributes of the given block from the track.
They were attached by burn_track_set_cdtext().
@param t Track where to remove the CD-TEXT attribute.
@param block Number of the language block in which the attribute
shall appear. Possible values: 0 to 7.
-1 causes text packs of all blocks to be removed.
@return > 0 is success, <= 0 failure
@since 1.2.0
*/
int burn_track_dispose_cdtext(struct burn_track *t, int block);
/* ts A90910 */
@ -1890,7 +2363,8 @@ int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes);
int burn_track_set_cdxa_conv(struct burn_track *t, int value);
/** Set the ISRC details for a track
/** Set the ISRC details for a track. When writing to CD media, ISRC will get
written into the Q sub-channel.
@param t The track to change
@param country the 2 char country code. Each character must be
only numbers or letters.
@ -1902,11 +2376,108 @@ int burn_track_set_cdxa_conv(struct burn_track *t, int value);
void burn_track_set_isrc(struct burn_track *t, char *country, char *owner,
unsigned char year, unsigned int serial);
/* ts B11226 */
/** Set the composed ISRC string for a track. This is an alternative to
burn_track_set_isrc().
@param t The track to be manipulated
@param isrc 12 characters which are composed from ISRC details.
Format is CCOOOYYSSSSS, terminated by a 0-byte:
Country, Owner, Year(decimal digits), Serial(decimal digits).
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return > 0 indicates success, <= 0 means failure
@since 1.2.0
*/
int burn_track_set_isrc_string(struct burn_track *t, char isrc[13], int flag);
/** Disable ISRC parameters for a track
@param t The track to change
*/
void burn_track_clear_isrc(struct burn_track *t);
/* ts B20103 */
/** Define an index start address within a track. The index numbers inside a
track have to form sequence starting at 0 or 1 with no gaps up to the
highest number used. They affect only writing of CD SAO sessions.
The first index start address of a track must be 0.
Blocks between index 0 and index 1 are considered to be located before the
track start as of the table-of-content.
@param t The track to be manipulated
@param index_number A number between 0 and 99
@param relative_lba The start address relative to the start of the
burn_source of the track. It will get mapped to the
appropriate absolute block address.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return > 0 indicates success, <= 0 means failure
@since 1.2.0
*/
int burn_track_set_index(struct burn_track *t, int index_number,
unsigned int relative_lba, int flag);
/* ts B20103 */
/** Remove all index start addresses and reset to the default indexing of
CD SAO sessions. This means index 0 of track 1 reaches from LBA -150
to LBA -1. Index 1 of track 1 reaches from LBA 0 to track end. Index 1
of track 2 follows immediately. The same happens for all further tracks
after the end of their predecessor.
@param t The track to be manipulated
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return > 0 indicates success, <= 0 means failure
@since 1.2.0
*/
int burn_track_clear_indice(struct burn_track *t, int flag);
/* ts B20110 */
/** Define whether a pre-gap shall be written before the track and how many
sectors this pre-gap shall have. A pre-gap is written in the range of track
index 0 and contains zeros resp. silence. No bytes from the track source
will be read for writing the pre-gap.
This setting affects only CD SAO write runs.
The first track automatically gets a pre-gap of at least 150 sectors. Its
size may be enlarged by this call. Further pre-gaps are demanded by MMC
for tracks which follow tracks of a different mode. (But Mode mixing in
CD SAO sessions is currently not supported by libburn.)
@param t The track to change
@param size Number of sectors in the pre-gap.
-1 disables pre-gap, except for the first track.
libburn allows 0, but MMC does not propose this.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return > 0 indicates success, <= 0 means failure
@since 1.2.0
*/
int burn_track_set_pregap_size(struct burn_track *t, int size, int flag);
/* ts B20111 */
/** Define whether a post-gap shall be written at the end of the track and
how many sectors this gap shall have. A post-gap occupies the range of
an additional index of the track. It contains zeros. No bytes from the
track source will be read for writing the post-gap.
This setting affects only CD SAO write runs.
MMC prescribes to add a post-gap to a data track which is followed by
a non-data track. (But libburn does not yet support mixed mode CD SAO
sessions.)
@param t The track to change
@param size Number of sectors in the post-gap.
-1 disables post-gap.
libburn allows 0, but MMC does not propose this.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return > 0 indicates success, <= 0 means failure
@since 1.2.0
*/
int burn_track_set_postgap_size(struct burn_track *t, int size, int flag);
/* ts A61024 */
/** Define whether a track shall swap bytes of its input stream.
@param t The track to change
@param swap_source_bytes 0=do not swap, 1=swap byte pairs
@return 1=success , 0=unacceptable value
@since 0.2.6
*/
int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes);
/** Hide the first track in the "pre gap" of the disc
@param s session to change
@param onoff 1 to enable hiding, 0 to disable
@ -2048,7 +2619,15 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size);
@param start The byte address where to start reading bytes for the
consumer. inp bytes may get skipped to reach this address.
@param size The number of bytes to be delivered to the consumer.
@param flag Bitfield for control purposes (unused yet, submit 0).
If size is <= 0 then it may be set later by a call of method
set_size(). If it is >= 0, then it can only be changed if
flag bit0 was set with burn_offst_source_new().
@param flag Bitfield for control purposes
bit0 = Prevent set_size() from overriding interval sizes > 0.
If such a size is already set, then the new one will
only affect the reply of get_size().
See also above struct burn_source.
@since 1.2.0
@return Pointer to a burn_source object, later to be freed by
burn_source_free(). NULL indicates failure.
@since 0.8.8
@ -2061,14 +2640,15 @@ struct burn_source *burn_offst_source_new(
/** Creates a fifo which acts as proxy for an already existing data source.
The fifo provides a ring buffer which shall smoothen the data stream
between burn_source and writer thread. Each fifo serves only for one
data source and gets attached to one track as its only data source
by burn_track_set_source().
data source. It may be attached to one track as its only data source
by burn_track_set_source(), or it may be used as input for other burn
sources.
A fifo starts its life in "standby" mode with no buffer space allocated.
As soon as its track requires bytes, the fifo establishes a worker thread
and allocates its buffer. After input has ended and all buffer content is
consumed, the buffer space gets freed and the worker thread ends.
This happens asynchronously. So expect two buffers and worker threads to
exist for a short time between tracks. Be modest in your size demands if
As soon as its consumer requires bytes, the fifo establishes a worker
thread and allocates its buffer. After input has ended and all buffer
content is consumed, the buffer space gets freed and the worker thread
ends. This happens asynchronously. So expect two buffers and worker threads
to exist for a short time between tracks. Be modest in your size demands if
multiple tracks are to be expected.
@param inp The burn_source for which the fifo shall act as proxy.
It can be disposed by burn_source_free() immediately
@ -2207,8 +2787,9 @@ int burn_fifo_fill(struct burn_source *fifo, int fill, int flag);
int burn_track_set_size(struct burn_track *t, off_t size);
/** Tells how long a track will be on disc
>>> NOTE: Not reliable with tracks of undefined length
/** Tells how many sectors a track will have on disc, resp. already has on
disc. This includes offset, payload, tail, and post-gap, but not pre-gap.
The result is NOT RELIABLE with tracks of undefined length
*/
int burn_track_get_sectors(struct burn_track *);
@ -2362,9 +2943,24 @@ int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
*/
void burn_write_opts_set_perform_opc(struct burn_write_opts *opts, int opc);
void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts, int has_mediacatalog);
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, unsigned char mediacatalog[13]);
/** The Q sub-channel of a CD may contain a Media Catalog Number of 13 decimal
digits. This call sets the string of digits, but does not yet activate it
for writing.
@param opts The write opts to change
@param mediacatalog The 13 decimal digits as ASCII bytes. I.e. '0' = 0x30.
*/
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
unsigned char mediacatalog[13]);
/** This call activates the Media Catalog Number for writing. The digits of
that number have to be set by call burn_write_opts_set_mediacatalog().
@param opts The write opts to change
@param has_mediacatalog 1= activate writing of catalog to Q sub-channel
0= deactivate it
*/
void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
int has_mediacatalog);
/* ts A61106 */
@ -2380,6 +2976,31 @@ void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, unsigned cha
*/
void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
/* ts B11204 */
/** Submit an array of CD-TEXT packs which shall be written to the Lead-in
of a SAO write run on CD.
@param opts The option object to be manipulated
@param text_packs Array of bytes which form CD-TEXT packs of 18 bytes
each. For a description of the format of the array,
see file doc/cdtext.txt.
No header of 4 bytes must be prepended which would
tell the number of pack bytes + 2.
This parameter may be NULL if the currently attached
array of packs shall be removed.
@param num_packs The number of 18 byte packs in text_packs.
This parameter may be 0 if the currently attached
array of packs shall be removed.
@param flag Bitfield for control purposes.
bit0= do not verify checksums
bit1= repair mismatching checksums
bit2= repair checksums if they are 00 00 with each pack
@return 1 on success, <= 0 on failure
@since 1.2.0
*/
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
unsigned char *text_packs,
int num_packs, int flag);
/* ts A61222 */
/** Sets a start address for writing to media and write modes which allow to
@ -2810,8 +3431,8 @@ void burn_version(int *major, int *minor, int *micro);
*/
#define burn_header_version_major 1
#define burn_header_version_minor 1
#define burn_header_version_micro 7
#define burn_header_version_minor 2
#define burn_header_version_micro 0
/** Note:
Above version numbers are also recorded in configure.ac because libtool
wants them as parameters at build time.
@ -3001,12 +3622,17 @@ typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag);
@param handle Opaque handle eventually pointing to an application
provided memory object
@param handler A function to be called on signals. It will get handle as
argument. flag will be 0.
@param handler A function to be called on signals, if the handling bits
in parameter mode are set 0.
It will get parameter handle as argument. flag will be 0.
It should finally call burn_abort(). See there.
@param mode : bit0 - bit3:
Receiving signals:
0 Call handler(handle, signum, 0) on nearly all signals
If the handler function returns 2 or -2, then the wrapping
signal handler of libburn will return and let the program
continue its operations. Any other return value causes
exit(1).
@param mode : bit0 - bit3: Handling of received signals:
0 Install libburn wrapping signal handler, which will call
handler(handle, signum, 0) on nearly all signals
1 Enable system default reaction on all signals
2 Try to ignore nearly all signals
10 like mode 2 but handle SIGABRT like with mode 0
@ -3246,7 +3872,8 @@ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag);
@param num_channels e.g. 1=mono, 2=stereo, etc
@param sample_rate e.g. 11025, 44100
@param bits_per_sample e.g. 8= 8 bits per sample, 16= 16 bits ...
@param msb_first Byte order of samples: 0=Intel 1=Motorola
@param msb_first Byte order of samples: 0= Intel = Little Endian
1= Motorola = Big Endian
@param flag Bitfield for control purposes (unused yet, submit 0)
@return >0 success, <=0 failure
@since 0.2.4
@ -3311,7 +3938,6 @@ int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag);
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag);
#ifndef DOXYGEN
BURN_END_DECLS

View File

@ -4,6 +4,8 @@ burn_abort;
burn_abort_pacifier;
burn_allow_drive_role_4;
burn_allow_untested_profiles;
burn_cdtext_from_session;
burn_cdtext_from_packfile;
burn_disc_add_session;
burn_disc_available_space;
burn_disc_close_damaged;
@ -17,6 +19,7 @@ burn_disc_get_bd_spare_info;
burn_disc_get_cd_info;
burn_disc_get_format_descr;
burn_disc_get_formats;
burn_disc_get_leadin_text;
burn_disc_get_media_id;
burn_disc_get_msc1;
burn_disc_get_multi_caps;
@ -111,14 +114,23 @@ burn_read_opts_transfer_damaged_blocks;
burn_scsi_transport_id;
burn_sectors_to_msf;
burn_session_add_track;
burn_session_by_cue_file;
burn_session_create;
burn_session_dispose_cdtext;
burn_session_free;
burn_session_get_cdtext;
burn_session_get_cdtext_par;
burn_session_get_hidefirst;
burn_session_get_leadout_entry;
burn_session_get_sectors;
burn_session_get_start_tno;
burn_session_get_tracks;
burn_session_hide_first_track;
burn_session_input_sheet_v07t;
burn_session_remove_track;
burn_session_set_cdtext;
burn_session_set_cdtext_par;
burn_session_set_start_tno;
burn_set_messenger;
burn_set_scsi_logging;
burn_set_signal_handling;
@ -129,18 +141,26 @@ burn_structure_print_disc;
burn_structure_print_session;
burn_structure_print_track;
burn_text_to_sev;
burn_track_clear_indice;
burn_track_clear_isrc;
burn_track_create;
burn_track_define_data;
burn_track_dispose_cdtext;
burn_track_free;
burn_track_get_cdtext;
burn_track_get_counters;
burn_track_get_entry;
burn_track_get_mode;
burn_track_get_sectors;
burn_track_set_byte_swap;
burn_track_set_cdxa_conv;
burn_track_set_cdtext;
burn_track_set_default_size;
burn_track_set_index;
burn_track_set_isrc;
burn_track_set_isrc_string;
burn_track_set_postgap_size;
burn_track_set_pregap_size;
burn_track_set_size;
burn_track_set_source;
burn_version;
@ -153,6 +173,7 @@ burn_write_opts_set_fillup;
burn_write_opts_set_force;
burn_write_opts_set_format;
burn_write_opts_set_has_mediacatalog;
burn_write_opts_set_leadin_text;
burn_write_opts_set_mediacatalog;
burn_write_opts_set_multi;
burn_write_opts_set_perform_opc;

View File

@ -436,6 +436,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002000b (FAILURE,HIGH) = File object '...' not found
0x0002000c (FAILURE,HIGH) = Cannot start device file enumeration
0x0002000d (FAILURE,HIGH) = Cannot enumerate next device
0x0002000e (NOTE,HIGH) = Failed to open device during
General library operations:
@ -517,7 +518,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
0x0002014d (SORRY,HIGH) = Asynchromous SCSI error
0x0002014f (SORRY,HIGH) = Timeout with asynchromous SCSI command
0x0002014f (SORRY,HIGH) = Timeout with asynchronous SCSI command
0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time
0x00020151 (FAILURE,HIGH) = Read attempt on write-only drive
0x00020152 (FATAL,HIGH) = Cannot start fifo thread
@ -575,6 +576,26 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken.
0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type
0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn
0x0002018a (SORRY,HIGH) = Timeout exceeded. Retry cancled.
0x0002018b (FAILURE,HIGH) = Too many CD-TEXT packs
0x0002018c (FAILURE,HIGH) = CD-TEXT pack type out of range
0x0002018d (FAILURE,HIGH) = CD-TEXT block number out of range
0x0002018e (FAILURE,HIGH) = Too many CD-TEXT packs in block
0x0002018f (FAILURE,HIGH) = CD-TEXT pack CRC mismatch
0x00020190 (WARNING,HIGH) = CD-TEXT pack CRC mismatch had to be corrected
0x00020191 (FAILURE,HIGH) = Unknown parameter in text input file
0x00020192 (FAILURE,HIGH) = Text input file sequence error
0x00020193 (FAILURE,HIGH) = Text input file readability problem
0x00020194 (FAILURE,HIGH) = Text input file syntax error or specs violation
0x00020195 (WARNING,HIGH) = Text input file warning
0x00020196 (FAILURE,HIGH) = Session has already defined tracks
0x00020197 (FAILURE,HIGH) = Unsupported text input file feature
0x00020198 (FAILURE,HIGH) = CD-TEXT pack file readability problem
0x00020199 (SORRY,HIGH) = Text input file reading aborted
0x0002019a (SORRY,HIGH) = Bad track index number
0x0002019b (SORRY,HIGH) = CD track number exceeds range of 1 to 99
0x0002019c (SORRY,HIGH) = Session has no defined tracks
libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -174,6 +174,7 @@ static unsigned char MMC_GET_MSINFO[] =
static unsigned char MMC_GET_TOC[] = { 0x43, 2, 2, 0, 0, 0, 0, 16, 0, 0 };
static unsigned char MMC_GET_TOC_FMT0[] = { 0x43, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
static unsigned char MMC_GET_ATIP[] = { 0x43, 2, 4, 0, 0, 0, 0, 16, 0, 0 };
static unsigned char MMC_GET_LEADTEXT[] = { 0x43, 2, 5, 0, 0, 0, 0, 4, 0, 0 };
static unsigned char MMC_GET_DISC_INFO[] =
{ 0x51, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
static unsigned char MMC_READ_CD[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@ -301,7 +302,7 @@ int mmc_start_if_needed(struct burn_drive *d, int flag)
}
void mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s)
int mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s)
{
struct buffer *buf = NULL;
struct command *c;
@ -309,7 +310,7 @@ void mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s)
c = &(d->casual_command);
mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_send_cue_sheet") <= 0)
return;
return 0;
BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
scsi_init_command(c, MMC_SEND_CUE_SHEET, sizeof(MMC_SEND_CUE_SHEET));
c->retry = 1;
@ -324,6 +325,11 @@ void mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s)
d->issue_command(d, c);
ex:;
BURN_FREE_MEM(buf);
if (c->error) {
d->cancel = 1;
scsi_notify_error(d, c, c->sense, 18, 2);
}
return !c->error;
}
@ -357,6 +363,7 @@ int mmc_reserve_track(struct burn_drive *d, off_t size)
c->page = NULL;
c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_reserve_timeouT;
d->issue_command(d, c);
if (c->error) {
d->cancel = 1;
@ -537,7 +544,7 @@ void mmc_close_disc(struct burn_write_opts *o)
/* a ssert(o->drive == d); */
o->multi = 0;
spc_select_write_params(d, o);
spc_select_write_params(d, NULL, 0, o);
mmc_close(d, 1, 0);
}
@ -558,7 +565,7 @@ void mmc_close_session(struct burn_write_opts *o)
/* a ssert(o->drive == d); */
o->multi = 3;
spc_select_write_params(d, o);
spc_select_write_params(d, NULL, 0, o);
mmc_close(d, 1, 0);
}
@ -588,6 +595,7 @@ void mmc_close(struct burn_drive *d, int session, int track)
c->opcode[5] = track & 0xFF;
c->page = NULL;
c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_close_timeouT;
d->issue_command(d, c);
/* ts A70918 : Immed : wait for drive to complete command */
@ -855,6 +863,7 @@ void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf)
mmc_int_to_four_char(c->opcode + 6, len);
c->page = buf;
c->dir = TO_DRIVE;
c->timeout = Libburn_scsi_write_timeouT;
d->issue_command(d, c);
@ -863,6 +872,31 @@ void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf)
d->pbf_altered = 1;
}
#ifdef Libburn_write_time_debuG
static int print_time(int flag)
{
static struct timeval prev = {0, 0};
struct timeval now;
struct timezone tz;
int ret, diff;
ret = gettimeofday(&now, &tz);
if (ret == -1)
return 0;
if (now.tv_sec - prev.tv_sec < Libburn_scsi_write_timeouT) {
diff = (now.tv_sec - prev.tv_sec) * 1000000 +
((int) (now.tv_usec) - (int) prev.tv_usec);
fprintf(stderr, "\nlibburn_DEBUG: %d.%-6d : %d\n", (int) now.tv_sec, (int) now.tv_usec, diff);
}
memcpy(&prev, &now, sizeof(struct timeval));
return 1;
}
#endif /* Libburn_write_time_debuG */
int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
{
int cancelled;
@ -870,6 +904,10 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
int len, key, asc, ascq;
char *msg = NULL;
#ifdef Libburn_write_time_debuG
extern int burn_sg_log_scsi;
#endif
c = &(d->casual_command);
#ifdef Libburn_log_in_and_out_streaM
@ -915,6 +953,11 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
if(d->wait_for_buffer_free)
mmc_wait_for_buffer_free(d, buf);
#ifdef Libburn_write_time_debuG
if (burn_sg_log_scsi & 3)
print_time(0);
#endif
/* ts A80412 */
if(d->do_stream_recording > 0 && start >= d->stream_recording_start) {
@ -935,11 +978,12 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
c->retry = 1;
c->page = buf;
c->dir = TO_DRIVE;
c->timeout = Libburn_scsi_write_timeouT;
#ifdef Libburn_log_in_and_out_streaM
/* <<< ts A61031 */
if(tee_fd!=-1) {
write(tee_fd,c->page->data,len*2048);
write(tee_fd, c->page->data, c->page->bytes);
}
#endif /* Libburn_log_in_and_out_streaM */
@ -1543,7 +1587,7 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
}
/* A80808 */
burn_disc_cd_toc_extensions(d->disc, 0);
burn_disc_cd_toc_extensions(d, 0);
ret = 1;
ex:;
@ -2023,6 +2067,77 @@ void mmc_read_disc_info(struct burn_drive *d)
}
/* @param flag bit= do not allocate text_packs
*/
static int mmc_get_leadin_text_al(struct burn_drive *d,
unsigned char **text_packs, int *alloc_len,
int flag)
{
struct buffer *buf = NULL;
struct command *c = NULL;
unsigned char *data;
int ret, data_length;
*text_packs = NULL;
BURN_ALLOC_MEM(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1);
scsi_init_command(c, MMC_GET_LEADTEXT, sizeof(MMC_GET_LEADTEXT));
c->dxfer_len = *alloc_len;
c->opcode[7]= (c->dxfer_len >> 8) & 0xff;
c->opcode[8]= c->dxfer_len & 0xff;
c->retry = 1;
c->page = buf;
c->page->bytes = 0;
c->page->sectors = 0;
c->dir = FROM_DRIVE;
d->issue_command(d, c);
if (c->error)
{ret = 0; goto ex;}
data = c->page->data;
data_length = (data[0] << 8) + data[1];
*alloc_len = data_length + 2;
if (*alloc_len >= 22 && !(flag & 1)) {
BURN_ALLOC_MEM(*text_packs, unsigned char, *alloc_len - 4);
memcpy(*text_packs, data + 4, *alloc_len - 4);
}
ret = 1;
ex:;
BURN_FREE_MEM(c);
BURN_FREE_MEM(buf);
return ret;
}
/* ts B11201 */
/* Read the CD-TEXT data from the Lead-in of an Audio CD
*/
int mmc_get_leadin_text(struct burn_drive *d,
unsigned char **text_packs, int *num_packs, int flag)
{
int alloc_len = 4, ret;
*num_packs = 0;
if (mmc_function_spy(d, "mmc_get_leadin_text") <= 0)
return -1;
ret = mmc_get_leadin_text_al(d, text_packs, &alloc_len, 1);
if (ret <= 0 || alloc_len < 22)
return (ret > 0 ? 0 : ret);
ret = mmc_get_leadin_text_al(d, text_packs, &alloc_len, 0);
if (ret <= 0 || alloc_len < 22) {
if (*text_packs != NULL)
free(*text_packs);
*text_packs = NULL;
return (ret > 0 ? 0 : ret);
}
*num_packs = (alloc_len - 4) / 18;
return ret;
}
void mmc_read_atip(struct burn_drive *d)
{
struct buffer *buf = NULL;
@ -2050,8 +2165,8 @@ void mmc_read_atip(struct burn_drive *d)
scsi_init_command(c, MMC_GET_ATIP, sizeof(MMC_GET_ATIP));
c->dxfer_len = alloc_len;
c->opcode[7]= (c->dxfer_len >> 8) & 0xff;
c->opcode[8]= c->dxfer_len & 0xff;
c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
c->opcode[8] = c->dxfer_len & 0xff;
c->retry = 1;
c->page = buf;
c->page->bytes = 0;
@ -2061,17 +2176,17 @@ void mmc_read_atip(struct burn_drive *d)
d->issue_command(d, c);
/* ts B00501 : now caring for error */
if (c->error) {
d->erasable= 0;
d->start_lba= 0;
d->end_lba= 0;
d->erasable = 0;
d->start_lba = 0;
d->end_lba = 0;
goto ex;
}
/* ts A61021 */
data = c->page->data;
d->erasable= !!(data[6]&64);
d->start_lba= burn_msf_to_lba(data[8],data[9],data[10]);
d->end_lba= burn_msf_to_lba(data[12],data[13],data[14]);
d->erasable = !!(data[6]&64);
d->start_lba = burn_msf_to_lba(data[8],data[9],data[10]);
d->end_lba = burn_msf_to_lba(data[12],data[13],data[14]);
if (data[6]&4) {
if (speed_value[(data[16]>>4)&7] > 0) {
d->mdata->min_write_speed =
@ -2271,6 +2386,7 @@ void mmc_erase(struct burn_drive *d, int fast)
c->retry = 1;
c->page = NULL;
c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_blank_timeouT;
d->issue_command(d, c);
}
@ -2313,6 +2429,7 @@ void mmc_perform_opc(struct burn_drive *d)
c->opcode[1] = 1;
c->page = NULL;
c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_opc_timeouT;
d->issue_command(d, c);
}
@ -2475,14 +2592,21 @@ void mmc_set_speed(struct burn_drive *d, int r, int w)
static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
{
struct buffer *buf = NULL;
int len, cp, descr_len = 0, feature_code, only_current = 1;
int len, cp, descr_len = 0, feature_code, only_current = 1, i;
int old_alloc_len, only_current_profile = 0, key, asc, ascq, ret;
int feature_is_current;
unsigned char *descr, *prf, *up_to, *prf_end;
struct command *c = NULL;
int phys_if_std = 0;
char *phys_name = "";
/* Enable this to get loud and repeated reports about the feature set :
# define Libburn_print_feature_descriptorS 1
*/
#ifdef Libburn_print_feature_descriptorS
int prf_number;
only_current = 0;
#endif
if (*alloc_len < 8)
@ -2608,9 +2732,6 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
d->current_is_supported_profile = 1;
#endif
/* Enable this to get loud and repeated reports about the feature set :
#define Libburn_print_feature_descriptorS 1
*/
/* ts A70127 : Interpret list of profile and feature descriptors.
see mmc5r03c.pdf 5.2
>>> Ouch: What to do if list is larger than buffer size.
@ -2629,14 +2750,19 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
for (descr = c->page->data + 8; descr + 3 < up_to; descr += descr_len){
descr_len = 4 + descr[3];
feature_code = (descr[0] << 8) | descr[1];
if (only_current && !(descr[2] & 1))
feature_is_current = descr[2] & 1;
if (only_current && !feature_is_current)
continue;
#ifdef Libburn_print_feature_descriptorS
fprintf(stderr,
"LIBBURN_EXPERIMENTAL : %s feature %4.4Xh\n",
descr[2] & 1 ? "+" : "-",
"LIBBURN_EXPERIMENTAL : %s feature %4.4Xh :",
(descr[2] & 1) ? "+" : "-",
feature_code);
if (feature_code != 0x00)
for (i = 2; i < descr_len; i++)
fprintf(stderr, " %2.2X", descr[i]);
fprintf(stderr, "\n");
#endif /* Libburn_print_feature_descriptorS */
if (feature_code == 0x0) {
@ -2663,9 +2789,8 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
}
} else if (feature_code == 0x21) {
int i;
d->current_has_feat21h = (descr[2] & 1);
d->current_has_feat21h = feature_is_current;
for (i = 0; i < descr[7]; i++) {
if (i == 0 || descr[8 + i] == 16)
d->current_feat21h_link_size =
@ -2680,8 +2805,10 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
}
} else if (feature_code == 0x23) {
d->current_feat23h_byte4 = descr[4];
d->current_feat23h_byte8 = descr[8];
if (feature_is_current) {
d->current_feat23h_byte4 = descr[4];
d->current_feat23h_byte8 = descr[8];
}
#ifdef Libburn_print_feature_descriptorS
if (cp >= 0x41 && cp <= 0x43)
fprintf(stderr,
@ -2694,7 +2821,7 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
#endif /* Libburn_print_feature_descriptorS */
} else if (feature_code == 0x2F) {
if (descr[2] & 1)
if (feature_is_current)
d->current_feat2fh_byte4 = descr[4];
#ifdef Libburn_print_feature_descriptorS
@ -2969,6 +3096,7 @@ void mmc_sync_cache(struct burn_drive *d)
c->opcode[1] |= 2; /* ts A70918 : Immed */
c->page = NULL;
c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_sync_timeouT;
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
@ -3113,6 +3241,7 @@ int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
c->page->bytes = 12;
c->page->sectors = 0;
c->dir = TO_DRIVE;
c->timeout = Libburn_mmc_blank_timeouT;
memset(c->page->data, 0, c->page->bytes);
descr[0] = 0;
@ -3890,10 +4019,14 @@ int mmc_get_write_performance(struct burn_drive *d)
memset(pd, 0, 2 + d->mdata->write_page_length);
is the eventual duty of the caller.
*/
int mmc_compose_mode_page_5(struct burn_drive *d,
const struct burn_write_opts *o,
int mmc_compose_mode_page_5(struct burn_drive *d, struct burn_session *s,
int tnum, const struct burn_write_opts *o,
unsigned char *pd)
{
unsigned char *catalog = NULL;
char isrc_text[13];
struct isrc *isrc;
pd[0] = 5;
pd[1] = d->mdata->write_page_length;
@ -4003,6 +4136,45 @@ fprintf(stderr, "libburn_EXPERIMENTAL: block_type = %d, pd[4]= %u\n",
/*XXX need session format! */
/* ts A61229 : but session format (pd[8]) = 0 seems ok */
/* Media Catalog Number at byte 16 to 31,
MMC-5, 7.5, Tables 664, 670
*/
if (o->has_mediacatalog)
catalog = (unsigned char *) o->mediacatalog;
else if (s != NULL) {
if (s->mediacatalog[0])
catalog = s->mediacatalog;
}
if (catalog != NULL && d->mdata->write_page_length >= 30) {
pd[16] = 0x80; /* MCVAL */
memcpy(pd + 17, catalog, 13);
}
/* ISRC at bytes 32 to 47. Tables 664, 671 */
/* SCMS at byte 3 bit 4 */
isrc_text[0] = 0;
if (s != NULL && o->write_type == BURN_WRITE_TAO) {
if (tnum >= 0 && tnum < s->tracks) {
if (s->track[tnum]->isrc.has_isrc) {
isrc = &(s->track[tnum]->isrc);
isrc_text[0] = isrc->country[0];
isrc_text[1] = isrc->country[1];
isrc_text[2] = isrc->owner[0];
isrc_text[3] = isrc->owner[1];
isrc_text[4] = isrc->owner[2];
sprintf(isrc_text + 5, "%-2.2u%-5.5u",
(unsigned int) isrc->year,
isrc->serial);
}
if ((s->track[tnum]->mode & BURN_SCMS) &&
!(s->track[tnum]->mode & BURN_COPY))
pd[3] |= 0x10;
}
}
if (isrc_text[0] != 0 && d->mdata->write_page_length >= 46) {
pd[32] = 0x80; /* TCVAL */
memcpy(pd + 33, isrc_text, 12);
}
}
return 1;
}

View File

@ -48,7 +48,8 @@ void mmc_get_configuration(struct burn_drive *);
@return 1=nwa is valid , 0=nwa is not valid , -1=error */
int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa);
void mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *);
/* ts B11228 : changed from void to int */
int mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *);
/* ts A61023 : get size and free space of drive buffer */
int mmc_read_buffer_capacity(struct burn_drive *d);
@ -71,12 +72,19 @@ int mmc_get_write_performance(struct burn_drive *d);
is the eventual duty of the caller.
*/
int mmc_compose_mode_page_5(struct burn_drive *d,
struct burn_session *s, int tno,
const struct burn_write_opts *o,
unsigned char *pd);
/* ts A70201 */
int mmc_four_char_to_int(unsigned char *data);
/* ts A70201 :
Common track info fetcher for mmc_get_nwa() and mmc_fake_toc()
*/
int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf,
int alloc_len);
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occured */
int mmc_read_10(struct burn_drive *d, int start, int amount,
struct buffer *buf);
@ -115,4 +123,9 @@ int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category,
char **book_name, int *part_version, int *num_layers,
int *num_blocks, int flag);
/* ts B11201 */
int mmc_get_leadin_text(struct burn_drive *d,
unsigned char **text_packs, int *num_packs, int flag);
#endif /*__MMC*/

View File

@ -12,6 +12,8 @@
#include "options.h"
#include "drive.h"
#include "transport.h"
#include "init.h"
#include "write.h"
/* ts A61007 */
/* #include <a ssert.h> */
@ -51,6 +53,9 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
opts->do_stream_recording = 0;
opts->dvd_obs_override = 0;
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
opts->text_packs = NULL;
opts->num_text_packs = 0;
opts->no_text_pack_crc_check = 0;
opts->has_mediacatalog = 0;
opts->format = BURN_CDROM;
opts->multi = 0;
@ -60,8 +65,11 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
void burn_write_opts_free(struct burn_write_opts *opts)
{
if (--opts->refcount <= 0)
free(opts);
if (--opts->refcount > 0)
return;
if (opts->text_packs != NULL)
free(opts->text_packs);
free(opts);
}
struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
@ -178,7 +186,7 @@ void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
unsigned char mediacatalog[13])
{
memcpy(opts->mediacatalog, &mediacatalog, 13);
memcpy(opts->mediacatalog, mediacatalog, 13);
}
@ -189,6 +197,64 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi)
}
/* ts B11204 */
/* @param flag bit0=do not verify checksums
bit1= repair mismatching checksums
bit2= repair checksums if they are 00 00 with each pack
*/
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
unsigned char *text_packs,
int num_packs, int flag)
{
int ret;
unsigned char *pack_buffer = NULL;
if (num_packs > Libburn_leadin_cdtext_packs_maX ) {
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
0x0002018b,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Too many CD-TEXT packs", 0, 0);
ret= 0; goto ex;
}
if (num_packs > 0)
BURN_ALLOC_MEM(pack_buffer, unsigned char, num_packs * 18);
if (opts->text_packs != NULL) {
free(opts->text_packs);
opts->text_packs = NULL;
}
if (flag & 1) {
opts->no_text_pack_crc_check = 1;
} else {
opts->no_text_pack_crc_check = 0;
ret = burn_cdtext_crc_mismatches(text_packs, num_packs,
(flag >> 1) & 3);
if (ret > 0) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002018f,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"CD-TEXT pack CRC mismatch", 0, 0);
ret = 0; goto ex;
} else if (ret < 0) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020190,
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
"CD-TEXT pack CRC mismatch had to be corrected",
0, 0);
}
}
if (num_packs > 0) {
memcpy(pack_buffer, text_packs, num_packs * 18);
opts->text_packs = pack_buffer;
}
opts->num_text_packs = num_packs;
ret = 1;
ex:;
return ret;
}
/* ts A61222 */
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
{
@ -296,6 +362,10 @@ do_sao:;
{wt = BURN_WRITE_SAO; goto ex;}
no_sao:;
try_tao:;
if (opts->num_text_packs > 0) {
strcat(reasons, "CD-TEXT: write type SAO required, ");
{wt = BURN_WRITE_NONE; goto ex;}
}
if ((flag & 1) && opts->write_type != BURN_WRITE_TAO)
goto try_raw;
reason_pt = reasons + strlen(reasons);

View File

@ -69,6 +69,10 @@ struct burn_write_opts
Values 0 or >= 32 counted in 2 KB blocks. */
int stdio_fsync_size;
/* ts B11203 : CD-TEXT */
unsigned char *text_packs;
int num_text_packs;
int no_text_pack_crc_check;
/** A disc can have a media catalog number */
int has_mediacatalog;
@ -84,6 +88,13 @@ struct burn_write_opts
*/
#define Libburn_stdio_fsync_limiT 8192
/* Maximum number of Lead-in text packs.
READ TOC/PMA/ATIP can at most return 3640.7 packs.
The sequence counters of the packs have 8 bits. There are 8 blocks at most.
Thus max 2048 packs.
*/
#define Libburn_leadin_cdtext_packs_maX 2048
/** Options for disc reading operations. This should be created with
burn_read_opts_new() and freed with burn_read_opts_free(). */

View File

@ -465,9 +465,9 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
wpt = data;
for (; start < upto; start += chunksize) {
chunksize = upto - start;
if (chunksize > 16) {
chunksize = 16;
cpy_size = 16 * 2048;
if (chunksize > (BUFFER_SIZE / 2048)) {
chunksize = (BUFFER_SIZE / 2048);
cpy_size = BUFFER_SIZE;
} else
cpy_size = data_size - *data_count;
if (flag & 2)

View File

@ -67,6 +67,7 @@ void sbc_load(struct burn_drive *d)
/* c->opcode[1] |= 1; / * ts A70918 : Immed */
c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_load_timeouT;
d->issue_command(d, c);
if (c->error)
return;

View File

@ -223,6 +223,43 @@ ex:;
}
}
/* ts B20113 : outsourced from get_sector() */
int sector_write_buffer(struct burn_drive *d,
struct burn_track *track, int flag)
{
int err, i;
struct buffer *out;
out = d->buffer;
if (out->sectors <= 0)
return 2;
err = d->write(d, d->nwa, out);
if (err == BE_CANCELLED)
return 0;
/* ts A61101 */
if(track != NULL) {
track->writecount += out->bytes;
track->written_sectors += out->sectors;
/* Determine current index */
for (i = d->progress.index; i + 1 < track->indices; i++) {
if (track->index[i + 1] > d->nwa + out->sectors)
break;
d->progress.index = i + 1;
}
}
/* ts A61119 */
d->progress.buffered_bytes += out->bytes;
d->nwa += out->sectors;
out->bytes = 0;
out->sectors = 0;
return 1;
}
/* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer
and to count hand outs as well as reserved bytes */
/* ts A61101 : added parameter track for counting written bytes */
@ -231,7 +268,7 @@ static unsigned char *get_sector(struct burn_write_opts *opts,
{
struct burn_drive *d = opts->drive;
struct buffer *out = d->buffer;
int outmode, seclen;
int outmode, seclen, write_ret;
unsigned char *ret;
outmode = get_outmode(opts);
@ -250,22 +287,9 @@ static unsigned char *get_sector(struct burn_write_opts *opts,
/* (there is enough buffer size reserve for track->cdxa_conversion) */
if (out->bytes + seclen > BUFFER_SIZE ||
(opts->obs > 0 && out->bytes + seclen > opts->obs)) {
int err;
err = d->write(d, d->nwa, out);
if (err == BE_CANCELLED)
write_ret = sector_write_buffer(d, track, 0);
if (write_ret <= 0)
return NULL;
/* ts A61101 */
if(track != NULL) {
track->writecount += out->bytes;
track->written_sectors += out->sectors;
}
/* ts A61119 */
d->progress.buffered_bytes += out->bytes;
d->nwa += out->sectors;
out->bytes = 0;
out->sectors = 0;
}
ret = out->data + out->bytes;
out->bytes += seclen;

View File

@ -24,6 +24,10 @@ int sector_postgap(struct burn_write_opts *, unsigned char tno,
int sector_lout(struct burn_write_opts *, unsigned char control, int mode);
int sector_data(struct burn_write_opts *, struct burn_track *t, int psub);
/* ts B20113 */
int sector_write_buffer(struct burn_drive *d,
struct burn_track *track, int flag);
/* ts A61009 */
int sector_headers_is_ok(struct burn_write_opts *o, int mode);

View File

@ -548,8 +548,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
ccb->csio.cdb_len = c->oplen;
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
memset(&ccb->csio.sense_data, 0, sizeof (ccb->csio.sense_data));
if (c->page) {
ccb->csio.data_ptr = c->page->data;
if (c->dir == FROM_DRIVE) {
@ -570,6 +568,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
}
do {
memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
err = cam_send_ccb(d->cam, ccb);
if (err == -1) {
libdax_msgs_submit(libdax_messenger,

View File

@ -768,10 +768,11 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
mmc_function_spy(NULL, "sg_issue_command");
if (d->cam == NULL) {
c->error = 0;
c->error = 0;
memset(c->sense, 0, sizeof(c->sense));
if (d->cam == NULL)
return 0;
}
if (burn_sg_log_scsi & 1) {
if (fp == NULL) {
fp= fopen("/tmp/libburn_sg_command_log", "a");
@ -783,6 +784,10 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
scsi_log_cmd(c,fp,0);
c->error = 0;
if (c->timeout > 0)
timeout_ms = c->timeout;
else
timeout_ms = 200000;
ccb = cam_getccb(d->cam);
cam_fill_csio(&ccb->csio,
@ -794,7 +799,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
0, /* dxfer_len */
sizeof (ccb->csio.sense_data), /* sense_len */
0, /* cdb_len */
30*1000); /* timeout */
timeout_ms); /* timeout */
switch (c->dir) {
case TO_DRIVE:
ccb->csio.ccb_h.flags |= CAM_DIR_OUT;
@ -827,8 +832,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
ccb->csio.cdb_len = c->oplen;
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
memset(&ccb->csio.sense_data, 0, sizeof (ccb->csio.sense_data));
if (c->page) {
ccb->csio.data_ptr = c->page->data;
if (c->dir == FROM_DRIVE) {
@ -854,8 +857,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
}
start_time = time(NULL);
timeout_ms = 200000;
for (i = 0; !done; i++) {
memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
memset(c->sense, 0, sizeof(c->sense));
err = cam_send_ccb(d->cam, ccb);
@ -963,6 +967,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
sense_len, 0, start_time,
timeout_ms, i,
2 | !!ignore_error);
if (d->cancel)
done = 1;
} else {
done = 1;
}

View File

@ -627,6 +627,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
cdio_mmc_request_sense_t *sense_pt = NULL;
c->error = 0;
memset(c->sense, 0, sizeof(c->sense));
if (d->p_cdio == NULL) {
return 0;
}
@ -660,11 +662,16 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
/* retry-loop */
start_time = time(NULL);
timeout_ms = 200000;
if (c->timeout > 0)
timeout_ms = c->timeout;
else
timeout_ms = 200000;
for(i = 0; !done; i++) {
memset(c->sense, 0, sizeof(c->sense));
i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction,
dxfer_len, c->page->data);
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
if (sense_valid >= 18) {
memcpy(c->sense, (unsigned char *) sense_pt,
@ -711,6 +718,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
sense_len = 0;
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len,
0, start_time, timeout_ms, i, 2);
if (d->cancel)
done = 1;
} /* end of retry-loop */

View File

@ -411,7 +411,7 @@ static int sgio_log_reply(unsigned char *opcode, int data_dir,
ret = scsi_log_reply(opcode, data_dir, data, dxfer_len, fp_in,
sense, sense_len, duration, flag);
return 1;
return ret;
}
@ -686,10 +686,15 @@ static int sg_fcntl_lock(int *fd, char *fd_name, int l_type, int verbous)
/* ts A60926 */
/* @param scan_mode 0= open for drivce aquiration
1= open for scanning with guessed names
2= open for scanning with /proc/sys/dev/cdrom/info names
*/
static int sg_open_drive_fd(char *fname, int scan_mode)
{
int open_mode = O_RDWR, fd, tries= 0;
int open_mode = O_RDWR, fd, tries= 0, is_std_adr, report_as_note = 0;
char msg[81];
struct stat stbuf;
/* ts A70409 : DDLP-B */
/* >>> obtain single lock on fname */
@ -746,12 +751,26 @@ try_open:;
return -1;
}
if (scan_mode)
return -1;
sprintf(msg, "Failed to open device '%s'",fname);
libdax_msgs_submit(libdax_messenger, -1, 0x00020005,
if (scan_mode) {
is_std_adr = (strncmp(fname, "/dev/sr", 7) == 0 ||
strncmp(fname, "/dev/scd", 8) == 0);
if(scan_mode == 1 && is_std_adr &&
stat(fname, &stbuf) != -1)
report_as_note = 1;
else if(scan_mode == 2 && (!is_std_adr) &&
stat(fname, &stbuf) != -1)
report_as_note = 1;
if (report_as_note)
libdax_msgs_submit(libdax_messenger, -1,
0x0002000e,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
msg, errno, 0);
} else {
libdax_msgs_submit(libdax_messenger, -1, 0x00020005,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, errno, 0);
}
return -1;
}
sg_fcntl_lock(&fd, fname, F_WRLCK, 1);
@ -1080,11 +1099,12 @@ ex:;
}
/* @param flag bit0= do not complain about failure to open /dev/sr /dev/scd */
static int sg_open_for_enumeration(char *fname, int flag)
{
int fd;
fd = sg_open_drive_fd(fname, 1);
fd = sg_open_drive_fd(fname, 1 + (flag & 1));
if (fd < 0) {
if (linux_sg_enumerate_debug || linux_ata_enumerate_verbous)
fprintf(stderr, "open failed, errno=%d '%s'\n",
@ -1225,6 +1245,7 @@ static int fname_drive_is_listed(char *fname, int flag)
/* ts A80731 : Directly open the given address.
@param flag bit0= do not complain about missing file
bit1= do not check whether drive is already listed
bit2= do not complain about failure to open /dev/sr /dev/scd
*/
static int fname_enumerate(char *fname, int flag)
{
@ -1247,7 +1268,7 @@ static int fname_enumerate(char *fname, int flag)
{ret = -1; goto ex;}
}
fd = sg_open_for_enumeration(fname, 0);
fd = sg_open_for_enumeration(fname, !!(flag & 4));
if (fd < 0)
{ret = 0; goto ex;}
is_ata = is_ata_drive(fname, fd);
@ -1399,7 +1420,7 @@ static int add_proc_info_drives(int flag)
for (i = 0; i < list_count; i++) {
if (burn_drive_is_banned(list[i]))
continue;
ret = fname_enumerate(list[i], 1);
ret = fname_enumerate(list[i], 1 | 4);
if (ret == 1)
count++;
}
@ -1877,6 +1898,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
BURN_ALLOC_MEM(msg, char, 161);
c->error = 0;
memset(c->sense, 0, sizeof(c->sense));
/* <<< ts A60821
debug: for tracing calls which might use open drive fds */
sprintf(msg, "sg_issue_command d->fd= %d d->released= %d\n",
@ -1929,8 +1953,10 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
s.cmdp = c->opcode;
s.mx_sb_len = 32;
s.sbp = c->sense;
memset(c->sense, 0, sizeof(c->sense));
s.timeout = 200000;
if (c->timeout > 0)
s.timeout = c->timeout;
else
s.timeout = Libburn_scsi_default_timeouT;
if (c->page && !no_c_page) {
s.dxferp = c->page->data;
if (c->dir == FROM_DRIVE) {
@ -1964,6 +1990,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
start_time = time(NULL);
for(i = 0; !done; i++) {
memset(c->sense, 0, sizeof(c->sense));
err = ioctl(d->fd, SG_IO, &s);
/* ts A61010 */
@ -1982,6 +2010,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
}
done = scsi_eval_cmd_outcome(d, c, fp, s.sbp, s.sb_len_wr,
s.duration, start_time, s.timeout, i, 0);
if (d->cancel)
done = 1;
}
if (s.host_status != Libburn_sg_host_oK ||

View File

@ -587,6 +587,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
c->error = 0;
memset(c->sense, 0, sizeof(c->sense));
if (d->fd == -1)
return 0;
@ -600,13 +601,17 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
if (burn_sg_log_scsi & 3)
scsi_log_cmd(c,fp,0);
if (c->timeout > 0)
timeout_ms = c->timeout;
else
timeout_ms = 200000;
memset (&cgc, 0, sizeof (struct uscsi_cmd));
/* No error messages, no retries,
do not execute with other commands, request sense data
*/
cgc.uscsi_flags = USCSI_SILENT | USCSI_DIAGNOSE | USCSI_ISOLATE
| USCSI_RQENABLE;
cgc.uscsi_timeout = 200;
cgc.uscsi_timeout = timeout_ms / 1000;
cgc.uscsi_cdb = (caddr_t) c->opcode;
cgc.uscsi_bufaddr = (caddr_t) c->page->data;
if (c->dir == TO_DRIVE) {
@ -629,9 +634,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
/* retry-loop */
start_time = time(NULL);
timeout_ms = 200000;
for(i = 0; !done; i++) {
memset(c->sense, 0, sizeof(c->sense));
ret = ioctl(d->fd, USCSICMD, &cgc);
/* For cgc.uscsi_status see SAM-3 5.3.1, Table 22
@ -666,6 +671,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
sense_len = 0;
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, 0,
start_time, timeout_ms, i, 2);
if (d->cancel)
done = 1;
} /* end of retry-loop */

View File

@ -15,6 +15,7 @@
#include "libburn.h"
#include "source.h"
#include "structure.h"
#include "init.h"
void burn_source_free(struct burn_source *src)
{
@ -41,12 +42,10 @@ struct burn_source *burn_source_new(void)
{
struct burn_source *out;
out = calloc(1, sizeof(struct burn_source));
/* ts A70825 */
/* ts A70825 , B11219 */
out = burn_alloc_mem(sizeof(struct burn_source), 1, 0);
if (out == NULL)
return NULL;
memset((char *) out, 0, sizeof(struct burn_source));
out->refcount = 1;
return out;

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -73,6 +73,7 @@ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen)
c->error = 0;
c->retry = 0;
c->page = NULL;
c->timeout = Libburn_scsi_default_timeouT;
return 1;
}
@ -101,7 +102,8 @@ int spc_decode_sense(unsigned char *sense, int senselen,
}
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq)
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq,
int *progress)
{
struct command *c;
@ -114,8 +116,13 @@ int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq)
c->dir = NO_TRANSFER;
d->issue_command(d, c);
*key = *asc = *ascq = 0;
*progress = -1;
if (c->error) {
spc_decode_sense(c->sense, 0, key, asc, ascq);
if (c->sense[0] == 0x70 &&
((c->sense[2] & 0x0f) == 0 || (c->sense[2] & 0x0f) == 2) &&
(c->sense[15] & 0x80))
*progress = (c->sense[16] << 8) + c->sense[17];
return (key == 0);
}
return 1;
@ -124,9 +131,9 @@ int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq)
int spc_test_unit_ready(struct burn_drive *d)
{
int key,asc,ascq;
int key, asc, ascq, progress;
return spc_test_unit_ready_r(d, &key, &asc, &ascq);
return spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress);
}
@ -140,7 +147,7 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
{
int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0;
static double tests_per_second = 2.0;
int sleep_usecs, loop_limit, clueless_timeout;
int sleep_usecs, loop_limit, clueless_timeout, progress;
char *msg = NULL;
unsigned char sense[14];
@ -153,7 +160,7 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
usleep(sleep_usecs);
for(i = !(flag & 1); i < loop_limit; i++) {
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq);
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress);
if (ret > 0) /* ready */
break;
if (key!=0x2 || asc!=0x4) {
@ -253,17 +260,37 @@ void spc_request_sense(struct burn_drive *d, struct buffer *buf)
d->issue_command(d, c);
}
/* @return -2 = drive is ready , -1 = not ready, but no progress reported
>= 0 progress indication between 0 and 65535
*/
int spc_get_erase_progress(struct burn_drive *d)
{
struct buffer *b = NULL;
int ret;
int ret, key, asc, ascq, progress;
if (mmc_function_spy(d, "get_erase_progress") <= 0)
{ret = 0; goto ex;}
/* ts B20104 :
TEST UNIT READY seems to be more reliable than REQUEST SENSE.
Nevertheless growisofs still uses the latter as fallback.
*/
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress);
if (ret > 0)
{ret = -2; goto ex;}
if (progress >= 0)
{ret = progress; goto ex;}
/* Fallback to request sense */
BURN_ALLOC_MEM(b, struct buffer, 1);
spc_request_sense(d, b);
ret = (b->data[16] << 8) | b->data[17];
/* Checking the preconditions as of SPC-3 4.5.2.4.4 and 4.5.3 */
ret = -1;
if (b->data[0] == 0x70 &&
((b->data[2] & 0x0f) == 0 || (b->data[2] & 0x0f) == 2) &&
(b->data[15] & 0x80))
ret = (b->data[16] << 8) | b->data[17];
ex:;
BURN_FREE_MEM(b);
return ret;
@ -718,8 +745,8 @@ Although command MODE SELECT is SPC, the content of the
Write Parameters Mode Page (05h) is MMC (Table 108 in MMC-1).
Thus the filling of the mode page is done by mmc_compose_mode_page_5().
*/
void spc_select_write_params(struct burn_drive *d,
const struct burn_write_opts *o)
void spc_select_write_params(struct burn_drive *d, struct burn_session *s,
int tnum, const struct burn_write_opts *o)
{
struct buffer *buf = NULL;
struct command *c = NULL;
@ -776,7 +803,7 @@ void spc_select_write_params(struct burn_drive *d,
c->page->bytes = alloc_len;
/* ts A61229 */
if (mmc_compose_mode_page_5(d, o, c->page->data + 8) <= 0)
if (mmc_compose_mode_page_5(d, s, tnum, o, c->page->data + 8) <= 0)
goto ex;
c->dir = TO_DRIVE;
@ -1041,6 +1068,11 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq);
msg= msg + strlen(msg);
if (key_def[*key & 0xf][0] != '(') {
sprintf(msg, "%s. ", key_def[*key & 0xf]);
msg= msg + strlen(msg);
}
switch (*asc) {
case 0x00:
if (*key > 0 || *ascq > 0)
@ -1050,17 +1082,15 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
case 0x02:
sprintf(msg, "Not ready");
return RETRY;
goto return_retry;
case 0x04:
if (*ascq == 1)
sprintf(msg,
"Logical unit is in the process of becoming ready");
else
sprintf(msg, "Logical unit is not ready");
return RETRY;
goto return_retry;
case 0x08:
if (*key != 4)
break;
if (*ascq == 0)
sprintf(msg, "Logical unit communication failure");
else if (*ascq == 1)
@ -1069,10 +1099,10 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
sprintf(msg, "Logical unit communication parity error");
else if (*ascq == 3)
sprintf(msg, "Logical unit communication crc error");
return RETRY;
case 0x09:
if (*key != 4)
else
break;
goto return_retry;
case 0x09:
if (*ascq == 0)
sprintf(msg, "Track following error");
else if (*ascq == 1)
@ -1085,24 +1115,27 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
sprintf(msg, "Head select fault");
else
break;
return FAIL;
goto return_fail;
case 0x0C:
if (*key == 2 && *ascq == 7)
sprintf(msg, "Write error, recovery needed");
else if (*key == 2 && *ascq == 0x0f)
sprintf(msg, "Defects in error window");
else if (*key == 3 && *ascq == 2)
sprintf(msg, "Write error, auto reallocation failed");
else if (*key == 3 && *ascq == 9)
sprintf(msg, "Write error, loss of streaming");
else if (*key == 3)
if (*ascq == 0)
sprintf(msg, "Write error");
else if (*ascq == 1)
sprintf(msg,
"Write error, recovered with auto-allocation");
else if (*ascq == 2)
sprintf(msg, "Write error, auto reallocation failed");
else if (*ascq == 7)
sprintf(msg, "Write error, recovery needed");
else if (*ascq == 8)
sprintf(msg, "Write error, recovery failed");
else if (*ascq == 9)
sprintf(msg, "Write error, loss of streaming");
else if (*ascq == 0x0f)
sprintf(msg, "Defects in error window");
else
break;
return FAIL;
goto return_fail;
case 0x11:
if (*key != 3)
break;
if (*ascq == 0)
sprintf(msg, "Unrecovered read error");
else if (*ascq == 1)
@ -1115,70 +1148,73 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
sprintf(msg, "CIRC uncorrectable error");
else
break;
return FAIL;
goto return_fail;
case 0x15:
if (*key != 3 && *key != 4)
if (*ascq == 0)
sprintf(msg, "Random positioning error");
else if (*ascq == 1)
sprintf(msg, "Mechanical positioning error");
else
break;
sprintf(msg, "Random positioning error");
return FAIL;
goto return_fail;
case 0x1a:
if (*key != 5)
if (*ascq == 0)
sprintf(msg, "Parameter list length error");
else
break;
sprintf(msg, "Parameter list length error");
return FAIL;
goto return_fail;
case 0x1b:
if (*key != 4)
if (*ascq == 0)
sprintf(msg, "Synchronous data transfer error");
else
break;
sprintf(msg, "Synchronous data transfer error");
return FAIL;
goto return_fail;
case 0x20:
if (*key != 5)
if (*ascq == 0)
sprintf(msg, "Invalid command operation code");
else
break;
sprintf(msg, "Invalid command operation code");
return FAIL;
goto return_fail;
case 0x21:
if (*key != 5)
break;
if (*ascq == 0)
sprintf(msg, "Lba out of range");
else if (*ascq == 1)
sprintf(msg, "Invalid element address");
else if (*ascq == 2)
sprintf(msg, "Invalid address for write");
else if (*ascq == 3)
sprintf(msg, "Invalid write crossing layer jump");
else
sprintf(msg, "Invalid address");
return FAIL;
break;
goto return_fail;
case 0x24:
if (*key != 5)
if (*ascq == 0)
sprintf(msg, "Invalid field in cdb");
else
break;
sprintf(msg, "Invalid field in cdb");
return FAIL;
goto return_fail;
case 0x26:
if (*key != 5)
break;
if (*ascq == 1)
if (*ascq == 0)
sprintf(msg, "Invalid field in parameter list");
else if (*ascq == 1)
sprintf(msg, "Parameter not supported");
else if (*ascq == 2)
sprintf(msg, "Parameter value invalid");
else
sprintf(msg, "Invalid field in parameter list");
return FAIL;
break;
goto return_fail;
case 0x27:
if (*key != 7)
break;
sprintf(msg, "Write protected");
return FAIL;
goto return_fail;
case 0x28:
if (*key != 6)
break;
if (*ascq == 0)
sprintf(msg, "Medium may have changed");
else if (*ascq == 2)
sprintf(msg, "Format layer may have changed");
else
break;
return RETRY;
goto return_retry;
case 0x29:
if (*key != 6)
break;
if (*ascq == 0)
sprintf(msg,
"Power on, reset, or bus device reset occured");
@ -1192,28 +1228,23 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
sprintf(msg, "Device internal reset");
else
break;
return RETRY;
goto return_retry;
case 0x2c:
if (*key != 5)
break;
if (*ascq == 0)
sprintf(msg, "Command sequence error");
else
break;
return FAIL;
goto return_fail;
case 0x2e:
if (*key != 6)
break;
if (*ascq == 0)
sprintf(msg,
"Insufficient time for operation");
sprintf(msg, "Insufficient time for operation");
else
break;
return FAIL;
goto return_fail;
case 0x30:
if (*key != 2 && *key != 5)
break;
if (*ascq == 1)
if (*ascq == 0)
sprintf(msg, "Incompatible medium installed");
else if (*ascq == 1)
sprintf(msg, "Cannot read medium, unknown format");
else if (*ascq == 2)
sprintf(msg,
@ -1229,47 +1260,50 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
else if (*ascq == 7)
sprintf(msg, "Cleaning failure");
else
sprintf(msg, "Incompatible medium installed");
return FAIL;
case 0x31:
if (*key != 3)
break;
goto return_fail;
case 0x31:
if (*ascq == 0)
sprintf(msg, "Medium unformatted or format corrupted");
else if (*ascq == 1)
sprintf(msg, "Format command failed");
return FAIL;
case 0x3A:
if (*key != 2)
else
break;
if (*ascq == 1)
goto return_fail;
case 0x3A:
if (*ascq == 0)
sprintf(msg, "Medium not present");
else if (*ascq == 1)
sprintf(msg, "Medium not present, tray closed");
else if (*ascq == 2)
sprintf(msg, "Medium not present, tray open");
else if (*ascq == 3)
sprintf(msg, "Medium not present, loadable");
else
sprintf(msg, "Medium not present");
break;
d->status = BURN_DISC_EMPTY;
return FAIL;
goto return_fail;
case 0x3E:
if (*ascq == 1)
sprintf(msg, "Logical unit failure");
else if (*ascq == 2)
sprintf(msg, "Timeout on logical unit");
return FAIL;
else
break;
goto return_fail;
case 0x44:
if (*ascq == 0)
sprintf(msg, "Internal target failure");
return FAIL;
else
break;
goto return_fail;
case 0x57:
if (*key != 3 || *ascq != 0)
if (*ascq == 0)
sprintf(msg, "Unable to recover Table-of-Content");
else
break;
sprintf(msg, "Unable to recover Table-of-Content");
return FAIL;
goto return_fail;
case 0x63:
if (*key != 5)
break;
if (*ascq == 0)
sprintf(msg,
"End of user area encountered on this track");
@ -1277,51 +1311,67 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
sprintf(msg, "Packet does not fit in available space");
else
break;
return FAIL;
goto return_fail;
case 0x64:
if (*key != 5)
break;
if (*ascq == 0)
sprintf(msg, "Illegal mode for this track");
else if (*ascq == 1)
sprintf(msg, "Invalid packet size");
else
break;
return FAIL;
goto return_fail;
case 0x72:
if (*key == 3)
if (*ascq == 0)
sprintf(msg, "Session fixation error");
else if (*key == 5 && *ascq == 3)
else if (*ascq == 1)
sprintf(msg, "Session fixation error writing lead-in");
else if (*ascq == 2)
sprintf(msg,
"Session fixation error writing lead-out");
else if (*ascq == 3)
sprintf(msg,
"Session fixation error, incomplete track in session");
else if (*key == 5 && *ascq == 4)
else if (*ascq == 4)
sprintf(msg,
"Empty or partially written reserved track");
else if (*key == 5 && *ascq == 5)
sprintf(msg,
"No more track reservations allowed");
"Empty or partially written reserved track");
else if (*ascq == 5)
sprintf(msg, "No more track reservations allowed");
else
break;
return FAIL;
goto return_fail;
case 0x73:
if (*key == 3 && *ascq == 0)
if (*ascq == 0)
sprintf(msg, "CD control error");
else if (*key == 3 && *ascq == 2)
else if (*ascq == 1)
sprintf(msg, "Power calibration area almost full");
else if (*ascq == 2)
sprintf(msg, "Power calibration area is full");
else if (*key == 3 && *ascq == 3)
else if (*ascq == 3)
sprintf(msg, "Power calibration area error");
else if (*key == 3 && *ascq == 4)
else if (*ascq == 4)
sprintf(msg, "Program memory area update failure");
else if (*key == 3 && *ascq == 5)
else if (*ascq == 5)
sprintf(msg, "Program memory area is full");
else
break;
return FAIL;
goto return_fail;
}
sprintf(msg_data,
"See MMC specs: Sense Key %X \"%s\", ASC %2.2X ASCQ %2.2X",
*key & 0xf, key_def[(*key) & 0xf], *asc, *ascq);
goto return_fail;
return_fail:
strcat(msg, ".");
if (*key == 1)
return GO_ON;
return FAIL;
return_retry:;
strcat(msg, ".");
if (*key == 1)
return GO_ON;
return RETRY;
}
@ -1655,38 +1705,64 @@ int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp,
int loop_count, int flag)
{
enum response outcome;
int done = -1, usleep_time;
int done = -1, usleep_time, ret;
char *msg = NULL;
if (burn_sg_log_scsi & 3)
scsi_log_err(c, fp, sense, sense_len, duration,
(sense_len > 0) | (flag & 2));
if (sense_len <= 0)
return 1;
{done = 1; goto ex;}
outcome = scsi_error(d, sense, sense_len);
if (outcome == RETRY && c->retry && !(flag & 1)) {
/* Calming down retries and breaking up endless cycle
*/
usleep_time = Libburn_scsi_retry_usleeP +
loop_count * Libburn_scsi_retry_incR;
if (c->opcode[0] == 0x2A || c->opcode[0] == 0xAA) {
/* WRITE(10) , WRITE(12) */
usleep_time = Libburn_scsi_write_retry_usleeP +
loop_count * Libburn_scsi_write_retry_incR;
if (usleep_time > Libburn_scsi_write_retry_umaX)
usleep_time = Libburn_scsi_write_retry_umaX;
} else {
usleep_time = Libburn_scsi_retry_usleeP +
loop_count * Libburn_scsi_retry_incR;
if (usleep_time > Libburn_scsi_retry_umaX)
usleep_time = Libburn_scsi_retry_umaX;
}
if (time(NULL) + usleep_time / 1000000 - start_time >
timeout_ms / 1000 + 1) {
BURN_ALLOC_MEM(msg, char, 320);
sprintf(msg,
"Timeout exceed (%d ms). Retry canceled.\n",
timeout_ms);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002018a,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
done = 1;
goto ex;
goto err_ex;
}
usleep(usleep_time);
if (d->cancel)
{done = 1; goto ex;}
if (usleep_time > 0)
usleep(usleep_time);
if (d->cancel)
{done = 1; goto ex;}
if (burn_sg_log_scsi & 3)
scsi_log_cmd(c, fp, 0);
return 0;
{done = 0; goto ex;}
} else if (outcome == RETRY) {
done = 1;
} else if (outcome == GO_ON) {
return 1;
{done = 1; goto ex;}
} else if (outcome == FAIL) {
done = 1;
}
ex:;
err_ex:;
c->error = 1;
scsi_notify_error(d, c, sense, sense_len, 0);
ex:;
BURN_FREE_MEM(msg);
return done;
}

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -21,6 +21,7 @@ void spc_select_error_params(struct burn_drive *,
void spc_getcaps(struct burn_drive *d);
void spc_sense_write_params(struct burn_drive *);
void spc_select_write_params(struct burn_drive *,
struct burn_session *, int,
const struct burn_write_opts *);
void spc_probe_write_modes(struct burn_drive *);
void spc_request_sense(struct burn_drive *d, struct buffer *buf);
@ -28,7 +29,8 @@ int spc_block_type(enum burn_block_types b);
int spc_get_erase_progress(struct burn_drive *d);
/* ts A70315 : test_unit_ready with result parameters */
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq);
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq,
int *progress);
int spc_test_unit_ready(struct burn_drive *d);
@ -110,12 +112,45 @@ int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp_in,
int duration, time_t start_time, int timeout_ms,
int loop_count, int flag);
/* The waiting time before eventually retrying a failed SCSI command.
Before each retry wait Libburn_scsi_retry_incR longer than with
the previous one.
the previous one. At most wait for Libburn_scsi_retry_umaX microseconds.
*/
#define Libburn_scsi_retry_usleeP 100000
#define Libburn_scsi_retry_incR 100000
#define Libburn_scsi_retry_umaX 500000
/* The retry waiting time for commands WRITE(10) and WRITE(12).
*/
#define Libburn_scsi_write_retry_usleeP 0
#define Libburn_scsi_write_retry_incR 2000
#define Libburn_scsi_write_retry_umaX 25000
/* ts B11124 */
/* Millisecond timeout for quickly responding SPC, SBC, and MMC commands */
#define Libburn_scsi_default_timeouT 30000
/* WRITE(10) and WRITE(12) */
#define Libburn_scsi_write_timeouT 200000
/* RESERVE TRACK */
#define Libburn_mmc_reserve_timeouT 200000
/* CLOSE TRACK/SESSION (with Immed bit) */
#define Libburn_mmc_close_timeouT 200000
/* BLANK , FORMAT UNIT (with Immed bit) */
#define Libburn_mmc_blank_timeouT 200000
/* SEND OPC INFORMATION */
#define Libburn_mmc_opc_timeouT 200000
/* MMC_SYNC_CACHE */
#define Libburn_mmc_sync_timeouT 200000
/* START STOP UNIT with Start bit and Load bit set */
#define Libburn_mmc_load_timeouT 300000
#endif /*__SPC*/

File diff suppressed because it is too large Load Diff

View File

@ -16,13 +16,32 @@ struct isrc
unsigned int serial; /* must be 0-99999 */
};
/* ts B11206 */
#define Libburn_pack_type_basE 0x80
#define Libburn_pack_num_typeS 0x10
#define Libburn_pack_type_nameS \
"TITLE", "PERFORMER", "SONGWRITER", "COMPOSER", \
"ARRANGER", "MESSAGE", "DISCID", "GENRE", \
"TOC", "TOC2", "", "", \
"", "CLOSED", "UPC_ISRC", "BLOCKSIZE"
struct burn_cdtext
{
unsigned char *(payload[Libburn_pack_num_typeS]);
int length[Libburn_pack_num_typeS];
int flags; /* bit0 - bit15= double byte characters */
};
struct burn_track
{
int refcnt;
struct burn_toc_entry *entry;
unsigned char indices;
/* lba address of the index */
unsigned int index[99];
/* lba address of the index. CD only. 0x7fffffff means undefined index.
To be programmed relative to track source start before burning,
but to hold absolute addresses after burning or reading.
*/
int index[100];
/** number of 0 bytes to write before data */
int offset;
/** how much offset has been used */
@ -71,8 +90,18 @@ struct burn_track
int pregap1;
/** The track contains interval two of a pregap */
int pregap2;
/* ts B20110 */
/** The number of sectors in pre-gap 2, if .pregap2 is set */
int pregap2_size;
/** The track contains a postgap */
int postgap;
/* ts B20111 */
/** The number of sectors in post-gap, if .postgap is set */
int postgap_size;
struct isrc isrc;
/* ts A61024 */
@ -82,6 +111,9 @@ struct burn_track
/* ts A90910 : conversions from CD XA prepared input */
int cdxa_conversion; /* 0=none, 1=remove -xa1 headers (first 8 bytes)*/
/* ts B11206 */
struct burn_cdtext *cdtext[8];
};
struct burn_session
@ -97,6 +129,15 @@ struct burn_session
int tracks;
struct burn_track **track;
int refcnt;
/* ts B11206 */
struct burn_cdtext *cdtext[8];
unsigned char cdtext_char_code[8];
unsigned char cdtext_copyright[8];
unsigned char cdtext_language[8];
/* ts B11226 */
unsigned char mediacatalog[14]; /* overrideable by burn_write_opts */
};
struct burn_disc
@ -128,7 +169,17 @@ off_t burn_track_get_default_size(struct burn_track *t);
/* ts A80808 : Enhance CD toc to DVD toc */
int burn_disc_cd_toc_extensions(struct burn_disc *d, int flag);
int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag);
/* ts B11206 */
struct burn_cdtext *burn_cdtext_create(void);
void burn_cdtext_free(struct burn_cdtext **cdtext);
/* ts B20119 */
/* @param flag bit0= do not add post-gap
*/
int burn_track_get_sectors_2(struct burn_track *t, int flag);
#endif /* BURN__STRUCTURE_H */

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -64,6 +64,7 @@ struct command
int error;
int retry;
struct buffer *page;
int timeout; /* milliseconds */
};
struct burn_scsi_inquiry_data
@ -380,8 +381,9 @@ struct burn_drive
void (*send_parameters) (struct burn_drive *,
const struct burn_read_opts *);
void (*send_write_parameters) (struct burn_drive *,
struct burn_session *, int tno,
const struct burn_write_opts *);
void (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *);
int (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *);
/* ts A70205 : Announce size of a DVD-R[W] DAO session. */
int (*reserve_track) (struct burn_drive *d, off_t size);

View File

@ -328,3 +328,38 @@ ex:
return ret;
}
/* ts B11216 */
/** Read a line from fp and strip LF or CRLF */
char *burn_sfile_fgets(char *line, int maxl, FILE *fp)
{
int l;
char *ret;
ret = fgets(line, maxl, fp);
if (ret == NULL)
return NULL;
l = strlen(line);
if (l > 0)
if (line[l - 1] == '\r')
line[--l] = 0;
if (l > 0)
if (line[l - 1] == '\n')
line[--l] = 0;
if(l > 0)
if(line[l - 1] == '\r')
line[--l] = 0;
return ret;
}
char *burn_printify(char *msg)
{
char *cpt;
for (cpt = msg; *cpt != 0; cpt++)
if (*cpt < 32 || *cpt > 126)
*cpt = '#';
return msg;
}

View File

@ -8,4 +8,8 @@ char *burn_strndup(char *s, int n);
/* ts A90905 */
int burn_util_make_printable_word(char **text, int flag);
/* ts B11216 */
char *burn_sfile_fgets(char *line, int maxl, FILE *fp);
char *burn_printify(char *msg);
#endif

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -272,7 +272,6 @@ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
}
/* ts A61030 */
int burn_write_close_session(struct burn_write_opts *o)
{
@ -298,49 +297,74 @@ int burn_write_close_session(struct burn_write_opts *o)
}
/* ts A60819:
This is unused since about Feb 2006, icculus.org/burn CVS.
The compiler complains. We shall please our compiler.
/* ts A60819, B20101:
This is useful only when changes about CD SAO get tested.
# define Libburn_write_with_function_print_cuE yes
*/
#ifdef Libburn_write_with_function_print_cuE
static char cue_printify(char c)
{
if (c >= 32 && c < 127)
return c;
return '#';
}
static void print_cue(struct cue_sheet *sheet)
{
int i;
unsigned char *unit;
printf("\n");
printf("ctladr|trno|indx|form|scms| msf\n");
printf("------+----+----+----+----+--------\n");
printf("ctladr|trno|indx|form|scms| msf | text\n");
printf("------+----+----+----+----+----------+--------\n");
for (i = 0; i < sheet->count; i++) {
unit = sheet->data + 8 * i;
printf(" %1X %1X | %02X | %02X | %02X | %02X |",
(unit[0] & 0xf0) >> 4, unit[0] & 0xf, unit[1], unit[2],
unit[3], unit[4]);
printf("%02X:%02X:%02X\n", unit[5], unit[6], unit[7]);
if ((unit[0] & 0xf) == 2) {
printf(
" %1X %1X | | | | | | %c%c%c%c%c%c%c\n",
(unit[0] & 0xf0) >> 4, unit[0] & 0xf,
cue_printify(unit[1]), cue_printify(unit[2]),
cue_printify(unit[3]), cue_printify(unit[4]),
cue_printify(unit[5]), cue_printify(unit[6]),
unit[7] == 0 ? ' ' : cue_printify(unit[7]));
} else if ((unit[0] & 0xf) == 3) {
printf(
" %1X %1X | %2d | | | | | %c%c%c%c%c%c\n",
(unit[0] & 0xf0) >> 4, unit[0] & 0xf,
unit[1], cue_printify(unit[2]),
cue_printify(unit[3]), cue_printify(unit[4]),
cue_printify(unit[5]), cue_printify(unit[6]),
cue_printify(unit[7]));
} else if (unit[1] > 99) {
printf(" %1X %1X |0x%02X| %2d | %02X | %02X |",
(unit[0] & 0xf0) >> 4, unit[0] & 0xf,
unit[1], unit[2], unit[3], unit[4]);
printf(" %02d:%02d:%02d |\n",
unit[5], unit[6], unit[7]);
} else {
printf(" %1X %1X | %2d | %2d | %02X | %02X |",
(unit[0] & 0xf0) >> 4, unit[0] & 0xf,
unit[1], unit[2], unit[3], unit[4]);
printf(" %02d:%02d:%02d |\n",
unit[5], unit[6], unit[7]);
}
}
fflush(stdout);
}
#endif /* Libburn_write_with_print_cuE */
/* ts A61009 : changed type from void to int */
/** @return 1 = success , <=0 failure */
static int add_cue(struct cue_sheet *sheet, unsigned char ctladr,
unsigned char tno, unsigned char indx,
unsigned char form, unsigned char scms, int lba)
/* ts B11226 */
static int new_cue(struct cue_sheet *sheet, int number, int flag)
{
unsigned char *unit;
unsigned char *ptr;
int m, s, f;
burn_lba_to_msf(lba, &m, &s, &f);
sheet->count++;
ptr = realloc(sheet->data, sheet->count * 8);
/* ts A61009 */
/* a ssert(ptr); */
ptr = realloc(sheet->data, (sheet->count + number) * 8);
if (ptr == NULL) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
@ -348,8 +372,26 @@ static int add_cue(struct cue_sheet *sheet, unsigned char ctladr,
0, 0);
return -1;
}
sheet->data = ptr;
sheet->count += number;
return 1;
}
/* ts B11226 : outsourced new_cue() */
/** @return 1 = success , <=0 failure */
static int add_cue(struct cue_sheet *sheet, unsigned char ctladr,
unsigned char tno, unsigned char indx,
unsigned char form, unsigned char scms, int lba)
{
unsigned char *unit;
int m, s, f, ret;
burn_lba_to_msf(lba, &m, &s, &f);
ret = new_cue(sheet, 1, 0);
if (ret <= 0)
return -1;
unit = sheet->data + (sheet->count - 1) * 8;
unit[0] = ctladr;
unit[1] = tno;
@ -362,13 +404,60 @@ static int add_cue(struct cue_sheet *sheet, unsigned char ctladr,
return 1;
}
/* ts B11226 */
static int add_catalog_cue(struct cue_sheet *sheet, unsigned char catalog[13])
{
unsigned char *unit;
int i, ret;
ret = new_cue(sheet, 2, 0);
if (ret <= 0)
return -1;
unit = sheet->data + (sheet->count - 2) * 8;
unit[0] = unit[8] = 0x02;
for (i = 0; i < 13; i++)
unit[1 + (i >= 7) * 8 + (i % 7)] = catalog[i];
unit[15] = 0x00;
return 1;
}
/* ts B11226 */
static int add_isrc_cue(struct cue_sheet *sheet, unsigned char ctladr, int tno,
struct isrc *isrc)
{
unsigned char *unit;
int i, ret;
char text[8];
ret = new_cue(sheet, 2, 0);
if (ret <= 0)
return -1;
unit = sheet->data + (sheet->count - 2) * 8;
unit[0] = unit[8] = (ctladr & 0xf0) | 0x03;
unit[1] = unit[9] = tno;
unit[2] = isrc->country[0];
unit[3] = isrc->country[1];
unit[4] = isrc->owner[0];
unit[5] = isrc->owner[1];
unit[6] = isrc->owner[2];
sprintf(text, "%-2.2u%-5.5u", (unsigned int) isrc->year, isrc->serial);
unit[7] = text[0];
for (i = 1; i < 7; i++)
unit[9 + i] = text[i];
return 1;
}
/* ts A61114: added parameter nwa */
struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
struct burn_session *session,
int nwa)
{
int i, m, s, f, form, pform, runtime = -150, ret, track_length;
unsigned char ctladr;
int leadin_form, leadin_start, pregap = 150, postgap;
unsigned char ctladr, scms;
struct burn_drive *d;
struct burn_toc_entry *e;
struct cue_sheet *sheet;
@ -376,6 +465,19 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
int ntr = session->tracks;
int rem = 0;
#define Libburn_track_multi_indeX yes
#ifdef Libburn_track_multi_indeX
int j;
#endif
if (ntr < 1) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002019c,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Session has no defined tracks", 0, 0);
return NULL;
}
d = o->drive;
#ifdef Libburn_sao_can_appenD
@ -404,13 +506,46 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
"Track mode has unusable value", 0, 0);
goto failed;
}
ret = add_cue(sheet, ctladr | 1, 0, 0, 1, 0, runtime);
if (o->num_text_packs > 0) {
leadin_form = 0x41;
} else {
leadin_form = 0x01;
/* Check for CD-TEXT in session. Not the final creation,
because the cue sheet content might be needed for CD-TEXT
pack type 0x88 "TOC".
*/
if (o->text_packs == NULL) {
ret = burn_cdtext_from_session(session, NULL, NULL, 1);
if (ret < 0)
goto failed;
else if (ret > 0)
leadin_form = 0x41;
}
}
if (o->has_mediacatalog)
ret = add_catalog_cue(sheet, o->mediacatalog);
else if (session->mediacatalog[0])
ret = add_catalog_cue(sheet, session->mediacatalog);
else
ret = 1;
if (ret <= 0)
goto failed;
ret = add_cue(sheet, ctladr | 1, 1, 0, form, 0, runtime);
/* ts B11225
MMC-5 6.33.3.15 Data Form of Sub-channel
seems to indicate that for leadin_form 0x41 one should announce
d->start_lba as start of the leadin (e.g. -12490) and that data
block type should 2 or 3 with mode page 05h. But my drives refuse
on that.
It works with LBA -150 and data block type 0. Shrug.
*/
leadin_start = runtime;
ret = add_cue(sheet, (ctladr & 64) | 1, 0, 0, leadin_form, 0,
leadin_start);
if (ret <= 0)
goto failed;
runtime += 150;
d->toc_entries = ntr + 3;
@ -432,6 +567,13 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
goto failed;
*/
}
if (session->firsttrack + ntr - 1 > 99) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002019b,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"CD track number exceeds 99", 0, 0);
goto failed;
}
session->lasttrack = session->firsttrack + ntr - 1;
d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry));
e = d->toc_entry;
@ -440,11 +582,11 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
e[0].control = TOC_CONTROL_AUDIO;
else
e[0].control = TOC_CONTROL_DATA;
e[0].pmin = 1;
e[0].pmin = session->firsttrack;
e[0].psec = o->format;
e[0].adr = 1;
e[1].point = 0xA1;
e[1].pmin = ntr;
e[1].pmin = session->lasttrack;
e[1].adr = 1;
if (tar[ntr - 1]->mode & BURN_AUDIO)
e[1].control = TOC_CONTROL_AUDIO;
@ -454,26 +596,119 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
e[2].control = e[1].control;
e[2].adr = 1;
/* ts A70121 : The pause before the first track is not a Pre-gap.
To count it as part 2 of a Pre-gap is a dirty hack. It also seems
to have caused confusion in dealing with part 1 of an eventual
real Pre-gap. mmc5r03c.pdf 6.33.3.2, 6.33.3.18 .
*/
tar[0]->pregap2 = 1;
if (tar[0]->pregap2_size < 150)
tar[0]->pregap2_size = 150;
pform = form;
for (i = 0; i < ntr; i++) {
type_to_form(tar[i]->mode, &ctladr, &form);
/* ts A70125 :
Still not understanding the sense behind linking tracks,
i decided to at least enforce the MMC specs' minimum
track length.
*/
track_length = burn_track_get_sectors_2(tar[i], 1);
if (track_length < 300 && !burn_track_is_open_ended(tar[i])) {
track_length = 300;
if (!tar[i]->pad)
tar[i]->pad = 1;
burn_track_set_sectors(tar[i], track_length);
}
type_to_form(tar[i]->mode, &ctladr, &form);
if (tar[i]->mode & BURN_SCMS)
scms = 0x80;
else
scms = 0;
if (tar[i]->isrc.has_isrc) {
ret = add_isrc_cue(sheet, ctladr,
i + session->firsttrack, &(tar[i]->isrc));
if (ret <= 0)
goto failed;
}
pregap = 0;
if (tar[i]->pregap2)
pregap = tar[i]->pregap2_size;
postgap = 0;
if (tar[i]->postgap) {
if (tar[i]->indices >= 99) {
libdax_msgs_submit(libdax_messenger, -1,
0x0002019a, LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH,
"Post-gap index number exceeds 99",
0, 0);
goto failed;
}
if (tar[i]->indices < 2)
tar[i]->indices = 2;
tar[i]->index[tar[i]->indices] = track_length;
postgap = tar[i]->postgap_size;
}
#ifdef Libburn_track_multi_indeX
for(j = 0; j < (tar[i]->indices + !!tar[i]->postgap) || j < 2;
j++) {
if(tar[i]->index[j] == 0x7fffffff) {
if (j > 1)
break;
if (j == 0 && pregap <= 0)
continue;
/* force existence of mandatory index */
tar[i]->index[j] = 0;
} else if (j == 0) {
tar[i]->index[j] = 0;
} else if (j == 1 && tar[i]->index[0] == 0x7fffffff) {
tar[i]->index[j] = 0;
}
if (j == 1) {
tar[i]->entry = &e[3 + i];
e[3 + i].point = i + session->firsttrack;
burn_lba_to_msf(runtime, &m, &s, &f);
e[3 + i].pmin = m;
e[3 + i].psec = s;
e[3 + i].pframe = f;
e[3 + i].adr = 1;
e[3 + i].control = type_to_ctrl(tar[i]->mode);
}
/* >>> ??? else if j == 0 && mode change to -data :
Extended pregap */;
/* >>> check index with track size */;
tar[i]->index[j] += runtime;
ret = add_cue(sheet, ctladr | 1,
i + session->firsttrack, j, form, scms,
tar[i]->index[j]);
if (ret <= 0)
goto failed;
runtime += pregap;
pregap = 0;
}
runtime += track_length + postgap;
#else /* Libburn_track_multi_indeX */
if (i == 0) {
ret = add_cue(sheet, ctladr | 1, session->firsttrack,
0, form, 0, runtime);
if (ret <= 0)
goto failed;
runtime += 150;
} else if (pform != form) {
/* ts A70121 : This seems to be thw wrong test. Correct would
be to compare tar[]->mode or bit2 of ctladr.
*/
if (pform != form) {
ret = add_cue(sheet, ctladr | 1, i + 1, 0, form, 0,
runtime);
ret = add_cue(sheet, ctladr | 1,
i + session->firsttrack, 0, form, scms,
runtime);
if (ret <= 0)
goto failed;
@ -494,6 +729,10 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
Next one has to care for Post-gap: table 555 in mmc5r03c.pdf does not
show any although 6.33.3.19 would prescribe some.
ts B20111: Table 1 of MMC-1 shows two post-gaps. The first matches the
precriptions with SEND CUE SHEET. The second one is riddling.
Both are part of a track and occupy the range of the last index
of the track. Length is 2 seconds for each.
Nobody seems to have ever tested this situation, up to now.
It is banned for now in burn_disc_write().
@ -505,7 +744,7 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
/* XXX HERE IS WHERE WE DO INDICES IN THE CUE SHEET */
/* XXX and we should make sure the gaps conform to ecma-130... */
tar[i]->entry = &e[3 + i];
e[3 + i].point = i + 1;
e[3 + i].point = i + session->firsttrack;
burn_lba_to_msf(runtime, &m, &s, &f);
e[3 + i].pmin = m;
e[3 + i].psec = s;
@ -513,24 +752,16 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
e[3 + i].adr = 1;
e[3 + i].control = type_to_ctrl(tar[i]->mode);
ret = add_cue(sheet, ctladr | 1, i + 1, 1, form, 0, runtime);
ret = add_cue(sheet, ctladr | 1, i + session->firsttrack,
1, form, scms, runtime);
if (ret <= 0)
goto failed;
/* ts A70125 :
Still not understanding the sense behind linking tracks,
i decided to at least enforce the MMC specs' minimum
track length.
*/
track_length = burn_track_get_sectors(tar[i]);
if (track_length < 300 && !burn_track_is_open_ended(tar[i])) {
track_length = 300;
if (!tar[i]->pad)
tar[i]->pad = 1;
burn_track_set_sectors(tar[i], track_length);
}
runtime += track_length;
#endif /* ! Libburn_track_multi_indeX */
/* if we're padding, we'll clear any current shortage.
if we're not, we'll slip toc entries by a sector every time our
shortage is more than a sector
@ -650,11 +881,155 @@ int burn_write_leadout(struct burn_write_opts *o,
return 1;
}
static int burn_create_text_packs(struct burn_write_opts *o,
struct burn_session *s,
int flag)
{
int ret, num_packs = 0;
unsigned char *text_packs = NULL;
ret = burn_cdtext_from_session(s, &text_packs, &num_packs, 0);
if (ret > 0) {
if (o->text_packs != NULL)
free(o->text_packs);
o->text_packs = text_packs;
o->num_text_packs = num_packs;
}
return(ret);
}
static int burn_write_leadin_cdtext(struct burn_write_opts *o,
struct burn_session *s, int flag)
{
int ret, i, j, si, lba, sub_cursor = 0, err, write_lba, sectors = 0;
int self_made_text_packs = 0;
unsigned char *subdata = NULL;
struct burn_drive *d = o->drive;
struct buffer *buf = NULL;
enum burn_drive_status was_busy = o->drive->busy;
#ifdef Libburn_debug_cd_texT
unsigned char *packs;
#endif
if (o->num_text_packs <= 0) {
if (o->text_packs != NULL)
{ret = 1; goto ex;}
/* Try to create CD-TEXT from .cdtext_* of session and track */
ret = burn_create_text_packs(o, s, 0);
self_made_text_packs = 1;
if (ret <= 0)
goto ex;
if (o->num_text_packs <= 0)
{ret = 1; goto ex;}
}
if (!o->no_text_pack_crc_check) {
ret = burn_cdtext_crc_mismatches(o->text_packs,
o->num_text_packs, 0);
if (ret != 0) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002018f,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Program error: CD-TEXT pack CRC mismatch",
0, 0);
{ ret = 0; goto ex; }
}
}
d->busy = BURN_DRIVE_WRITING_LEADIN;
#ifdef Libburn_debug_cd_texT
packs = o->text_packs;
fprintf(stderr,
"libburn_DEBUG: 8 bit CD-TEXT packs to be transmitted:\n");
for (i = 0; i < 18 * o->num_text_packs; i += 18) {
fprintf(stderr, "%4d :", i / 18);
for (j = 0; j < 18; j++) {
if (j >= 4 && j <= 15 && packs[i + j] >= 32 &&
packs[i + j] <= 126 && packs[i] != 0x88 &&
packs[i] != 0x89 && packs[i] != 0x8f)
fprintf(stderr, " %c", packs[i + j]);
else
fprintf(stderr, " %2.2X", packs[i + j]);
}
fprintf(stderr, "\n");
}
#endif /* Libburn_debug_cd_texT */
/* Chop from 8 bit text pack to 6 bit subchannel */
BURN_ALLOC_MEM(subdata, unsigned char, o->num_text_packs * 24);
for (i = 0; i < 18 * o->num_text_packs; i += 3) {
si = i / 3 * 4;
subdata[si + 0] = (o->text_packs[i + 0] >> 2) & 0x3f;
subdata[si + 1] = (o->text_packs[i + 0] << 4) & 0x30;
subdata[si + 1] |= (o->text_packs[i + 1] >> 4) & 0x0f;
subdata[si + 2] = (o->text_packs[i + 1] << 2) & 0x3c;
subdata[si + 2] |= (o->text_packs[i + 2] >> 6) & 0x03;
subdata[si + 3] = (o->text_packs[i + 2] >> 0) & 0x3f;
}
/* Start at Lead-in address of ATIP and write blocks up to -150 */
BURN_ALLOC_MEM(buf, struct buffer, 1);
write_lba = d->start_lba;
for (lba = d->start_lba; lba < -150; lba++) {
/* Collect subdata in buf */
for (j = 0; j < 4; j++) {
memcpy(buf->data + buf->bytes,
subdata + sub_cursor * 24, 24);
sub_cursor = (sub_cursor + 1) % o->num_text_packs;
buf->bytes += 24;
}
buf->sectors++;
sectors++;
/* When full or last sector : perform WRITE */
if (buf->bytes + 96 >= 32768 || lba == -151) {
#ifdef Libburn_debug_cd_texT
fprintf(stderr,
"libburn_DEBUG: 6 bit data to be transmitted:\n");
for (i = 0; i < buf->bytes; i += 24) {
fprintf(stderr, "%4d :", i / 24);
for (j = 0; j < 24; j++)
fprintf(stderr, " %2.2X",
buf->data[i + j]);
fprintf(stderr, "\n");
}
#endif /* Libburn_debug_cd_texT */
err = d->write(d, write_lba, buf);
if (err == BE_CANCELLED)
{ ret = 0; goto ex; }
write_lba += sectors;
sectors = buf->sectors = buf->bytes = 0;
}
}
ret = 1;
ex:;
if (self_made_text_packs) {
if (o->text_packs != NULL)
free(o->text_packs);
o->text_packs = NULL;
o->num_text_packs = 0;
}
BURN_FREE_MEM(subdata);
BURN_FREE_MEM(buf);
d->busy = was_busy;
return ret;
}
int burn_write_session(struct burn_write_opts *o, struct burn_session *s)
{
struct burn_drive *d = o->drive;
int i, ret;
if (o->write_type == BURN_WRITE_SAO) {
ret = burn_write_leadin_cdtext(o, s, 0);
if (ret <= 0)
goto ex;
}
d->rlba = 0;
for (i = 0; i < s->tracks; i++) {
if (!burn_write_track(o, s, i))
@ -672,12 +1047,15 @@ ex:;
/* ts A61218 : outsourced from burn_write_track() */
int burn_disc_init_track_status(struct burn_write_opts *o,
struct burn_session *s, int tnum, int sectors)
struct burn_session *s, struct burn_track *t,
int tnum, int sectors)
{
struct burn_drive *d = o->drive;
/* Update progress */
d->progress.start_sector = d->nwa;
d->progress.sectors = sectors;
d->progress.sector = 0;
@ -685,6 +1063,13 @@ int burn_disc_init_track_status(struct burn_write_opts *o,
by bonfire-app@wanadoo.fr in http://libburn.pykix.org/ticket/58 */
d->progress.track = tnum;
/* ts B20113 */
d->progress.indices = t->indices;
d->progress.index = 0;
if (d->progress.indices > 1)
if (t->index[0] == 0x7fffffff)
d->progress.index = 1;
/* ts A61102 */
d->busy = BURN_DRIVE_WRITING;
@ -712,7 +1097,7 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
if (t->pregap1)
d->rlba += 75;
if (t->pregap2)
d->rlba += 150;
d->rlba += t->pregap2_size;
if (t->pregap1) {
@ -742,13 +1127,20 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
{ ret = 0; goto ex; }
}
if (t->pregap2)
for (i = 0; i < 150; i++)
for (i = 0; i < t->pregap2_size; i++)
if (!sector_pregap(o, t->entry->point,
t->entry->control, t->mode))
{ ret = 0; goto ex; }
/* ts B20113 : Flush buffer to avoid influence pregap
on track counter */
ret = sector_write_buffer(d, NULL, 0);
if (ret <= 0)
goto ex;
} else {
o->control = t->entry->control;
d->send_write_parameters(d, o);
d->send_write_parameters(d, s, tnum, o);
/* ts A61103 */
ret = d->get_nwa(d, -1, &lba, &nwa);
@ -759,9 +1151,11 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
/* <<< */
sprintf(msg,
"TAO pre-track %2.2d : get_nwa(%d)=%d, d=%d , demand=%.f , cap=%.f\n",
tnum+1, nwa, ret, d->nwa, (double) burn_track_get_sectors(t) * 2048.0,
(double) d->media_capacity_remaining);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
tnum+1, nwa, ret, d->nwa,
(double) burn_track_get_sectors_2(t, 1) * 2048.0,
(double) d->media_capacity_remaining);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
@ -781,10 +1175,10 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
/* user data */
sectors = burn_track_get_sectors(t);
sectors = burn_track_get_sectors_2(t, 1);
open_ended = burn_track_is_open_ended(t);
burn_disc_init_track_status(o, s, tnum, sectors);
burn_disc_init_track_status(o, s, t, tnum, sectors);
/* ts A61030 : this cannot happen. tnum is always < s->tracks */
if (tnum == s->tracks)
@ -827,29 +1221,20 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
d->progress.sector++;
}
if (t->postgap)
for (i = 0; i < 150; i++)
if (!sector_postgap(o, t->entry->point, t->entry->control,
t->mode))
{ ret = 0; goto ex; }
i = t->offset;
if (o->write_type == BURN_WRITE_SAO) {
if (d->buffer->bytes) {
int err;
err = d->write(d, d->nwa, d->buffer);
if (err == BE_CANCELLED)
{ ret = 0; goto ex; }
/* ts B20113 : Flush buffer to get buffered bytes assigned to the
track counter */
ret = sector_write_buffer(d, t, 0);
if (ret <= 0)
goto ex;
/* A61101 : probably this is not all payload data */
/* A61108 : but audio count is short without this */
t->writecount += d->buffer->bytes;
t->written_sectors += d->buffer->sectors;
d->progress.buffered_bytes += d->buffer->bytes;
d->nwa += d->buffer->sectors;
d->buffer->bytes = 0;
d->buffer->sectors = 0;
}
if (t->postgap && o->write_type != BURN_WRITE_TAO) {
for (i = 0; i < t->postgap_size; i++)
if (!sector_postgap(o, t->entry->point,
t->entry->control, t->mode))
{ ret = 0; goto ex; }
ret = sector_write_buffer(d, NULL, 0);
if (ret <= 0)
goto ex;
}
/* ts A61103 */
@ -967,6 +1352,35 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
}
static int precheck_write_is_audio(struct burn_disc *disc, int flag)
{
struct burn_session **sessions;
int num_sessions, i, j;
sessions = burn_disc_get_sessions(disc, &num_sessions);
for (i = 0; i < num_sessions; i++)
for (j = 0; j < sessions[i]->tracks; j++)
if (!(sessions[i]->track[j]->mode & BURN_AUDIO))
return 0;
return 1;
}
static int precheck_disc_has_cdtext(struct burn_disc *disc, int flag)
{
struct burn_session **sessions;
int num_sessions, i, ret;
sessions = burn_disc_get_sessions(disc, &num_sessions);
for (i = 0; i < num_sessions; i++) {
ret = burn_cdtext_from_session(sessions[i], NULL, NULL, 1);
if (ret > 0)
return 1;
}
return 0;
}
/* ts A70219 : API */
int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
char reasons[BURN_REASONS_LEN], int silent)
@ -974,7 +1388,7 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
enum burn_write_types wt;
struct burn_drive *d = o->drive;
char *msg = NULL, *reason_pt;
int no_media = 0;
int no_media = 0, ret, has_cdtext;
reason_pt= reasons;
reasons[0] = 0;
@ -1001,6 +1415,22 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
reason_pt= reasons + strlen(reasons);
if (d->status == BURN_DISC_UNSUITABLE)
goto unsuitable_profile;
if (o->num_text_packs > 0) {
has_cdtext = 1;
} else {
has_cdtext = precheck_disc_has_cdtext(disc, 0);
}
if (has_cdtext > 0) {
if (d->current_profile == 0x09 || d->current_profile == 0x0a) {
ret = precheck_write_is_audio(disc, 0);
if (ret <= 0)
strcat(reasons,
"CD-TEXT supported only with pure audio CD media, ");
} else {
strcat(reasons,
"CD-TEXT supported only with CD media, ");
}
}
if (d->drive_role == 2 || d->drive_role == 5 ||
d->current_profile == 0x1a || d->current_profile == 0x12 ||
d->current_profile == 0x43) {
@ -1014,6 +1444,14 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
strcat(reasons, "unsuitable track mode found, ");
if (o->start_byte >= 0)
strcat(reasons, "write start address not supported, ");
if (o->num_text_packs > 0) {
if (o->write_type != BURN_WRITE_SAO)
strcat(reasons,
"CD-TEXT supported only with write type SAO, ");
if (d->start_lba == -2000000000)
strcat(reasons,
"No Lead-in start address known with CD-TEXT, ");
}
} else if (d->current_profile == 0x13) {
/* DVD-RW Restricted Overwrite */
if (o->start_byte >= 0 && (o->start_byte % 32768))
@ -1076,12 +1514,12 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
off_t size;
BURN_ALLOC_MEM(msg, char, 160);
d->send_write_parameters(d, o);
d->send_write_parameters(d, NULL, -1, o);
ret = d->get_nwa(d, -1, &lba, &nwa);
sprintf(msg,
"DVD pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d",
tnum+1, nwa, ret, d->nwa);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
if (nwa > d->nwa)
d->nwa = nwa;
@ -1102,7 +1540,7 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
#endif
if (o->write_type == BURN_WRITE_SAO) { /* DAO */
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
size = ((off_t) burn_track_get_sectors_2(s->track[tnum], 1))
* (off_t) 2048;
/* Eventually round track size up to write chunk */
@ -1141,7 +1579,7 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
sprintf(msg,
"DVD+R pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d",
tnum+1, nwa, ret, d->nwa);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
if (nwa > d->nwa)
d->nwa = nwa;
@ -1151,7 +1589,7 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
if (o->write_type == BURN_WRITE_SAO &&
! burn_track_is_open_ended(s->track[tnum])) {
/* Round track size up to write chunk size and reserve track */
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
size = ((off_t) burn_track_get_sectors_2(s->track[tnum], 1))
* (off_t) 2048;
/* o->obs should be 32k or 64k already. But 32k alignment
was once performed in d->reserve_track() */
@ -1425,12 +1863,12 @@ int burn_dvd_write_track(struct burn_write_opts *o,
goto ex;
}
sectors = burn_track_get_sectors(t);
sectors = burn_track_get_sectors_2(t, 1);
open_ended = burn_track_is_open_ended(t);
/* (offset padding is done within sector_data()) */
burn_disc_init_track_status(o, s, tnum, sectors);
burn_disc_init_track_status(o, s, t, tnum, sectors);
for (i = 0; open_ended || i < sectors; i++) {
/* From time to time inquire drive buffer */
@ -1747,7 +2185,7 @@ int burn_disc_setup_dvd_minus_rw(struct burn_write_opts *o,
5.4.14 finally states that profile 0013h includes feature
002Ch rather than 0026h.
d->send_write_parameters(d, o);
d->send_write_parameters(d, NULL, -1, o);
*/
d->busy = BURN_DRIVE_FORMATTING;
@ -2268,8 +2706,8 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
BURN_ALLOC_MEM(buf, char, bufsize);
sectors = burn_track_get_sectors(t);
burn_disc_init_track_status(o, s, tnum, sectors);
sectors = burn_track_get_sectors_2(t, 1);
burn_disc_init_track_status(o, s, t, tnum, sectors);
open_ended = burn_track_is_open_ended(t);
t->end_on_premature_eoi = (o->write_type == BURN_WRITE_TAO);
@ -2386,6 +2824,7 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
struct cue_sheet *sheet;
struct burn_drive *d = o->drive;
struct buffer *buffer_mem = o->drive->buffer;
struct burn_session *s;
struct burn_track *lt, *t;
int first = 1, i, ret, lba, nwa = 0, multi_mem;
off_t default_size;
@ -2498,8 +2937,11 @@ return crap. so we send the command, then ignore the result.
if (o->write_type == BURN_WRITE_TAO) {
nwa = 0; /* get_nwa() will be called in burn_track() */
} else {
d->send_write_parameters(d, o);
if (disc->sessions > 0)
s = disc->session[0];
else
s = NULL;
d->send_write_parameters(d, s, -1, o);
ret = d->get_nwa(d, -1, &lba, &nwa);
sprintf(msg,
@ -2524,14 +2966,23 @@ return crap. so we send the command, then ignore the result.
/* ts A61009 */
if (sheet == NULL)
goto fail;
goto fail_wo_sync;
/* print_cue(sheet);*/
#ifdef Libburn_write_with_function_print_cuE
print_cue(sheet);
/* goto fail_wo_sync; */
#endif /* Libburn_write_with_function_print_cuE */
ret = 1;
if (o->write_type == BURN_WRITE_SAO)
d->send_cue_sheet(d, sheet);
ret = d->send_cue_sheet(d, sheet);
if (sheet->data != NULL)
free(sheet->data);
free(sheet);
if (ret <= 0)
goto fail_wo_sync;
/* --- From here on, final sync is needed. --- */
if (o->write_type == BURN_WRITE_RAW) {
if (!burn_write_leadin(o, disc->session[i], first))
@ -2555,7 +3006,7 @@ return crap. so we send the command, then ignore the result.
sprintf(msg,
"SAO appendable d->nwa= %d\n", d->nwa);
libdax_msgs_submit(
libdax_messenger, d->global_index, 0x000002,
libdax_messenger, d->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
@ -2812,7 +3263,7 @@ int burn_disc_close_damaged(struct burn_write_opts *o, int flag)
o->write_type = BURN_WRITE_TAO; /* no action without TAO */
/* Send mode page 5 */;
d->send_write_parameters(d, o);
d->send_write_parameters(d, NULL, -1, o);
ret = burn_write_close_session(o);
if (ret <= 0)
@ -2823,7 +3274,7 @@ int burn_disc_close_damaged(struct burn_write_opts *o, int flag)
o->write_type = BURN_WRITE_TAO; /* no action without TAO */
/* Send mode page 5 */;
d->send_write_parameters(d, o);
d->send_write_parameters(d, NULL, -1, o);
ret = burn_disc_close_track_dvd_minus_r(o, 0);
if (ret <= 0)

View File

@ -39,6 +39,13 @@ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
int tnum);
int burn_write_close_session(struct burn_write_opts *o);
/* @param flag bit0= repair checksum
bit1= repair checksum if all pack CRCs are 0
@return 0= no mismatch , >0 number of unrepaired mismatches
<0 number of repaired mismatches
*/
int burn_cdtext_crc_mismatches(unsigned char *packs, int num_packs, int flag);
/* mmc5r03c.pdf 6.3.3.3.3: DVD-R DL: Close Function 010b: Close Session

View File

@ -1,41 +0,0 @@
#!/bin/sh
set -e
cd ..
if [ ! -x configure ]; then
printf "\n*** please run ./bootstrap first.\n"
exit 1
fi
build()
{
for F in ${1}
do
make clean
clear
printf "\n *** building with: %s\n" CPPFLAGS=-D${F}
sleep 1
# libcdio is not autodetected by default; should be available everywhere
CPPFLAGS=-D${F} ./configure --enable-libcdio; make 2> releng/libburn.${F}.log
make clean
done
}
OS=`uname -o`
case ${OS} in
GNU/Linux)
printf "OS: %s\n" ${OS}
sleep 1
build "__linux Libburn_use_sg_dummY Libburn_use_libcdiO"
;;
*)
printf "Unknown OS: %s\n" ${OS}
exit 1
;;
esac
# just in case
unset CPPFLAGS