Compare commits
124 Commits
Author | SHA1 | Date | |
---|---|---|---|
b69baec77a | |||
516e509198 | |||
9736695026 | |||
e2295ddbf8 | |||
bfb798b51b | |||
72645c8fba | |||
f338575f41 | |||
cc3ff147fe | |||
dcd1eab82d | |||
3ea4892040 | |||
e0d7eb4820 | |||
daf744276e | |||
8963905bbc | |||
88da4e9ead | |||
cc9ec8666c | |||
7ce13c6dd3 | |||
6549072dcd | |||
a88039e222 | |||
a75a838af9 | |||
024701c220 | |||
72c31e89b2 | |||
2f548e046d | |||
9f8e4fb36b | |||
645d41fdd2 | |||
853928815a | |||
38bbbf2496 | |||
6a13187e03 | |||
ce0f35831b | |||
0e9a79e352 | |||
0c01912143 | |||
66639c6e11 | |||
a0540651eb | |||
34195c3037 | |||
9623a04ce9 | |||
ef7999342b | |||
cb8c85579d | |||
ebf2fe5c28 | |||
66eba145d3 | |||
5cd7b09d5c | |||
ac7f4e90a4 | |||
2c10b444a1 | |||
ea1160f077 | |||
d4c4430a40 | |||
a2493b97e4 | |||
4d70043e78 | |||
c9a44d0128 | |||
a9b400833c | |||
0446226aa6 | |||
18efcd6299 | |||
775eb175b6 | |||
b8b6734cd1 | |||
688a6fccca | |||
792a5896e7 | |||
c1bd3ced61 | |||
dcb6f8344b | |||
83fa2ce51b | |||
b8eb8b35d9 | |||
c851520684 | |||
4c9783d7ae | |||
8ac3ee15f1 | |||
e5742f724a | |||
0c3fa9b341 | |||
a1f18ad44e | |||
3845e1af05 | |||
23d7867331 | |||
38aaa2f8aa | |||
ce29b4b38c | |||
f1ae493c57 | |||
4afaaf3fb6 | |||
8f725bab11 | |||
7b5040af17 | |||
47e5ce5da2 | |||
cdaa2971db | |||
67ae1413e3 | |||
6716f7041d | |||
94c50a0145 | |||
74fa33bc42 | |||
8cdba24ff9 | |||
c8debb85a3 | |||
eeef039aab | |||
1cc7c7f8b2 | |||
8f40e66fa4 | |||
a34596d7b7 | |||
e15e949a20 | |||
8e8ed3e682 | |||
52798b0b4a | |||
de6d193eec | |||
d774aa0b35 | |||
350971a34e | |||
64b90c1da6 | |||
398ee89348 | |||
c3a02f8631 | |||
89e5450fb8 | |||
e05285e246 | |||
9ab0edae71 | |||
8a9c6176c2 | |||
620871c91d | |||
2063dc2ca7 | |||
358ebaf458 | |||
38387c0cb0 | |||
f594e30f39 | |||
39bdf8c725 | |||
8a8a84b0f6 | |||
3b0f6b742f | |||
0e5149d716 | |||
c085581224 | |||
c84ba30220 | |||
7b0a23d553 | |||
7be652ac6b | |||
b385a3863e | |||
25d61ceba0 | |||
9aa23d6695 | |||
94a66f72d4 | |||
48e6a5975c | |||
1d5ee82c16 | |||
56c02fa394 | |||
7a5f1ab35c | |||
6b7e0f134a | |||
417a4cc0bf | |||
041f0e357e | |||
6629d05eea | |||
8d6c28b6c5 | |||
4814e8c13a | |||
2718016de6 |
32
ChangeLog
32
ChangeLog
@ -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
|
||||
|
13
Makefile.am
13
Makefile.am
@ -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
21
README
@ -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.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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"
|
@ -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"
|
||||
|
@ -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.
|
||||
|
1043
cdrskin/cdrskin.c
1043
cdrskin/cdrskin.c
File diff suppressed because it is too large
Load Diff
@ -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> </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> </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
|
||||
|
@ -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
@ -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 \
|
||||
|
@ -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
|
||||
|
20
configure.ac
20
configure.ac
@ -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
700
doc/cdtext.txt
Normal 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.
|
||||
-------------------------------------------------------------------------------
|
||||
|
156
doc/cookbook.txt
156
doc/cookbook.txt
@ -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.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -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
1111
libburn/cdtext.c
Executable file
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
{
|
||||
|
106
libburn/drive.c
106
libburn/drive.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
230
libburn/mmc.c
230
libburn/mmc.c
@ -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;
|
||||
}
|
||||
|
@ -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*/
|
||||
|
@ -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);
|
||||
|
@ -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(). */
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 ||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
316
libburn/spc.c
316
libburn/spc.c
@ -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;
|
||||
}
|
||||
|
@ -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*/
|
||||
|
1462
libburn/structure.c
1462
libburn/structure.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
663
libburn/write.c
663
libburn/write.c
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
Reference in New Issue
Block a user