Stone Oakvalley's Amiga Music Collection (SOAMC=)
The automated Commodore Amiga Music recorded to MP3. Project covers 193 different Amiga Music File Formats!


                        



T H E   R E A L   D E A L   I N   -   A U T H E N T I C  -   C O M M O D O R E   A M I G A   M U S I C  !




Music Ripping - 100% automated!
in All about SOAMC= | Saturday, June 09, 2018 | 17:10


The following procedure explains how I managed to automate ExoticRipper, EaglePlayer (EagleRippers), Pro-Wizard (they have no desent or no command line/script support by its own) by using Arexx, External tools, my own code and scripts that will be used to rip out tunes in files that has previously been tagged.

Additionally "ProWizard 4 PC" will be used on the PC side to scan and find even more tunes.


Update 15 Nov 2018: As of this date, this page will not be updated anymore, it is now just part of history :-)

External tools (made by other people or me) - used in the AREXX script below:

1: Parts from/modified "AutoIconOpen.c" by Tony (**all at sea in C**) Wills, 15 FEB 87, VERSION : 1.2.
Reference: http://aminet.net/package/util/batch/AutoIconOpen
Used for faking a mouse click.

2: "MovePointer" by G.S.G. 9 (Cewy), Fish Collection, 1987-07-07
Reference: http://aminet.net/package/util/batch/MovePointer
Used for position the mouse pointer at coords 0,0.

3: "Clip" v2.0 by cisc@c2i.net (Sigbjørn Skjæret), 2001-02-06
Reference: http://aminet.net/package/util/cli/clip
Used to put filename load/save into clipboard

4: "Fakekey" by thomas-rapp@web.de (Thomas Rapp) (Not sure, but most likely)
Reference: http://thomas-rapp.homepage.t-online.de/download.html
Used to perform certain keypresses (like RETURN, paste filename and more)

5: "Mon" v1.65 by trossi at jyu.fi (Timo Rossi), 1994-05-23
Reference: http://aminet.net/package/dev/moni/mon165
Used to hunt for specific strings to find ExoticRipper CON: window and progress bar.

6: "Show" v0.58 by JM, Supervisor Software, February 29, 1992
Reference: http://aminet.net/package/util/moni/show
Used to locate the memory adress of ExoticRipper's CON window/GUI and the precense of certain Pro-Wizard windows/requesters.

7: "BetterEdit" v1.5 by Allan Odgaard , 16-Feb-98
Reference: http://aminet.net/package/util/cdity/BetterEdit
Used to enable RAMIGA+V as copy paste inside string gadget.
Note: Started during startup-sequence.

8: "ActivateWindow" v1.3 by Deniil 715
Reference: http://aminet.net/package/util/cli/ActivateWindow
Used to Activate EaglePlayer window during automatic ripping via Rexx/Batch files.

9: "Peek" v1.0 by Stone Oakvalley Studios, June 2018
Used for peeking into memory for "tSt!" and "NAME: "
Programmed in Blitz Basic 2 on Amiga.

10: "Peek_Progress" v1.0 by Stone Oakvalley Studios, June 2018
Used for peeking into memory of ExoticRipper progress bar.
Programmed in Blitz Basic 2 on Amiga.

11: "WaitFrames" v1.0 by Stone Oakvalley Studios, July 2018
Used for waiting in frames rather than seconds (like standard Shell/Workbench wait command). To generally speed up things during batch/Arexx operations.
Programmed in Blitz Basic 2 on Amiga.

