#!/opt/local/bin/tclsh
# The above line calls up the tcl shell.  If tclsh has a different
# path on the system that you're using, edit this line.  You can
# find out the path by typing "which tclsh".
# 
# script starttime.tcl
# 
# Syntax:  
#    starttime extension file(s)
#
# Arguments:
#    extension   alphanumeric tag to append to the basename
#                as an the extension for the output file names
#    file(s)     a (list of) pathname(s) to xlabel label file(s)
#
# Results:
#     For files where the audio file has a start time of 0.0 s
#     this script will simply copy the input label file to 
#     another file with the same basename and the new extension.
#     For files where the audio file has a start time > 0.0 s, it
#     subtracts the start time from all of the label times in the
#     input label file and prints the file out to the new label
#     with the same basename and the new extension.
#
# Example: 
#     starttime.tcl tones *.Intone
#
#     Creates a .tones file for each of the .Intone files in the
#     current directory, adjusting the label times as necessary
#
# Note that this script assumes that the name of the audio
# file will have .d as the extension to the base file name;
# if that's not the case, edit the line where you create the
# speech file name from the label file name, just before the 
# comment that begins "n.b. change this line if audio file ..."
# in the third command within the main "for" loop of the script.
#
###################################################################
# proc subtr_time  
#     This is the procedure that does the actual subtracting.
#     It could be extracted to put into another tcl program.
#
# Arguments:
#    infile      an input label file name
#    outfile     an output label file name
#    starttime   a start time to subtract from each label time
#
# Results:
#    the contents of infile are copied to outfile, except that
#    all of the lines with labels have the start time subtracted
#    from the original label time.
# This next line defines the procedure name and arguments.  The 
# following 50 some lines (up to the start of the script proper) is 
# the body of the procedure.
proc subtr_time {infile outfile starttime} {
    
    # Open a channel to the input label file, and set the variable
    # "labFile" to that channel.
    set labFile [open $infile "r"]
    # Read in the data from the file into the "labels" variable.
    set labels [read $labFile]
    # Split the "labels" variable into a list of lines in the 
    # "linelist" variable.
    set linelist [split $labels "\n"]
    # Clean up by closing input label file.
    close $labFile
    
    # Open another channel to the output label file.
    set labFile [open $outfile "w+"]
        
    # Set the pos (for "position") variable to 0, to point to
    # the first line in the linelist variable.
    set pos 0
    
    # Print out successive lines from there up to the the 
    # line with the hash mark that demarcates the header.
    # Do this by testing to see if the line is not the hash mark
    # character "#", and if it's not 
    while {![string match "\#" [lindex $linelist $pos]]} {
       # print that line to the output label file, and 
       puts $labFile [lindex $linelist $pos]
       # increment the pos variable to point to the next line.
       incr pos
    }
        
    # Then write a line with a hash mark, and ...
    puts $labFile "\#"
    # increment the pos variable so that you're pointing to the
    # first line where there is an actual label.
    incr pos
        
    # Print out all of the rest with the start time subtracted from
    # the label time.  Do this by testing to see if the line has a
    # floating point number (for the time) on it, and if it does,
    # put that number into the variable "labtime".
    while { [regexp {([0-9]+\.[0-9]+)} [lindex $linelist $pos] labtime] } {
       # Subtract the starttime argument from the labtime, and set the
       # variable "fixedtime" to the result of that operation.
       set fixedtime [expr $labtime - $starttime]
       # Substitute the fixedtime for the original labtime, and put the
       # result of that substitution in the variable "fixedline". 
       regsub $labtime [lindex $linelist $pos] $fixedtime fixedline
       # Print the fixedline to the ouptut file./
       puts $labFile $fixedline
       # Increment pos to point to the next line in the list.
       incr pos
    }
    # n.b. The above code assumes that there will be no empty lines
    # in the file.  It will stop at an empty line
    
    # Clean up by closing the output label file.
    close $labFile
}
#######  The main body of the script starts here  ######
#
# First check to see whether there fewer than the required number 
# of arguments (need at least two), and if there are too few,
# use the error command to print an error message to the screen and exit
# the script.  
if {$argc < 2} {
    error "too few arguments"
# " need extension for output label file and input label file name(s)"
}

# Set the variable "exten" to the first command line argument, but
# if it doesn't fits the description of an extension (which is a 
# string of alphanumeric characters -- i.e., not including a "." --
# use the error command to print out an error message and exit.
if { ![regexp {^[a-zA-Z0-9]+$} [lindex $argv 0] exten] } {
    error "first argument must be a valid file extension"
    } else {
    # Prepend a "." to the extension, if no error.
    set exten [subst .${exten}]
}

# Loop through the lab file names that are specified as the rest
# of the arguments, after the extension argument.
for {set i 1} {$i < $argc} {incr i} {
    # Read the next lab file name from the arguments list, and 
    # set the variable "file" to the result.
    set file [lindex $argv $i]

    # Create the output label file name from the input label
    # file name and the extension argument by substituting the
    # variable exten for any alphanumeric string after (last)
    # period in the variable "file" and putting the result in 
    # the variable "outputFile".
    regsub {\.[a-zA-Z0-9]+$} $file $exten outputFile

    # Create the speech file name from the input label file name
    # by substituting "d" for the original extension, and put 
    # the result of this substitution in the variable "audioFile".
    regsub {\.[a-zA-Z0-9]+$} $file ".d" audioFile
    # n.b. change this line if audio file has extension other than .d 

    # Check to make sure that the file exists, and if it doesn't, ...
    if {![file exists $audioFile]} {
        # Generate a warning message saying the file doesn't exist.
        puts "cannot find file $audioFile"
    } else {
        # Otherwise, go on to process the file.
        # Execute the hditem command on the speech file, to get the 
        # start time of the speech file to substract from label times.
        set starttime [exec hditem -i start_time $audioFile]
 
        # Check to see whether starttime is zero.
        if {[expr $starttime == 0]} {
           # If it is, just copy the input label file to the output,
           # by executing the UNIX cp command.
           exec "cp $file $outputFile"
        } else {
           # Otherwise, call up the procedure to subtract the start 
           # time from the label times as you copy the file.
           subtr_time $file $outputFile $starttime
       } 
   }
}

