\ io
\
\ io_input
\ input parsing component of io.
\
\
\ these input components send data and messages primarily to the hp_ objects
\ (see the file io_hp) via the matrix (see the file io_matrix). An exception
\ is that the players (see: io_output) derive their pulse value from the
\ pulse.trackers defined in this file. The other exception is that the
\ banalyzers may start and stop the performance via the global control
\ procedures (IO.START and IO.STOP respectively) stated in the file io_glob, and
\ defined in io_top.
\
\ io_input ====> io_matrix io_hp io_output io_top
\ ^^^^^^^^ ^^^^^^^^^
\ parser ----------------------> hp.noteon
\ -----> hp.noteoff
\ pTracker ----------------------------------> player
\
\ banalyzer ================================================> io.start
\ =====> io.stop
\
\ input parameters that are analyzed (banalyzed?) are the following:
\
\ parameter dim# selector description
\
\ pulse - parser_time_dim# - time between sucessive ON events
\ volume - parser_vol_dim# - volume level
\ pitch - parser_pitch_dim# - midi pitch bend and note number
\ density - n/a - see below
\
\ additionally, three classes of input parsers are available:
\
\ mono.parser - for monophonic input on a single midi channel
\ poly.parser - polyphonic input on a single channel
\ guitar.parser - six monophonic inputs on six consecutive channels
\
\ the pulse, volume and pitch parameters are analyzed in a similarly across
\ the various parser types. Density, however, is handled differently between
\ the parsers. A mono.parser considers the sustain time of a note as the
\ density; a poly.parser or guitar.parser will use the vertical polyphony
\ (number of notes in a chord) as the density.
\
\
\ see the file io_top for more information.
\
\
\ constructor: Han-earl Park
\ copyright 2008 buster & friends' C-ALTO Labs
\
\ www.busterandfriends.com/io
\
\ (Edinburgh, November 1996 -
\ (London, August 1997 -
\ (Den Haag, October 1997 -
\ (Valencia, March 1999 -
\ (Southampton, May 2000 -
\ (Cork, April 2006 -
\
\ (Cork, October 2008 -
\
\ REV: 0.0.1 alpha (Southampton, October 2000)
\ REV: 0.0.1 beta (Southampton, November 2000)
\ REV: 0.0.1 alpha++ (Southampton, July 2004)
\ REV: 0.0.1 beta++ (Cork, May 2010)
\
\
\ MOD: HeP 03/05/99 Started project afresh!
\ This version keeps most of the "intelligence" in the
\ objects, while the piece specific elements are kept to a
\ minimum. It is also a test for the "laurie" project.
\ MOD: HeP 02/07/00 Get rid of conditional compilation of the multiple parser
\ objects -- they all get compiled now.
\ MOD: HeP 02/21/00 Add the global control word IO.STANDBY and corresponding
\ words to each component.
\ MOD: HeP 04/09/00 Load the file myt:parser_list.
\ MOD: HeP 04/10/00 Trash input-channel-holder since we use the components
\ from myt:parser_list file.
\ MOD: HeP 04/17/00 Move INPUT.PRESENT? to io_glob since the output components
\ need to use it.
\ MOD: HeP 05/08/00 Move INPUT.PRESENT? back from io_glob.
\ MOD: HeP 05/09/00 Implement NEXT.ON to return time interval to next
\ predicted note on event.
\ MOD: HeP 05/10/00 Rename SET.PARSER to SET.PARSER.TYPE.
\ MOD: HeP 05/15/00 New functions for setting up parser type, channel, etc.
\ Uglier code, but a little tighter...
\ MOD: HeP 05/31/00 Assume that the static.particle will be held in the first
\ element of the space.
\ MOD: HeP 06/01/00 Replace the confusing array of configuration words with
\ IO.INPUT and SET.INPUT.TYPE. Add provisions for setting up
\ ptrackers and banalyzers for different types of input.
\ MOD: HeP 06/04/00 Trash the global input pulse.tracker and banalyzers.
\ Parsers are OPEN: and CLOSE:ed when performance is started
\ or stoped, _not_ when instantiated and deinstantiated.
\ MOD: HeP 06/08/00 Check if non-zero before deinstantiating the items held by
\ the parser-holder.
\ MOD: HeP 06/20/00 Split off io_ui from io_screen and io_input.
\ MOD: HeP 09/26/00 Trash the io specific variable last-parser, and instead
\ use current-parser defined in file myt:parser.
\ Move the current-parser zero-ing from io_glob (don't know
\ what it was doing there).
\ MOD: HeP 10/13/00 Add the PUT.DATA: and GET.DATA: methods to the device (and
\ thus the parser) class. This eases calling the matrix.
\ MOD: HeP 10/18/00 static.particle's mass is normalized when a note on is
\ recieved.
\ Current version uses a single static.particle.
\ MOD: HeP 10/19/00 midi parser is kept on for io_ui.
\ REV: 0.0.1 alpha __________________________________________________________
\ MOD: HeP 10/25/00 Fix incorrect resetting of midi parser vectors in
\ IO.INPUT.STOP.
\ MOD: HeP 10/28/00 Separate on and off functions for the guitar.parser since
\ it has an extra value (string number) passed to it.
\ MOD: HeP 11/01/00 Banalyzers are reconfigured depending on input type!
\ Correctly assign dimension# to banalyzers.
\ MOD: HeP 11/02/00 Rename dcycle-blyzer-holder as density-blyzer-holder since
\ the function of these banalyzers will depend on the type
\ of input.
\ MOD: HeP 11/02/00 Update doc and comments.
\ MOD: HeP 11/02/00 Load the file myt:mono_parser+.
\ MOD: HeP 11/06/00 Use the words PTRK.NEXT.TIME and PTRK.NEXT.ON.DUR from
\ myt:pulse_tracker for predicting input events.
\ io's rhythmic sense is pretty good now!
\ Use ob.mono.parser+ and add separate parser functions per
\ input type.
\ MOD: HeP 11/07/00 Implement and enable density banalyzers.
\ The polyphonic density measurements don't work because the
\ system does not account for stepwise reduction of
\ polyphony!
\ MOD: HeP 11/09/00 First attempt at auto start/stop of performance.
\ MOD: HeP 11/11/00 Fix bug when banalyzer stops performance: Other banalyzer
\ pending input would recieve bogus shape from closed
\ parser. See file myt:banalyzer for fix.
\ MOD: HeP 11/14/00 Set banalyzers' tolerance mode to linear_tolerance.
\ MOD: HeP 11/17/00 Enable #parsers_enabled number of parser at when .DEFAULT
\ (and thus .INIT) is called.
\ MOD: HeP 11/18/00 Use INPUT.PARSER@ and INPUT.CHANNEL@ from file io_config.
\ MOD: HeP 11/20/00 Move PARSER.ERROR.DIALOG from io_screen.
\ REV: 0.0.1 beta __________________________________________________________
\ MOD: HeP 03-21-04 Use return stack version of CONFIGURE.BANALYZER.
\ Working version of POLY.DENSITY.FUNC using the updated
\ polyphonic parser classes. Experiment with calling these
\ during note on or off.
\ MOD: HeP 03-21-04 Experiments with revised pulse.tracker.
\ MOD: HeP 05-11-04 Updated the description/comment.
\ MOD: HeP 07-03-04 Each component's .INIT function no longer calls the
\ corresponding .DEFAULT function. Instead these are all
\ called at the end of IO.INIT. See file io_top.
\ REV: 0.0.1 a ++ __________________________________________________________
\ MOD: HeP 03-20-09 Add meta-blyzer. We have an alert for alerts. ToDo: Need
\ someway of triggering changes of patch, interp-tables and
\ time-advance values from this.
\ MOD: HeP 03-21-09 See: io_matrix for details on what the meta-blyzer
\ triggers.
\ MOD: HeP 03-24-09 Fix bug in ob.banalyzer+ (see myt:banalyzer+) and have
\ consequently increased the alert windows of banalyzers.
\ REV: 0.0.1 b ++ __________________________________________________________
\ Version for performance at Blackrock Castle Observatory,
\ Cork, Ireland, May 25, 2010.
\
\
\ ToDo: Does not go into standby if no parser (external input) -- io must be
\ doing a solo if no one else is playing.
\ ToDo: Couple static.particles with parsers? Use current-parser?
\ ToDo: Clearup the parser setup/configuration words!
\ ToDo: More consistent and comprehensive error reporting.
anew task-io_input
ob.objlist parser-holder
ob.objlist fout-holder
ob.objlist ptracker-holder
ob.objlist pulse-blyzer-holder
ob.objlist volume-blyzer-holder
ob.objlist density-blyzer-holder
ob.objlist pitch-blyzer-holder
\ input stats
variable last-ptracker \ most recently updated pulse tracker
variable last-alert \ banalyzer which sent the last alert
variable last-alert-time \ time of the last alert
variable last-pulse-alert
variable last-volume-alert
variable last-density-alert
variable last-pitch-alert
: RESET.INPUT.STATS ( -- , zero variables )
0 current-parser !
\
0 last-ptracker !
0 last-alert !
0 last-pulse-alert !
0 last-volume-alert !
0 last-density-alert !
0 last-pitch-alert !
;
\ input activity
: INPUT.PRESENT? ( -- flag , true if input is active )
current-parser @ \ -- addr | 0
dup
IF get.time: []
time@ swap -
io_timeout < \ -- flag
THEN
;
: PULSE@ ( -- ticks | false , current pulse value of input )
last-ptracker @ \ -- addr | 0
dup
IF get: [] \ -- ticks | 0
THEN
;
: NEXT.ON.TIME@ ( -- ticks | false , time of next predicted note on event )
last-ptracker @ \ -- addr | 0
dup
IF ptrk.next.time \ -- ticks | 0
THEN
;
: NEXT.ON.DUR@ ( -- ticks | false , duration until next predicted note on )
last-ptracker @ \ -- addr | 0
dup
IF ptrk.next.on.dur \ -- ticks | 0
THEN
;
\ input parser
: PARSER.ON.FUNC ( note# vel prsr -- , generic parser on function )
-rot HP.NOTEON \ note# vel --
get.data: [] execute: on-matrix
;
: PARSER.OFF.FUNC ( note# vel prsr -- , generic parser off function )
-rot HP.NOTEOFF \ note# vel --
get.data: [] execute: off-matrix
;
: MONO.ON.FUNC ( pitch vel ontime prsr -- )
2over 2over RAW.ON: []
nip PARSER.ON.FUNC
;
: MONO.OFF.FUNC ( pitch vel ontime prsr -- )
2over 2over RAW.OFF: []
nip PARSER.OFF.FUNC
;
: POLY.ON.FUNC ( pitch vel prsr -- )
3dup RAW.ON: []
PARSER.ON.FUNC
;
: POLY.OFF.FUNC ( pitch vel prsr -- )
3dup RAW.OFF: []
PARSER.OFF.FUNC
;
: GUITAR.ON.FUNC ( pitch vel strg# prsr -- )
2over 2over RAW.ON: []
nip PARSER.ON.FUNC
;
: GUITAR.OFF.FUNC ( pitch vel strg# prsr -- )
2over 2over RAW.OFF: []
nip PARSER.OFF.FUNC
;
\ configure parsers
: PARSER.ENABLED? ( indx -- flag )
get: parser-holder 0= NOT
;
: DISABLE.PARSER ( indx -- , disable parser with given index )
dup get: parser-holder
?dup
IF dup delete.parser: midi-parser-holder
deinstantiate
THEN
\
0 swap put: parser-holder
;
: USE.MONO.PARSER ( prsr -- )
'c mono.on.func over put.on.function: []
'c mono.off.func swap put.off.function: []
;
: USE.POLY.PARSER ( prsr -- )
'c poly.on.func over put.on.function: []
'c poly.off.func swap put.off.function: []
;
: USE.GUITAR.PARSER ( prsr -- )
'c guitar.on.func over put.on.function: []
'c guitar.off.func swap put.off.function: []
;
: HOOKUP.PARSER { p_type indx | prsr -- , setup parser for use }
indx get: parser-holder -> prsr
\
indx put.data: prsr \ assign parser's indx
\
p_type
CASE
mono_parser OF prsr use.mono.parser ENDOF
poly_parser OF prsr use.poly.parser ENDOF
guitar_parser OF prsr use.guitar.parser ENDOF
ENDCASE
\
indx get: fout-holder \ -- fout
put.instrument: prsr \ assign fan.out as instrument to parser
;
\ error handling
0 constant err_null \ *** put these in io_glob? ***
1 constant err_out_of_range \ *** should these constants ***
2 constant err_overlap \ *** be used by other ***
3 constant err_instantiate \ *** components? ***
: CHAN.OUT.OF.RANGE.DIALOG ( -- )
" Channel number out of range. Guitars are expected to transmit on six channels (eg. 11 to 16)."
dialog.a
;
: CHAN.OVERLAP.DIALOG ( -- )
" Invalid channel number. Two input devices cannot share the same MIDI channel(s)."
dialog.a
;
: OBJ.INSTANTIATE.DIALOG ( -- )
" Sorry, unable to create input object (maybe a memory error). The program will quit, but you might want to try again."
dialog.a
TRUE quit-hmsl !
;
: PARSER.ERROR.DIALOG ( err -- , report appropriate error message )
CASE
err_out_of_range OF chan.out.of.range.dialog ENDOF
err_overlap OF chan.overlap.dialog ENDOF
err_instantiate OF obj.instantiate.dialog ENDOF
ENDCASE
update.screen
;
: PARSER.CHANNEL.ERROR? { chan# prsr -- err }
get.#channels: prsr chan# +
17 >
IF
err_out_of_range
ELSE
chan# put.channel: prsr
\
prsr ?available: midi-parser-holder
IF
err_null
ELSE
err_overlap
THEN
THEN
;
: (SET.PARSER.TYPE) ( p_type -- addr | 0 )
CASE
mono_parser OF instantiate ob.mono.parser+ ENDOF
poly_parser OF instantiate ob.poly.parser ENDOF
guitar_parser OF instantiate ob.guitar.parser ENDOF
ENDCASE
;
: SET.PARSER.TYPE { p_type indx | p_old p_new -- err , set parser type }
p_type (set.parser.type)
?dup
IF
-> p_new
\
indx get: parser-holder -> p_old \ save old parser
p_old delete.parser: midi-parser-holder
\
get.channel: p_old p_new PARSER.CHANNEL.ERROR?
dup
IF
p_new deinstantiate
\
p_old add.parser: midi-parser-holder \ restore old parser
ELSE
get.channel: p_old put.channel: p_new
\
p_old deinstantiate
\
p_new indx put: parser-holder
p_new add.parser: midi-parser-holder
\
p_type indx HOOKUP.PARSER
THEN
ELSE
err_instantiate
THEN
;
: SET.PARSER.CHAN# { chan# indx | prsr -- err , set parser's channel number }
indx get: parser-holder -> prsr
\
get.channel: prsr \ save old channel number
\
chan# prsr PARSER.CHANNEL.ERROR?
dup
IF
swap put.channel: prsr \ restore old channel number
ELSE
nip
\
prsr delete.parser: midi-parser-holder
\
chan# put.channel: prsr
prsr add.parser: midi-parser-holder
THEN
;
: SET.PARSER.BEND ( bend indx -- , set bend range for given parser )
get: parser-holder
dup
IF put.bend.range: [] ELSE 2drop
THEN
;
: SET.PARSER { p_type chan# bend indx | p_old p_new -- err }
p_type (set.parser.type)
?dup
IF
-> p_new
\
indx get: parser-holder -> p_old \ save old parser
p_old
IF p_old delete.parser: midi-parser-holder
THEN
\
chan# p_new PARSER.CHANNEL.ERROR?
dup
IF
p_new deinstantiate
\
p_old
IF p_old indx put: parser-holder \ restore old parser
p_old add.parser: midi-parser-holder
THEN
ELSE
p_old
IF p_old deinstantiate
THEN
\
chan# put.channel: p_new
bend put.bend.range: p_new
\
p_new indx put: parser-holder
p_new add.parser: midi-parser-holder
\
p_type indx HOOKUP.PARSER
THEN
ELSE
err_instantiate
THEN
;
: IO.PARSER.INIT ( -- )
sub" io.parser.init"
\
io_#input new: parser-holder
io_#input set.many: parser-holder
\
'c ob.fan.out io_#input ?instantiate: fout-holder
IF io_#input 0
DO 5 i get: fout-holder new: []
LOOP
ELSE
" Sorry, an error occurred while trying to create input fan.out objects. Quit and try restarting the program."
init.error
THEN
;
: IO.PARSER.TERM ( -- )
sub" io.parser.term"
\
mp.reset
midi.parser.off
\
many: parser-holder 0
DO i get: parser-holder
?dup
IF deinstantiate
THEN
LOOP
\
deinstantiate: fout-holder
;
: IO.PARSER.RESET ( -- )
sub" io.parser.reset"
\
\ *** do parsers have a useful RESET: method? ***
\
;
\ pulse tracker
: PTRACKER.ON.FUNC ( elm# shape ptrckr -- )
dup last-ptracker !
ON: []
\
2drop
;
\ configure pulse trackers
: CONFIGURE.PTRACKER ( pTracker -- )
\ *** stuff goes here ***
drop
;
: USE.MONO.PTRACKER ( indx# -- )
get: ptracker-holder
\ *** stuff goes here ***
configure.ptracker
;
: USE.POLY.PTRACKER ( indx# -- )
get: ptracker-holder
\ *** stuff goes here ***
configure.ptracker
;
: USE.GUITAR.PTRACKER ( indx# -- )
get: ptracker-holder
\ *** stuff goes here ***
configure.ptracker
;
: SET.PTRACKER ( p_type indx# -- , configure ptracker for parser type )
swap
CASE
mono_parser OF use.mono.ptracker ENDOF
poly_parser OF use.poly.ptracker ENDOF
guitar_parser OF use.guitar.ptracker ENDOF
ENDCASE
;
: IO.PTRACKER.INIT ( -- )
sub" io.ptracker.init"
\
io_#input new: ptracker-holder
\
'c ob.pulse.tracker+ io_#input ?instantiate: ptracker-holder
IF io_#input 0
DO i get: ptracker-holder
\
'c ptracker.on.func over put.on.function: []
io_min_pulse io_max_pulse rot put.range: []
LOOP
ELSE
" Sorry, an error occurred while trying to create input pulse.trackers. Quit and try restarting the program."
init.error
THEN
;
: IO.PTRACKER.TERM ( -- )
sub" io.ptracker.term"
\
deinstantiate: ptracker-holder
;
: RESET.PTRACKERS ( -- )
many: ptracker-holder 0
DO i get: ptracker-holder reset: []
LOOP
;
: IO.PTRACKER.RESET ( -- )
sub" io.ptracker.reset"
\
reset.ptrackers
;
io_test? .IF
\ testing banalyzers: alert stats
variable meta-alerts
variable pulse-alerts
variable volume-alerts
variable density-alerts
variable pitch-alerts
: zero.alerts ( -- )
0 meta-alerts !
0 pulse-alerts !
0 volume-alerts !
0 density-alerts !
0 pitch-alerts !
;
: print.alerts ( -- )
cr
tab ." Meta =" meta-alerts @ 3 .r cr
tab ." Pulse =" pulse-alerts @ 3 .r cr
tab ." Volume =" volume-alerts @ 3 .r cr
tab ." Density =" density-alerts @ 3 .r cr
tab ." Pitch =" pitch-alerts @ 3 .r cr
cr
;
.THEN
\ meta banalyzer
ob.banalyzer+ meta-blyzr
: META.ALERT ( data addr -- , test and maybe execute meta alert )
[ io_test? .IF ]
>newline ." META.ALERT" meta-alerts incr
[ .THEN ]
\
2drop
0 execute: meta-alert-matrix
;
: MAYBE.META.ALERT ( -- , test and maybe execute meta alert )
midi.rtc.time@
dup last-alert-time @ - io_min_pulse >
IF
dup on: meta-blyzr
THEN
last-alert-time !
;
: IO.META.BANALYZER.INIT ( -- )
sub" io.meta.banalyzer.init"
\
'c meta.alert put.alert.function: meta-blyzr
\
DELTA.ON: meta-blyzr
\
16 put.alert.window: meta-blyzr
io_timeout put.tolerance: meta-blyzr
io_timeout 4/ put.tolerance.increment: meta-blyzr
io_min_pulse 2* io_timeout put.tolerance.range: meta-blyzr
io_min_pulse io_timeout put.tolerance.range: meta-blyzr
\
open: meta-blyzr
;
: IO.META.BANALYZER.TERM ( -- )
sub" io.meta.banalyzer.term"
\
close: meta-blyzr
;
: IO.META.BANALYZER.RESET ( -- )
sub" io.meta.banalyzer.reset"
\
reset: meta-blyzr
;
\ banalyzers
\ alert functions
: PULSE.ALERT ( data addr -- )
[ io_test? .IF ]
>newline ." PULSE.ALERT" pulse-alerts incr
[ .THEN ]
\
MAYBE.META.ALERT
\
nip
dup last-alert !
dup last-pulse-alert !
\
get.data: [] execute: alert-matrix
;
: VOLUME.ALERT ( data addr -- )
[ io_test? .IF ]
>newline ." VOLUME.ALERT" volume-alerts incr
[ .THEN ]
\
MAYBE.META.ALERT
\
nip
dup last-alert !
dup last-volume-alert !
\
dup get.average: [] HP.ALERT \ vel -- , reposition static.particle
\
get.data: [] execute: alert-matrix
;
: DENSITY.ALERT ( data addr -- )
[ io_test? .IF ]
>newline ." DENSITY.ALERT" density-alerts incr
[ .THEN ]
\
MAYBE.META.ALERT
\
nip
dup last-alert !
dup last-density-alert !
\
get.data: [] execute: alert-matrix
;
: PITCH.ALERT ( data addr -- )
[ io_test? .IF ]
>newline ." PITCH.ALERT" pitch-alerts incr
[ .THEN ]
\
MAYBE.META.ALERT
\
nip
dup last-alert !
dup last-pitch-alert !
\
get.data: [] execute: alert-matrix
;
\ auto start and stop
: STANDBY.ALERT ( data addr -- , start playing when alert is executed )
test" *** STANDBY.ALERT *** "
2drop
\
SAFE.START
;
: IMBNF.ALERT ( data addr -- , stop playing when alert is executed )
test" *** IMBNF.ALERT *** "
2drop
\
SAFE.STOP
;
variable saved-banalyzer-holder
variable saved-alert-cfa
: SAVE.ALERT ( -- )
4 choose
CASE
0 OF pulse-blyzer-holder saved-banalyzer-holder ! ENDOF
1 OF volume-blyzer-holder saved-banalyzer-holder ! ENDOF
2 OF density-blyzer-holder saved-banalyzer-holder ! ENDOF
3 OF pitch-blyzer-holder saved-banalyzer-holder ! ENDOF
ENDCASE
\
0 saved-banalyzer-holder @ get: []
get.alert.function: [] saved-alert-cfa !
;
: RESTORE.ALERT ( -- )
saved-banalyzer-holder @ many: [] 0
DO
saved-alert-cfa @
i saved-banalyzer-holder @ get: []
put.alert.function: []
LOOP
;
\ density OFF functions
: MONO.DENSITY.FUNC { elm# shape blyzr -- , analyze input's duty cycle }
elm# parser_ontime_dim# ed.at: shape ON: blyzr
;
\ polyphonic density depends on the number of held notes (notes in a "chord")
\ against the time in which those notes occurred.
: (POLY.DENSITY.FUNC) { blyzr | parser chord -- }
current-parser @
?dup
IF -> parser
get.chord: parser -> chord
\
0 \ -- poly , initial value thru loop
time: parser \ -- poly time , time of last event
\
many: chord 0
DO
dup \ -- poly time time
i 1 ed.at: chord \ -- poly time time timeB , time of ith note in chord
- \ -- poly time timeD
io_max_pulse <=
IF
nip \ -- time
many: chord i - \ -- time poly
swap \ -- poly time
LEAVE
THEN
LOOP
drop
ON: blyzr
THEN
;
: POLY.DENSITY.FUNC ( elm# shape blyzr -- )
-rot 2drop (poly.density.func)
;
: GUITAR.DENSITY.FUNC ( elm# shape blyzr -- )
-rot 2drop (poly.density.func)
;
\ configure banalyzers
false .IF \ local variable or return stack versions
: CONFIGURE.BANALYZER { aWindow tolerance tIncr tMin tMax blyzr -- }
aWindow put.alert.window: blyzr
tolerance put.tolerance: blyzr
tIncr put.tolerance.increment: blyzr
tMin tMax put.tolerance.range: blyzr
;
.ELSE
: CONFIGURE.BANALYZER ( aWindow tolerance tIncr tMin tMax blyzr -- )
>r
r@ put.tolerance.range: []
r@ put.tolerance.increment: []
r@ put.tolerance: []
r> put.alert.window: []
;
.THEN
: USE.MONO.BANALYZER ( indx# -- )
dup get: pulse-blyzer-holder
dup DELTA.ON: []
>r
32 \ alert window
io_rtc_rate 2/ \ tolerance
io_min_pulse \ tolerance increment
io_min_pulse io_timeout \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
\
dup get: volume-blyzer-holder
>r
32 \ alert window
64 \ tolerance
8 \ tolerance increment
8 96 \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
\
dup get: density-blyzer-holder
'c mono.density.func over put.off.function: []
>r
8 \ alert window
io_min_pulse 4/ \ tolerance
io_min_pulse 2/ \ tolerance increment
1 io_max_pulse \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
\
get: pitch-blyzer-holder
>r
32 \ alert window
1200 \ tolerance
100 \ tolerance increment
100 2400 \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
;
: USE.POLY.BANALYZER ( indx# -- )
dup get: pulse-blyzer-holder
dup DELTA.ON: []
>r
64 \ alert window
io_rtc_rate 2/ \ tolerance
io_min_pulse \ tolerance increment
io_min_pulse io_timeout \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
\
dup get: volume-blyzer-holder
>r
64 \ alert window
64 \ tolerance
8 \ tolerance increment
8 96 \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
\
dup get: density-blyzer-holder
'c POLY.DENSITY.FUNC over put.off.function: []
>r
64 \ alert window
4 \ tolerance
1 \ tolerance increment
1 7 \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
\
get: pitch-blyzer-holder
>r
48 \ alert window
2400 \ tolerance
100 \ tolerance increment
300 9600 \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
;
: USE.GUITAR.BANALYZER ( indx# -- )
dup get: pulse-blyzer-holder
dup DELTA.ON: []
>r
48 \ alert window
io_rtc_rate 2/ \ tolerance
io_min_pulse \ tolerance increment
io_min_pulse io_timeout \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
\
dup get: volume-blyzer-holder
>r
48 \ alert window
64 \ tolerance
8 \ tolerance increment
8 96 \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
\
dup get: density-blyzer-holder
'c GUITAR.DENSITY.FUNC over put.off.function: []
>r
48 \ alert window
2 \ tolerance
1 \ tolerance increment
1 4 \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
\
get: pitch-blyzer-holder
>r
48 \ alert window
1200 \ tolerance
100 \ tolerance increment
300 3600 \ tolerance min and max
r>
configure.banalyzer \ aWindow tolerance tIncr tMin tMax blyzr --
;
: SET.BANALYZER ( p_type indx# -- , configure banalyzer for parser type )
swap
CASE
mono_parser OF use.mono.banalyzer ENDOF
poly_parser OF use.poly.banalyzer ENDOF
guitar_parser OF use.guitar.banalyzer ENDOF
ENDCASE
;
: BUILD.BANALYZERS { indx dim# cfa list -- indx }
io_#input new: list
'c ob.banalyzer+ io_#input ?instantiate: list
IF
io_#input 0
DO i get: list
dim# over put.dim: []
cfa over put.alert.function: []
indx over put.data: []
\
linear_tolerance swap PUT.TOLERANCE.MODE: []
\
indx 1+ -> indx
LOOP
ELSE
" Sorry, an error occurred while trying to create input analyzers. Quit and try restarting the program."
init.error
THEN
indx
;
: IO.BANALYZER.INIT ( -- )
sub" io.banalyzer.init"
\
0 \ -- indx
\
parser_time_dim#
'c pulse.alert
pulse-blyzer-holder build.banalyzers \ -- indx
\
parser_vol_dim#
'c volume.alert
volume-blyzer-holder build.banalyzers \ -- indx
\
0
'c density.alert
density-blyzer-holder build.banalyzers \ -- indx
\
parser_pitch_dim#
'c pitch.alert
pitch-blyzer-holder build.banalyzers \ -- indx
\
drop
\
many: density-blyzer-holder 0
DO 'c 3DROP i get: density-blyzer-holder put.on.function: []
LOOP
;
: IO.BANALYZER.TERM ( -- )
sub" io.banalyzer.term"
\
deinstantiate: pulse-blyzer-holder
deinstantiate: volume-blyzer-holder
deinstantiate: density-blyzer-holder
deinstantiate: pitch-blyzer-holder
;
: (RESET.BANALYZERS) { list -- }
many: list 0
DO i get: list reset: []
LOOP
;
: RESET.BANALYZERS ( -- )
pulse-blyzer-holder (reset.banalyzers)
volume-blyzer-holder (reset.banalyzers)
density-blyzer-holder (reset.banalyzers)
pitch-blyzer-holder (reset.banalyzers)
;
: IO.BANALYZER.RESET ( -- )
sub" io.banalyzer.reset"
\
reset.banalyzers
;
\ configure input
: SET.INPUT.TYPE { p_type indx -- err }
p_type indx set.parser.type
dup NOT
IF p_type indx set.ptracker
p_type indx set.banalyzer
THEN
;
: SET.INPUT { p_type chan# bend indx -- err }
p_type chan# bend indx set.parser
dup NOT
IF p_type indx set.ptracker
p_type indx set.banalyzer
THEN
;
\ system control
: IO.INPUT.DEFAULT ( -- )
io_#input 0
DO i disable.parser
LOOP
\
#parsers_enabled 0
DO
i input.parser@ \ -- p_type
i input.channel@ \ -- chan#
io_input_bend \ -- bend
i \ -- indx
\
SET.INPUT \ p_type chan# bend indx -- err
\
err_instantiate =
IF
obj.instantiate.dialog
LEAVE
THEN
LOOP
;
: IO.INPUT.RESET ( -- )
test" IO.INPUT.RESET"
\
io.parser.reset
io.ptracker.reset
io.meta.banalyzer.reset
io.banalyzer.reset
\
reset.input.stats
;
: IO.INPUT.UPDATE ( -- )
reset.input.stats
;
: IO.INPUT.PANIC ( -- )
midi.clear
;
: IO.INPUT.STANDBY ( -- )
midi.clear
\
'c parser.on.vector mp-on-vector !
'c parser.off.vector mp-off-vector !
'c parser.bend.vector mp-bend-vector !
\
io_#input 0
DO
i get: parser-holder
?dup
IF open: []
THEN
LOOP
\
reset.input.stats
\
save.alert \ save alert function of selected banalyzers
\
io_#input 0
DO
'c STANDBY.ALERT
i saved-banalyzer-holder @ get: []
put.alert.function: []
LOOP
;
: IO.INPUT.START ( -- )
[ io_test? .IF ]
zero.alerts
[ .THEN ]
\
restore.alert \ restore normal alert function of selected banalyzers
;
: INPUT.IMBNF ( -- , it must be nearly finished )
io_#input 0
DO
'c IMBNF.ALERT
i saved-banalyzer-holder @ get: []
put.alert.function: []
LOOP
;
: IO.INPUT.STOP ( -- )
[ io_test? .IF ]
print.alerts
[ .THEN ]
\
'c 2drop mp-on-vector !
'c 2drop mp-off-vector !
'c 2drop mp-bend-vector !
\
io_#input 0
DO i get: parser-holder
?dup
IF close: []
THEN
LOOP
\
restore.alert \ restore normal alert function of selected banalyzers
\
reset.ptrackers
reset.banalyzers
;
: IO.INPUT.PAUSE ( -- )
'c 2drop mp-on-vector !
'c 2drop mp-off-vector !
'c 2drop mp-bend-vector !
;
: IO.INPUT.RESUME ( -- )
'c parser.on.vector mp-on-vector !
'c parser.off.vector mp-off-vector !
'c parser.bend.vector mp-bend-vector !
;
\ setup & clearup
: IO.INPUT.INIT ( -- )
test" IO.INPUT.INIT"
\
reset.input.stats
\
PARSER.INIT \ initialize midi parser list
\
'c 2drop mp-on-vector !
'c 2drop mp-off-vector !
'c 2drop mp-bend-vector !
\
io.parser.init
io.ptracker.init
io.banalyzer.init
io.meta.banalyzer.init
\
io_#input 0
DO
i get: fout-holder
\
i get: ptracker-holder over add: []
i get: pulse-blyzer-holder over add: []
i get: volume-blyzer-holder over add: []
i get: density-blyzer-holder over add: []
i get: pitch-blyzer-holder swap add: []
LOOP
\
\ io.input.default \ removed MOD: 07-03-04
\
midi.clear
midi.parser.on
;
: IO.INPUT.TERM ( -- )
test" IO.INPUT.TERM"
\
PARSER.TERM
\
io.parser.term
io.ptracker.term
io.banalyzer.term
io.meta.banalyzer.term
\
midi.clear
midi.parser.off
;
if.forgotten io.input.term
io_test? .IF
: IO.INPUT.PRINT ( -- )
>newline
." IO_INPUT" cr
." Parsers" cr
." last parser = " current-parser @ ob.name cr
." Pulse Trackers" cr
." last ptracker = " last-ptracker @ ob.name cr
." Banalyzers" cr
." last alert = " last-alert @ ob.name cr
." pule alert = " last-pulse-alert @ ob.name cr
." volume alert = " last-volume-alert @ ob.name cr
." density alert = " last-density-alert @ ob.name cr
." pitch alert = " last-pitch-alert @ ob.name cr
>newline ." Print objects?" y/n cr
IF >newline ." Print parsers?" y/n cr
IF print: midi-parser-holder ?pause >newline cr
many: parser-holder 0
DO i get: parser-holder
?dup
IF print: [] ?pause >newline
THEN
LOOP
THEN
>newline ." Print ptrackers?" y/n cr
IF many: ptracker-holder 0
DO i get: ptracker-holder print: [] ?pause >newline
LOOP
THEN
>newline ." Print banalyzers?" y/n cr
IF >newline ." Print pulse banalyzers?" y/n cr
IF many: pulse-blyzer-holder 0
DO i get: pulse-blyzer-holder print: [] ?pause >newline
LOOP
THEN
>newline ." Print volume banalyzers?" y/n cr
IF many: volume-blyzer-holder 0
DO i get: volume-blyzer-holder print: [] ?pause >newline
LOOP
THEN
>newline ." Print density banalyzers?" y/n cr
IF many: density-blyzer-holder 0
DO i get: density-blyzer-holder print: [] ?pause >newline
LOOP
THEN
>newline ." Print pitch banalyzers?" y/n cr
IF many: pitch-blyzer-holder 0
DO i get: pitch-blyzer-holder print: [] ?pause >newline
LOOP
THEN
THEN
THEN
;
.THEN