12: "Scanner" v1.0 by Stefan Parmark (d84sp@efd.lth.sei, 1989
Reference: http://aminet.net/package/dev/gui/Scanner
Used to hunt for the precense of two requesters of Pro-Wizard (either "SAVE" or "CONVERT" buttons, as the shortcut would interfere meaning LAMIGA + S would actually click "SKIP" when a "CONVERT" situation occured. The original scanner.c source code listed all kinds of structures including the sizes of these gadgets luckily for me! So, I adjusted the very old .c code and compiled with SAS/C 6.58 to produce an output of a single value of 108 or 128 then exit with a return-code which my .rexx script picked up and pressed either LAMIGA+S or LAMIGA+C promptly. Without this source I'm not sure how long the automation ripping using Pro-Wizard would need to be investigated further - I managed to solve it during 2 nights in early November 2018 = success in automation!


----------
The following source scripts below isn't really for anybody else than my system, but perhaps parts of them are helpful for others doing automation using Arexx/batch files out there, so feel free to steal my ideas :-)

It should be noted that they might be adjusted in my system in future, so don't expect these to be updated on this website in future. As they are right now, they are working during debugging and one-time scanning for automation.
----------


AutoIconOpen.c
The original code can be found in my reference above, but my modified version as used during ripping are presented below (with a small tweak to prevent the gadget becoming stuck. Remember original code was for Workbench 1.2/1.3, but at least in 3.0/3.1 the gadget clicked was stuck).

Note: As the arguments for placing the mouse is relative it means you should first use "MovePointer 0 0" to reset mouse into topleft corner, then use AutoIconOpen to correctly place the mouse pointer where it should be, otherwise, it will only add to the current mouse position as no reset function is present.

/*
Based on AutoIconOpen.c by Tony (**all at sea in C**) Wills 15 FEB 87, V1.2
reference: http://aminet.net/package/util/batch/AutoIconOpen

This version modified by Stone Oakvalley Studios to automate ExoticRipper 3.3 during SOAMC= ENDGAME
Arguments added for x,y :-) by Waxhead very late at night, haha. All done during 2-3 June 2018

In fact, this little gem of re-compiled software can be used in many other automation procedures :-)

Additionally the original source code (at least for OS3.0) we need to change
SimulatedEvent.ie_Code = IECODE_LBUTTON;
into
SimulatedEvent.ie_Code = IECODE_LBUTTON IECODE_UP_PREFIX;
otherwise the gadgetpress was stuck.

Compiled now with Lattice C v5.03.

This is BTW my first c compiled source/program on Amiga ever! Imagine a source from 1987 made Stone Oakvalley edit, tweak
and compile it 31 years later!
*/

#include
#include
#include
#include
#include
#include
#include

struct MsgPort *inputDevPort;
struct IOStdReq *input_request_block;
struct InputEvent SimulatedEvent;
extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();

main(argc,argv)
int argc;
char *argv[];
{
if ((inputDevPort=CreatePort(0,0)) == NULL) exit(-1);
if ((input_request_block=CreateStdIO(inputDevPort))==0) exit (-2);
if (OpenDevice("input.device",0,input_request_block,0) !=0) exit(-1);

input_request_block->io_Command=IND_WRITEEVENT;
input_request_block->io_Flags=0;
input_request_block->io_Length=sizeof(struct InputEvent);
input_request_block->io_Data=(APTR)&SimulatedEvent;

/* Move Mouse to x,y click mouse button DOWN */
SimulatedEvent.ie_NextEvent = NULL;
SimulatedEvent.ie_Class = IECLASS_RAWMOUSE;
SimulatedEvent.ie_TimeStamp.tv_secs = 0;
SimulatedEvent.ie_TimeStamp.tv_micro = 0;
SimulatedEvent.ie_Code = IECODE_LBUTTON;
SimulatedEvent.ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
SimulatedEvent.ie_X = atoi(argv[1]);
SimulatedEvent.ie_Y = atoi(argv[2]);
DoIO(input_request_block);

/* Keep mouse postion, but release mouse button UP to activate the correct response */
SimulatedEvent.ie_NextEvent = NULL;
SimulatedEvent.ie_Class = IECLASS_RAWMOUSE;
SimulatedEvent.ie_TimeStamp.tv_secs = 0;
SimulatedEvent.ie_TimeStamp.tv_micro = 0;
SimulatedEvent.ie_Code = IECODE_LBUTTON IECODE_UP_PREFIX;
SimulatedEvent.ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
SimulatedEvent.ie_X = 0;
SimulatedEvent.ie_Y = 0;
DoIO(input_request_block);

CloseDevice(input_request_block);
}


ExoticRipper ToolChain.bat
The following script accepts a filename to load into ExoticRipper automatically directly from CLI, it ends with an AREXX scripts that performs the rest of the magic :-)

.KEY filename
; By Stone Oakvalley Studios - May-June 2018 for the SOAMC= ENDGAME automation
; 1: Execute a list of windows and output to PIPE:mega
; 2: The rexx script will detect read the PIPE:mega and proceed to automate "EagleRipper 3.3"
; .KEY filename is the file to be scanned, it is also the filename to save module (if any found), this argument is passed on :-)

