Fortraneries/GrafAnim/soundscope.f90

288 lines
7.8 KiB
Fortran
Raw Normal View History

2024-01-02 20:14:43 +11:00
! *****************************************************
2023-12-25 06:53:27 +11:00
!
2024-01-02 20:14:43 +11:00
! *****************************************************
2023-12-25 06:53:27 +11:00
program soundscope
use pixrgb
use utils_ga
implicit none
2024-02-07 13:22:44 +11:00
integer :: width = 800
integer :: height = 600
integer :: marge = 32
integer :: samplerate = 44100
integer :: framerate = 30
integer, parameter :: overtrig = 25200
2024-01-02 20:14:43 +11:00
2023-12-25 06:53:27 +11:00
type(t_pixrgb), allocatable :: pix(:,:)
character (len=280) :: filename
integer :: iter, foo, tx, ty
2024-01-02 20:14:43 +11:00
integer :: smppf
logical :: flagdone
2023-12-25 06:53:27 +11:00
2024-01-02 20:14:43 +11:00
smppf = samplerate / framerate
2024-02-07 13:22:44 +11:00
write(0, *) "sample rate = ", samplerate
write(0, *) "frames per second = ", framerate
write(0, *) "samples per frame = ", smppf
2023-12-25 06:53:27 +11:00
2024-01-02 20:14:43 +11:00
allocate(pix(width, height))
2024-02-07 13:22:44 +11:00
! call fill_random_gauss(pix, 65000, marge)
2024-01-02 20:14:43 +11:00
iter = 0
do
write(0, *) "----- iteration", iter, " -----"
iter = iter + 1
2024-01-06 02:50:25 +11:00
do foo=0, 100
2024-01-02 20:14:43 +11:00
tx = (marge/2) + fair_random_gauss(width-marge)
ty = (marge/2) + fair_random_gauss(height-marge)
if (is_pixel_inside(tx, ty)) then
call make_red_dot(pix, tx, ty)
endif
tx = (marge/2) + fair_random_gauss(width-marge)
ty = (marge/2) + fair_random_gauss(height-marge)
if (is_pixel_inside(tx, ty)) then
call make_blue_dot(pix, tx, ty)
endif
enddo
2023-12-25 06:53:27 +11:00
2024-01-06 02:50:25 +11:00
call dim_pix_rgb_mul(pix, 0.86)
2024-02-07 13:22:44 +11:00
foo = mod(iter/36, 3)
! print *, iter, " --> ", foo
select case(foo)
case(0)
call make_a_frame_xy(pix, smppf, flagdone)
case(1)
call make_a_frame_bargraph(pix, smppf, flagdone)
case(2)
call make_a_frame_dplot(pix, smppf, flagdone)
end select
call dessine_cadre(pix, 51000, 65000, 51000, marge)
2023-12-25 06:53:27 +11:00
write (filename, "(a,i5.5,a)") "./F/np/", iter, ".pnm"
call rgbpix_spit_as_pnm_16(pix, filename)
2024-01-02 20:14:43 +11:00
if (flagdone) then
exit
endif
2024-02-07 13:22:44 +11:00
if (iter .EQ. 360) exit
2023-12-25 06:53:27 +11:00
enddo
2024-01-02 20:14:43 +11:00
write(0, *) " [done]"
2023-12-25 06:53:27 +11:00
contains
!-- ------------------------------------------------------------------
2024-02-07 13:22:44 +11:00
!-
! This is the classic Lissajou
!-
2023-12-25 06:53:27 +11:00
2024-01-06 02:50:25 +11:00
subroutine make_a_frame_xy(image, nbdata, jobdone)
2023-12-25 06:53:27 +11:00
type(t_pixrgb), intent(inout) :: image(:,:)
integer, intent(in) :: nbdata
2024-01-02 20:14:43 +11:00
logical, intent(out) :: jobdone
integer :: idx, errcode
2023-12-25 06:53:27 +11:00
real :: vl, vr
integer :: ix, iy
2024-01-02 20:14:43 +11:00
jobdone = .FALSE.
2023-12-25 06:53:27 +11:00
do idx=0, nbdata
2024-01-02 20:14:43 +11:00
! get a sample
read(5, *, iostat=errcode) vl, vr
if (0 .NE. errcode) then
write(0, *) "iostat", errcode
jobdone = .TRUE.
exit
endif
2024-01-06 02:50:25 +11:00
! add flash !
2024-02-07 13:22:44 +11:00
if ( (idx .LT. 50) .AND. &
((abs(vl).GT.overtrig).OR.(abs(vr).GT.overtrig)) ) then
write(0,*) "overshoot in xy!"
2024-01-06 02:50:25 +11:00
call fill_random_gauss(image, 65000, marge)
2024-01-04 12:22:39 +11:00
endif
2024-01-02 20:14:43 +11:00
! scale it to the window
2024-02-07 13:22:44 +11:00
ix = int((vl/65536.9) * real(width)) + width/2
ix = width - ix
iy = int((vr/65536.9) * real(height)) + height/2
2024-01-02 20:14:43 +11:00
if (is_pixel_inside(ix, iy)) then
call make_big_dot(image, ix, iy)
endif
2023-12-25 06:53:27 +11:00
enddo
end subroutine
!-- ------------------------------------------------------------------
2024-02-07 13:22:44 +11:00
! new: Sat Jan 6 00:04:23 UTC 2024
!-
! TODO bien calculer la largeur et la position des vumetres !
!-
! Largeur utile : largeur ecran moins deux fois la marge
subroutine make_a_frame_bargraph(image, nbdata, jobdone)
type(t_pixrgb), intent(inout) :: image(:,:)
integer, intent(in) :: nbdata
logical, intent(out) :: jobdone
integer :: idx, errcode
integer :: ir, il, foo
integer :: sigma_l, sigma_r
integer :: largutil, haututil, xpos, ypos
sigma_l = 0
sigma_r = 0
do idx=0, nbdata
! get a sample
read(5, *, iostat=errcode) il, ir
if (0 .NE. errcode) then
write(0, *) "iostat =", errcode
jobdone = .TRUE.
exit
endif
sigma_l = sigma_l + abs(il)
sigma_r = sigma_r + abs(ir)
enddo
! ici on a lu tous les samples, on a la somme des abs()
write(0, *) "sigmas = ", sigma_l, sigma_r
il = sigma_l / nbdata
ir = sigma_r / nbdata
call clear_image(image, marge)
! il ne reste plus qu'à tracer la barre.
largutil = width - (marge*2)
haututil = height - (marge*2)
ypos = marge + ((il*haututil) / 32768 )
! write(0, *) "ypos = ", ypos
do xpos=1, largutil
! write(0, *) " xpos", xpos
call make_big_dot(image, xpos, ypos)
enddo
ypos = marge + ((il*haututil) / 32768 )
write(0, *) "ypos = ", ypos
do xpos=(width/2)+8, width - (marge + 8)
write(0, *) " xpos", xpos
call make_big_dot(image, xpos, ypos)
enddo
! et ma fin de la trace : une séparation au milieu.
do foo=marge+9, height-(marge+9)
image(width/2, foo - 9)%r = 65500
image(width/2, foo - 4)%r = 65500
image(width/2, foo )%r = 65500
image(width/2, foo + 4)%r = 65500
image(width/2, foo + 9)%r = 65500
enddo
end subroutine
2023-12-25 06:53:27 +11:00
2024-02-07 13:22:44 +11:00
!-- ------------------------------------------------------------------
!-
! THIS SUBROUTINE IS BOGUS !
!-
2024-01-06 02:50:25 +11:00
subroutine make_a_frame_dplot(image, nbdata, jobdone)
2024-01-04 12:22:39 +11:00
type(t_pixrgb), intent(inout) :: image(:,:)
2024-01-06 02:50:25 +11:00
integer, intent(in) :: nbdata
logical, intent(out) :: jobdone
integer :: idx, errcode
real :: vl, vr
integer :: il, ir, xpos
jobdone = .FALSE.
xpos = 1
do idx=0, nbdata
! get a sample
read(5, *, iostat=errcode) vl, vr
if (0 .NE. errcode) then
write(0, *) "iostat", errcode
jobdone = .TRUE.
exit
endif
! add flash !
if ( (idx .LT. 100) .AND. &
2024-02-07 13:22:44 +11:00
((abs(vl).GT.overtrig).OR.(abs(vr).GT.overtrig)) ) then
write(0,*) "overshoot in dplot!"
2024-01-06 02:50:25 +11:00
call fill_random_gauss(image, 65000, marge)
endif
if (xpos .LT. width) then
! scale it to the window
il = int((vl/65536.9) * real(height)) + height/2
ir = int((vr/65536.9) * real(height)) + height/2
! print *, vl, il, " | ", vr, ir
if (is_pixel_inside(xpos, il)) then
call make_big_dot(image, xpos, il)
endif
if (is_pixel_inside(xpos, ir)) then
call make_big_dot(image, xpos, ir)
endif
xpos = xpos + 1
endif
enddo
end subroutine
!-- ------------------------------------------------------------------
subroutine dessine_cadre(image, R, G, B, border)
type(t_pixrgb), intent(inout) :: image(:,:)
integer,intent(in) :: R, G, B, border
2024-01-04 12:22:39 +11:00
integer :: ix, iy, foo
2024-01-06 02:50:25 +11:00
foo = ubound(image, 2) - border
do ix=1+marge, ubound(image, 1) - border
2024-01-04 12:22:39 +11:00
image(ix, marge)%r = R
image(ix, marge)%g = G
image(ix, marge)%b = B
image(ix, foo)%r = R
image(ix, foo)%g = G
image(ix, foo)%b = B
enddo
2024-01-06 02:50:25 +11:00
foo = ubound(image, 1) - border
do iy=1+marge, ubound(image, 2)-border
2024-01-04 12:22:39 +11:00
image(marge, iy)%r = R
image(marge, iy)%g = G
image(marge, iy)%b = B
image(foo, iy)%r = R
image(foo, iy)%g = G
image(foo, iy)%b = B
enddo
end subroutine
!-- ------------------------------------------------------------------
2024-02-07 13:22:44 +11:00
!-- ------------------------------------------------------------------
2024-01-02 20:14:43 +11:00
function is_pixel_inside(ix, iy)
integer,intent(in) :: ix, iy
logical :: is_pixel_inside
is_pixel_inside = .TRUE.
if ( (ix .LT. marge) .OR. (ix .GT. width-marge) ) then
is_pixel_inside = .FALSE.
return
endif
if ( (iy .LT. marge) .OR. (iy .GT. height-marge) ) then
is_pixel_inside = .FALSE.
return
endif
2023-12-25 06:53:27 +11:00
2024-01-02 20:14:43 +11:00
end function
2023-12-25 06:53:27 +11:00
!-- ------------------------------------------------------------------
end program soundscope