user/4957: two issues in cdio(1)

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

user/4957: two issues in cdio(1)

Juha Erkkila
>Number:         4957
>Category:       user
>Synopsis:       two issues in cdio(1)
>Confidential:   yes
>Severity:       non-critical
>Priority:       low
>Responsible:    bugs
>State:          open
>Quarter:        
>Keywords:      
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Dec 30 13:30:02 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Juha Erkkila
>Release:        OpenBSD 3.8-stable
>Organization:
net
>Environment:
        System      : OpenBSD 3.8
        Architecture: OpenBSD.i386
        Machine     : i386
>Description:

I've found some problems in cdio(1) - compact disc audio player.
The manpage does not mention playback from points relative to
the start of the track, but the utility itself has info about
this, simply type ``help'' in cdio prompt:

cdio> help
...
        Play tr1 m1:s1[.f1] [[tr2] [m2:s2[.f2]]]
...

This, however, does not work quite as expected.  Relative play
always chooses to play from the next track, for example, trying to
play track 4 from 2:30 makes the cd drive play track 5 from 2:30.
It is not possible to play the first track from any relative address.
The addressing also does not properly take account tracks lengths,
allowing to play track from 7:00 even if its only 4:30 long (it
simply moves on to subsequent tracks).

The other issue is that the ``lba'' ioctl() mode does not work
very well at all.  Simple try setting it and then type ``info''
command, at least for me the results are quite impossible.

>How-To-Repeat:

As explained above.

>Fix:

The patch below fixes the issues for me.  Problems in LBA mode
are due to improper ntohl() conversion (the source data appears
to be in host-order already), and the problems in relative play
are due to misunderstandings about the contents of toc_buffer.

Juha

Index: usr.bin/cdio/cdio.c
===================================================================
RCS file: /cvs/src/usr.bin/cdio/cdio.c,v
retrieving revision 1.39
diff -u -p -r1.39 cdio.c
--- usr.bin/cdio/cdio.c 22 Jan 2005 10:21:26 -0000 1.39
+++ usr.bin/cdio/cdio.c 30 Dec 2005 12:04:08 -0000
@@ -136,7 +136,7 @@ struct cmdtab {
 { 0, 0, 0, 0}
 };
 
-struct cd_toc_entry     *toc_buffer;
+struct cd_toc_entry     *toc_buffer = NULL;
 
 char *cdname;
 int             fd = -1;
@@ -538,7 +538,7 @@ play(char *arg)
     toc_buffer[n].addr.msf.second,
     toc_buffer[n].addr.msf.frame) - blk;
  else
- len = ntohl(toc_buffer[n].addr.lba) - blk;
+ len = toc_buffer[n].addr.lba - blk;
  }
  return play_blocks(blk, len);
  }
@@ -577,6 +577,11 @@ play(char *arg)
  goto Play_Relative_Addresses;
 
  tr2 = m2 = s2 = f2 = f1 = 0;
+ if (6 == sscanf(arg, "%d %u:%u %d %u:%u",
+    &tr1, &m1, &s1, &tr2, &m2, &s2))
+ goto Play_Relative_Addresses;
+
+ tr2 = m2 = s2 = f2 = f1 = 0;
  if (6 == sscanf(arg, "%d %u:%u.%u %u:%u",
     &tr1, &m1, &s1, &f1, &m2, &s2))
  goto Play_Relative_Addresses;
@@ -592,7 +597,8 @@ play(char *arg)
  goto Play_Relative_Addresses;
 
  tr2 = m2 = s2 = f2 = f1 = 0;
- if (5 == sscanf(arg, "%d %u:%u %u:%u", &tr1, &m1, &s1, &m2, &s2))
+ if (5 == sscanf(arg, "%d %u:%u %u:%u",
+    &tr1, &m1, &s1, &m2, &s2))
  goto Play_Relative_Addresses;
 
  tr2 = m2 = s2 = f2 = f1 = 0;
@@ -606,7 +612,7 @@ play(char *arg)
  goto Play_Relative_Addresses;
 
  tr2 = m2 = s2 = f2 = f1 = 0;