setfont digiboostered 6
echo c
echo 
IF EXISTS results_mon.txt
delete results_mon.txt >NIL:
ENDIF

IF EXISTS results_progress.txt
delete results_progress.txt <NIL:
ENDIF

IF EXISTS RAM:EXITCODE
delete RAM:EXITCODE >NIL:
ENDIF

show w >PIPE:mega

IF EXISTS <filename>
rx exoticripper_check.rexx <filename>
ELSE
echo <filename> " file not found!"
ENDIF


ExoticRipper REXX Automation
The following AREXX script performs the entire loading, hunting, tracking, saving of modules found and supports multi-find it that happens. The script is a delicate mix between standard CLI commands, external tools mentioned above and some AREXX trickery all working together to just work on its own :-)


/* Check if ExoticRipper 3.3 is started and find its approximate address so we can execute mon165 */
/* From that point on we can find the CONSOLE output window and check if ExoticRipper writes "NAME: " in it */
/* Script loops until returncode is <>0. */

/* Written by Stone Oakvalley Studios May-June 2018 for the SOAMC= ENDGAME automation */

fileptr="infile"
path="PIPE:mega"

fileptr2="infile2"
path2="results_mon.txt"

fileptr3="infile3"
path3="results_progress.txt"

fileptr4="infile4"
path4="RAM:EXITCODE"

idcount=1
found_exotic=0
filename=ARG(1)
found_string=""

ADDRESS COMMAND

OPTIONS FAILAT 1000000

len=LENGTH(filename)
IF len>0 THEN DO

/* In this loop we must wait until ExoticRipper found something or a timeout occured */
IF OPEN(fileptr,path,"R") THEN DO
DO WHILE ~Eof(fileptr)
in_string=Readln(fileptr)
IF FIND(in_string,'ExoticRipper 3.3') THEN DO
found_string=in_string
found_exotic=1
END
END
CALL CLOSE(fileptr)
END

IF found_exotic=1 THEN DO
cutter=RIGHT(found_string,49)
cutter=LEFT(cutter,9)
SAY "EagleRipper ca. start:" cutter

/* Generate the script automatically, first tell mon to output responses by o */
/*The file results_mon.txt now contains 1 hex code like 00266C3E*/
"echo o results_mon.txt >mon.script"
"echo h " cutter " " cutter "+300000 $ff,$ff,$74,$53,$74,$21 >>mon.script" /* Scan for tSt! */
"echo x >>mon.script"
"mon >NIL: -w130 -h50 -s mon.script" /* Start Mon v1.65 with the script created above */

/* Generate the script automatically, first tell mon to output responses by o */
/*The file results_progress.txt now contains 1 hex code like 00266C3E*/
/* This adress will be used with PEEK_PROGRESS to find the progress bar realtime text in memory */

"echo o results_progress.txt >mon2.script"
"echo h " cutter " " cutter "+300000 $45,$46,$41,$FA,$00,$0A,$61,$00,$FC,$06 >>mon2.script" /* Scan for EFA */
"echo x >>mon2.script"
"mon >NIL: -w130 -h50 -s mon2.script" /* Start Mon v1.65 with the script created above */

/* Read the location of progress bar */
IF OPEN(fileptr3,path3,"R") THEN DO
in_string3=Readln(fileptr3)
CALL Close(fileptr3)
END

/* Start the READING and HUNTING */
CALL click_read
CALL insert_loadfile
CALL click_hunt


/*Read that file add +14d in which we would find " Name:" if exotic found a module */
IF OPEN(fileptr2,path2,"R") THEN DO
in_string2=Readln(fileptr2)
CALL Close(fileptr2)

If LENGTH(in_string2)>6 THEN DO
/* Stone Oakvalley's Peeker to find "NAME: " in exactly 6 bytes = means Exoticripper got a module and we can save it! */
n=X2D(in_string2)+334
new_hunt=D2X(n)


