#!/bin/csh -f
# ----------------------------------------------------------------- #
#             The Speech Signal Processing Toolkit (SPTK)           #
#             developed by SPTK Working Group                       #
#             http://sp-tk.sourceforge.net/                         #
# ----------------------------------------------------------------- #
#                                                                   #
#  Copyright (c) 1984-2007  Tokyo Institute of Technology           #
#                           Interdisciplinary Graduate School of    #
#                           Science and Engineering                 #
#                                                                   #
#                1996-2017  Nagoya Institute of Technology          #
#                           Department of Computer Science          #
#                                                                   #
# All rights reserved.                                              #
#                                                                   #
# Redistribution and use in source and binary forms, with or        #
# without modification, are permitted provided that the following   #
# conditions are met:                                               #
#                                                                   #
# - Redistributions of source code must retain the above copyright  #
#   notice, this list of conditions and the following disclaimer.   #
# - Redistributions in binary form must reproduce the above         #
#   copyright notice, this list of conditions and the following     #
#   disclaimer in the documentation and/or other materials provided #
#   with the distribution.                                          #
# - Neither the name of the SPTK working group nor the names of its #
#   contributors may be used to endorse or promote products derived #
#   from this software without specific prior written permission.   #
#                                                                   #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND            #
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,       #
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF          #
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE          #
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS #
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          #
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED   #
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     #
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON #
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,   #
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY    #
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE           #
# POSSIBILITY OF SUCH DAMAGE.                                       #
# ----------------------------------------------------------------- #
#                                                                   #
#                                      Mar. 2010  A. Tamamori       #

onintr clean

set path    = ( /opt/local/libexec/sptk $path )
set sptkver = '3.11'
set cvsid   = '$Id$'


set cmnd	= $0
set cmnd	= $cmnd:t

set file
set flagfile    = 0

set directory
set flagdirectory = 0


set swab		= 0
set normalization	= 0
set normalization_all = 0
set OutputType = s
set OutMaxVal = 32767
set data_position
set read_fmt = 0
set enter_datachunk = 0
set read_data = 0
set left = 0
set right = 0
set decimate_start = 0
set Channels = 1

set _argv
set white
set whitespace = 0
set index

if ($?uid) then
else
    if ($?UID) then
        set uid = $UID
    else
        set uid
    endif
endif

