Archive
How to do model imitation recording exercises to improve language learner pronunciation in the LRC and beyond
- Sometimes teachers ask about support for voice recognition in the LRC. The term voice recognition or speech recognition (the former appears to be analogous to face recognition in authentication and other security contexts?) is usually reserved for software that can transcribe your voice into text – still no free option for this, AFAIK. Dragon naturally speaking is the oft recommended market leader outside of education (and within, Auralog Tell me more, see below). Update summer 2012: We are working on enabling the Speech recognition built into Windows 7 Enterprise for English, Chinese (Simplified and Traditional), French, Spanish, German, and Japanese.
- Often times, what is actually desired is a digital audio recorder with voice graph, ideally a dual track recorder.
- In the LRC student computers, we have for exactly this purpose a digital audio recorder as part of the SANAKO Study 1200language learning system
- It features a dual track recorder (allows to listen to teacher track which can be a prerecorded model to imitate on the left channel while recording the student track on the right channel of a stereo track) with a voice graph:
. See this dual-track-voice-graph screencast demo from the vendor and also our student cheat sheet from the vendor documentation. - The Sanako is available in the LRC, as well as in many other educational institutions around the world, but neither free nor web-based (although a web-based version seems to be in the works). It currently requires MS-Windows to run.
- It features a dual track recorder (allows to listen to teacher track which can be a prerecorded model to imitate on the left channel while recording the student track on the right channel of a stereo track) with a voice graph:
- A popular and free audio editor (but not an SLA – specific application, let alone geared towards model imitation; also, for all practical ends and purposes, requires an extra download and installations of an MP3 encoder to be able to save recordings as compressed MP3) is Audacity. To use for model imitation exercises,
- the student can open a model track (mp3 recommended)
- and manage within the program the imitation portion, using the voice graph:

- then export back out as mp3,
- either her responses individually (see my demo screencast, requires Windows Media Player on Windows, which actually shows a question/response rather than a model imitation, but same principle),
- or, by deleting the model track, the response parts mixed down to one track,
- or also, if, like in my demo screencast, the timeline sequence of model (with pauses) and responses is carefully managed (so that model and imitation do not overlap), mixed down to one track.
- In one language program, I have worked extensively with Auralog Tell me more
- which was (not exclusively, but arguably too much) based on this pedagogic concept of having students compare the voice graph of their imitation with the model voice graph (while it do did not allow for teachers to upload their own content, and was certainly not free).

- To my knowledge, Auralog Tell me more does not allow for adding teacher-produced content as models.
- I did like the self-reflective and repetitive practice element. However, I found that students – apart from intonation and (not useful for not pitch based languages) pitch -, did not benefit as much as one might have expected from viewing the voice graph, indeed tended to get overwhelmed, even confused by the raw voice information in such a voice graph.
- And automated scoring of pronunciation (or speech recognition” – not free form, but on a level that has been commoditized in operating systems like Windows 7, the level of voice-directed selection between a limited set of different options, like menu options, and in the case of Auralog, choosing between different response options) seemed iffy and less than transparent in Auralog Tell me more, even though this is their primary selling point. E.g. when I made deliberate gross mistakes, the program seemed to change its standards and wave me through ( English pronunciation example; also observed by me when testing Auralog with East Asian speakers of English).
- which was (not exclusively, but arguably too much) based on this pedagogic concept of having students compare the voice graph of their imitation with the model voice graph (while it do did not allow for teachers to upload their own content, and was certainly not free).
- In the LRC student computers, we have for exactly this purpose a digital audio recorder as part of the SANAKO Study 1200language learning system
- A voice graph is not the same as a more abstract phonetic transcription (although I do not know whether language learners can be trained in phonetic symbol sets like the IPA). There are now experimental programs that can automate the transcription of text into phonetic symbol sets for e.g. Portuguese or Spanish. Maybe you will find that practice with recording and a phonetic transcription of the recorded text is more useful for your students’ pronunciation practice than a fancy voice graph.
How to subscribe to an LRC calendar – in one screenshot
Subscribing to LRC calendars, e.g. for tutoring, will give you access from your Ninermail/OWA and always keep you updated of late-breaking changes. Here is how, starting from our list of bookable resources:
How students access language learning materials on the Library ereserves system
- Note the important update in red below.
- This has been tested at post date with Firefox. ereserves seems to be not compatible with Internet Explorer 8: i

