home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: Multimed
/
Multimed.zip
/
lechmp3.zip
/
leechmp3.rxx
< prev
next >
Wrap
Text File
|
2000-05-13
|
13KB
|
438 lines
/********************************************************************/
/* */
/* LEECHMP3: Version 1.0 */
/* Author: Michel SUCH. Email: msuch@free.fr */
/* */
/* Multithreaded conversion from CD to MP3. */
/* */
/* This program requires several components to be installed */
/* */
/* 1: LEECH 1.20. */
/* 2: LAME MP3 encoder. */
/* All components may be obtained on HOBBES: http://hobbes.nmsu.edu */
/* */
/* LEECH.EXE and LAME.EXE must be located in a directory defined */
/* in the path variable of the CONFIG.SYS file */
/* or in the directory containing the LEECHMP3 program. */
/********************************************************************/
parse arg parms
x= pos('-', parms)
if x > 0 then do
lameparms = substr(parms, x)
parms = delstr(parms, x)
end
else lameparms = ''
parse upper value(strip(parms)) with process parms
call init_prog
select
when process = "GRAB" then do /* start grabbing process */
parse var parms grabber encoder cdrom wavqueue
call init_cd
call leech
call end_cd
end
when process = "ENCODE" then do /* start mp3 encoding process */
parse var parms encoder qname
call init_mp3
call lame
call end_mp3
end
when process = '' | process = "T" then do /* initial process */
call presentation
/* Check if we have all needed programs */
grabber = find_prog('LEECH.EXE')
if grabber = '' then do
say "Cannot find LEECH.EXE grabber program"
exit
end
say "Grabbing using" grabber
encoder = find_prog('LAME.EXE')
if encoder = '' then do
say "Cannot find LAME.EXE encoding program"
exit
end
say "Encoding using" encoder
call get_cdrom
if translate(process) = "T" then do /* tracklist */
call check_list
end
else tracks = "" /* all tracks */
call get_ntracks
call sort_trks
'@START "CD GRABBING THREAD" /C' pgm "GRAB" grabber encoder cdrom wavqueue lameparms
exit
end
otherwise do
say "invalid parameter" process
exit
end
end
exit
init_prog:
if rxfuncquery('sysloadfuncs') <> 0 then do
call rxfuncadd 'sysloadfuncs', 'rexxutil', 'sysloadfuncs'
call sysloadfuncs
end
parse source . . pgm .
rundir = directory()
progdir = filespec('D', pgm) || filespec('p', pgm)
return /* init_prog */
find_prog:
procedure
/* First, search in the program's directory */
parse source . . me .
dir = filespec('d', me) || filespec('p', me)
call sysfiletree dir || arg(1), lst.
if lst.0 > 0 then pgm = word(lst.1, 5)
else do /* search in the path environment variable */
pgm = syssearchpath( 'path', arg(1))
end
drop lst.
return pgm /* get_progs */
presentation:
parse value(filespec('n', pgm)) with me'.'ext
say me": Multithreaded CD to MP3, Version 1.0"
say ""
say "Author: Michel SUCH. Email: msuch@free.fr"
say ""
return /* presentation */
get_cdrom:
/* Determine the unit letter for the CD-ROM */
cdrom = ''
list = sysdrivemap('c')
do i = 1 to words(list)
dk = word(list, i)
info = sysdriveinfo(dk)
free = word(info, 2)
select
when info = '' then do
cdrom = dk
leave
end
when free = 0 then do
cdrom = dk
leave
end
otherwise nop
end
end
if cdrom = '' then do
say "Cannot determine your CD-ROM drive letter"
exit
end
say "CD-ROM unit:" cdrom
return /* get_cdrom */
check_list:
procedure expose parms tracks
/* checks that all track numbers are numeric */
/* and they are between 1 and 99 */
if parms = '' then do
say "No track list specified"
exit
end
tracks = ''
do i = 1 to words(parms)
trk = strip(word(parms, i), 'l', '0')
if datatype(trk) <> 'NUM' then do
say "INVALID TRACK NUMBER" trk
exit
end
if trk < 1 | trk > 99 then do
say "Track number" trk "out of range"
exit
end
tracks = tracks trk
end
return /* check_list */
get_ntracks:
procedure expose grabber cdrom trks trklst. tracks progdir
/* Determines the number of audio tracks on the cd */
trks = 0
/* make a local queue to prevent conflicts with other process */
qtrk = rxqueue('create')
oldq = rxqueue('set', qtrk)
"@"grabber cdrom "TOC | rxqueue" qtrk
total = 0
do queued()
pull ln
if word(ln, 2) = "PANIC" then do
rc = rxqueue('set,', oldq)
rc = rxqueue('delete', qtrk)
say "Drive" cdrom "not ready or in use"
call sayfile "notready"
exit
end
if wordpos("CDDA", ln) <> 0 then do /* audio track found */
n = strip(word(ln, 1), 'l', '0') /* track number */
total = total + 1
if (tracks = "") | (wordpos(n, tracks) > 0) then do
trks = trks + 1
trklst.trks = n strip(word(ln, 8), "T", ")") /* track size in sectors */
end
end
end
rc = rxqueue('set,', oldq)
rc = rxqueue('delete', qtrk)
do i = 1 to words(tracks) /* check if all selected tracks exist */
t = word(tracks, i)
if t > total then do
Say "Track" t "Does not exist on this CD"
exit
end
end
trklst.0 = trks
select
when trks = 0 then do
say "No audio track to grab"
exit
end
when trks = 1 then say trks "track will be grabbed"
otherwise do
say trks "tracks will be grabbed"
end
end
return /* get_ntracks */
sort_trks:
procedure expose trklst. wavqueue
/* let's sort tracks in ascending size order */
/* so that the shortest track is grabbed first */
/* and encoding starts asap */
wavqueue = rxqueue('create')
oldq = rxqueue('set', wavqueue)
do while trklst.0 > 0
minptr = 1
do i = 2 to trklst.0
if word(trklst.i, 2) < word(trklst.minptr, 2) then do
minptr = i
end
end
queue trklst.minptr
do j = minptr to trklst.0
k = j + 1
trklst.j = trklst.k
end
trklst.0 = trklst.0 - 1
end
oldq = rxqueue('set', oldq)
return /* sort_trks */
/**********************************************************************/
/* grabber section. */
/**********************************************************************/
init_cd:
mp3queue = rxqueue('create') /* communication queue with mp3 thread */
oldq = rxqueue('set', mp3queue)
'@START "MP3 ENCODING THREAD" /c' pgm "ENCODE" encoder mp3queue lameparms
return /* init_cd */
get_trklst:
procedure expose wavqueue trklst.
say ''
oldq = rxqueue('set', wavqueue)
trklst.0 = queued()
do i = 1 to trklst.0
pull trklst.i
end
oldq = rxqueue('set', oldq)
rc = rxqueue('delete', wavqueue)
return /* get_trklst */
leech:
/* grabs tracks and pass them to mp3 process */
call get_trklst
do i = 1 to trklst.0
t = word(trklst.i, 1)
call sayfile "read"
call sayfile right(t, 2, ' ')
/* use a big buffer to improve multitasking */
"@"grabber cdrom "T" t "-w4096 -s15 -j25 -o -a"
if rc <> 0 then do /* process killed */
queue "END" /* abort encoding for next track */
leave
end
queue "TRACK_" || right(t, 2, '0') /* pass file name to encoder */
end
queue 'END' /* stop encoder */
call sayfile "endread"
return /* leech */
end_cd:
/* finish grabbing process */
oldq = rxqueue('set', oldq)
"@EJECT" cdrom
return /* end_cd */
/**********************************************************************/
/* MP3 encodr section. */
/**********************************************************************/
init_mp3:
oldq2 = rxqueue('set', qname) /* setup the input queue */
say "Waiting for first wave file"
return /* init_mp3 */
lame:
/* encoding part */
do forever
do while queued() = 0 /* wait for something in the queue */
call syssleep 1
end
pull fname
if fname = "END" then leave
call sayfile "encode"
call sayfile strip(right(fname, 2, ' '), 'l', '0')
wavname = rundir'\'fname'.WAV'
mp3name = rundir'\'fname'.MP3'
"@"encoder lameparms wavname mp3name
call sysfiledelete wavname
end
call sayfile "endenc"
return /* lame */
end_mp3:
rc = rxqueue('delete', qname)
do i = 1 to 5 /* make a little noise */
call beep 440, 100
call beep 660, 100
end
return /* end_mp3 */
/**********************************************************************/
/* Speech section */
/**********************************************************************/
sayfile:
procedure expose progdir
parse arg fn .
file = progdir"\sounds\"fn".wav"
call sysfiletree file, lst.
if lst.0 = 0 then return 1
rc = RXFUNCADD('mciRxInit','MCIAPI','mciRxInit')
InitRC = mciRxInit()
MciCmd = "open" file "alias leechmp3 wait"
do forever
MacRC = SendString(MciCmd)
select
when macrc = 5032 then do /* sound card in use */
call syssleep 1
iterate
end
when macrc = 0 then leave /* can play */
otherwise do /* non recoverable error */
MacRC = mciRxExit() /* Tell the DLL we're going away */
return 1
end
end
end
MacRC = SendString("capability leechmp3 device type wait")
if MacRC <> 0 then do
junk = SendString("close leechmp3 wait")
junk = SendString("release waveaudio wait")
MacRC = mciRxExit() /* Tell the DLL we're going away */
return 1
end
if TRANSLATE(RetSt) = 'WAVEAUDIO' then do
MacRC = SendString("status leechmp3 length wait") /* If length is 0 no file exists */
if MacRC <> 0 then do
junk = SendString("close leechmp3 wait")
junk = SendString("release waveaudio return resource wait")
MacRC = mciRxExit() /* Tell the DLL we're going away */
return 1
end
if RetSt = 0 then do
junk = SendString("close leechmp3 wait")
ErrRC = 70555
macRC = mciRxGetErrorString(ErrRC, 'ErrStVar')
/* say 'mciRxGetErrorString('ErrRC') =' ErrStVar*/
junk = SendString("release waveaudio return resource wait")
MacRC = mciRxExit() /* Tell the DLL we're going away */
return 1
end
end
DeviceID = mciRxGetDeviceID(""leechmp3"")
MciCmd = 'play leechmp3 wait'
MacRC = SendString(MciCmd)
if MacRC <> 0 then do
junk = SendString("close leechmp3 wait")
junk = SendString("release waveaudio return resource wait")
MacRC = mciRxExit() /* Tell the DLL we're going away */
return 1
end
MacRC = SendString("close leechmp3 wait")
junk = SendString("release waveaudio return resource wait")
if MacRC <> 0 then do
MacRC = mciRxExit() /* Tell the DLL we're going away */
return 1
end
MacRC = mciRxExit() /* Tell the DLL we're going away */
return 0
SendString:
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