motifs Program

Uses

  • program~~motifs~~UsesGraph program~motifs motifs module~gm_instruments GM_instruments program~motifs->module~gm_instruments module~midi_control_changes MIDI_control_changes program~motifs->module~midi_control_changes module~midi_file_class MIDI_file_class program~motifs->module~midi_file_class module~music music program~motifs->module~music iso_fortran_env iso_fortran_env module~midi_file_class->iso_fortran_env module~utilities utilities module~midi_file_class->module~utilities module~music->iso_fortran_env module~music_common music_common module~music->module~music_common module~music->module~utilities module~utilities->iso_fortran_env

An example mixing Dmitri Shostakovich's DSCH motif and BACH motif, with four musical tracks.


Calls

program~~motifs~~CallsGraph program~motifs motifs proc~control_change MIDI_file%Control_Change program~motifs->proc~control_change proc~dotted dotted program~motifs->proc~dotted proc~end_of_track MIDI_file%end_of_track program~motifs->proc~end_of_track proc~get_name MIDI_file%get_name program~motifs->proc~get_name proc~midi_note MIDI_Note program~motifs->proc~midi_note proc~new MIDI_file%new program~motifs->proc~new proc~play_broken_chord MIDI_file%play_broken_chord program~motifs->proc~play_broken_chord proc~play_chord MIDI_file%play_chord program~motifs->proc~play_chord proc~play_note MIDI_file%play_note program~motifs->proc~play_note proc~program_change MIDI_file%Program_Change program~motifs->proc~program_change proc~track_header MIDI_file%track_header program~motifs->proc~track_header proc~checked_int8 checked_int8 proc~control_change->proc~checked_int8 proc~delta_time MIDI_file%delta_time proc~control_change->proc~delta_time proc~end_of_track->proc~delta_time proc~write_track_size MIDI_file%write_track_size proc~end_of_track->proc~write_track_size proc~new->proc~end_of_track proc~new->proc~track_header proc~checked_int16 checked_int16 proc~new->proc~checked_int16 proc~checked_int32 checked_int32 proc~new->proc~checked_int32 proc~new->proc~checked_int8 proc~copyright_notice MIDI_file%copyright_notice proc~new->proc~copyright_notice proc~init_formidi MIDI_file%init_formidi proc~new->proc~init_formidi proc~set_tempo MIDI_file%set_tempo proc~new->proc~set_tempo proc~set_time_signature MIDI_file%set_time_signature proc~new->proc~set_time_signature proc~text_event MIDI_file%text_event proc~new->proc~text_event proc~play_broken_chord->proc~checked_int32 proc~play_broken_chord->proc~delta_time proc~note_off MIDI_file%Note_OFF proc~play_broken_chord->proc~note_off proc~note_on MIDI_file%Note_ON proc~play_broken_chord->proc~note_on proc~play_chord->proc~checked_int32 proc~play_chord->proc~delta_time proc~play_chord->proc~note_off proc~play_chord->proc~note_on proc~play_note->proc~checked_int32 proc~play_note->proc~delta_time proc~play_note->proc~note_off proc~play_note->proc~note_on proc~program_change->proc~checked_int8 proc~program_change->proc~delta_time proc~sequence_track_name MIDI_file%sequence_track_name proc~track_header->proc~sequence_track_name proc~track_header->proc~text_event proc~write_string MIDI_file%write_string proc~copyright_notice->proc~write_string proc~delta_time->proc~checked_int32 proc~write_variable_length_quantity MIDI_file%write_variable_length_quantity proc~delta_time->proc~write_variable_length_quantity proc~note_off->proc~checked_int8 proc~note_on->proc~checked_int8 proc~sequence_track_name->proc~write_string proc~set_tempo->proc~checked_int32 proc~set_tempo->proc~delta_time proc~set_time_signature->proc~checked_int8 proc~set_time_signature->proc~delta_time proc~text_event->proc~write_string proc~write_string->proc~checked_int8 proc~write_string->proc~delta_time proc~write_string->proc~write_variable_length_quantity proc~variable_length_quantity variable_length_quantity proc~write_variable_length_quantity->proc~variable_length_quantity

Variables

Type Attributes Name Initial
integer :: BACH(4)
integer :: DSCH(4)
integer, parameter :: arpeggio(1:6) = [0, 7, 12, 7, 12, 7]
integer :: i
integer :: j
integer :: k
type(MIDI_file) :: midi
integer :: n
integer, parameter :: octave = 12
integer :: scale(6)
integer :: v
integer :: values(1:6)

