-- EG Serene Software
-- written by Barbara Lattanzi
-- copyleft
07.20.02
------------------
-- Copyleft for this code in summary:
-- 1. Use this code or modify it however you want.
-- 2. For any use or modification you make of it, you will
-- make that same or modified code freely available to others.
-- (That's all.) Read
more about it.
------------------
-- EG Serene Software is based on the structural algorithm,
-- conceived by Ernie Gehr for his structural film,
-- "Serene Velocity" (1970).
------------------
-- This script is applied to a Quicktime video sprite.
-- This script is written in Lingo, the programming language associated
-- with Macromedia Director, but is translatable to any language capable
-- of controlling digital video.
-- What the algorithm derives from "Serene Velocity" is its
overarching time structure
-- in which simulated perceptual events emerge out of the incremental alternation
of the two halves
-- of a bisected passage of film.
-- Video playback begins in the middle of the Quicktime movie.
-- The playback is always "foward" (never reverse).
-- Call the first half of the movie "part A", the second half "part B"...
-- The time interval for playback is determined by the viewer (within a certain
range).
-- 1. The Quicktime movie starts playing from its midpoint, for the given time
interval.
-- 2. After the given interval, the movie begins from the same midpoint and
plays it again.
-- 3. After the same given time interval, the movie increments forward into
"part B" -- in the amount of 1 tic (60 tics per second) and plays the given
time interval.
-- 4. Then the movie leaps back (into "part A") in the amount of 1 tic and plays
the given time interval.
-- 5. Repeat steps 3 and 4, continuously incrementing the 2 playback points
further and further apart.
-- The parametized values for viewer determination include:
-- 1. actual starting point (the "mid-point") can be placed anywhere on the
timeline, because
-- the 2 portions of the Quicktime movie can each autonomously loop through
their respective portions.
-- The starting point is a message sent from the timeline bar sprite.
-- 2. the increment (within a preset range) that the Quicktime movie advances
or retreats
-- at the start of each interval of playback.
-- 3. the interval (within a preset range), i.e., the amount of time (measured
in tics)
-- that the Quicktime movie plays the video before the timer resets the movie
to the next point of playback.
property sereneQT, sereneDur, sereneStart, someFPS
property flagDirection, sereneInterval, sereneIncrement
property sereneForwardMemory, sereneBackwardMemory, bodyFrameLbl
property sereneMem, setDirection, thisCalc, sereneDurMod, sereneDurModMinus1
property forwardAmt, rewindAmt, startTheAlgorithm, stopTheAlgorithm, tempInterval, diffValue, reversalAmt
property videoPlaybackMemberNum, videoForwardSome, fixedFraction, someFloatNumber
property startThisPoint, stopAtThisPoint, sprChannelForRewindControl, controllerBarSpr, manipulatorSpr
property sereneNum, sereneBody, checkStoredValFlag
property ancestor
on beginSprite me
me.ancestor = script "calculateMovieTimeAncestorObject"
sereneQT = sprite(me.spriteNum)
sereneNum = me.spriteNum
sereneQT.movieRate = 0
sereneMem = sereneQT.member
sereneMem.directToStage = 1
sereneMem.crop = 1
sereneMem.video = 1
sereneMem.sound = 0
sereneMem.loop = 1
sereneBody = "body"
sereneDur = sereneQT.duration -- this stores a value measured in tics (60 tics per second)
sereneDurMod = sereneDur - (sereneDur mod 2)
sereneStart = sereneDurMod / 2 -- parametize later with sendsprite message
sereneDurModMinus1 = sereneDurMod - 1
sereneQT.movieTime = sereneStart -- position the playback at the determined starting point
sereneForwardMemory = sereneStart
sereneBackwardMemory = sereneStart
me.sereneMidStorage(sereneStart) --send ancestor script info for placing movietimelocation on initial timeline bar
controllerBarSpr = sprChannelForRewindControl
flagMovieRate = 1
checkStoredValFlag = 1
tempStartFlag = 1
circleSpr = manipulatorSpr
bodyFrameLbl = bodyFrameLbl
sereneIncrement = 1 --value should be determined by length of secondary (LEFT) gadget
sereneInterval =sprite(controllerBarSpr).width --value should be determined by length of primary (RIGHT) gadget
-- these next 2 properties allow for later changes in movieRate via sendsprite messages from "faster_slower" behavior
setDirection = 1
thisCalc = 1
flagDirection = 0
if sereneQT.movieTime <= startTheAlgorithm then -- the movie is under one-second playback
sereneQT.movieTime = startTheAlgorithm
end if
startTimer
flagDirection = 1 -- toggles the playback between the 2 portions of the Quicktime movie
end beginSprite
on exitFrame me
if the framelabel = sereneBody then ---necessary to prevent motion at relocater frame
if checkStoredValFlag = 1 then
checkStoredValFlag = 0
me.divulgeStoredMovieTime(sereneNum)
end if
if flagDirection = 1 then
if the timer >= sereneInterval then --should be determined by length of right gadget
checkForwardAmount
tmp = sereneForwardMemory + sereneIncrement --increment should be determined by length of left gadget
if tmp > sereneDurModMinus1 then
tmp = sereneStart
end if
sereneQT.movieTime = tmp
--revise memory of position
sereneForwardMemory = tmp
startTimer
end if
end if
if flagDirection = 0 then
if the timer >= sereneInterval then --should be determined by length of right gadget
checkReversalAmount
tmp = sereneBackwardMemory - sereneIncrement --increment should be determined by length of left gadget
if tmp < 2 then
tmp = sereneStart
end if
sereneQT.movieTime = tmp
sereneBackwardMemory = tmp
startTimer
end if
end if
end if
end
-- a sendsprite message from the ancestor script and/or bttnBetweenReloc&Body script
on getStoredValue me, timeLoc
sereneForwardMemory = timeLoc
sereneBackwardMemory = timeLoc
checkStoredValFlag = 0
end
---------------------------------
---------------------------------
-- This handler called by script attached to LEFT slider bar gadget sprite (see script "lengthForSereneIncrement")
on changeTimeOverlap me, newAmount
-- Subtract small amount to insure that the video segment doesn't go into an endless loop.
newAmt = (newAmount * 2) - 4
fixedFraction = integer(.1* newAmt) --.01 * newAmt
sereneIncrement = fixedFraction
end
on changeTimeOverlapNow me, newAmount
-- Subtract small amount to insure that the video segment doesn't go into an endless loop.
tempStartFlag = 1
newAmt = (newAmount * 2) - 4
fixedFraction = integer(.1* newAmt) --.01 * newAmt
sereneIncrement = fixedFraction
end
---------------------------------
---------------------------------
on checkForwardAmount me
if sprite(controllerBarSpr).width > 2 then -- This value is problematic if it = 0 or 1, so set at a min. of 2
forwardAmt = sprite(controllerBarSpr).width -- measure this width to determine time-span measure.
else
forwardAmt = 2
end if
rewindAmt = forwardAmt * fixedFraction
tempInterval = sereneQT.movieTime + forwardAmt
sereneInterval = forwardAmt
flagDirection = 0
end checkForwardAmount
---------------------------------
---------------------------------
on checkReversalAmount me
if sprite(controllerBarSpr).width > 2 then -- This value is problematic if it = 0 or 1, so set at a min. of 2
reversalAmt = sprite(controllerBarSpr).width -- measure this width to determine time-span measure.
else
reversalAmt = 2
end if
reversalJumpAmt = reversalAmt * fixedFraction
tempInterval = sereneQT.movieTime - reversalAmt
sereneInterval = reversalAmt
flagDirection = 1
end checkReversalAmount
---------------------------------
---------------------------------
on forwardOrBackward me, setDirectionNow
-- Parameter passed in by another sprite broadcasting with "sendSprite" message, based on
-- whether the interactor has moved the moveable sprite across the middle boundary
-- between forward and reverse.
-- NOTE: in order for the parameter to be read as a value, use keyword "me".
setDirection = setDirectionNow
if setDirection = 1 then
sereneQT.movieRate = 1 * thisCalc
flagMovieRate = 1
else
if setDirection = -1 then
sereneQT.movieRate = -1 * thisCalc
flagMovieRate = 0
end if
end if
end forwardOrBackward
on setNewRate me, thisCalcRate --sendsprite message from faster_slower sprite behavior
thisCalc = thisCalcRate
sereneQT.movieRate = thisCalc * setDirection
end
---------------------------------
---------------------------------
---------------------------------
on getPropertyDescriptionList
sereneList = [:]
addProp sereneList , #videoPlaybackMemberNum, [#default :0, #format :#integer, #comment:"slot into which video is imported for playback algorithm"]
addProp sereneList , #videoForwardSome, [#default :120, #format :#integer, #comment:"advance how many tics, 60/sec"]
addProp sereneList , #someFloatNumber, [#default :.90, #format :#float, #comment:"rewind by what fraction of forward amount"]
addProp sereneList , #startThisPoint, [#default :0, #format :#integer, #comment:"when to begin algorithm"]
addProp sereneList , #stopAtThisPoint, [#default :#0, #format :#integer, #comment:"stop algorithm this amount prior to end of clip"]
addProp sereneList , #manipulatorSpr, [#default :#0, #format :#integer, #comment:"sprite that viewer uses to change playback"]
-- The following property is to accomodate user-interface for manipulating the video:
addProp sereneList , #sprChannelForRewindControl, \
[#default :0, #format :#integer, #comment:"leave at 0 if viewer does not control, else spriteNum that changes length"]
return sereneList
end