- On the Library home page, from the top menu: “Research & Course Help”, choose menu item: “Course Reserves” (or, if this menu changes again, I have a hunch that deeplinking may be more stable: http://library.uncc.edu/caos/coursereserve, what’s in a URL…),
- sign in with your Ninernet ID,
- enter search term
- select from the dropdown “search by name”, an enter part of your course name in the textbox,
- or click on tab:”Course Reserves Pages by Instructor”, and from the dropdown, select your instructor,
- click search,
- then select your course from the results grid.

- Enter the password, which has been given to your by your instructor.

- In the results grid, click on the desired chapter and tracks. Note: You need to disable your web browser”s “popup blocker”.
- In the popup window, click on link: “More information”,
- when offered, , like in this screenshot:
- you cannot save the file, or rather: only a text file with links to the audio which you cannot play, like rtsp://dlib4.uncc.edu:554/e_reserves/CD1bonneforme12-16.rm). That is by design.
- Instead of trying to save, select to “open” the file. You need have a streaming audio playing software installed, like Real Player or the open source VLC-Player.
- instead of VLC, as offered by default, like so :

- choose “Open with”, “Other”, pick “RealPlayer” from the list, like so:

- Here is a more on what does not work with ereserves. The only combination I could get to work with eReserves streaming audio is – see resulting screencast (requires Windows Media Player) of streaming a long file successfully – is RealPlayer 14, Firefox 3.6 on Windows XP3, and that only after resetting the Winsock catalog which I can do for the entire LRC only nownext time the lab is reimaged. For now, use instead audio from Moodle metacourses where possible.
Sample of how students use the foreign language TTS (text-to-speech) in the LRC
Last week, I noticed this student in the LRC working on a speaking assignment in her SLA class. First, she wrote a draft of her presentation. She then had the Deskbot TTS wizard (in the lower right of her screen) read out the draft to her. She recorded her version, modeling after the Deskbot’s pronunciation. Then she had the Deskbot read out the draft again, to compare with her own recording.
Look for the little guy in the lower right corner of the screen with the cartoon bubble over his head.
I favor the use of the Deskbot TTS (a Windows XP technology) as an easily accessible speaking dictionary, including during face-to-face teaching, when students may otherwise be too shy to make an utterance because they are not sure about the pronunciation of a single word, or even ask the teacher to pronounce it for them. Prosodically, the deskbot TTS leaves many things to be desired. Let’s hope that Windows 7 will enable us to set up more advanced TTS support in the LRC.
How to use the online Portuguese pronunciation help to generate phonetic alphabet transcriptions and text-to-speech
- Go to http://www.co.it.pt/~labfala/g2p/
- Write or paste your text into the textbox:“Grafemas”
- Choose your preferred phonetic alphabet (IPA, SAMPA) and other options.
- Press button: “Converter” to see results.
- Press button: “Sintetizar” to hear results.
- Like so:

- Or click here to view a demo (requires Windows Media Player) with audio (download requires Windows Media Player). Our example was:
- Input: Tudo bem? É o jeitinho brasileiro. Oí, árbitro! Cadê o penalty? Não, não posso faze-lo.
- Output: tˈudu bɐ̃ĩ ˈɛ u ʒɐitˈiɲu bɾɐzilˈɐiɾu oˈi ˈaɾbitɾu kɐdˈe u pˈenalti nˈɐ̃ũ nˈɐ̃ũ pˈɔsu fˈazɘlu
LRC Assistant Start of Year Training: The Screencast
Click here to view a sample LRC assistant training presentation.
Varying the speed of animated GIFs for learners – the technology: Shell-scripting ImageMagick
Animated GIFs for visualizing teaching content were the first e-learning tool that I heard a conference presentation on, in the early nineties.
In the recent past, I have been trying to revive animated GIFs for use in minimalistic training materials.
Now, for different learner personalities, and also to accompany each learner in their practice of Chinese character stroke order, as they get more proficient in drawing, I wanted to provide varied animation speeds of the Chinese characters drawings.
This bash script can do this, using a downloaded set with several hundred source characters in one animation speed to produce 75000 animated GIF (via 95000 temporary) files:
#!/bin/sh
shopt -s nocasematch # shopt -s sets the option, whereas shopt -u disables it.; however, Find is an external command and not affected by shopt
echo `date -u`
# todo: parameterize
# -maindir todo: convert param to $maindir
blnskipcreated=1 # 1=do not recreate anims if _mydelaylimit exists
echo "blnskipcreated:" $blnskipcreated
mydelaystep=10
mydelaylimit=1010
 
# test: what happens if i add zi to maindir
maindir="/cygdrive/G/myfiles/doc/work/students/ms-office/charinput/mandarin_chinese/stroke-order/Zi/Animated-characters/azi"
# todo: the rootdir is unimportant, it contains only a shortcut which points to nothing
rootdir="/cygdrive/G/myfiles/doc/work/students/ms-office/charinput/mandarin_chinese/stroke-order/Zi/Animated-characters"
framefilefilepath=${rootdir}/azi/page1.htm # the actual framefile which loads the azi.html and the character is G:\myfiles\doc\work\students\ms-office\charinput\mandarin_chinese\stroke-order\Zi\Animated characters\azi\page1.htm
# wrong ${rootdir}/animated-characters.htm
framefilefileextension="htm"
framefilenamenopath="`expr "//$framefilefilepath" : '.*/\([^/]*\)'`" # remove path to file
framefilenamenoextension="`expr "$framefilenamenopath" : '\(.*\)\.[^.]*$'`" # remove last suffix ${i}
framefilefilepathnoextension=${rootdir}/${framefilenamenoextension}
echo "DOLLAR 1framefilefilepath, 2framefilefilepathnoextension, 3framefilenamenopath 4framefilenamenoextension:"1${framefilefilepath}:2${framefilefilepathnoextension}:3${framefilenamenopath}:4${framefilenamenoextension}:
# todo DOLLAR framefilefilepathnoextension, framefilenamenopath framefilenamenoextension:
 
cd $maindir
if [ -d "$maindir" ] ; then # needs "" around vriable, space before ]
echo "Good!"
else
echo "not a dir"
exit 1
fi
 
sourcehtmlfilename="azi" # todo: how to i need to reference (enclose) the variables so that can the maindir and sourcehtmlfilename can contain spaces
# todo: document: "give the string one has to add to the maindir to get to the html file that links to the gifs": complication: animated-characters is just al link to azi/azi.htm`- so why not change the maindir to include azi-subdir
sourcehtmlfileextension="htm"
sourcehtmlfilepathnoextension=${maindir}/${sourcehtmlfilename}
sourcehtmlfilepath=${sourcehtmlfilepathnoextension}.${sourcehtmlfileextension}
echo "dollar sourcehtmlfilepath =" $sourcehtmlfilepath # debug
# exit 0 # debug
if [ -e "$sourcehtmlfilepath" ] ; then # needs "" around vriable, space before ]
echo "Html File good!"
sourcehtmlfileswitch=1
else
echo "$sourcehtmlfilepath not an html file"
# no need, leave the html alone then, but set a switch exit 1
sourcehtmlfileswitch=0
fi
mfiles=`find $maindir -iname '*.gif'` # Simply enclosing the wildcard in single quotes makes it work! unix find is case-sensitiv
# todo: if you want to be able to resume gif creation, you have to remove (previously created) files that match pattern _[0-9]+.gif
# shopt -s extglob - does this work with find or only ls
# shopt -s extglob
# mfiles=`find $maindir -name '*!(_[0-9]+).gif'`
# shopt -u extglob
# Find is an external command, so its globbing isn't affected by bash shopt options, but you can use: find . ! -name 's.*.java'
# mfiles=`find $maindir -name '*!(_[0-9]+).gif'`
# i will include the full path
# done: skip some, not all gifs are animated, e.g. G:\myfiles\doc\work\students\ms-office\charinput\mandarin_chinese\stroke-order\Zi\Animated-characters\azi\18b.gif
k=0 #debug:break
# echo "mfiles:$mfiles"
for i in $mfiles ; do
if [[ $i =~ _([0-9]+|strip).gif ]]; then
echo "skipping previously produced file $i"
else
echo "Converting {$i}..." # this prints 1 line extra per space in dir - may cause problems with i down the road?
curdelay=0
delaystep=$mydelaystep # cs
delaylimit=$mydelaylimit # cs
filepath=$i
filenamenopath="`expr "//$i" : '.*/\([^/]*\)'`" # remove path to file
filenamenoextension="`expr "$filenamenopath" : '\(.*\)\.[^.]*$'`" # remove last suffix ${i}
filepathnoextension=${maindir}/${filenamenoextension} # test: w/o azi ${maindir}/azi/${filenamenoextension} # todo: stupid workaround, but i supsect i cannot just add /azi to maindir
echo "DOLLAR 1filepathnoextension,2filenamenopath,3filenamenoextension:"1${filepathnoextension}:2${filenamenopath}:3${filenamenoextension}:
# suffix="`expr "$name" : '.*\.\([^./]*\)$'`" # extract last suffix
# name="`expr "$name" : '\(.*\)\.[^.]*$'`" # remove last suffix
 
############################################################################################### BREAK APART
# path2name
# as a animation disassembler, producing a summary of animation in terms of IM options
# gif2anim [options] image_anim.gif.
#. gif2anim.sh -s MIFF -b $i -o ${i}.anim $i
# the s-switch of gif2anim.sh never worked, can i do without it ? ainim2gif.convert will complain: unable to open idid0_20.gif_001.-s
# -s seems to result in ext -s, miff seems to result in all params fro mmiff on being interpreted as filenames
#. gif2anim.sh -o ${i}.anim $i
framesfileext="xpm" # change this to give if you not use -x - CASESENSITIVE
. gif2anim.sh -x -o ${filenamenoextension}.anim $filepath
#. gif2anim.sh -s MIFF -b $i -o ${i}.anim $i
#. gif2anim.sh MIFF -b $i -o ${i}.anim $i
# -c coalesce animation before parsing
# -t Add time synchronization comment before each frame
# -l just list the anim file to stdout, no images
# -v Be verbose in animation conversions
# -n no images, just create the '.anim' file
#1 -g use an GIF suffix for frame images (default)
# -x use an XPM suffix for frame images
#todo: did this work? b0aej.gif_001.-s 1 MIFF -s suffix use this suffix for the frame images
# -i initframe number of the first frame image (def=1)
#needed? -b framename basename for the individual frames
# 1 -o file.anim output to this .anim file (- for stdout)
#
 
# grep 'delay ' ${i}.anim # check return 0exit good, 1exit bad - You can see what a commands exit status is by looking at the variable $?.
# might be safer
grep 'delay ' ${filenamenoextension}.anim
if [ $? == 1 ]; then # is no animated gif, skip
echo "NO ANIM GIF grep finds no delay in: " ${i}.anim
# do nothing: # done: if there is no delay in the gif.anim, do not enter while for curdelay, go to next file
else # is animated gif, curdelay
echo "since delay is matched for this gif, ENTERING curdelay WHILE"
while [ $curdelay -lt $delaylimit ] ; do # go in step 20cs from 20s = tile, to 40cs - default is 80cs\
echo "CURDELAY : " $curdelay
if [ $curdelay == 0 ]; then # branch into strip producing programm
############################################################################################## MAKE A STRIP
# The "gif_anim_montage" script also the special option '-u' which will also underlay a semi-transparent copy of the coalesced animation.
# interface: if you just output to samename.gif, you can leave the original links intact
# advantage: synchronous overview:
# disadvantage: viewing even more, and pseudo-signs
# gif_anim_montage [options] animation.gif [output_image]
# done: query how many frame files into a variable and use this as param 1x${frames} of call to gif_anim_montage.sh
if [ -e ${filepathnoextension}_strip.gif ] ; then
echo "skipping found ${filepathnoextension}_strip.gif"
else
striplength=$(ls ${filenamenoextension}.${framesfileext} 2> /dev/null | wc -l) # count matching files, errors redirected
echo "found ${striplength} of frames framesfileext with ${framesfileext}, calling montage 1x${striplength} -u -w ${filepath} ${filepathnoextension}_strip.gif"
if [ "striplength" != "0" ] ; then
. gif_anim_montage.sh 1x${striplength} -u -w -n ${filepath} ${filepathnoextension}_strip.gif
#1 -u Underlay a dimmed coaleased image (context for frame)
#0 -c Add checkerboard background for transparent areas
#0 -g Use granite for background
#1 -w Use a white background
#0 -b Use a black background
#0 -t image Use this image (or color image) for background
#0 -r Use a red border color rather than black
#0 todo: not USE DEFAULT, need column #x# tile the images (default one single row)
#0 -n Don't label the animation frames (not important)
else
echo "NO STRIP MADE!"
fi
fi # strip file already exists?
else # $curdelay > 0 -> branch into gif producing program
# first you need to stream edit the .anim textfile for each iteration match "-delay 80"/"-delay curdelay"
# echo "CALLING sed $curdelay ${i}.anim ${filepathnoextension}_${curdelay}.gif.anim" # debug
# sed 's/-delay 80/-delay '$curdelay'/g' ${i}.anim > ${filepathnoextension}_${curdelay}.gif.anim # todo: break delay loop if no match in gif.anim = no animated gif
echo "1:what is i now ${i} and filepathnoextension.anim is: ${filepathnoextension}.anim"
echo "CALLING sed $curdelay in: ${filepathnoextension}.anim out: ${filepathnoextension}_${curdelay}.anim" # debug
sed 's/\-delay\s.*/-delay '$curdelay'/g' ${filepathnoextension}.anim > ${filepathnoextension}_${curdelay}.anim # todo: break delay loop if no match in
# first stream edit the .anim textfile for each iteration match
# redirection: file is UNCHANGED the modified file is file.bak
# watch variable expansion '/'$license'/p' README.txt
# skip timeconsuming recreate
if [ $blnskipcreated == 1 ] ; then # if not needed (assuming generated files are correct - todo:parameterize!)
if [ -e ${filepathnoextension}_${mydelaylimit}.gif ] ; then
echo "skipping recreating gifs for ${filepathnoextension}_${mydelaylimit}.gif and below "
else
echo "NOT skipping recreating gifs for ${filepathnoextension}_${mydelaylimit}.gif and below "
############################################################################################### PUT TOGETHER AGAIN - w different delay AS PARAM -cs centiseconds
# read in prior output file .anim
# anim2gif [-b BASENAME] file.anim...
# anim2gif: Failed to convert "/cygdrive/G/myfiles/doc/work/students/ms-office/charinput/mandarin_chinese/stroke-order/Zi/Animated-characters/azi/b0b2_400.gif.anim" into "B0B2_400.GIF.GIF"
echo "CALLING CP ${filepathnoextension}_${curdelay}.anim ${filepathnoextension}.anim"
cp ${filepathnoextension}_${curdelay}.anim ${filepathnoextension}.anim #
# now try to call the ${filepathnoextension}.gif w/o${curdelay} to not muddy the output file name
echo "CALLING anim2gif.sh -g ${filepathnoextension}.gif" # debug exists: idid0.gif.anim - do we have curdelay?
. anim2gif.sh -g ${filepathnoextension}.anim # determine: we overwrite the ori gif here, does it matter? -> final cleanup
echo "CALLING mv4 ${filepathnoextension}.gif ${filepathnoextension}_${curdelay}.gif" # debug
mv ${filepathnoextension}.gif ${filepathnoextension}_${curdelay}.gif
# OPTIONS
#is this needed? not taken from the .anim ? -b framename basename for the individual frames
# 1 -g Add '.gif' to end of basename, not '_anim.gif'
# we rather want to overwrite the original gif: The "anim2gif" by default will re-create the GIF animation with a "_anim.gif" suffix.
# -c Input frames are coalesced, ignore any initial page size
# todo: since there is only one "animated characters.htm", one could append the _curdelay to all the output.gifs
# todo: and once per all gif files within one curdelay iteration, to the occurence of .gif within "animated characters.htm" and to the filename "animated characters_curdelay.htm"
fi # _mydelaysteplimit.gif already exists, can skip?
fi # blnskipcreated, allowed to skip?
fi # is $curdelay > 0 -> s or gif producing?
echo " before exec:" $curdelay "delaystep:" $delaystep
curdelay=$(( $curdelay + $delaystep )) # 0=20 command not found, does not work here: `expr $curdelay + $delaystep` # increment for next iteration #todo: command not found
# k=$(( $k + 1 ))
echo " afterexec:" $curdelay
if [ $sourcehtmlfileswitch == 1 ] ; then #################### update the azi-html that points to the _curdelay.gif
if [ -e ${sourcehtmlfilepathnoextension}_${curdelay}.${sourcehtmlfileextension} ] ; then # only once per pseudo $curdelay=0=strip
echo "file ${sourcehtmlfilepathnoextension}_${curdelay}.${sourcehtmlfileextension} already exists, nothing to do "
else
# todo: is das cp nicht überflüssig before sed
cp ${sourcehtmlfilepath} ${sourcehtmlfilepathnoextension}_${curdelay}.${sourcehtmlfileextension} # create file
echo "dollar sourcehtmlfilepath =" $sourcehtmlfilepath # debug
sed -e 's/\.gif/_'${curdelay}'\.gif/gI' $sourcehtmlfilepath > ${sourcehtmlfilepathnoextension}_${curdelay}.${sourcehtmlfileextension} # update gif links in html file to reflect curdelay
fi # if sourcehtmlfilename_curdelay already exists
 
#################### update the frames-html that points to azi.html
if [ -e ${framefilefilepathnoextension}_${curdelay}.${framefilefileextension} ] ; then # only once per pseudo $curdelay=0=strip
echo "framefile already exists, nothing to do "
else
# todo: is das cp nicht überflüssig before sed
echo "CALLING CP ${framefilefilepath} ${framefilefilepathnoextension}_${curdelay}.${framefilefileextension}"
cp ${framefilefilepath} ${framefilefilepathnoextension}_${curdelay}.${framefilefileextension} # create file
echo "dollar framefilefilepath =" $framefilefilepath # debug
# todo: magic string
sed -e 's/azi.htm/azi_'${curdelay}'\.htm/gI' $framefilefilepath > ${framefilefilepathnoextension}_${curdelay}.${framefilefileextension} # update gif links in html file to reflect curdelay
fi # if framefilefilename_curdelay already exists
fi # if $sourcehtmlfileswitch=1
# does break jump across below
# obsolete echo " NOBREAK ${i}.anim $curdelay "
done # all curdelay steps to limit
echo " could be BREAK ${i}.anim $curdelay "
# does break go here?
echo " before exec $k:" $k
k=$(( $k + 1 )) # `expr $k + 1` #debug: test only
echo " after exec $k:" $k
 
if [ $k -gt 6 ] ; then # increased to 2 since 1 is skipped then # the "if [ ... ]" and the "then" commands must be on different lines. Alternatively, the semicolon ";" can separate the
echo "let it run freely , or uncomment the next line"
# exit 0
fi # debug
fi # is animated gif?
 
# final cleanup todo: only if the ori gif and ori htmlsource do not get deleted
if [ -e ${filepathnoextension}_${curdelay}.gif ] ; then # this errors now for undeleted non-animated gifs (break)
# todo: ${i} something wrgon is in ${i}
# echo "5: what is in ${i} now"?
rm ${filepathnoextension}.gif # the ori gif name, whatever is not in there is also in ${i}_${curdelay}.gif
fi
fi #skipping previously produced?
done # all gif files
# final cleanup delete the compromised ori gif and ori htmlsource
# debug this causes to many probs rm $sourcehtmlfilepath # the ori html name, whatever is not in there is also in ${sourcehtmlfilename}_${curdelay}.${sourcehtmlfileextension}
echo 'animated gif conversion complete!'
# todo: azi.htm is the file to be made into azi_10...1010.htm, ot animated characters
# todo:b1caf_strip.gif wont displaty inphotoviewer, strip gets way too long with empty spots at end
# -> redo only the strips and
# deleate all (after variable creation and loopstarting) and (before grep 'delay ' ${filenamenoextension}.anim)
# delete all after echo "NO STRIP MADE!" except fi and loop closing
# todo:labelling of strips - can one also label the animated gifs
#todo: der erste rame sollte nicht blank sein, sonst kann erst lange gar nichts sichtbar sein
#todo: found 0 of frames, calling montage 1x0 -u -w /cygdrive/G/myfiles/doc/work/students/ms-office/charinput/mandarin_chinese/stroke-order/Zi/Animated-characters/azi/a1f5.gif/cygdrive/G/myfiles/doc/work/students/ms-office/charinput/mandarin_chinese/stroke-order/Zi/Animated-characters/azi/a1f5_strip.gif
# afterexec:10
#dollar sourcehtmlfilepath = /cygdrive/G/myfiles/doc/work/students/ms-office/charinput/mandarin_chinese/stroke-order/Zi/Animated-characters/azi/azi.htm
#CALLING CP _10.htm
# cp: missing destination file operand after `_10.htm'
#/cygdrive/g/conf/lang/bat/imagemagick/animated-gifs-slow-down.sh: line 26: /cygdrive\
#G\myfiles\doc\work\students\ms-office\charinput\mandarin_chinese\stroke-order\Zi\Animated-characters\animated-characters.htm: No such file or directory
#G:\myfiles\doc\work\students\ms-office\charinput\mandarin_chinese\stroke-order\Zi\Animated-characters\animated-characters.htm
One day, I hope to generalize this script for adapting other animated GIF collections from the Web, e.g . parameterizing it. For now, it can run out of the box on the Chinese website if you setup the necessary environment.
I am running this from mintty using Cygwin’s ImageMagick, to avoid having to port the great shell ImageMagick scripts gif2anim.sh, anim2gif.sh and gif_anim_montage.sh by Anthony Thyssen which you need to put in the same directory as my animated-gifs-slow-down-pub.sh
And if you change the rootdir and maindir to point to the disk location where you downloaded the website package.
Call the script with “animated-gifs-slow-down.sh &>slowing.log” to log the chatty debug information.
If you use it and/or adapt it to process other websites that use animated GIFs, kindly link back.
Hint: When done, be careful when moving such a large set of files. InfoZip’s zip utility ate the last 10000 of my gif files, without warning, as if it can handle only 64k files? Since this happened during a “move into zip-file”operation, this was costly, at least in CPU cycles required to rerun the gif animation script…
AviSynth scripting should be next…