Source Code

program motifs
    use MIDI_file_class
    use music
    use MIDI_control_changes, only: Effects_1_Depth, Effects_3_Depth, Pan
    ! Contains the list of General MIDI 128 instruments and 47 percussions:
    use GM_instruments

    implicit none
    type(MIDI_file) :: midi
    integer, parameter :: arpeggio(1:6) = [ 0, 7, 12, 7, 12, 7 ]
    integer, parameter :: octave=12
    integer :: values(1:6)
    integer :: i, j, k, n, v
    integer :: BACH(4)
    integer :: DSCH(4)
    integer :: scale(6)

    ! BACH and DSCH are in German notation:
    BACH(1) = MIDI_Note("Bb2")  ! B
    BACH(2) = MIDI_Note("A2")   ! A
    BACH(3) = MIDI_Note("C3")   ! C
    BACH(4) = MIDI_Note("B2")   ! H

    DSCH(1) = MIDI_Note("D3")   ! D
    DSCH(2) = MIDI_Note("Eb3")  ! Es
    DSCH(3) = MIDI_Note("C3")   ! C
    DSCH(4) = MIDI_Note("B2")   ! H

    ! The total value of the arpeggio is a whole note (four quarter notes):
    values(1) = dotted(eighth_note)
    values(2) = eighth_note
    values(3) = dotted(eighth_note)
    values(4) = eighth_note
    values(5) = dotted(eighth_note)
    values(6) = dotted(eighth_note)

    ! A scale composed of all notes in the two motifs:
    scale = [ MIDI_Note("A2"), MIDI_Note("Bb2"), MIDI_Note("B2"), MIDI_Note("C3"), MIDI_Note("D3"), MIDI_Note("Eb3")]

    ! Create a file with 5 tracks (including the metadata track):
    ! A quarter note will last 375000 µs = 0.375 s => tempo = 160 bpm
    ! The time signature is 4/4 (default value).
    call midi%new("motifs.mid", format=1, tracks=5, divisions=quarter_note, tempo=375000)

    ! (1) A bass track on MIDI channel 0
    call midi%track_header(track_name="bass")
    ! Chorus:
    call midi%Control_Change(channel=0, type=Effects_3_Depth, ctl_value=32)
    ! Panning, slightly on the left (center is 64):
    call midi%Control_Change(channel=0, type=Pan, ctl_value=44)
    ! Choosing the instrument:
    call midi%Program_Change(channel=0, instrument=Electric_Bass_finger)

    ! The four musical tracks will use the same loops, to follow the structure
    ! of the song and stay synchronized, using silence when necessary.

    ! Intro
    ! Silence (velocity=0):
    call midi%play_note(channel=0, note=0, velocity=0, value=whole_note)
    ! Playing the scale:
    do i = 1, size(scale)
        call midi%play_note(channel=0, note=scale(i), velocity=f_level, value=half_note)
    end do

    do k = 1, 2
        ! Chorus
        do j = 1, 4
            do i = 1, size(DSCH)
                ! Duration = whole note
                call midi%play_broken_chord(channel=0, note=DSCH(i), chord=arpeggio, velocity=ff_level, values=values)
            end do
        end do

        ! Verse
        do j = 1, 4
            do i = 1, size(BACH)
                ! Duration = whole note
                call midi%play_broken_chord(channel=0, note=BACH(i), chord=arpeggio, velocity=ff_level, values=values)
            end do
        end do
    end do

    ! Outro
    ! Reverb:
    call midi%Control_Change(channel=0, type=Effects_1_Depth, ctl_value=127)
    do i = 1, size(scale)
        ! With decreasing level and increasing duration:
        call midi%play_chord(channel=0, note=scale(i), chord=MAJOR_CHORD, &
                           & velocity=int(ff_level/(1.2**i)), value=int(half_note*1.2**i))
    end do

    call midi%end_of_track()

    !---------------------------------------------------------------------------
    ! (2) A synth track on MIDI channel 1
    call midi%track_header(track_name="synth")
    ! Reverb:
    call midi%Control_Change(channel=1, type=Effects_1_Depth, ctl_value=64)
    ! Panning, slightly on the right (center is 64):
    call midi%Control_Change(channel=1, type=Pan, ctl_value=80)
    ! Choosing the instrument:
    call midi%Program_Change(channel=1, instrument=Pad_2_warm)

    ! Intro
    ! Silence:
    call midi%play_note(channel=1, note=0, velocity=0, value=whole_note)
    ! Playing the scale:
    do i = 1, size(scale)
        call midi%play_chord(channel=1, note=scale(i), chord=MAJOR_CHORD, velocity=f_level, value=half_note)
    end do

    do k = 1, 2
        ! Chorus
        do j = 1, 4
            do i = 1, size(DSCH)
                call midi%play_chord(channel=1, note=DSCH(i), chord=MAJOR_CHORD, velocity=ff_level, value=whole_note)
            end do
        end do

        ! Verse
        do j = 1, 4
            do i = 1, size(BACH)
                call midi%play_chord(channel=1, note=BACH(i), chord=MAJOR_CHORD, velocity=ff_level, value=whole_note)
            end do
        end do
    end do

    call midi%end_of_track()

    !---------------------------------------------------------------------------
    ! (3) A drums track
    call midi%track_header(track_name="drums")
    ! Reverb:
    call midi%Control_Change(channel=drums, type=Effects_1_Depth, ctl_value=127)
    ! Panning (center is 64):
    call midi%Control_Change(channel=drums, type=Pan, ctl_value=64)

    ! Intro
    do i = 1, size(scale)+2
        call midi%play_note(channel=drums, note=Side_Stick, velocity=ff_level, value=half_note)
    end do

    do k = 1, 2
        ! Chorus
        do j = 1, 4
            ! The total value of the broken chord is a whole note (four quarter notes):
            do i = 1, size(DSCH)
                call midi%play_note(channel=drums, note=Bass_Drum_1,    velocity=ffff_level, &
                                  & value=quarter_note)
                call midi%play_note(channel=drums, note=Closed_Hi_Hat,  velocity=ffff_level, &
                                  & value=quarter_note)
                call midi%play_note(channel=drums, note=Bass_Drum_1,    velocity=ffff_level, &
                                  & value=quarter_note)
                call midi%play_note(channel=drums, note=Acoustic_Snare, velocity=ffff_level, &
                                  & value=quarter_note)
            end do
        end do

        ! Verse
        do j = 1, 4
            do i = 1, size(BACH)
                call midi%play_note(channel=drums, note=Bass_Drum_1,   velocity=ffff_level, value=quarter_note)
                call midi%play_note(channel=drums, note=Closed_Hi_Hat, velocity=ffff_level, value=quarter_note)
                call midi%play_note(channel=drums, note=Bass_Drum_1,   velocity=ffff_level, value=quarter_note)
                call midi%play_note(channel=drums, note=Closed_Hi_Hat, velocity=ffff_level, value=quarter_note)
            end do
        end do
    end do

    call midi%end_of_track()

    !---------------------------------------------------------------------------
    ! (4) A guitar track on MIDI channel 2
    call midi%track_header(track_name="guitar")
    ! Reverb:
    call midi%Control_Change(channel=2, type=Effects_1_Depth, ctl_value=127)
    ! Panning, slightly on the left (center is 64):
    call midi%Control_Change(channel=2, type=Pan, ctl_value=32)
    ! Choosing the instrument:
    call midi%Program_Change(channel=2, instrument=Acoustic_Guitar_nylon)

    ! Intro
    ! Silence:
    call midi%play_note(channel=2, note=0, velocity=0, value=whole_note)
    ! Silence:
    do i = 1, size(scale)
        call midi%play_note(channel=2, note=0, velocity=0, value=half_note)
    end do

    ! Base note:
    n = DSCH(1)+octave
    ! fifth=+7, fourth=+5, 7th=+10, octave=+12
    do k = 1, 2
        do j = 1, 4*4
            if ((k == 1).and.(j<=8)) then
                v = 0   ! silence at the beginning of the song
            else
                v = f_level-4
            end if
            call midi%play_note(channel=2, note=n+7, velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+5, velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+7, velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+5, velocity=v, value=quarter_note)
        end do

        do j = 1, 4
            call midi%play_note(channel=2, note=n+7,  velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+10, velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+7,  velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+10, velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+12, velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+10, velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+7,  velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+12, velocity=v, value=quarter_note)
        end do

        do j = 1, 4
            call midi%play_note(channel=2, note=n+7,  velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+10, velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+7,  velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+10, velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+12, velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+10, velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+7,  velocity=v, value=quarter_note)
            call midi%play_note(channel=2, note=n+5,  velocity=v, value=quarter_note)
        end do
    end do

    call midi%end_of_track()

    !---------------------------------------------------------------------------
    call midi%close()

    print *,"You can now play the file ", midi%get_name()

end program motifs