Musica e suoni in ambiente Pascal

(Nota di redazione: questo articolo è molto vecchio. All’epoca avevo 15 anni. Proseguendo nella lettura potresti sentire il bisogno di strapparti i bulbi oculari. Buona lettura.)

Nella libreria crt del Pascal esistono dei comandi speciali che spesso non si insegnano nei licei o nelle scuole, perchè “non utili all’appredimento del linguaggio”. Cioè, non solo ci tocca imparare questo linguaggio proprietario di merda, ma pure manco lo sfruttiamo.

Dato che ho tempo per cazzeggiare, ecco qui ciò che ho trovato:

  1. SOUND(hz); produce un suono alla frequenza inserita
  2. DELAY(time); produce un ritardo in millisecondi
  3. NOSOUND; interrompe il suono (indispensabile!)

Questi tre comandi si utilizzano in successione così elencati: con il primo lo speaker emette una frequenza (ad esempio 440 per un LA perfetto) con il secondo si prolunga la frequenza (ad esempio 1000 per un secondo) e con il terzo si interrompe la nota.

Un utilizzo molto interessante di queste nozioni può essere quello di far eseguire dal nostro Turbo Pascal (aka Masturbo Pasquale) una parte dell’Inno alla Gioia di Beehtoven, ad esempio…

Listato:
PROGRAM B; USES CRT;
VAR X,I:INTEGER;
PROCEDURE A(X:INTEGER);
BEGIN
SOUND(X);
DELAY(1000);
NOSOUND;
END;
BEGIN
CLRSCR;
WRITE('Stai ascoltanto l''Inno alla Gioia di Beethoven.');
FOR I:=0 TO 1 DO BEGIN
A(330);A(330);A(349);A(392);
A(392);A(349);A(330);A(294);
A(262);A(262);A(294);A(330);
IF(I=0)THEN BEGIN
A(330);A(294);A(294);
DELAY(1000);
END
ELSE BEGIN
A(294);A(262);A(262);
END;
NOSOUND;
END;
CLRSCR;
WRITE('Grazie per aver ascoltato Beethoven.');
READLN;
END.

Qui sopra abbiamo creato una procedura A(x), che richiama al suo interno SOUND(x), DELAY(200) e NOSOUND; esclusivamente per non ripetere i tre comandi di volta in volta.

La frequenza delle note

Per creare la scala di do che ci è servita per comporre il brano superiore, abbiamo soltanto utilizzato questo schema di note/frequenze da inserire nel comando SOUND()

Do 262 Do# 277 Re 294 Re# 311 Mi 330 Fa 349
Fa# 370 Sol 392 Sol# 415 La 440 La# 466 Si 49

Quindi, in conclusione, se vogliamo far emettere dalla macchina un LA per 2 secondi faremo:

begin
SOUND(440);
DELAY(2000);
NOSOUND;
end;

Tutto questo perchè il LA è rappresentato da un suono con frequenza 440 hertz, e due secondi sono rappresentati da un delay di 2000 millisecondi. Insomma, capito no?

Dunque è tutto, buona navigazione!

Orologio analogico in Turbo Pascal

Oggi vi presenteremo un programma in grado di simulare un orologio digitale. Per una piccola anteprima cliccate sull’immagine.

Immagine orologio offerta dal Reyboz Blog

Il file è disponibile gratuitamente da qui:

Analizziamo il programma

All’inizio vedremo una videata nera con una serie di numeri da zero a venti, e ci verrà chiesto di inserire il numero che per noi è al centro dello schermo. Il tutto verrà ripetuto finche non si inserisce uno di quei numeri da 0 a 20:

