!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Sergio Steffe' - Laboratorio Sperimentale di Matematica Computazionale
! Dipartimento di Matematica - Universita' di Pisa - AA 2002/2003
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
program moto1
!
!!!!!!!!!!!!!!! descrizione !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
!punto che si muove lineramente emettendo una frequenza data
!
!formato di uscita: (16bit big endian stereo PCM)
!
!!!!!!!!!!!!!!! dichiarazioni !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
IMPLICIT NONE
!
!
INTEGER,PARAMETER ::  iduemax=32767
!mi tengo sotto il minimo valore 32767 per non avere guai con l'arrotondamento
!
!
!2 pi greco
DOUBLE PRECISION pi2
!
!frequenza di campionamento
DOUBLE PRECISION  fsample
!
!velocita' del suono
DOUBLE PRECISION  csound
!
!semidistanza orecchie
DOUBLE PRECISION delta
!
!distanza della retta
DOUBLE PRECISION dretta,b
!
!velocita del punto
DOUBLE PRECISION vp
!
!coordinate del punto all'istante t
!DOUBLE PRECISION xp,yp
!
!distanze dalle orecchie
DOUBLE PRECISION dds, dsn
!
!tempi di generazione del segnale ai due orecchi
!DOUBLE PRECISION tds,tsn
!
!frequenza del suono generato
DOUBLE PRECISION freq
!
!durata totale del suono
DOUBLE PRECISION TTIME
!
!numero capionature
INTEGER NTOT
!
!ampiezza del suono generato
DOUBLE PRECISION :: amp=1.0
!
!nome del file di output
CHARACTER(len=25) FILENAME
!
!posfisso da aggiungere al nome file
CHARACTER(len=4) :: POSTF='.cdr'
!
!variabile per lettura nome file
CHARACTER(len=20) FILENAME1
!
!
!contatore principale del generatore del suono
INTEGER I
!
!istante di tempo 
DOUBLE PRECISION t
!
!segnale sonoro a ds e sn in scala arbitraria tra -1 e +1
DOUBLE PRECISION soundds,soundsn
!
!interi usati per conversioni da real a intero due bytes big little endian
INTEGER(2) iids,iisn,ii
!
!reali usati per i calcoli
DOUBLE PRECISION tt,aa,bb,cc
!
!
!!!!!!!!!!!!!! assegnazione delle variabili !!!!!!!!!!!!!!!!!!!!!!!!!!!
write(*,*)'Nome del file (max 20 char senza spazi): '
read(*,*) FILENAME1
FILENAME = FILENAME1(1:SCAN( FILENAME1,' ',.FALSE.)-1)//POSTF
write(*,*)'hai detto: ',FILENAME
!
write(*,*)'Frequenza (Hz):'
read(*,*) freq
write(*,*)'hai detto: ',freq
!
write(*,*)'Ampiezza (da 0 a 1.0):'
read(*,*) amp
write(*,*)'hai detto: ',amp
!
write(*,*)'Velocita (m/sec):'
read(*,*)vp
write(*,*)'hai detto: ',vp
!
write(*,*)'distanza della retta(m):'
read(*,*)dretta
write(*,*)'hai detto: ',dretta
!
!
!!!!!!!!!!!!!! inizio calcoli !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
!si apre il file
!REPLACE crea o cancella se esistente
!UNFORMATTED usa formato interno per salvare i dati
!DIRECT usa l'accesso ad un qualsiasi record
!RECL e' la lunghezza di ogni record (4 bytes)
!
open(unit=10,file=FILENAME,status='REPLACE',form='UNFORMATTED',access='DIRECT',RECL=4)
!
!setup delle variabili
!
pi2=8*atan(1.0)
fsample=44100.0
csound=330.0
!
delta=0.1
!
TTIME=4.0
!
!posizione iniziale del punto
b=-vp*TTIME/2.0
!
NTOT=TTIME*fsample +0.5
!
!
!loop principale
!
do I=1,NTOT
!istante di tempo
t=i
t=t/fsample
!
! al momento t il punto si trova in 
! x(t)=b+vp*t e y(t)=dretta ed ha distanza
! dds(t)=sqrt((x+dretta)^2+y^2) e dsn(t)=sqrt((x-dretta)^2+y^2) dalle orecchie.
! le onde impiegano dei tempi dds(t)/csound e dsn(t)/csound
! per arrivare agli orecchi in istanti t+tds t t+tsn
! dato t+tds si deve calcolare tds e poi dds
! dato t+tsn si deve calcolare tsn e poi dsn
! 
aa=t*csound**2+(b+delta)*vp
bb=(t*csound)**2 -(b+delta)**2 -dretta**2
cc=csound**2-vp**2
tt=(aa-sqrt(aa**2-cc*bb))/cc
dds=sqrt(dretta**2+(b+delta+vp*tt)**2)
soundds=amp*sin((tt)*pi2*freq)/dds
!
aa=t*csound**2+(b-delta)*vp
bb=(t*csound)**2 -(b-delta)**2 -dretta**2
cc=csound**2-vp**2
tt=(aa-sqrt(aa**2-cc*bb))/cc
dsn=sqrt(dretta**2+(b-delta+vp*tt)**2)
soundsn=amp*sin((tt)*pi2*freq)/dsn
!
!compressore brutto e cattivo per tenere il suono tra -1 e +1
!
IF (soundds > 1.0) THEN
soundds = 1.0
END IF
IF (soundds < -1.0) THEN
soundds = -1.0
END IF
IF (soundsn > 1.0) THEN
soundsn = 1.0
END IF
IF (soundsn < -1.0) THEN
soundsn = -1.0
END IF
!
ii=NINT(soundds*iduemax)
call MVBITS(ii,0,8,iids,8)
call MVBITS(ii,8,8,iids,0)
ii=NINT(soundsn*iduemax)
call MVBITS(ii,0,8,iisn,8)
call MVBITS(ii,8,8,iisn,0)
!
write(unit=10,rec=i) iids,iisn
!
end do	
close(unit=10)

write(*,*)'Scritti',TTIME,'secondi suono (PCM 2x16 bit big endian) nel file:',FILENAME

end program moto1