- if (4 == sscanf(arg, "%d %u:%u %u", &tr1, &m1, &s1, &tr2))
+ if (4 == sscanf(arg, "%d %u:%u %d", &tr1, &m1, &s1, &tr2))
  goto Play_Relative_Addresses;
 
  tr2 = m2 = s2 = f2 = f1 = 0;
@@ -626,23 +632,27 @@ Play_Relative_Addresses:
  else if (tr1 > n)
  tr1 = n;
 
- if (msf) {
- tm = toc_buffer[tr1].addr.msf.minute;
- ts = toc_buffer[tr1].addr.msf.second;
- tf = toc_buffer[tr1].addr.msf.frame;
- } else
- lba2msf(ntohl(toc_buffer[tr1].addr.lba),
- &tm, &ts, &tf);
+ tr1--;
+ tracklength(&toc_buffer[tr1], &toc_buffer[tr1 + 1],
+ &tm, &ts, &tf);
+
  if ((m1 > tm)
     || ((m1 == tm)
     && ((s1 > ts)
     || ((s1 == ts)
     && (f1 > tf))))) {
- printf("Track %d is not that long.\n", tr1);
+ printf("Track %d is not that long.\n", tr1 + 1);
  return (0);
  }
 
- tr1--;
+ /* get track start times, add them to user requested times */
+
+ if (msf) {
+ tm = toc_buffer[tr1].addr.msf.minute;
+ ts = toc_buffer[tr1].addr.msf.second;
+ tf = toc_buffer[tr1].addr.msf.frame;
+ } else
+ lba2msf(toc_buffer[tr1].addr.lba, &tm, &ts, &tf);
 
  f1 += tf;
  if (f1 >= 75) {
@@ -681,7 +691,7 @@ Play_Relative_Addresses:
  s2 = toc_buffer[n].addr.msf.second;
  f2 = toc_buffer[n].addr.msf.frame;
  } else {
- lba2msf(ntohl(toc_buffer[n].addr.lba),
+ lba2msf(toc_buffer[n].addr.lba,
  &tm, &ts, &tf);
  m2 = tm;
  s2 = ts;
@@ -699,7 +709,7 @@ Play_Relative_Addresses:
  ts = toc_buffer[tr2].addr.msf.second;
  tf = toc_buffer[tr2].addr.msf.frame;
  } else
- lba2msf(ntohl(toc_buffer[tr2].addr.lba),
+ lba2msf(toc_buffer[tr2].addr.lba,
  &tm, &ts, &tf);
  f2 += tf;
  if (f2 >= 75) {
@@ -721,8 +731,7 @@ Play_Relative_Addresses:
  ts = toc_buffer[n].addr.msf.second;
  tf = toc_buffer[n].addr.msf.frame;
  } else
- lba2msf(ntohl(toc_buffer[n].addr.lba),
- &tm, &ts, &tf);
+ lba2msf(toc_buffer[n].addr.lba, &tm, &ts, &tf);
  if ((tr2 < n)
     && ((m2 > tm)
     || ((m2 == tm)
@@ -750,8 +759,7 @@ Try_Absolute_Timed_Addresses:
  s2 = toc_buffer[n].addr.msf.second;
  f2 = toc_buffer[n].addr.msf.frame;
  } else {
- lba2msf(ntohl(toc_buffer[n].addr.lba),
- &tm, &ts, &tf);
+ lba2msf(toc_buffer[n].addr.lba, &tm, &ts, &tf);
  m2 = tm;
  s2 = ts;
  f2 = tf;
@@ -1066,7 +1074,7 @@ entry2time(struct cd_toc_entry *e)
  if (msf) {
  return (e->addr.msf.minute * 60 + e->addr.msf.second);
  } else {
- block = ntohl(e->addr.lba);
+ block = e->addr.lba;
  lba2msf(block, &m, &s, &f);
  return (m*60+s);
  }
@@ -1082,7 +1090,7 @@ entry2frames(struct cd_toc_entry *e)
  return e->addr.msf.frame + e->addr.msf.second * 75 +
     e->addr.msf.minute * 60 * 75;
  } else {
- block = ntohl(e->addr.lba);
+ block = e->addr.lba;
  lba2msf(block, &m, &s, &f);
  return f + s * 75 + m * 60 * 75;
  }
@@ -1091,7 +1099,7 @@ entry2frames(struct cd_toc_entry *e)
 void
 prtrack(struct cd_toc_entry *e, int lastflag, char *name)
 {
- int block, next, len;
+ int block, len;
  u_char m, s, f;
 
  if (msf) {
@@ -1103,7 +1111,7 @@ prtrack(struct cd_toc_entry *e, int last
  block = msf2lba(e->addr.msf.minute, e->addr.msf.second,
  e->addr.msf.frame);
  } else {
- block = ntohl(e->addr.lba);
+ block = e->addr.lba;
  if (!name || lastflag) {
  lba2msf(block, &m, &s, &f);
  /* Print track start */
@@ -1118,14 +1126,8 @@ prtrack(struct cd_toc_entry *e, int last
  printf("\n");
  return;
  }
-
- if (msf)
- next = msf2lba(e[1].addr.msf.minute, e[1].addr.msf.second,
- e[1].addr.msf.frame);
- else
- next = ntohl(e[1].addr.lba);
- len = next - block;
- lba2msf(len, &m, &s, &f);
+
+ len = tracklength(&e[0], &e[1], &m, &s, &f);
 
  if (name)
  printf("%2d:%02d.%02d  %s\n", m, s, f, name);
@@ -1136,6 +1138,30 @@ prtrack(struct cd_toc_entry *e, int last
 }
 
 int
+tracklength(struct cd_toc_entry *tr1, struct cd_toc_entry *tr2,
+    u_char *m, u_char *s, u_char *f)
+{
+ int block, len, next;
+
+ /* calculate the time between any two tracks */
+
+ if (msf) {
+ block = msf2lba(tr1->addr.msf.minute, tr1->addr.msf.second,
+ tr1->addr.msf.frame);
+ next = msf2lba(tr2->addr.msf.minute, tr2->addr.msf.second,
+ tr2->addr.msf.frame);
+ } else {
+ block = tr1->addr.lba;
+ next = tr2->addr.lba;
+ }
+
+ len = abs(next - block);
+ lba2msf(len, m, s, f);
+
+ return len;
+}
+
+int
 play_track(int tstart, int istart, int tend, int iend)
 {
  struct ioc_play_track t;
@@ -1177,10 +1203,8 @@ read_toc_entrys(int len)
 {
  struct ioc_read_toc_entry t;
 
- if (toc_buffer) {
+ if (toc_buffer)
  free(toc_buffer);
- toc_buffer = 0;
- }
 
  toc_buffer = malloc(len);
 
@@ -1234,8 +1258,7 @@ status(int *trk, int *min, int *sec, int
  *sec = s.data->what.position.reladdr.msf.second;
  *frame = s.data->what.position.reladdr.msf.frame;
  } else {
- lba2msf(ntohl(s.data->what.position.reladdr.lba),
-    &mm, &ss, &ff);
+ lba2msf(s.data->what.position.reladdr.lba, &mm, &ss, &ff);
  *min = mm;
  *sec = ss;
  *frame = ff;

dmesg:

OpenBSD 3.8-stable (PURPLESEA) #0: Sat Dec 17 13:24:55 EET 2005
    [hidden email]:/usr/src/sys/arch/i386/compile/PURPLESEA
cpu0: Intel Pentium III ("GenuineIntel" 686-class, 512KB L2 cache) 551 MHz
cpu0: FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,SER,MMX,FXSR,SSE
cpu0: disabling processor serial number
real mem  = 133787648 (130652K)
avail mem = 115462144 (112756K)
using 1658 buffers containing 6791168 bytes (6632K) of memory
mainbus0 (root)
bios0 at mainbus0: AT/286+(75) BIOS, date 08/18/99, BIOS32 rev. 0 @ 0xf0530
apm0 at bios0: Power Management spec V1.2
apm0: AC on, battery charge unknown
apm0: flags 30102 dobusy 0 doidle 1
pcibios0 at bios0: rev 2.1 @ 0xf0000/0xbe2
pcibios0: PCI IRQ Routing Table rev 1.0 @ 0xf0b60/128 (6 entries)
pcibios0: PCI Interrupt Router at 000:04:0 ("VIA VT82C586 ISA" rev 0x00)
pcibios0: PCI bus #2 is the last bus
bios0: ROM list: 0xc0000/0x8000
cpu0 at mainbus0
pci0 at mainbus0 bus 0: configuration mode 1 (no bios)
pchb0 at pci0 dev 0 function 0 "VIA VT82C691 PCI" rev 0x22
ppb0 at pci0 dev 1 function 0 "VIA VT82C598 AGP" rev 0x00
pci1 at ppb0 bus 1
vga1 at pci1 dev 0 function 0 "ATI Rage Pro" rev 0x5c
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
pcib0 at pci0 dev 4 function 0 "VIA VT82C596A ISA" rev 0x09
pciide0 at pci0 dev 4 function 1 "VIA VT82C571 IDE" rev 0x06: ATA33, channel 0 configured to compatibility, channel 1 configured to compatibility
wd0 at pciide0 channel 0 drive 0: <Maxtor 91021U2>
wd0: 16-sector PIO, LBA, 9770MB, 20010816 sectors
wd1 at pciide0 channel 0 drive 1: <ST33232A>
wd1: 16-sector PIO, LBA, 3077MB, 6303024 sectors
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 2
wd1(pciide0:0:1): using PIO mode 4, Ultra-DMA mode 2
atapiscsi0 at pciide0 channel 1 drive 0
scsibus0 at atapiscsi0: 2 targets
cd0 at scsibus0 targ 0 lun 0: <PLEXTOR, CD-R PX-320A, 1.03> SCSI0 5/cdrom removable
atapiscsi1 at pciide0 channel 1 drive 1
scsibus1 at atapiscsi1: 2 targets
st0 at scsibus1 targ 0 lun 0: <HP, COLORADO 8GB, 2.06> SCSI2 1/sequential removable
st0: drive empty or not ready
cd0(pciide0:1:0): using PIO mode 4, Ultra-DMA mode 2
st0(pciide0:1:1): using PIO mode 4, DMA mode 2
uhci0 at pci0 dev 4 function 2 "VIA VT83C572 USB" rev 0x02: irq 5
usb0 at uhci0: USB revision 1.0
uhub0 at usb0
uhub0: VIA UHCI root hub, rev 1.00/1.00, addr 1
uhub0: 2 ports with 2 removable, self powered
ppb1 at pci0 dev 4 function 3 "VIA VT82C596 Power" rev 0x00
ppb1: not configured by system firmware
eap0 at pci0 dev 9 function 0 "Ensoniq AudioPCI97" rev 0x06: irq 5
ac97: codec id 0x43525913 (Cirrus Logic CS4297A rev 3)
ac97: codec features headphone, 20 bit DAC, 18 bit ADC, Crystal Semi 3D
audio0 at eap0
midi0 at eap0: <AudioPCI MIDI UART>
isa0 at pcib0
isadma0 at isa0
pckbc0 at isa0 port 0x60/5
pckbd0 at pckbc0 (kbd slot)
pckbc0: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
pckbc0: using irq 12 for aux slot
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
midi1 at pcppi0: <PC speaker>
spkr0 at pcppi0
sysbeep0 at pcppi0
lpt0 at isa0 port 0x378/4 irq 7
lm0 at isa0 port 0x290/8: W83781D
npx0 at isa0 port 0xf0/16: using exception 16
pccom0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
pccom1 at isa0 port 0x2f8/8 irq 3: ns16550a, 16 byte fifo
fdc0 at isa0 port 0x3f0/6 irq 6 drq 2
fd0 at fdc0 drive 0: 1.44MB 80 cyl, 2 head, 18 sec
isapnp0 at isa0 port 0x279: read port 0x20b
ep1 at isapnp0 "3Com 3C509B EtherLink III, TCM5095, PNP80F7, " port 0x210/16 irq 9: address 00:50:04:23:7a:70, utp (default utp)
biomask ed65 netmask ef65 ttymask ffe7
pctr: 686-class user-level performance counters enabled
mtrr: Pentium Pro MTRR support
dkcsum: wd0 matches BIOS drive 0x80
dkcsum: wd1 matches BIOS drive 0x81
root on wd0a
rootdev=0x0 rrootdev=0x300 rawdev=0x302


>Release-Note:
>Audit-Trail:
>Unformatted: