diff --git a/CMakeLists.txt b/CMakeLists.txt index e3bb73c8d..af1474e32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -368,6 +368,7 @@ set (wsjt_FSRCS lib/polyfit.f90 lib/prog_args.f90 lib/ps4.f90 + lib/readwav.f90 lib/rectify_msk.f90 lib/savec2.f90 lib/sec_midn.f90 diff --git a/getfile.cpp b/getfile.cpp index d04f9ce58..2034ae21d 100644 --- a/getfile.cpp +++ b/getfile.cpp @@ -1,6 +1,8 @@ #include "getfile.h" #include #include +#include +#include #include #ifdef WIN32 @@ -60,10 +62,41 @@ void getfile(QString fname, int ntrperiod) memset(dec_data.d2,0,2*npts); if(fp != NULL) { + struct + { + char id[4]; + uint32_t size; + } desc; + char type[4]; + struct + { + uint16_t nfmt2; + uint16_t nchan2; + uint32_t nsamrate; + uint32_t nbytesec; + uint16_t nbytesam2; + uint16_t nbitsam2; + } fmt; + + // read header + fread(&desc, 1, sizeof desc, fp); // RIFF + fread(type, 1, sizeof type, fp); // WAVE + do + { + fread(&desc, 1, sizeof desc, fp); // WAVE component + if (!memcmp(desc.id,"fmt ",4)) { + fpos_t pos; + fgetpos(fp,&pos); + fread(&fmt,1,sizeof fmt,fp); + fsetpos(fp,&pos); + } + if (!memcmp(desc.id,"data",sizeof desc.id)) break; + } while (!fseek(fp,(desc.size + 1) / 2 * 2,SEEK_CUR)); + // Read (and ignore) a 44-byte WAV header; then read data - int n=fread(&hdr,1,44,fp); - n=fread(dec_data.d2,2,npts,fp); - if(hdr.nsamrate==11025) wav12_(dec_data.d2,dec_data.d2,&n,&hdr.nbitsam2); +// int n=fread(&hdr,1,44,fp); + int n=fread(dec_data.d2,2,npts,fp); + if(hdr.nsamrate==11025) wav12_(dec_data.d2,dec_data.d2,&n,(short*)&fmt.nbitsam2); fclose(fp); dec_data.params.newdat=1; dec_data.params.kin=n; diff --git a/lib/jt65.f90 b/lib/jt65.f90 index b4af9b811..30288c7b9 100644 --- a/lib/jt65.f90 +++ b/lib/jt65.f90 @@ -6,17 +6,17 @@ program jt65 use timer_module, only: timer use timer_impl, only: init_timer use jt65_test + use readwav character c logical :: display_help=.false.,nrobust=.false. - integer*4 ihdr(11) + type(wav_header) :: wav integer*2 id2(NZMAX) real*4 dd(NZMAX) character*80 infile character(len=500) optarg character*12 mycall,hiscall character*6 hisgrid - equivalence (lenfile,ihdr(2)) type (option) :: long_options(10) = [ & option ('aggressive',.true.,'a','aggressiveness [0-10], default AGGR=0','AGGR'), & option ('freq',.true.,'f','signal frequency, default FREQ=1270','FREQ'), & @@ -95,21 +95,17 @@ program jt65 minsync=0 call get_command_argument(ifile,optarg,narglen) infile=optarg(:narglen) - open(10,file=infile,access='stream',status='old',err=998) call timer('read ',0) - read(10) ihdr + call wav%read (infile) i1=index(infile,'.wav') if( i1 .eq. 0 ) i1=index(infile,'.WAV') read(infile(i1-4:i1-1),*,err=998) nutc npts=52*12000 - read(10) id2(1:npts) + read(unit=wav%lun) id2(1:npts) + close(unit=wav%lun) call timer('read ',1) dd(1:npts)=id2(1:npts) dd(npts+1:)=0. - - ! open(56,file='subtracted.wav',access='stream',status='unknown') - ! write(56) ihdr(1:11) - call test(dd,nutc,nfa,nfb,nfqso,ntol,nsubmode, & n2pass,nrobust,ntrials,naggressive, & mycall,hiscall,hisgrid,nexp_decoded) diff --git a/lib/jt9.f90 b/lib/jt9.f90 index 984d02d85..dcfe3b018 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -9,11 +9,12 @@ program jt9 use FFTW3 use timer_module, only: timer use timer_impl, only: init_timer, fini_timer + use readwav include 'jt9com.f90' integer(C_INT) iret - integer*4 ihdr(11) + type(wav_header) wav real*4 s(NSMAX) character c character(len=500) optarg, infile @@ -172,10 +173,8 @@ program jt9 do iarg = offset + 1, offset + remain call get_command_argument (iarg, optarg, arglen) infile = optarg(:arglen) - open(10,file=infile,access='stream',status='old',err=998) - read(10) ihdr - nfsample=ihdr(7) - nutc=ihdr(1) !Silence compiler warning + call wav%read (infile) + nfsample=wav%audio_format%sample_rate i1=index(infile,'.wav') if(i1.lt.1) i1=index(infile,'.WAV') if(infile(i1-5:i1-5).eq.'_') then @@ -218,7 +217,7 @@ program jt9 do iblk=1,npts/kstep k=iblk*kstep call timer('read_wav',0) - read(10,end=3) shared_data%id2(k-kstep+1:k) + read(unit=wav%lun,end=3) shared_data%id2(k-kstep+1:k) go to 4 3 call timer('read_wav',1) print*,'EOF on input file ',infile @@ -239,7 +238,7 @@ program jt9 if(nhsym.ge.181) exit endif enddo - close(10) + close(unit=wav%lun) shared_data%params%nutc=nutc shared_data%params%ndiskdat=.true. shared_data%params%ntr=60 @@ -290,10 +289,6 @@ program jt9 call timer('jt9 ',1) call timer('jt9 ',101) - go to 999 - -998 print*,'Cannot open file:' - print*,infile 999 continue ! Output decoder statistics diff --git a/lib/readwav.f90 b/lib/readwav.f90 new file mode 100644 index 000000000..f2d2ed377 --- /dev/null +++ b/lib/readwav.f90 @@ -0,0 +1,51 @@ +module readwav + implicit none + + type format_chunk + integer*2 audio_format + integer*2 num_channels + integer sample_rate + integer byte_rate + integer*2 block_align + integer*2 bits_per_sample + end type format_chunk + + type, public :: wav_header + integer :: lun + type(format_chunk) :: audio_format + contains + procedure :: read + end type wav_header + + private +contains + subroutine read (this, filename) + implicit none + + type riff_descriptor + character(len=4) :: id + integer :: size + end type riff_descriptor + + class(wav_header), intent(inout) :: this + character(len=*), intent(in) :: filename + + integer :: filepos + type(riff_descriptor) :: desc + character(len=4) :: riff_type + + open (newunit=this%lun, file=filename, access='stream', form='unformatted', status='old') + read (unit=this%lun) desc,riff_type + inquire (unit=this%lun, pos=filepos) + do + read (unit=this%lun, pos=filepos) desc + inquire (unit=this%lun, pos=filepos) + if (desc%id .eq. 'fmt ') then + read (unit=this%lun) this%audio_format + else if (desc%id .eq. 'data') then + exit + end if + filepos = filepos + (desc%size + 1) / 2 * 2 ! pad to even alignment + end do + end subroutine read +end module readwav