| 
									
										
										
										
											2016-01-02 15:04:26 +00:00
										 |  |  | !
 | 
					
						
							|  |  |  | ! readwav - open and read the header of a WAV format file
 | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! On successful exit the file is left positioned at the start of the
 | 
					
						
							|  |  |  | ! data.
 | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! Example of usage:
 | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | !  use readwav
 | 
					
						
							|  |  |  | !  integer*2 sample
 | 
					
						
							|  |  |  | !  type(wav_header) wav
 | 
					
						
							|  |  |  | !  call wav%read ('file.wav')
 | 
					
						
							|  |  |  | !  write (*,*) 'Sample rate is: ', wav%audio_format%sample_rate
 | 
					
						
							|  |  |  | !  do i=0,wav%data_size
 | 
					
						
							|  |  |  | !    read (unit=wav%lun) sample
 | 
					
						
							|  |  |  | !    ! process sample
 | 
					
						
							|  |  |  | !  end do
 | 
					
						
							|  |  |  | !
 | 
					
						
							| 
									
										
										
										
											2016-01-02 14:29:02 +00:00
										 |  |  | 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
 | 
					
						
							| 
									
										
										
										
											2016-01-02 15:04:26 +00:00
										 |  |  |      integer :: data_size
 | 
					
						
							| 
									
										
										
										
											2016-01-02 14:29:02 +00:00
										 |  |  |    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
 | 
					
						
							| 
									
										
										
										
											2016-01-02 15:04:26 +00:00
										 |  |  |           this%data_size = desc%size
 | 
					
						
							| 
									
										
										
										
											2016-01-02 14:29:02 +00:00
										 |  |  |           exit
 | 
					
						
							|  |  |  |        end if
 | 
					
						
							|  |  |  |        filepos = filepos + (desc%size + 1) / 2 * 2 ! pad to even alignment
 | 
					
						
							|  |  |  |     end do
 | 
					
						
							|  |  |  |   end subroutine read
 | 
					
						
							|  |  |  | end module readwav
 |