/* MAIN LOOP to repeat until no module or no more modules was found */
DO FOREVER
CALL hunt_song
IF STATUS<0 THEN DO
SAY "No more modules"
EXIT
END
END
END
END
END
ELSE
SAY "ExoticRipper not started?"
EXIT
END
ELSE
SAY "Unable to open PIPE:mega"
EXIT
END


; Procedures to make it easier to re-use functions


hunt_song: PROCEDURE EXPOSE new_hunt filename idcount singlefile status revpos in_string3 fileptr4 path4
'peek_progress $'in_string3
'peek $'new_hunt' "Name: " >NIL:'

IF OPEN(fileptr4,path4,"R") THEN DO
in_string4=Readln(fileptr4)

IF LENGTH(in_string4)=3 THEN DO
STATUS=0 /* success */
END

IF LENGTH(in_string4)=2 THEN DO
STATUS=-1 /* no success */
END

IF LENGTH(in_string4)=1 THEN DO
STATUS=-2 /* fail */
END

CALL Close(fileptr4)
'delete RAM:EXITCODE >NIL:'
END

/* While peek is hunting, an return code of 0=module found, -1=nothing found, -2=errors in arguments, like new_hunt was empty */
IF status=0 THEN DO
/* Split out the filename ONLY when saving the module */
/* First we reverse the complete filename that contains path */
/* Then find the first instance of "/" and cut it out */
/* Finally reverse the string again leaving the path gone, just filename left */

singlefile=REVERSE(filename)
revpos=INDEX(singlefile,"/")-1
singlefile=LEFT(singlefile,revpos)
singlefile=REVERSE(singlefile)"."idcount
idcount=idcount+1
SAY "Module Found, saving as: "singlefile
CALL click_write
CALL click_songsamples

/* Now we have the filerequester already popped up so first delete the current filename */
"fakekey lshift right"
"wait 1"

/* Now clear old filename that ExoticRipper automatically inserts */
"fakekey x ramiga"

CALL insert_savefile
CALL click_continue
END
RETURN STATUS



insert_loadfile: PROCEDURE EXPOSE filename
"clip STRING="filename

/* Paste the Filename into ReqTools filename requester (BetterEdit was installed to prevent EPIC FAIL by ReqTools to assign RightAmiga + V to 'Volumes'. Duh! How could they make such a decision?!!) */
"fakekey v RAMIGA"

/* Press Return two times, since first is to choose directory, then filename is left */
"fakekey return"
"fakekey return"
"wait 2" /* Let filerequester go away and ExoticRipper load the file */
RETURN


insert_savefile: PROCEDURE EXPOSE singlefile
"clip STRING="singlefile
"fakekey v RAMIGA"
"fakekey return"
"wait 2" /* Let ExoticRipper save and close window */
RETURN


click_hunt: PROCEDURE
"movepointer 0 0"
"autoiconopen 460 380"
RETURN


click_read: PROCEDURE
"movepointer 0 0" /* Reset mousepointer first */
"autoiconopen 340 400" /* Position over READ button and click it*/
"wait 1"
RETURN


click_continue: PROCEDURE
"movepointer 0 0" /* Reset mousepointer first */
"autoiconopen 460 410" /* Position over CONTINUE button and click it*/
"wait 1"
RETURN


click_write: PROCEDURE
"movepointer 0 0" /* Reset mousepointer first */
"autoiconopen 340 370" /* Position over WRITE button and click it*/
"wait 1"
RETURN


click_songsamples: PROCEDURE
"movepointer 0 0" /* Reset mousepointer first */
"autoiconopen 250 290" /* Position over SONG+SAMPLES button and click it*/
"wait 1"
RETURN

click_quit: PROCEDURE
"fakekey q RAMIGA" /* To exit from ExoticRipper */
"fakekey return" /* and press OK to quit */
RETURN


EaglePlayer ToolChain.bat

.KEY filename
; By Stone Oakvalley Studios - July 2018 for the SOAMC= ENDGAME automation
; 1: Loads a file to Rip-Scan into EaglePlayer
; 2: The rexx script will monitor the presence of and "Eagleplayer-Request" and automate the saving of module
; 3: When module was finished scanning an error requester will appear "Eagleexotic" with "Can't load ExoticRipper !" x 2 which means the file was scanned 100% and procedure was done. (We will simply press RETURN two times when this happens)
; 4: Then we QUIT Eagleplayer and everything restarts.
; .KEY filename is the file to be scanned, it is also the filename to save module (if any found), this argument is passed on :-)

