sonify_from_array Subroutine

public subroutine sonify_from_array(signal, output_file, autocenter, downsampling, repetitions)

Convert an array of reals to a WAV file, using RATE samples per second (44,100 by default). - If your signal is not centered around zero, you can use the autocenter option. - Downsampling allows to take only each Mth sample and can be used to make a low tone higher. - The repetitions argument allows to repeat the signal N times, which can be interesting if it is too short.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in), dimension(:) :: signal
character(len=*), intent(in) :: output_file
logical, intent(in), optional :: autocenter
integer, intent(in), optional :: downsampling
integer, intent(in), optional :: repetitions

Calls

proc~~sonify_from_array~~CallsGraph proc~sonify_from_array sonify_from_array proc~close_wav_file WAV_file%close_WAV_file proc~sonify_from_array->proc~close_wav_file proc~create_wav_file WAV_file%create_WAV_file proc~sonify_from_array->proc~create_wav_file proc~get_name WAV_file%get_name proc~sonify_from_array->proc~get_name proc~mix_tracks tape_recorder%mix_tracks proc~sonify_from_array->proc~mix_tracks proc~finalize tape_recorder%finalize proc~close_wav_file->proc~finalize proc~write_normalized_data WAV_file%write_normalized_data proc~close_wav_file->proc~write_normalized_data proc~new tape_recorder%new proc~create_wav_file->proc~new proc~write_header WAV_file%write_header proc~create_wav_file->proc~write_header proc~clear_tracks tape_recorder%clear_tracks proc~new->proc~clear_tracks

Called by

proc~~sonify_from_array~~CalledByGraph proc~sonify_from_array sonify_from_array proc~sonify_from_file sonify_from_file proc~sonify_from_file->proc~sonify_from_array program~sonify sonify program~sonify->proc~sonify_from_file

Source Code

    subroutine sonify_from_array(signal, output_file, autocenter, downsampling, repetitions)
        real(wp), dimension(:), intent(in) :: signal
        character(*), intent(in)      :: output_file
        logical, intent(in), optional :: autocenter
        integer, intent(in), optional :: downsampling
        integer, intent(in), optional :: repetitions        ! Including the original
        integer :: i, step, j, sz
        real(wp) :: length, delta
        type(WAV_file) :: tape

        sz = size(signal)

        delta = 0._wp
        if (present(autocenter)) then
            ! Center the signal on 0 by subtracting its mean value:
            if (autocenter) delta = sum(signal)/sz
        end if

        if (present(downsampling)) then
            ! Downsampling factor must be >=1
            step = max(1, downsampling)
        else
            step = 1
        end if

        length = real(sz, kind=wp) / RATE
        if (present(repetitions)) then
            length = length * repetitions
        end if
        length = length /step + 0.01_wp       ! To avoid rounding problems

        ! We can now create a new WAV file:
        call tape%create_WAV_file(output_file, tracks=1, duration=length)

        j = 0
        ! The signal array index begins at 1:
        do i = 1, sz, step
            j = j + 1
            ! Track 1, sample j-1:
            tape%left (1, j-1) = signal(i) - delta
            tape%right(1, j-1) = signal(i) - delta
        end do

        ! Repeat if needed:
        if (present(repetitions)) then
            if (repetitions >= 2) then
                ! Size after subsampling:
                sz = j
                do i = 2, repetitions
                    tape%left (1, (i-1)*sz:i*sz - 1) = tape%left (1, (i-2)*sz:(i-1)*sz - 1)
                    tape%right(1, (i-1)*sz:i*sz - 1) = tape%right(1, (i-2)*sz:(i-1)*sz - 1)
                end do
            end if
        end if

        ! All tracks will be mixed on track 0.
        ! Needed even if there is only one track!
        call tape%mix_tracks()
        call tape%close_WAV_file()

        print *,"You can now play the file ", tape%get_name()
    end subroutine sonify_from_array