...
CLRSCR; (* Pulisci schermo *)
CC:=-1;
REPEAT (* Punto di ripetizione *)
FOR A:=0 TO 20 DO (* Ripeti 20 volte per scrivere 20 numeri *)
BEGIN
CC:=CC+1;
WRITE(CC:2,' ');
END; (* Fine ripetizione *)
WRITELN;
WRITELN;
WRITE('Scrivi il numero al centro del monitor: ');
READ(CC); (* L'utente inserisce CC *)
CLRSCR;
UNTIL (CC <= 20)AND(CC >= 0);
(* Da qui torna a 'repeat' se CC non è tra 0 e 20 *)
...

A questo punto il programma avrà come input questa fantomatica variabile CC. Servirà per sapere dove posizionare in futuro l’orologio, in modo che sembri al centro. Ma passiamo al punto in cui ci chiederà di inserire ore e minuti attuali, rappresentati da variabili intere HH e MM. Anche qui se l’ora inserita non sarà tra 0 e 24, e i minuti tra 0 e 60, il programma non andrà avanti e tornerà da capo:

...
REPEAT (* Punto di ritorno Until *)
IF(HH > 23)OR(MM > 59)OR(HH < 0)OR(MM < 0) THEN
WRITE('Errore formato. ');
WRITE('Scrivi l''ora attuale (HH MM): ');
READ(HH,MM); (* L'utente inserisce ora e minuti *)
CLRSCR; (* Ripulisci schermo *)
UNTIL (HH <= 23)AND(MM <= 59)AND(HH >= 0)AND(MM >=0);
...

Inseriti ore e minuti, siamo pronti a produrre l’orologio. Per fare ciò creeremo un’ulteriore variabile SS che conterrà i secondi, calcolati tramite uno script che rallenta di (17)*(17) mila volte il programma, avvicinandosi di molto ad un secondo reale:

...
T:=1700; (* T vale 1700 *)
WHILE(0 = 0)DO (* Inizia un ciclo infinito *)
BEGIN
SS:=SS+1; (* Aggiungi un secondo *)
FOR C:=0 TO T DO (* Inizio rallentamento *)
BEGIN FOR D:=0 TO T DO
BEGIN
END;
END; (* Fine rallentamento *)
CLRSCR;
IF(SS = 60)THEN (* Se ci sono 60 secondi crea un minuto *)
BEGIN
SS:=0;
MM:=MM+1;
END;
IF(MM = 60)THEN (* Se ci sono 60 min. crea un ora *)
BEGIN
SS:=0;
MM:=0;
HH:=HH+1;
END;
WRITE('Per interrompere: ctrl+pausa');
(* A questo punto a seconda di CC... *)
FOR A:=0 TO CC DO WRITELN; (* Crea CC spazi vuoti in verticale... *)
FOR B:=0 TO CC DO WRITE('   '); (* ...e in orizzontale *)
(* Ora scrivi ora, minuti, secondi *)
WRITE(' ',S1,HH:2,': ',MM:2,': ',SS:2,S2);
END;
...

Buona navigazione dallo staff.

Turbo Pascal di base

Ecco finalmente un riassunto schematico su funzioni condizioni strutture e operatori del Turbo Pascal, il famoso compilatore e esecutore di listati.

Turbo Pascal - Reyboz Blog

Download

Capiamo il linguaggio

Piccolo esempio

Program Potenza; Uses crt;
Var x,y: integer;
Begin
clrscr;
write('Inserisci qui un numero: ');
read(x);
y:=x*x;
writeln('Il quadrato di ',x,' è ,y);
readln
End.

Parti essenziali

  • Program per dare un nome al programma.
  • Uses per determinare la libreria (non lo cambiamo)
  • Var per nominare una lista di variabili e definirne il tipo
  • Begin per iniziare
  • End. per terminare.

Regole di scrittura essenziale

  • Ogni comando deve terminare con punto e virgola, il Begin fa eccezione.
  • L’End finale termina sempre in punto.
  • Prima di un Else non ci va mai il punto e virgola.

Funzioni predefinite

Legate a scrittura o lettura di una variabile

  • Clrscr; cancella l’output corrente
  • Delay(x); interrompe per x millisecondi il programma (solo in ambienti msdos)
  • Write(x); scrive x
  • Writeln(x); scrive x e va a capo
  • Writeln; scrive una riga vuota
  • Read(x); legge x da tastiera premendo invio
  • Readln(x); legge x da tastiera premendo invio e va a capo
  • Readln; crea una pausa che termina premendo invio
  • Sound(x); emette un bip alla frequenza inserita (occorre terminarlo con nosound;)
  • Nosound; interrompe il beep
  • X=Readkey; legge x da tastiera

Legate a calcoli con numeri interi

  • x=Sqr(x); calcola il quadrato di x
  • x=Chr(x); trova il carattere ASCII corrispondente a x
  • x=Sqrt(x); calcola il radicale di x
  • x=(x)div(y) esegue la divisione tra x e y
  • x=(x)mod(y) calcola il resto intero tra x e y

Legati a calcoli con numeri reali

  • x=In(x); calcola il logaritmo naturale di x
  • x=Int(x); calcola restituendo la parte intera di x
  • x=Sin(x); calcola il seno di x
  • x=Abs(x); calcola il modulo di x
  • x=Cos(x); calcola il coseno di x
  • x=Round(x); calcola approssimando ad intero x

Legati a calcoli con stringhe di testo

  • x=Lenght(x); conta il numero di caratteri di x

Calcoli con un carattere

  • x=Ord(x); individua il numero corrispondente a x come carattere

Condizioni logiche

Servono per definire un controllo tra più variabili.

  • (a<b) a minore di b
  • (a>b) a maggiore di b
  • (a<=b) a minore o uguale a b
  • (a>=b) a maggiore o uguale a b
  • (a<>b) a diverso da b
  • (a=b) a uguale a b

Operazioni logiche

Servono per definire un controllo tra più condizioni logiche.

  • ()and() Verifica una congiunzione logica
  • ()not() Verifica una negazione logica
  • ()or() Verifica una disgiunzione logica
  • ()xor() Verifica una disgiunzione esclusiva logica

Strutture iterattive

Servono per ripetere un operazione a seconda dell’uso.

  • While do
    Cosa fa: Controlla una condizione e ripete un’istruzione finchè la condizione è vera
    come si presenta: While (condizioni) do begin … end
  • Repeat until
    Cosa fa: Esegue un’istruzione e la ripete fintanto che la condizione non risulta vera
    Repeat (istruzioni) until (condizioni)
  • For to do
    Cosa fa: Impone un valore iniziale e finale, ripetendo un istruzione n volte
    Come si presenta: for a to n do begin (istruzioni) end