setfont digiboostered 6
echo c
echo 
rx eagleplayer_rip_check.rexx <filename>
echo "Finished"


EaglePlayer / EagleRipper REXX Automation

/* Check if Eagleplayer-Request pops up during ripping and automates save module and continue! */
/* Another nice script done for SOAMC= ENDGAME July 2018 by Stone Oakvalley Studios */

filename=ARG(1)
ADDRESS command

fileptr='infile'
path='PIPE:mega'
idcount=1

/* Detections performed */
/* 1: "Eagleplayer-Request" comes = save module */
/* 2: "Eagleexotic" comes = no more modules, finished */
/* 3: Time-out mode. After 2 minutes, if neither appears, we need to QUIT Eagle and this script */

/* Loop until Eagleplayer arexx port is found, then start monitoring of Requesters */

ADDRESS COMMAND 'run HD1:EaglePlayer/EaglePlayer NoEngines'
ADDRESS COMMAND 'WaitForPort rexx_EP'

/* Port is now available as WaitForPort found it, so continue with fake-key loading the module */
'clip STRING='filename /* Put entire filename into clipboard */
'waitframes 100' /* Wait for Eagle to load completely */
'activatewindow ACTIVATE WT="EaglePlayer V2.05 Registered"' /*Activate Eagleplayer so we can fake-key stuff loading */
'fakekey l RAMIGA' /* Bring up the load module requester */
'waitframes 10'
"fakekey lshift right" /* Make sure we clear file requester properly */
'waitframes 10'
'fakekey x RAMIGA' /* Empty out file requester */
'waitframes 10'
'fakekey v RAMIGA' /* Paste the entire filename to load */
'waitframes 10'
'fakekey return'
'waitframes 10'
'fakekey return' /* and load it for ripping, it will start instantly */
'waitframes 10'

/* In this loop we must wait until "Eagleplayer-Request", "Eagleexotic" appears or a timeout appears */
DO FOREVER
ADDRESS COMMAND
'show w >PIPE:mega'
SAY 'Detection activated'
'waitframes 100'

IF OPEN(fileptr,path,'R') THEN DO
DO WHILE ~Eof(fileptr)
in_string=Readln(fileptr)

IF FIND(in_string,'Eagleplayer-Request') THEN DO
singlefile=filename"."idcount
idcount=idcount+1
"clip STRING="singlefile /* Put unique filename into clipboard */
SAY "Module Found, saving as: "singlefile

'fakekey s RAMIGA' /* Press the SAVE button */
'waitframes 10'
'fakekey lshift right' /* Make sure we clear file requester properly */
'waitframes 10'
'fakekey x RAMIGA' /* Clear the filerequester first */
'waitframes 10'
'fakekey v RAMIGA' /* Paste the save filename */
'waitframes 10'
'fakekey return' /* Chooses the path part of original filename */
'waitframes 10'
'fakekey return' /* The filename is now in input path + modified filename, so save it now! */
'waitframes 10'
'fakekey c RAMIGA' /* Make sure we click continue */
'waitframes 100'
END

IF FIND(in_string,'Eagleexotic') THEN DO /* Actually its an unconfigured ExoticRipper path by me, to catch the end */
SAY 'no more modules'

/* Press OK on "Cant load ExoticRipper requester" two times */
'movepointer 0 0'
'autoiconopen 130 90'
'waitframes 50'

'movepointer 0 0'
'autoiconopen 130 90'
'waitframes 50'

ADDRESS 'rexx_EP'
QUIT /* Make sure we exit EaglePlayer completly to clean memory etc */

EXIT /* Fully Exit the arexx and batch file scripts now */
END
END
CALL CLOSE(fileptr)
END
END


Pro-Wizard ToolChain.bat

