program file2wav
implicit none

INTEGER(4), DIMENSION(13) :: filedata
integer*1, allocatable :: wavbinary(:)
integer*4 :: j=0,bigpiece,ios,ios2
integer*1, dimension(4) :: fraghex=0,bigfrag=0
integer(4), dimension(0:7) :: sixteens
character(len=1024) :: clinefile, outfile

sixteens(0) = 1
sixteens(1) = 16
sixteens(2) = 256
sixteens(3) = 4096
sixteens(4) = 65536
sixteens(5) = 1048576
sixteens(6) = 16777216
sixteens(7) = 268435456

call get_command_argument(1,clinefile)
IF (LEN_TRIM(clinefile) == 0) then
  print*, 'Syntax for file2wav is: file2wav [INPUT_FILE] [OUTPUT_FILE].'
  stop
endif

call get_command_argument(2,outfile)
IF (LEN_TRIM(outfile) == 0) then
  print*, 'Syntax for file2wav is: file2wav [INPUT_FILE] [OUTPUT_FILE].'
  stop
endif

if(outfile(len(trim(outfile))-3:len(trim(outfile))) .ne. '.wav') then
  outfile = trim(outfile)//'.wav'
  else
endif

call stat(clinefile,filedata)
fraghex(1)=floor(real(filedata(8))/sixteens(6))
fraghex(2)=floor(real(filedata(8)-(fraghex(1)*sixteens(6)))/sixteens(4))
fraghex(3)=floor(real(filedata(8)-fraghex(1)*sixteens(6)-fraghex(2)*sixteens(4))/sixteens(2))
fraghex(4)=floor(real(filedata(8)-fraghex(1)*sixteens(6)-fraghex(2)*sixteens(4)-fraghex(3)*sixteens(2)))

bigpiece=filedata(8)+36
bigfrag(1)=floor(real(bigpiece)/sixteens(6))
bigfrag(2)=floor(real(bigpiece-(bigfrag(1)*sixteens(6)))/sixteens(4))
bigfrag(3)=floor(real(bigpiece-bigfrag(1)*sixteens(6)-bigfrag(2)*sixteens(4))/sixteens(2))
bigfrag(4)=floor(real(bigpiece-bigfrag(1)*sixteens(6)-bigfrag(2)*sixteens(4)-bigfrag(3)*sixteens(2)))

allocate(wavbinary(filedata(8)+44))

open(100, file=clinefile,access='direct',recl=filedata(8),iostat=ios)
if(ios .eq. 5002) then
  print*, 'Input file error: Make sure that file "',trim(clinefile),'" exists.' 
  stop
  elseif(ios .ne. 0) then
  print*, 'Input file error: gfortran error code ',ios
  stop
endif

open(200, file=outfile,access='direct',recl=44+filedata(8),iostat=ios2)
if(ios .ne. 0) then
  print*, 'Output file error: gfortran error code ',ios2
  stop
endif

!.wav file format specifier
wavbinary(1)=82 !R
wavbinary(2)=73 !I
wavbinary(3)=70 !F
wavbinary(4)=70 !F
!The next 4 bytes specify the length of the rest of the file, in little endian
wavbinary(5)=bigfrag(4)   
wavbinary(6)=bigfrag(3) 
wavbinary(7)=bigfrag(2) 
wavbinary(8)=bigfrag(1) 
wavbinary(9)=87  !W
wavbinary(10)=65 !A
wavbinary(11)=86 !V
wavbinary(12)=69 !E
wavbinary(13)=102 !f
wavbinary(14)=109 !m
wavbinary(15)=116 !t
wavbinary(16)=32  !blank space
!Subchunk 1 Size in bits (little endian)
wavbinary(17)=16 
wavbinary(18)=0
wavbinary(19)=0
wavbinary(20)=0
!PCM--uncompressed wav
wavbinary(21)=1 
wavbinary(22)=0
!stereo=num channels (little endian)
wavbinary(23)=2 
wavbinary(24)=0
!Sample rate=44100 Hz in little endian
wavbinary(25)=68 
wavbinary(26)=-84
wavbinary(27)=0
wavbinary(28)=0
!byte rate=sample rate*num channels*bits per sample/8=176400 (little endian)
wavbinary(29)=16 
wavbinary(30)=-79
wavbinary(31)=2
wavbinary(32)=0
!Block align=num channels*bits per sample/8 (little endian)
wavbinary(33)=4  
wavbinary(34)=0
!bits per sample (little endian)
wavbinary(35)=16 
wavbinary(36)=0
wavbinary(37)=100 !d
wavbinary(38)=97  !a
wavbinary(39)=116 !t
wavbinary(40)=97  !a
!Subchunk 2 size=length of actual sound data (little endian)
wavbinary(41)=fraghex(4)
wavbinary(42)=fraghex(3)
wavbinary(43)=fraghex(2)
wavbinary(44)=fraghex(1)

read(100,rec=1) wavbinary(45:filedata(8)+44)
close(100)

write(200,rec=1) wavbinary

close(200)

deallocate(wavbinary)

end program

