#! /usr/bin/perl
#
# Move all files after splitting
# Do a precission alignment using a
# cross-corelations (lag -0.2, 0.2)
# between downsampled (4000 Hz) original and recorded
# Alignment is done by "shifting" the sound in the file,
# adding silence where needed.
# files.
#
# Use: MoveSplitFiles.pl [RecordingGlob] [PlaylistFile] [TargetHomeDir]
#      [--NODIFFADDING]
#
#	[RecordingGlob] The file with the ORIGINAL Unsplit recording
#					Files are assumed to be called <RecordingFile>[n].wav
#					where [n] is the order number
#	[PlaylistFile]  Play list with the corresponding original file paths
#	[TargetHomeDir]	Homedir where the new files should be copied into
#					e.g., ~/SmdSLcorpus. Files will be added to 
#					[TargetHomeDir]/sentences/[fh]m/<speaker>/
#   [--NODIFFADDING] Do NOT perform precission alignment
# 
#    
# Copyright (C) 2002  R.J.J.H. van Son
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
# 
#
my $DiffAdding = 'SHIFT';
if(grep(/\-\-NODIFFADDING/i, @ARGV))
{
	$DiffAdding = 'NONE';
	@ARGV = grep(!/\-\-NODIFFADDING/i, @ARGV);
};
# Get remaining arguments
my $RecordingGlob = shift(@ARGV) || '../../../../record/SonyMDrecordingMono1-020702*_.wav';
my $PlayList = shift(@ARGV) || 'PlayList.txt';
my $TargetHomeDir = shift(@ARGV) || 'Smd';

my @SplitList = glob($RecordingGlob);

foreach $SourceRecording (@SplitList)
{
	open(PLAYLIST, "<$PlayList") || die "$!: $PlayList\n";


	my @PraatMasterScript = ();
	my $FileCounter = 0;
	while(<PLAYLIST>)
	{
		++$FileCounter;
		my ($SourceFile, @rest) = split;
		my $TargetFile = $SourceFile;
		if(-d $TargetHomeDir)
		{
			$TargetHomeDir .= '/' unless $TargetHomeDir =~ m@/$@;
			$TargetFile =~ m@/SLspeech/@;
			$TargetFile = $TargetHomeDir.$';
		}
		else
		{
			$TargetFile =~ s@/SLspeech/@/${TargetHomeDir}SLspeech/@ig;
		};
		#
		# Add Target Marker
		if($TargetFile =~ m@/(\w+)SLspeech/@)
		{
			my $SoundMarker = $1;
			$TargetFile =~ s@\.(wav|aifc|nist|au)$@_$SoundMarker.wav@ig;
		};
		#
		# Make directory
		$CurrentTargetDir = $TargetFile;
		# Remove FileName
		$CurrentTargetDir =~ s@[^/]+$@@ig;
		`mkdir -p $CurrentTargetDir`;

		my $CurrentRecordingFile = $SourceRecording;
		$CurrentRecordingFile =~ s/\.wav/$FileCounter\.wav/ig;

		# Compare sizes (convert bytes to seconds)
		my $SourceSize = (-s $SourceFile);
		$SourceSize /= 44100*2;
		my $TargetSize = (-s $CurrentRecordingFile);
		$TargetSize /= 44100*2;
		my $DiffSize = $TargetSize - $SourceSize;
		print "Sizes $FileCounter: $SourceFile $SourceSize -> ", $TargetSize, " Diff: ", $DiffSize, "\n" 
			if abs($DiffSize) > 0.010;
		
		# Get offset by DTW
		my $DetermineOffset = << "DETERMINEOFFSETEND";
# Use Cross correlation to determine offset
lagduration = 0.2
Read from file... $CurrentRecordingFile
Resample... 4000 50
Rename... Target
Read from file... $SourceFile
Resample... 4000 50
Rename... Source
duration = Get duration
select Sound Target
plus Sound Source
Cross-correlate... -lagduration lagduration yes
Rename... CrossCorrelation
Formula... abs(self)
offset = Get time of maximum... 0 0 Sinc70
 
select all
Remove

DETERMINEOFFSETEND
		push(@PraatMasterScript, $DetermineOffset);
		
		# Copy alligned path
		if($DiffAdding eq 'SHIFT')
		{
				my $ShiftFile = << "SHIFTFILEEND"; 
# Change onset    
if offset > 0.0001
    Create Sound... silence 0.0 'offset' 44100 0
    Read from file... $CurrentRecordingFile
    select all
    Concatenate
else
    Read from file... $CurrentRecordingFile
	if offset < -0.0001
    	duration = Get duration
    	Extract part... -offset duration Rectangular 1.0 no
	endif
endif
Rename... target

# Change offset
newduration = Get duration
if newduration > duration
    Extract part... 0 duration Rectangular 1.0 no
elsif newduration + 0.0001 < duration
    addedlength = duration - newduration
    Create Sound... silence 0.0 'addedlength' 44100 0
    plus Sound target
    Concatenate
else
	select Sound target
endif
Write to WAV file... $TargetFile

# Clean up
select all
Remove

SHIFTFILEEND
				push(@PraatMasterScript, $ShiftFile);
		}
		else
		{
			`cp $CurrentRecordingFile $TargetFile`;
		};
	};
	# Ready with this source
	close(PLAYLIST);
	
	# Play Praat script (if necesarry)
	if(@PraatMasterScript)
	{
		my $time = time;
		my $ScratchFile = "SCRATCH$time.praat";
		open(PRAATSCRIPT, ">$ScratchFile");
		# print @PraatMasterScript;
		print PRAATSCRIPT @PraatMasterScript;
		print PRAATSCRIPT "Quit\n";
		close(PRAATSCRIPT);
		`praat $ScratchFile;rm $ScratchFile`;
		@PraatMasterScript = ();
	};
};