.KEY filename
; By Stone Oakvalley Studios - July 2018 for the SOAMC= ENDGAME automation
; 1: Loads a file to Rip-Scan into Pro Wizard
; 2: The rexx script will monitor the hits for modules or other requesters.
; 3: Then we QUIT ProWizard and everything restarts.
; .KEY filename is the file to be scanned, it is also the filename to save module (if any found), this argument is passed on :-)

avail flush

;Start ProWizard clean and wait for it. After any potentional END-OF-SCAN, it will AutoExit by the "AE" parameter :-)
run HD1:ProWizard/Pro-Wizard <filename> AE
wait 1
rx prowizard_rip_check.rexx <filename>
echo "Finished"


Pro-Wizard REXX Automation
/* Check if Prowizard pops up during ripping and automates save module and continue! */
/* Another nice script done for SOAMC= ENDGAME July 2018 by Stone Oakvalley Studios */

filename=ARG(1)
ADDRESS command

fileptr='infile'
path='PIPE:mega'
idcount=1
founder=0

/* Detections performed */
/* 1: "Taratata !!" comes = save module */
/* 2: "Nothing recognized at all" comes = no modules found at the end of buffer = quit and die */

'clip STRING='filename /* Put entire filename into clipboard */


/* Now loop until either requesters appear or Pro-Wizard autoexits = also detected, script ends */
DO FOREVER
ADDRESS COMMAND
'show w >PIPE:mega'
SAY 'Detection activated'
'waitframes 50'
founder=0

/* First make sure "Pro-Wizard v2.2" is found as a window. When its not there, its probably AutoExit and we shall quit too */
IF OPEN(fileptr,path,'R') THEN DO
DO WHILE ~Eof(fileptr)
in_string=Readln(fileptr)
IF FIND(in_string,'Pro-Wizard') THEN DO
founder=1
END
END
CALL CLOSE(fileptr)
IF founder=0 THEN DO
SAY "Pro-Wizard ended automatically"
EXIT
END
END

IF founder=1 THEN DO
/* Start the window scan a second time */
'show w >PIPE:mega'
'waitframes 50'
IF OPEN(fileptr,path,'R') THEN DO
DO WHILE ~Eof(fileptr)
in_string=Readln(fileptr)

IF FIND(in_string,'Taratata') THEN DO
singlefile=filename"."idcount
idcount=idcount+1
"clip STRING="singlefile /* Put unique filename into clipboard */
SAY "Module Found, saving as: "singlefile

'fakekey s RAMIGA' /* Press the SAVE button */
'waitframes 10'
'fakekey lshift right' /* Make sure we clear file requester properly */
'waitframes 10'
'fakekey x RAMIGA' /* Clear the filerequester first */
'waitframes 10'
'fakekey v RAMIGA' /* Paste the save filename */
'waitframes 10'
'fakekey return' /* Chooses the path part of original filename */
'waitframes 10'
'fakekey return' /* The filename is now in input path + modified filename, so save it now! */
'waitframes 10'
END

IF FIND(in_string,'Nothing recognized') THEN DO /* Nothing found in entire scan, so quit and die */
SAY 'no more modules'
'fakekey return'
'waitframes 10'
EXIT /* Fully Exit the arexx and batch file scripts now */
END
END
CALL CLOSE(fileptr)
END
END
END



ProWizard 4 PC Automation"
Since this a Windows command line tool, it does not need anything else than "filename" to start doing its job.

Naturally, we need to keep track of filenames generated by this tool, rename them into our numbered id style, along with keeping track of its progress. A own tool will be started on-top of ProWizard 4 PC to achieve this, but its not something special to write about here, its just standard CMD magic anyway)




Please review these related article links:
Click to open batExoticRipper_toolchain.bat
Click to open rexxExoticRipper_check.rexx
Click to open batEaglePlayer_rip_toolchain.bat
Click to open rexxEagleplayer_rip_check.rexx
Click to open cAutoIconOpen.c (My modified version)
Click to open batProwizard_rip_toolchain.bat
Click to open rexxProwizard_rip_check.rexx


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Posted by: Old-schooler, Stone Oakvalley | Publisher: Crazy Multi Talent, Stone Oakvalley
Last revised: November 15, 2018 - 22:59 | Page views: 421


Website Design by post@stone-oakvalley-studios.com - Copyright © 2018 www.stone-oakvalley-studios.com