Author Topic: Playing last track of audio CD to completion hangs the system  (Read 321 times)

Lars

  • Hero Member
  • *****
  • Posts: 1483
  • Karma: +75/-0
I wonder if anyone else is experiencing the same:

I recently played an audio CD with both, Chris Wohlgemuths audio player integrated into the WPS as well as the classic CD audio player that comes with OS/2. I used a USB attached CD/DVD device.

After the last track was played to completion, the system hung. I had to unplug the CD/DVD device to recover from the hang.
This was true regardless of if I used built-in audio via UNIAUD or a USB audio 1.1 device supported via USBAUDIO.SYS. Therefore, this was not a problem with USB isochronous audio transfer.

When I used this self-written REXX script (modify "cdaudio02" to "cdaudio01" if you want to play from the first/only CD/DVD device):
Code: [Select]
/* REXX script */

signal on error name error
signal on halt name halt
signal on failure name halt
signal on notready name halt
signal on syntax name error

/* Load the REXXUTIL DLL */
rc = RXFUNCADD('SysLoadFuncs','REXXUTIL','SysLoadFuncs')
InitRC = SysLoadFuncs()

/* Load the DLL, initialize MCI REXX support */
rc = RXFUNCADD('mciRxInit','MCIAPI','mciRxInit')
InitRC = mciRxInit()

/* open audio CD drive */
MacRC = SendString('open cdaudio02 alias rexxalias shareable wait')
/* query digital transfer capability */
MacRC = SendString('capability rexxalias can stream wait')
/* will return "TRUE" if capability is supported, else "FALSE" */
/* set digital transfer mode */
MacRC = SendString('connector rexxalias enable type cd stream wait')
/* query number of tracks */
MacRC = SendString('status rexxalias number of tracks wait')
NumberOfTracks = RetSt

pos = SysCurPos()
row = word(pos,1)
col = word(pos,2)
promptstring = 'Track to play [1 to 'NumberOfTracks']:'
len = length(promptstring)
say promptstring
rc = SysCurPos(row,col+len)
parse pull TrackToPlay .


if (datatype(TrackToPlay) <> 'NUM') | (TrackToPlay < 1) | (TrackToPlay > NumberOfTracks) then do
   say 'Specify a Track Number between 1 and 'NumberOfTracks'!'
   signal halt
end /* do */

MacRC = SendString('set rexxalias time format msf wait')

/* computing start and end of track */
MacRC = SendString('status rexxalias position track 'TrackToPlay' wait')
StartPos = RetSt
MacRC = SendString('status rexxalias length track 'TrackToPlay' wait')
TrackLength = RetSt
EndPos = ComputeEndMSF(StartPos,TrackLength)

/* playing the selected track */
MacRC = SendString('play rexxalias from 'StartPos' to 'EndPos)

MacRC = SendString('status rexxalias mode wait')
StatusString = RetSt
rc = SysCurPos(row+1,0)
do while(StatusString = 'playing')
   MacRC = SendString('status rexxalias position in track wait')
   CurrTrackPos = RetSt
   say 'Position from 'CurrTrackPos' to 'TrackLength
   rc = SysCurPos(row+1,0)
   MacRC = SendString('status rexxalias mode wait')
   StatusString = RetSt
end /* do */

MacRC = SendString('stop rexxalias wait')

MacRC = SendString('close rexxalias wait')
if MacRC <> 0 then signal ErrExit

return 0

ComputeEndMSF:
StartPos = arg(1)
TrackLength = arg(2)

parse var StartPos     smin ':' ssec ':' sframe
parse var TrackLength  lmin ':' lsec ':' lframe

frame = (sframe + lframe)//75
carry = (sframe + lframe)%75
sec   = (ssec + lsec + carry)//60
carry = (ssec + lsec + carry)%60
min   = (smin + lmin + carry)//60
return (min':'sec':'frame)



SendString: procedure expose RetSt
   arg CmndTxt
   /* Last two parameters are reserved, must be set to 0           */
   /* Future use of last two parms are for notify window handle    */
   /* and userparm.                                                 */
   MacRC = mciRxSendString(CmndTxt, 'RetSt', '0', '0')
   if MacRC<>0 then
      do
      ErrRC = MacRC
      say 'MciCmd=' CmndTxt
      say 'Err:mciRxSendString RC=' ErrRC RetSt
      MacRC = mciRxGetErrorString(ErrRC, 'ErrStVar')
      say 'mciRxGetErrorString('ErrRC') =' ErrStVar
      MacRC = ErrRC /* return the error rc */
      end
   return MacRC

ErrExit:
   MacRC = mciRxExit()   /* Tell the DLL we're going away        */
   exit 1;               /* exit, tell caller things went poorly */

error:
   ErrRC = rc
   say
   say 'Error' ErrRC 'at line' sigl ', sourceline:' sourceline(sigl)
   MacRC = mciRxExit()       /* Tell the DLL we're going away */
   exit ErrRC                /* exit, tell caller things went poorly */

halt:
   say
   say 'Halting...'
   MacRC = SendString('stop rexxalias wait')
   MacRC = SendString('close rexxalias wait')
   if MacRC <> 0 then signal ErrExit
   MacRC = mciRxExit()
   exit MacRC

it turned out that in fact the track was not entirely played to completion as the current timestamp never reached the end of track timestamp.


However, when I tried the same with a built-in CD/DVD device attached via AHCI, the system did not hang.

Can someone confirm that there is a problem with USB attached CD/DVD devices ? I am using a USB CD/DVD device from ASUS (ASUS SDRW-08D2S-U).
Please also report if you are using the USB stack from AN or not.
« Last Edit: April 14, 2026, 08:25:23 am by Lars »

Wim Brul

  • Sr. Member
  • ****
  • Posts: 307
  • Karma: +26/-0
    • Wim's home page
Re: Playing last track of audio CD to completion hangs the system
« Reply #1 on: April 18, 2026, 12:53:19 pm »
Although I don't have a USB attached CD/DVD drive, I tried your self-written REXX script, and it appears to work allright for audio CD's with up to 60 minutes of audio only. To play longer audio CD's, one line of code needs to be changed.

from:
Code: [Select]
min   = (smin + lmin + carry)//60

Into:
Code: [Select]
min   = (smin + lmin + carry)

On my Dell Latitude e6500 with both ArcaOS 5.0 (USB stack 12.18) and eComStation 2.2 (USB stack 10.252) playing audio CD's with the classic multimedia audio player and using digital transfer works without problems.

Lars

  • Hero Member
  • *****
  • Posts: 1483
  • Karma: +75/-0
Re: Playing last track of audio CD to completion hangs the system
« Reply #2 on: April 19, 2026, 01:31:29 am »
Hi Wim,

yes, that code is a typo/copy-paste error, thanks for pointing that out.

Nonetheless, the problem is the USB attached drive. For some reason, I get a "stalled endpoint" error in USBMSD.ADD but only occasionally as it seems because I tested today and would not hang even if it would idle a few seconds before the REXX script would finally finish.
If I find the time, I'll investigate further into USBMSD.ADD. On the other hand, for CD devices, OS2CDROM.DMD is in effect and the only IORB command it invokes on USBMSD.ADD is IOCC_ADAPTER_PASSTHRU which means OS2CDROM.DMD assembles a CDB block and directly sends that to USBMSD.ADD (so there is no risk of USBMSD.ADD incorrectly assembling a SCSI-type command to send to the device).
« Last Edit: April 19, 2026, 01:36:02 am by Lars »