@ i = 0
while ($i < $#argv)
	@ i++
    set whitespace = 0
    set _argv = `echo $argv[$i] | sed -e 's/ /_/g'`
    if ( "$_argv" != "$argv[$i]" ) then
       @ whitespace = 1
    endif
	switch ($_argv)
	case -swab:
		set swab = 1
		breaksw
    case +c:
        set OutputType = c
        set OutMaxVal = 127
        breaksw
	case +s:
		set OutputType = s
        set OutMaxVal = 32767
		breaksw
    case +i3:
        set OutputType = i3
        set OutMaxVal = 8388067
        breaksw
	case +i:
		set OutputType = i
        set OutMaxVal = 2147483647
		breaksw
	case +l:
		set OutputType = l
        set OutMaxVal = 2147483647
		breaksw
	case +C:
		set OutputType = C
        set OutMaxVal = 255
		breaksw
	case +S:
		set OutputType = S
        set OutMaxVal = 65535
		breaksw
	case +I3:
		set OutputType = I3
        set OutMaxVal = 16776135
		breaksw
	case +I:
		set OutputType = I
        set OutMaxVal = 4294967296
		breaksw
	case +L:
		set OutputType = L
        set OutMaxVal = 4294967296
		breaksw
	case +f:
		set OutputType = f
        set OutMaxVal = 1
		breaksw
	case +d:
		set OutputType = d
        set OutMaxVal = 1
		breaksw
	case +a:
		set OutputType = a
		breaksw
	case -d:
		@ i++
		set directory = $argv[$i]
		set flagdirectory = 1
		if ( ! -d $argv[$i] ) then
			echo2 "${cmnd}: Can't find directory "'"'"$directory"'"'" \!"
			set exit_status = 1
			goto usage
		endif
		breaksw
	case -n:
		set normalization = 1
		breaksw
	case -N:
		set normalization = 1
		set normalization_all = 1
		breaksw
	case -L:
		if ( $right == 1 ) then
			echo2 "${cmnd}: Can't convert left and right sounds at the same time\!"
			set exit_status = 1
			goto usage
		endif
		set left = 1
		set decimate_start = 0
		breaksw
	case -R:
		if ( $left == 1 ) then
			echo2 "${cmnd}: Can't convert left and right sounds at the same time\!"
			set exit_status = 1
			goto usage
		endif
		set right = 1
		set decimate_start = 1
		breaksw
	case -h:
		set exit_status = 0
		goto usage
		breaksw
	default:
		set file = ( $file $_argv )
		set white = ( $white $whitespace )
		set index = ( $index $i )
		set flagfile = 1
		if ( $whitespace == 1 ) then
			if ( ! -f "$argv[$i]" ) then
				echo2 "${cmnd}: Can't open file "'"'"$argv[$i]"'"'" \!"
				set exit_status = 1
			goto usage
			endif
		endif
		breaksw
	endsw
end

goto main

usage:
        echo2 ''
        echo2 " $cmnd - wav to raw "
        echo2 ''
        echo2 '  usage:'
        echo2 "       $cmnd [ options ] [ infile(s) ]"
        echo2 '  options:'
        echo2 '       -swab         : change endian                             [FALSE]'
        echo2 '       -d d          : destination directory                     [N/A]'
        echo2 '       -n            : normalization with the maximum value'
        echo2 '                       according to bit/sample of the wav file'
        echo2 '                       if max >= 255 (8bit), 32767 (16bit),'
        echo2 '                       8388067 (24bit), 2147483647 (32bit).'
        echo2 '       -N            : normalization with the maximum value      [FALSE]'
        echo2 '       -L            : convert left sound from stereo wav file   [FALSE]'
        echo2 '       -R            : convert right sound from stereo wav file  [FALSE]'
        echo2 '       +type         : output data type                          [s]'
        echo2 '                        c  (char)         C  (unsigned char) '
        echo2 '                        s  (short)        S  (unsigned short)'
        echo2 '                        i3 (int, 3byte)   I3 (unsigned int, 3byte)'
        echo2 '                        i  (int)          I  (unsigned int)'
        echo2 '                        l  (long)         L  (unsigned long)'
        echo2 '                        f  (float)        d  (double)'
        echo2 '                        a  (ascii)'
        echo2 '       -h            : print this message'
        echo2 '  infile(s):'
        echo2 '       wavfile                                                   [N/A]'
        echo2 '  output:'
        echo2 "       $cmnd removes RIFF header(s) from input wav file(s)."
        echo2 '                                                         '
        echo2 '       The outfile has an extention ".raw", e.g.,'
        echo2 '          sample.m15 ---> sample.m15.raw'
        echo2 '                                                         '
        echo2 '       If the infile has an extention ".wav",'
        echo2 '       the extention is converted into ".raw", e.g.,'
        echo2 '          sample.m15.wav ---> sample.m15.raw'
        echo2 '                                                         '
        echo2 '       The outfile is stored in the same directory'
        echo2 '       as the infile.'
        echo2 '       However, once a destination directory is specified,'
        echo2 '       all raw files are stored in that directory.'
        echo2 ''
        echo2 " SPTK: version $sptkver"
        echo2 " CVS Info: $cvsid"
        echo2 ''
exit $exit_status

main:

@ j = 1
while ( $j <= $#file )
    set f = $file[$j]
    if ( $white[$j] ) then
        /bin/ln -f -s "$argv[$index[$j]]" $f
    endif

    set tmp = `bcut +c -s 4 -e 7 $f | x2x +Ia`
    @ FileSize = $tmp + 8

    @ Current = 12
    @ Rest = $FileSize
    while( $Rest > 0 )
        #Read the chunk ID (4byte)
        set i = 0; set tmp = $Current; set ChunkID
        while( $i < 4 )
            set tmp2 = `bcut +c -s $tmp -e $tmp $f | x2x +Ca`
            set ChunkID = ${ChunkID}`printf "%X" $tmp2`
            @ i++; @ tmp++
        end
        @ Current = $Current + 4

        #Read the chunk size (4byte)
        @ tmp = $Current + 3
        set ChunkSize = `bcut +c -s $Current -e $tmp $f | x2x +Ia`
        @ Current = $Current + 4

        switch( $ChunkID )
        case 666D7420: #The chunk ID is "fmt " (ASCII code, hexadecimal number)
            set fmt_start = $Current
            @ tmp = $Current + 1
            set FormatID = `bcut +c -s $Current -e $tmp $f | x2x +Sa`
            @ Current = $Current + 2

            #Read the channels (2byte)
            @ tmp = $Current + 1
            set Channels = `bcut +c -s $Current -e $tmp $f | x2x +Sa`

            @ Current = $Current + 12
            @ tmp = $Current + 1
            set BitPerSample = `bcut +c -s $Current -e $tmp $f | x2x +Sa`
            switch( $BitPerSample )
            case  8:
                set InputType = c
                breaksw
            case 16:
                set InputType = s
                breaksw
            case 24:
                set InputType = i3
                breaksw
            case 32:
                if ( $FormatID == 1 ) then # PCM
                    set InputType = i
                else if ( $FormatID == 3 ) then # IEEE float
                    set InputType = f
                else
                    echo2 "Format id $FormatID is not acceptable!"
                    exit
                endif
                breaksw
            endsw

            @ Current = $fmt_start + $ChunkSize

            set read_fmt = 1 # enable to read "data" chunk
            if ( $enter_datachunk == 0) then
                breaksw
            else
                # if "data" chunk has been read
                @ Current = $data_position
                # immediately read "data" chunk. no need to use 'breaksw'.
            endif

        case 64617461: #The chunk ID is "data" (ASCII code, hexadecimal number)
            if ( $read_fmt == 0 ) then
                set enter_datachunk = 1
                set data_position = $Current
                breaksw
            endif
            @ tmp = $Current + $ChunkSize
            if ( $normalization ) then
                if ( $FormatID == 3) then
                    if ( $swab ) then
                       if ( $Channels == 2 && ( $left == 1 || $right == 1 ) ) then
                        bcut +c -s $Current -e $tmp $f | swab | decimate -p 2 -s $decimate_start |\
                        sopr -m ${OutMaxVal} > /tmp/sptk-wav2raw-$uid-$$.tmp
                       else
                        bcut +c -s $Current -e $tmp $f | swab |\
                        sopr -m ${OutMaxVal} > /tmp/sptk-wav2raw-$uid-$$.tmp
                       endif
                    else
                       if ( $Channels == 2 && ( $left == 1 || $right == 1 ) ) then
                        bcut +c -s $Current -e $tmp $f | decimate -p 2 -s $decimate_start |\
                        sopr -m ${OutMaxVal} > /tmp/sptk-wav2raw-$uid-$$.tmp
                       else
                        bcut +c -s $Current -e $tmp $f |\
                        sopr -m ${OutMaxVal} > /tmp/sptk-wav2raw-$uid-$$.tmp
                       endif
                    endif

                    set max = `minmax < /tmp/sptk-wav2raw-$uid-$$.tmp | sopr -ABS |\
                               minmax | bcut -s 1 | x2x +fa %.100f`

                    if ( $normalization_all || `echo "$max > ${OutMaxVal}" | bc -l` ) then
                        sopr -m ${OutMaxVal} -d $max < /tmp/sptk-wav2raw-$uid-$$.tmp |\
                        x2x -r +f${OutputType} > /tmp/sptk-wav2raw-$uid-$$.raw
                    else
                        x2x -r +f${OutputType} < /tmp/sptk-wav2raw-$uid-$$.tmp \
                            > /tmp/sptk-wav2raw-$uid-$$.raw
                    endif
                else #FormatID is not 3
                    if ( $swab ) then
                      if ( $Channels == 2 && ( $left == 1 || $right == 1 ) ) then
                        bcut +c -s $Current -e $tmp $f | swab +$InputType |\
                        x2x +${InputType}f | decimate -p 2 -s $decimate_start > /tmp/sptk-wav2raw-$uid-$$.tmp
                      else
                        bcut +c -s $Current -e $tmp $f | swab +$InputType |\
                        x2x +${InputType}f > /tmp/sptk-wav2raw-$uid-$$.tmp
                      endif
                    else
                      if ( $Channels == 2 && ( $left == 1 || $right == 1 ) ) then
                        bcut +c -s $Current -e $tmp $f |\
                        x2x +${InputType}f | decimate -p 2 -s $decimate_start > /tmp/sptk-wav2raw-$uid-$$.tmp
                      else
                        bcut +c -s $Current -e $tmp $f |\
                        x2x +${InputType}f > /tmp/sptk-wav2raw-$uid-$$.tmp
                      endif
                    endif

                    set max = `minmax < /tmp/sptk-wav2raw-$uid-$$.tmp | sopr -ABS |\
                               minmax | bcut -s 1 | x2x +fa %.100f`

                    if ( $normalization_all || `echo "$max > ${OutMaxVal}" | bc -l` ) then
                        sopr -m ${OutMaxVal} -d $max < /tmp/sptk-wav2raw-$uid-$$.tmp |\
                        x2x -r +f${OutputType} > /tmp/sptk-wav2raw-$uid-$$.raw
                    else
                        x2x -r +f${OutputType} < /tmp/sptk-wav2raw-$uid-$$.tmp \
                            > /tmp/sptk-wav2raw-$uid-$$.raw
                    endif
                endif

                rm -fr /tmp/sptk-wav2raw-$uid-$$.tmp
            else #No normalization
                if ( $FormatID == 3) then
                    if ( $swab ) then
                      if ( $Channels == 2 && ( $left == 1 || $right == 1 ) ) then
                        bcut +c -s $Current -e $tmp $f | swab | decimate -p 2 -s $decimate_start |\
                        sopr -m ${OutMaxVal} |\
                        x2x -r +f${OutputType} > /tmp/sptk-wav2raw-$uid-$$.raw
                      else
                        bcut +c -s $Current -e $tmp $f | swab |\
                        sopr -m ${OutMaxVal} |\
                        x2x -r +f${OutputType} > /tmp/sptk-wav2raw-$uid-$$.raw
                      endif
                    else
                      if ( $Channels == 2 && ( $left == 1 || $right == 1 ) ) then
                        bcut +c -s $Current -e $tmp $f | decimate -p 2 -s $decimate_start |\
                        sopr -m ${OutMaxVal} |\
                        x2x -r +f${OutputType} > /tmp/sptk-wav2raw-$uid-$$.raw
                      else
                        bcut +c -s $Current -e $tmp $f |\
                        sopr -m ${OutMaxVal} |\
                        x2x -r +f${OutputType} > /tmp/sptk-wav2raw-$uid-$$.raw
                      endif
                    endif
                else #FormatID is not 3
                    if ( $swab ) then
                      if ( $Channels == 2 && ( $left == 1 || $right == 1 ) ) then
                        bcut +c -s $Current -e $tmp $f | swab +$InputType | x2x +${InputType}f |\
                        decimate -p 2 -s $decimate_start | x2x -r +f${OutputType} > /tmp/sptk-wav2raw-$uid-$$.raw
                      else
                        bcut +c -s $Current -e $tmp $f | swab +$InputType |\
                        x2x -r +${InputType}${OutputType} > /tmp/sptk-wav2raw-$uid-$$.raw
                      endif
                    else
                      if ( $Channels == 2 && ( $left == 1 || $right == 1 ) ) then
                        bcut +c -s $Current -e $tmp $f | x2x +${InputType}f |\
                        decimate -p 2 -s $decimate_start | x2x -r +f${OutputType} > /tmp/sptk-wav2raw-$uid-$$.raw
                      else
                        bcut +c -s $Current -e $tmp $f |\
                        x2x -r +${InputType}${OutputType} > /tmp/sptk-wav2raw-$uid-$$.raw
                      endif
                    endif
                endif
            endif

            if ( $f:e == "wav" ) then
                if ( $flagdirectory ) then
                    set outfile = $directory/"$argv[$index[$j]]:t:r".raw
                else
                    set outfile = "$argv[$index[$j]]:r".raw
                endif
            else
                if ( $flagdirectory ) then
                    set outfile = $directory/"$argv[$index[$j]]:t".raw
                else
                    set outfile = "$argv[$index[$j]]".raw
                endif
            endif

            /bin/mv /tmp/sptk-wav2raw-$uid-$$.raw "$outfile"
            if ( $white[$j] ) then
                /bin/rm -f $f
            endif

            set read_data = 1

            @ Current = $Current + $ChunkSize
            breaksw

        default:
            @ Current = $Current + $ChunkSize
            breaksw

        endsw # end of switch($ChunkID)

        if (($read_fmt == 1) && ($read_data == 1)) then
            break
        endif

        @ Rest = $FileSize - $Current
    end # end of while( $Rest > 0 )
    @ j++
end # end of while ($j <= $#file)

clean:
rm -fr /tmp/sptk-wav2raw-$uid-$$.raw /tmp/sptk-wav2raw-$uid-$$.tmp
