diff options
author | av <av@cvs.openbsd.org> | 2008-06-30 23:35:40 +0000 |
---|---|---|
committer | av <av@cvs.openbsd.org> | 2008-06-30 23:35:40 +0000 |
commit | 18d2e2d2106a01c55babb507cdb2188bee28e6d5 (patch) | |
tree | 4387dc28189e5383baca788410ae6868b5b33fb4 /usr.bin/cdio | |
parent | 1ab1e704c992505e56e6c41e808331016b8e1e20 (diff) |
set speed for writing tracks in TAO.
ok and tweaks by fgsch
manual page by jmc
Diffstat (limited to 'usr.bin/cdio')
-rw-r--r-- | usr.bin/cdio/cdio.1 | 15 | ||||
-rw-r--r-- | usr.bin/cdio/cdio.c | 41 | ||||
-rw-r--r-- | usr.bin/cdio/extern.h | 26 | ||||
-rw-r--r-- | usr.bin/cdio/mmc.c | 33 | ||||
-rw-r--r-- | usr.bin/cdio/rip.c | 12 |
5 files changed, 103 insertions, 24 deletions
diff --git a/usr.bin/cdio/cdio.1 b/usr.bin/cdio/cdio.1 index 8a63d15a1bf..41190ad87a3 100644 --- a/usr.bin/cdio/cdio.1 +++ b/usr.bin/cdio/cdio.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: cdio.1,v 1.50 2008/06/24 14:00:01 jmc Exp $ +.\" $OpenBSD: cdio.1,v 1.51 2008/06/30 23:35:39 av Exp $ .\" .\" Copyright (c) 1995 Serge V. Vakulenko .\" All rights reserved. @@ -29,7 +29,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: June 24 2008 $ +.Dd $Mdocdate: June 30 2008 $ .Dt CDIO 1 .Os .Sh NAME @@ -210,6 +210,7 @@ and the current values of the volume for left and right channels. Stop the disc. .It Xo Ic tao .Op Fl ad +.Op Fl s Ar speed .Ar trackfile ... .Xc .Bq command line only @@ -226,6 +227,16 @@ with 2 channels of PCM audio, signed 16-bit (little endian) values sampled at 44100 Hz. .It Fl d Write files as data tracks (the default). +.It Fl s Ar speed +Specify a write speed for tracks. +.Ar speed +may be a numerical value between 1 and +the maximum speed supported by the media and drive, +or one of the literal strings +.Dq auto +or +.Dq max , +meaning the optimal or maximum speed detected. .El .It Ic volume Ar left_channel Ar right_channel Set the volume of the left channel to diff --git a/usr.bin/cdio/cdio.c b/usr.bin/cdio/cdio.c index bbe157f6b18..2691f97bb0d 100644 --- a/usr.bin/cdio/cdio.c +++ b/usr.bin/cdio/cdio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cdio.c,v 1.62 2008/06/22 21:04:01 av Exp $ */ +/* $OpenBSD: cdio.c,v 1.63 2008/06/30 23:35:39 av Exp $ */ /* Copyright (c) 1995 Serge V. Vakulenko * All rights reserved. @@ -149,6 +149,7 @@ struct cd_toc_entry *toc_buffer; char *cdname; int fd = -1; int writeperm = 0; +int mediacap = 0; int verbose = 1; int msf = 1; const char *cddb_host; @@ -166,7 +167,7 @@ int play_msf(int, int, int, int, int, int); int play_track(int, int, int, int); int get_vol(int *, int *); int status(int *, int *, int *, int *); -int is_wave(int fd); +int is_wave(int); __dead void tao(int argc, char **argv); int play(char *arg); int info(char *arg); @@ -315,7 +316,7 @@ main(int argc, char **argv) int run(int cmd, char *arg) { - int l, r, rc, cap; + int l, r, rc; static char newcdname[MAXPATHLEN]; switch (cmd) { @@ -513,11 +514,11 @@ run(int cmd, char *arg) if (!open_cd(cdname, 1)) return 0; - if (get_media_capabilities(&cap) == -1) { + if (get_media_capabilities(&mediacap) == -1) { warnx("Can't determine media type"); return (0); } - if ((cap & MEDIACAP_CDRW_WRITE) == 0) { + if ((mediacap & MEDIACAP_CDRW_WRITE) == 0) { warnx("The media doesn't support blanking"); return (0); } @@ -576,23 +577,24 @@ tao(int argc, char **argv) u_int blklen; u_int ntracks = 0; char type; - int ch, cap; + int ch, speed; + const char *errstr; if (argc == 1) usage(); SLIST_INIT(&tracks); type = 'd'; + speed = DRIVE_SPEED_OPTIMAL; blklen = 2048; while (argc > 1) { tr = malloc(sizeof(struct track_info)); if (tr == NULL) err(1, "tao"); - tr->type = type; optreset = 1; optind = 1; - while ((ch = getopt(argc, argv, "ad")) != -1) { + while ((ch = getopt(argc, argv, "ads:")) != -1) { switch (ch) { case 'a': type = 'a'; @@ -602,12 +604,31 @@ tao(int argc, char **argv) type = 'd'; blklen = 2048; break; + case 's': + if (strcmp(optarg, "auto") == 0) { + speed = DRIVE_SPEED_OPTIMAL; + } else if (strcmp(optarg, "max") == 0) { + speed = DRIVE_SPEED_MAX; + } else { + speed = (int)strtonum(optarg, 1, + CD_MAX_SPEED, &errstr); + if (errstr != NULL) { + errx(1, + "incorrect speed value"); + } + } + break; default: usage(); /* NOTREACHED */ } } + if (speed != DRIVE_SPEED_OPTIMAL && speed != DRIVE_SPEED_MAX) + tr->speed = CD_SPEED_TO_KBPS(speed, blklen); + else + tr->speed = speed; + tr->type = type; tr->blklen = blklen; argc -= optind; @@ -637,9 +658,9 @@ tao(int argc, char **argv) if (!open_cd(cdname, 1)) exit(1); - if (get_media_capabilities(&cap) == -1) + if (get_media_capabilities(&mediacap) == -1) errx(1, "Can't determine media type"); - if ((cap & MEDIACAP_TAO) == 0) + if ((mediacap & MEDIACAP_TAO) == 0) errx(1, "The media can't be written in TAO mode"); get_disc_size(&availblk); diff --git a/usr.bin/cdio/extern.h b/usr.bin/cdio/extern.h index 90c33cebf04..6a6a45b716b 100644 --- a/usr.bin/cdio/extern.h +++ b/usr.bin/cdio/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.11 2008/06/22 21:04:01 av Exp $ */ +/* $OpenBSD: extern.h,v 1.12 2008/06/30 23:35:39 av Exp $ */ /* * Copyright (c) 2002 Marc Espie. * @@ -35,12 +35,30 @@ struct track_info { char *file; SLIST_ENTRY(track_info) track_list; char type; + int speed; }; SLIST_HEAD(track_head, track_info) tracks; -/* Media capabilities */ -#define MEDIACAP_TAO 0x01 -#define MEDIACAP_CDRW_WRITE 0x02 +/* Media capabilities (bitmask) */ +#define MEDIACAP_TAO 0x01 /* Track-At-Once writing mode */ +#define MEDIACAP_CDRW_WRITE 0x02 /* media is CD-RW and can be written */ +#define MEDIACAP_CDRW_CAV 0x04 /* Constant Angular Velocity */ + +/* Read/Write speed */ +#define DRIVE_SPEED_MAX 0xfffe +#define DRIVE_SPEED_OPTIMAL 0xffff /* automatically adjusted by drive */ + +/* Convert writing speed into Kbytes/sec (1x - 75 frames per second) */ +#define CD_SPEED_TO_KBPS(x, blksz) ((x) * 75 * (blksz) / 1024) + +/* + * It's maximum possible speed for CD (audio track). + * Data tracks theoretically can be written at 436x but in practice I + * believe, 380x will be never reached. + * NOTE: this value must never be changed to a bigger value, it can cause + * DRIVE_SPEED_MAX overrun. + */ +#define CD_MAX_SPEED 380 extern unsigned long entry2time(struct cd_toc_entry *); extern unsigned long entry2frames(struct cd_toc_entry *); diff --git a/usr.bin/cdio/mmc.c b/usr.bin/cdio/mmc.c index 42b7d3845b6..6089ef7730b 100644 --- a/usr.bin/cdio/mmc.c +++ b/usr.bin/cdio/mmc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mmc.c,v 1.21 2008/06/22 21:04:01 av Exp $ */ +/* $OpenBSD: mmc.c,v 1.22 2008/06/30 23:35:39 av Exp $ */ /* * Copyright (c) 2006 Michael Coulter <mjc@openbsd.org> @@ -31,10 +31,13 @@ #include "extern.h" extern int fd; +extern int mediacap; extern char *cdname; #define SCSI_GET_CONFIGURATION 0x46 +#define SCSI_SET_SPEED 0xbb +#define MMC_FEATURE_CDRW_CAV 0x27 #define MMC_FEATURE_CD_TAO 0x2d #define MMC_FEATURE_CDRW_WRITE 0x37 @@ -79,7 +82,9 @@ get_media_capabilities(int *cap) break; /* partial feature descriptor */ feature = betoh16(*(u_int16_t *)(buf + i)); - if (feature == MMC_FEATURE_CD_TAO) + if (feature == MMC_FEATURE_CDRW_CAV) + *cap |= MEDIACAP_CDRW_CAV; + else if (feature == MMC_FEATURE_CD_TAO) *cap |= MEDIACAP_TAO; else if (feature == MMC_FEATURE_CDRW_WRITE) *cap |= MEDIACAP_CDRW_WRITE; @@ -91,6 +96,28 @@ get_media_capabilities(int *cap) } int +set_speed(int wspeed) +{ + scsireq_t scr; + int r; + + memset(&scr, 0, sizeof(scr)); + scr.cmd[0] = SCSI_SET_SPEED; + scr.cmd[1] = (mediacap & MEDIACAP_CDRW_CAV) != 0; + *(u_int16_t *)(scr.cmd + 2) = htobe16(DRIVE_SPEED_OPTIMAL); + *(u_int16_t *)(scr.cmd + 4) = htobe16(wspeed); + + scr.cmdlen = 12; + scr.datalen = 0; + scr.timeout = 120000; + scr.flags = SCCMD_ESCAPE; + scr.senselen = SENSEBUFLEN; + + r = ioctl(fd, SCIOCCOMMAND, &scr); + return (r == 0 ? scr.retsts : -1); +} + +int blank(void) { struct scsi_blank *scb; @@ -210,6 +237,8 @@ writetao(struct track_head *thp) warnx("mode select failed: %d", r); return (r); } + + set_speed(tr->speed); writetrack(tr, track); synchronize_cache(); } diff --git a/usr.bin/cdio/rip.c b/usr.bin/cdio/rip.c index 47bbbf9b12a..3a93cabfa25 100644 --- a/usr.bin/cdio/rip.c +++ b/usr.bin/cdio/rip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rip.c,v 1.7 2007/08/02 07:31:16 jakemsr Exp $ */ +/* $OpenBSD: rip.c,v 1.8 2008/06/30 23:35:39 av Exp $ */ /* * Copyright (c) 2007 Alexey Vatchenko <av@bsdua.org> @@ -80,9 +80,9 @@ static u_char wavehdr[44] = { 'd', 'a', 't', 'a', 0x0, 0x0, 0x0, 0x0 }; -static int write_sector(int fd, u_char *sec, u_int32_t secsize); +static int write_sector(int, u_char *, u_int32_t); -int read_data_sector(u_int32_t lba, u_char *sec, u_int32_t secsize); +int read_data_sector(u_int32_t, u_char *, u_int32_t); struct track_info { int fd; /* descriptor of output file */ @@ -93,10 +93,10 @@ struct track_info { u_int32_t end_lba; /* starting address of the next track */ }; -int read_track(int fd, struct track_info *ti); +int read_track(int, struct track_info *); -int rip_next_track(struct track_info *info); -int play_next_track(struct track_info *info); +int rip_next_track(struct track_info *); +int play_next_track(struct track_info *); static int rip_tracks_loop(struct track_pair *tp, u_int n_tracks, int (*next_track)(struct track_info *)); |