// Main

// Prologo

0x5555523d <+0>: push rbp
0x5555523e <+1>: mov rbp,rsp
0x55555241 <+4>: sub rsp,0x30 // crea spazio nello stack per le variabili locali
0x55555245 <+8>: mov DWORD PTR [rbp-0x24],edi
0x55555248 <+11>: mov QWORD PTR [rbp-0x30],rsi

// malloc per la stringa

0x5555524c <+15>: mov edi,0xf
0x55555251 <+20>: call0x555555555070 <malloc@plt>
0x55555256 <+25>: mov QWORD PTR [rbp-0x8],rax // potrebbe essere quello che ritorna il malloc, un indirizzo, che poi viene assegnato strres

// printf

0x5555525a <+29>: lea rdi,[rip+0xda7] // stringa da passare alla printf
0x55555261 <+36>: mov eax,0x0
0x55555266 <+41>: call0x555555555050 <printf@plt>

// fgets

0x5555526b <+46>: mov rdx,QWORD PTR [rip+0x2dee] // indirizzo stdin <stdin@@GLIBC_2.2.5>
0x55555272 <+53>: lea rax,[rbp-0x17] // variabile str
0x55555276 <+57>: mov esi,0xf // parametro 15
0x5555527b <+62>: mov rdi,rax
0x5555527e <+65>: call0x555555555060 <fgets@plt> // fscanf

// printf

0x55555283 <+70>: lea rdi,[rip+0xd96] # 0x555555556020
0x5555528a <+77>: mov eax,0x0
0x5555528f <+82>: call0x555555555050 <printf@plt>

// scanf

0x55555294 <+87>: lea rax,[rbp-0x18] // variabile ch
0x55555298 <+91>: mov rsi,rax
0x5555529b <+94>: lea rdi,[rip+0xda5] //format string
0x555552a2 <+101>: mov eax,0x0
0x555552a7 <+106>: call0x555555555080 <__isoc99_scanf@plt>

// call removechar

0x555552ac <+111>: movzx eax,BYTE PTR [rbp-0x18] // da 8 bit a 32 bit inserendo 0
0x555552b0 <+115>: movsx edx,al // da 8 bit a 32 bit estendendo il segno
0x555552b3 <+118>: lea rax,[rbp-0x17] // variabile str
0x555552b7 <+122>: mov esi,edx
0x555552b9 <+124>: mov rdi,rax
0x555552bc <+127>: call0x555555555185 <removechar> // chiamata alla funzione removechar

// printf

0x555552c1 <+132>: mov QWORD PTR [rbp-0x8],rax //c'è il valore di ritorno delle funzione?
0x555552c5 <+136>: mov rax,QWORD PTR [rbp-0x8] // perchè rimetterlo in rax?
0x555552c9 <+140>: mov rsi,rax // strres
0x555552cc <+143>: lea rdi,[rip+0xd77] // format string # 0x55555555604a
0x555552d3 <+150>: mov eax,0x0
0x555552d8 <+155>: call0x555555555050 <printf@plt>

// ret

0x555552dd <+160>: mov eax,0x0
0x555552e2 <+165>: leave
0x555552e3 <+166>: ret

// removechar

// Dump of assembler code for function removechar:

// prologo

0x55555185 <+0>: push rbp
0x55555186 <+1>: mov rbp,rsp
0x55555189 <+4>: sub rsp,0x30
0x5555518d <+8>: mov QWORD PTR [rbp-0x28],rdi // rbp-0x28 indirizzo di str


0x55555191 <+12>: mov eax,esi
0x55555193 <+14>: mov BYTE PTR [rbp-0x2c],al // rbp-0x2c c'è il carattere
0x55555196 <+17>: mov DWORD PTR [rbp-0x8],0x0

// strlen

0x5555519d <+24>: mov rax,QWORD PTR [rbp-0x28] // rbp-0x28, str
0x555551a1 <+28>: mov rdi,rax
0x555551a4 <+31>: call0x555555555040 <strlen@plt>
0x555551a9 <+36>: mov DWORD PTR [rbp-0xc],eax // rbp-0xc, n

// malloc

0x555551ac <+39>: mov edi,0xf
0x555551b1 <+44>: call0x555555555070 <malloc@plt>
0x555551b6 <+49>: mov QWORD PTR [rbp-0x18],rax // rbp-0x18, strres


0x555551ba <+53>: mov DWORD PTR [rbp-0x4],0x0 // j=0
0x555551c1 <+60>: jmp 0x555555555213 <removechar+142> // salta a j<n


0x555551c3 <+62>: mov eax,DWORD PTR [rbp-0x4] // valore di i
0x555551c6 <+65>: movsxd rdx,eax // estende da 32 a 64 bit con il segno
0x555551c9 <+68>: mov rax,QWORD PTR [rbp-0x28] // indirizzo di str
0x555551cd <+72>: add rax,rdx // a cui aggiungiamo i, visto che si tratta di char
0x555551d0 <+75>: movzx eax,BYTE PTR [rax] // mette in eax il carattere iesimo
0x555551d3 <+78>: cmp BYTE PTR [rbp-0x2c],al // e lo compara a il ch passato alla funzione
0x555551d6 <+81>: je 0x55555555520f <removechar+138>

// il blocco seguente mette in OR la prima condzione negata con la seconda :
// if (str[i]!=ch && str[i]!='\0') { -> if (str[i]==ch || str[i]=='\0') {
// leggi di De Morgan , una AND di due espressioni negate diventa una OR di due espressioni non negate

0x555551d8 <+83>: mov eax,DWORD PTR [rbp-0x4]
0x555551db <+86>: movsxd rdx,eax
0x555551de <+89>: mov rax,QWORD PTR [rbp-0x28]
0x555551e2 <+93>: add rax,rdx // str + i
0x555551e5 <+96>: movzx eax,BYTE PTR [rax] // contenuto di str[i]
0x555551e8 <+99>: test al,al // confronto con il byte null
0x555551ea <+101>: je 0x55555555520f <removechar+138> // salta all'incremento di i

// blocco di costruzione della nuova stringa senza il carattere da rimuovere, copiando i caratteri dalla
// vecchia stringa

0x555551ec <+103>: mov eax,DWORD PTR [rbp-0x4] // i
0x555551ef <+106>: movsxd rdx,eax // esteso a 64 bit con segno
0x555551f2 <+109>: mov rax,QWORD PTR [rbp-0x28] // str
0x555551f6 <+113>: add rax,rdx // str + i
0x555551f9 <+116>: mov edx,DWORD PTR [rbp-0x8] // j
0x555551fc <+119>: movsxd rcx,edx // esteso a 64 bit con segno in rcx
0x555551ff <+122>: mov rdx,QWORD PTR [rbp-0x18] // strres
0x55555203 <+126>: add rdx,rcx // strres + j
0x55555206 <+129>: movzx eax,BYTE PTR [rax] // valore di str[i]
0x55555209 <+132>: mov BYTE PTR [rdx],al // in strres + j ci metto il carattere str[i]
0x5555520b <+134>: add DWORD PTR [rbp-0x8],0x1 // incremento j

// incremento di i e confronto con n

0x5555520f <+138>: add DWORD PTR [rbp-0x4],0x1 // incrementa i
0x55555213 <+142>: mov eax,DWORD PTR [rbp-0x4] // i
0x55555216 <+145>: cmp eax,DWORD PTR [rbp-0xc] // i<n
0x55555219 <+148>: jl 0x5555555551c3 <removechar+62> // se è minore torno indietro

// blocco che setta l'ultimo carattere della strres a \0

0x5555521b <+150>: mov eax,DWORD PTR [rbp-0x8]
0x5555521e <+153>: movsxd rdx,eax
0x55555221 <+156>: mov rax,QWORD PTR [rbp-0x18]
0x55555225 <+160>: add rax,rdx
0x55555228 <+163>: mov BYTE PTR [rax],0x0

// printf della strres

0x5555522b <+166>: mov rax,QWORD PTR [rbp-0x18]
0x5555522f <+170>: mov rdi,rax
0x55555232 <+173>: call0x555555555030 <puts@plt>

// ret

0x55555237 <+178>: mov rax,QWORD PTR [rbp-0x18] // in reax ci metto l'indirizzo della stringa risultato

0x5555523b <+182>: leave
0x5555523c <+183>: ret

// C Code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* removechar(char* str, char ch)
{

char* strres;
int n,i,j;
j=0;

n=strlen(str);

strres=malloc(15*sizeof(char));

for (i=0; i<n; i++) {
if (str[i]!=ch && str[i]!='\0') {
strres[j]=str[i];
j++;
}

}
strres[j]='\0';
printf("%s\n",strres);
return strres;


}


int main(int argc, char** argv) {

char str[15];
char* strres;
strres=malloc(15*sizeof(char));

printf("Inserisci la stringa : ");
fgets(str, 15, stdin);
char ch;

printf("Inserisci il carattere da rimuovere : ");
scanf("%c",&ch);

strres=removechar(str,ch);
printf("la stringa finale è %s",strres);


return 0;

}

// primi 4 byte indirizzo 0x00005555;

// prologo :

55555145 <+0>: push rbp
55555146 <+1>: mov rbp,rsp
55555149 <+4>: sub rsp,0x50 // qui crea lo spazio anche per l'array di interi

// non ho ben copreso ma potrebbe essere che mette in queste due locazioni, argc e *argv[], in effetti l'int è un DWORD, mentre l'indirizzo è un QWORD;

5555514d <+8>: mov DWORD PTR [rbp-0x44],edi
55555150 <+11>: mov QWORD PTR [rbp-0x50],rsi

// variabili intere;

55555154 <+15>: mov DWORD PTR [rbp-0xc],0xa
5555515b <+22>: mov DWORD PTR [rbp-0x8],0x0
55555162 <+29>: mov DWORD PTR [rbp-0x4],0x0
55555169 <+36>: jmp 0x5555555551ae <main+105> // qui salta al for;

// dovrebbe essere il blocco per puntare a arr[i] per poi passarlo alla scanf;

5555516b <+38>: lea rax,[rbp-0x40]
5555516f <+42>: mov edx,DWORD PTR [rbp-0x4] // mette in edx l'indice i;
55555172 <+45>: movsxd rdx,edx // da DWORD a QWORD;
55555175 <+48>: shl rdx,0x2 // questo doppio shift a sinistra trova il numero da;
55555179 <+52>: add rax,rdx // aggiungere a rax (che punta all'inizio dell'array) per puntare all'iesimo elemento di arr in memoria visto che ogni int sono 4 byte;

// la scanf che i due parametri, nell'rsi l'indirizzo di arr[i] e nel rdi il format string;

5555517c <+55>: mov rsi,rax
5555517f <+58>: lea rdi,[rip+0xe7e] # 0x555555556004
55555186 <+65>: mov eax,0x0
5555518b <+70>: call 0x555555555040 <__isoc99_scanf@plt>

// l'if per vedere se è il nuovo max e aggiornare la variabile max;

55555190 <+75>: mov eax,DWORD PTR [rbp-0x4] // questo è il valore di i;
55555193 <+78>: cdqe // qui viene convertito da eax a rax;
55555195 <+80>: mov eax,DWORD PTR [rbp+rax*4-0x40] // qui viene ricavato il valore di arr[i];
55555199 <+84>: cmp DWORD PTR [rbp-0x8],eax // se max è piu grande salta a 101 e incrementa i;
5555519c <+87>: jg 0x5555555551aa <main+101>

// se abbiamo il nuovo max;

5555519e <+89>: mov eax,DWORD PTR [rbp-0x4]
555551a1 <+92>: cdqe
555551a3 <+94>: mov eax,DWORD PTR [rbp+rax*4-0x40]
555551a7 <+98>: mov DWORD PTR [rbp-0x8],eax // viene assegnato a max il valore di arr[i]

// incremento della variabile i;

555551aa <+101>: add DWORD PTR [rbp-0x4],0x1

// for (i=0; i<n; i++), la pare della comparazione, tra rbp-0x04 che è la i, e rbp-0xc che è a quindi 10;

555551ae <+105>: mov eax,DWORD PTR [rbp-0x4]
555551b1 <+108>: cmp eax,DWORD PTR [rbp-0xc]
555551b4 <+111>: jl 0x55555555516b <main+38>

// la funzione printf che stampa il max valore dell'array;

555551b6 <+113>: mov eax,DWORD PTR [rbp-0x8]
555551b9 <+116>: mov esi,eax
555551bb <+118>: lea rdi,[rip+0xe45] // stringa printf # 0x555555556007
555551c2 <+125>: mov eax,0x0
555551c7 <+130>: call 0x555555555030 <printf@plt>

// ret;

555551cc <+135>: mov eax,0x0
555551d1 <+140>: leave
555551d2 <+141>: ret


#include <stdio.h>

int main(int argc, char** argv)
{

int arr[10];int n=10;
int i;
int max=0;

for (i=0; i<n; i++) {
scanf("%d",&arr[i]);
if (arr[i]>=max) max=arr[i];
}

printf("il massimo è %d\n:", max);
return 0;

 } 


r2 ./license_1

aaa, analisi automatica del binario

[0x004005c5]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for objc references
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.

afl, list functions

[0x004005c5]> afl
0x004004d0    1 41           entry0
0x004004a0    1 6            sym.imp.__libc_start_main
0x00400500    4 41           sym.deregister_tm_clones
0x00400530    4 57           sym.register_tm_clones
0x00400570    3 28           entry.fini0
0x00400590    4 45   -> 42   entry.init0
0x004006b0    1 2            sym.__libc_csu_fini
0x004006b4    1 9            sym._fini
0x00400640    4 101          sym.__libc_csu_init
0x004005bd    6 119          main
0x00400450    3 26           sym._init
0x004004c0    1 6            loc.imp.__gmon_start
0x00400480    1 6            sym.imp.puts
0x00400490    1 6            sym.imp.printf
0x004004b0    1 6            sym.imp.strcmp

s sym.main

V , ti permette di visualizzare il binario in diversi modi, codice assembler, ascii, debug, byte colorati

[0x004005c5]> V

ti muovi tra le varie visualizzazione con p per adnare avanti e P per tornare indietro, mentre con le frecce ti sposti nel codice, selezionando l'indirizzo dell'istuzione nella prima linea in alto;

axt [addr] find data/code references to this address
axf [addr] find data/code references from this address


KAFKA RELOADED.
Di Andrea Zhok.

Zhok è un fuoriclasse, poco da aggiungere.
Con il Green Pass sono state gettate le basi per la cittadinanza a punti.
Andrea Zhok è un filosofo e accademico italiano, professore di Antropologia filosofica e Filosofia morale presso l’Università degli Studi di Milano.

"Con gli occhi che si spegnevano K. vide ancora come, davanti al suo viso, appoggiati guancia a guancia, i signori scrutavano il momento risolutivo. «Come un cane!», disse, fu come se la vergogna gli dovesse sopravvivere."
Proviamo a fare il seguente esercizio mentale. Eliminiamo per un momento dalla discussione sulla Certificazione Verde la questione sanitaria, e proviamo a guardare all'essenza del Certificato Verde come a un precedente in via di introduzione nell'amministrazione e nella giurisprudenza italiane (e non solo).
1. Cos'è il GP nel suo nucleo formale?
Il GP è un permesso ad accedere a forme primarie di vita sociale: il lavoro innanzitutto e poi treni, aerei, palestre, teatri, biblioteche, università, ecc. ecc.
2. In cosa trova legittimazione il GP?
Il GP trova fondamento nella determinazione di un "bene superiore". Chi contribuisce a questo bene superiore - nei modi predefiniti per contribuirvi - ha titolo al GP, e con ciò all'accesso alle forme primarie di vita civile.
Siamo dunque di fronte ad un meccanismo che definisce una specie di cittadinanza sub iudice: se contribuisci al bene superiore sei un cittadino a pieno titolo, altrimenti no.
3. Chi è che decide qual è il "bene superiore"?
Semplice: il governo con il supporto dell'opinione pubblica.
4. Ma allora chi è che determina il governo?
Idealmente il voto popolare. Ma tecnicamente il voto può scegliere solo tra le opzioni disponibili, e oggi - e da qualche tempo - esse sono sostanzialmente intercambiabili. Sono intercambiabili perché per entrare nel novero delle opzioni parlamentari disponibili ciò di cui c'è primariamente bisogno è denaro, dunque le opzioni parlamentari disponibili finiscono per riflettere puramente e semplicemente gli interessi dei finanziatori, della "moneyed class". Nelle democrazie occidentali possiamo votare più o meno solo tra varianti del P.U.N.: il Partito Unico Neoliberale.
5. E chi è che determina l'opinione pubblica?
Naturalmente il sistema mediatico, statale o privato. Quello statale dipende dal governo e dunque mediatamente dalla moneyed class. Quello privato è invece alle dirette dipendenze dei medesimi detentori di capitale.
6. Qual è dunque la catena di conferimento della legittimazione di un simile meccanismo sanzionatorio?
La moneyed class, attraverso le cinghie di trasmissione del governo e dell'opinione pubblica, può determinare unilateralmente di volta in volta cosa conta come "bene superiore", e questo può essere tanto una presunta strategia di salute pubblica, che qualche altro nobilissimo intento come, per dire, la salvaguardia dell'ambiente, o l'avvenuto pagamento delle imposte dovute, o magari la lontananza da opinioni barbare e inaccettabili (inserire qui gli '-ismi' sgraditi).
7. Quale è dunque lo scenario che si affaccia con la piena implementazione di tale meccanismo?
Una volta definito il "bene superiore" cui istanze particolari, diritti, libertà o volontà individuali possono essere subordinati, l'esistenza di un "permesso di cittadinanza per meritevoli" consente di escludere i "trasgressori" con un 'clic' in remoto dalla vita sociale e dalle fonti di sostentamento. Il mancato riconoscimento della validità della propria certificazione da parte di una banca dati governativa può istantaneamente ridurre chiunque alla più completa impotenza.
Non ci vuole molta fantasia per immaginare un "malfunzionamento ad hoc" di questa abilitazione alla cittadinanza, a titolo di benevolo ammonimento a tenere la retta via.
Ma non è necessario che si prendano queste strade oblique.
Una volta definito il "bene superiore" e un tale meccanismo sanzionatorio, la condanna per la violazione non prende l'accidentata ed inefficiente via di un tribunale, che accerti se effettivamente le condizioni di punibilità ci sono o meno. No, non è necessario, perché la punizione per via amministrativa telematica è immediata, massimamente efficiente, senza processi di sorta; e starà eventualmente al condannato cercar di provare la propria innocenza (se è in grado di farlo, una volta deprivato di reddito, mobilità, ecc.).
8. Quali difese rimarrebbero a chi fosse così colpito?
Sotto queste condizioni chi mai sarebbe nelle condizioni di mettere la mano sul fuoco per qualcun altro che venisse 'obliterato' dal sistema in questo modo, con l'accusa di aver trasgredito, violato o sabotato il "bene superiore"?
Le informazioni sul trasgressore le avrebbe per definizione la banca dati governativa, dunque se dicono che qualcosa non va, avranno le loro ragioni.
A fronte di una sanzione immediata, visti i tempi impossibili di un ricorso per via giudiziaria, a chi si potrebbe rivolgere il cittadino preso di mira?
All'opposizione parlamentare?
Ai giornali?
(Volevo aggiungere “ai sindacati?”, ma poi ho pensato che anche nella fantapolitica ci sono limiti di credibilità se non si vuole scadere nel grottesco).

next [count]

    Continue to the next source line in the current (innermost) stack frame. This is similar to step, but function calls that appear within the line of code are executed without stopping. Execution stops when control reaches a different line of code at the original stack level that was executing when you gave the next command. This command is abbreviated n.

    An argument count is a repeat count, as for step.

004005ef <+50>:    mov    rax,QWORD PTR [rbp-0x10]
004005f3 <+54>:    add    rax,0x8
004005f7 <+58>:    mov    rax,QWORD PTR [rax]
004005fa <+61>:    mov    esi,0x4006da
004005ff <+66>:    mov    rdi,rax
00400602 <+69>:    call   0x4004b0 <strcmp@plt>

(gdb) b main

(gdb) run BBBB

(gdb) b *0x0000000000400602

(gdb) n

(gdb) x/10s $rsi
0x4006da:    "AAAA-Z10N-42-OK"
0x4006ea:    "Access Granted!"

la strcmp viene fatta tra i due registri rsi e rdi, e ritorna zero se contengono stringhe uguali;

ltrace ./license_1 AAAA
__libc_start_main(0x4005bd, 2, 0x7ffccebfc2d8, 0x400640 <unfinished ...>
printf("Checking License: %s\n", "AAAA"Checking License: AAAA
)                                                  = 23
strcmp("AAAA", "AAAA-Z10N-42-OK")                                                         = -45
puts("WRONG!"WRONG!
)                                                                            = 7
+++ exited (status 0) +++ 

C Code

#include <string.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
        if(argc==2) {
        printf("Checking License: %s\n", argv[1]);
        if(strcmp(argv[1], "AAAA-Z10N-42-OK")==0) {
            printf("Access Granted!\n");
        } else {
            printf("WRONG!\n");
        }
    } else {
        printf("Usage: <key>\n");
    }
    return 0;
}
 


substring.c
===========

#include <stdio.h> // librerie standard input/output

// il main ti fa inserire una stringa, poi una posizione from, primo carattere? nesimo carattere? e un numero n, cioè quanti caratteri andare a considerare per la sottostringa partendo dal from;

int substring(char *source, int from, int n, char *target) {

int length, i;

// qui si calcola la lunghezza della stringa immessa come input, scorre la stringa, carattere dopo carattere fino al byte null;

for (length=0; source[length]!='\0'; length++);

// se il from immesso è maggiore della lunghezza della stringa appena calcolata, esce fuori con un codice di errore 1;

if (from>length) {
printf("Starting index is invalid.\n");
return 1;
}

// se (from + n) è un numero maggiore della lunghezza calcolata, imposta n, al massimo n possibile, in modo da raggiungere la fine della stringa;

if ((from+n)>length) {
n = (length - from);
}

// partendo da from, per tutti gli n caratteri, copia il carattere sorgente nella stringa target;

for (i=0; i target[i]=source[from+i];
}

// finalizza la stringa target con il byte null;


target[i]='\0';

return 0;

}


int main(int argc,char *argv[]) {

char str[100], targetString[100];
int from, n;

printf("Enter any string:");

// la funzione gets è una funzione non sicura, andrebbe usata la funziona fscanf;

gets(str);

printf("Enter from index (count from 0): ");
scanf("%d",&from);

printf("Enter number of characters: ");
scanf("%d",&n);

// se la funzione substring ritorna un valore 0, stampa la sottostringa estratta dalla stringa immessa;

if (substring(str, from, n, targetString) == 0) {
printf("Substring is: %s\n",targetString);
}

return 0;

}






















p={Saw.ar(SinOsc.kr(30,0,440,440),mul:0.2)+AY.ar(SinOsc.kr(1200,0,713,713),mul:0.5);}.plot(0.01);

(
{
 var snd,cutoff;
 snd=Saw.ar(SinOsc.kr(30,0,440,440),mul:0.2)+AY.ar(SinOsc.kr(1200,0,713,713),mul:0.5);
 cutoff=Saw.kr(50,0.3,0.3)+PinkNoise.kr(0.1);
 snd=CombN.ar(snd,0.01,XLine.kr(0.00713, 1, 140),0.2);
 snd=RLPF.ar(snd,713*cutoff,0.2);
 snd!2;
}.plot(0.1);
)

il suono principale nasce dalla sovrapposizione tra un segnale a dente di sega modulato in frequenza da una sinusoide e il suono generato dal chip sonoro AY, modulato in frequenza sempre da una sinusoide;

la cutoff del Filtro Passa Basso Risonante RLPF è modulata da un segnale di controllo che è dato dalla somma tra un segnale a dente di sega e un segnale generato da un generatore di rumore rosa la cui ampiezza è moltiplicata per 0.1;

il delaytime, tempo di ritardo, della linea di ritardo del Filtro a Pettine CombN senza interpolazione è modulato da un generatore di curva esponenziale, che in 140 secondi passa dal valore 0.00713 al valore 1; il suono fatto passare in questa linea di ritardo subisce una trasformazione a livello timbrico, dovuta a cancellazione e rafforzamento di diverse armoniche; lo spettro armonico del segnale risultante assume la forma di un pettine; il passaggio attraverso questo Filtro produce un carattere metallico nel timbro finale del suono;






s.boot;

p={RLPF.ar(Pulse.ar([11, 13]), LFNoise1.ar([3, 7], 200, 300), 0.01)*0.1}.plot;
play({RLPF.ar(Pulse.ar([11, 13]), LFNoise1.ar([3, 7], 200, 300), 0.01)*0.1})





















qui abbiamo un RLPF, un filtro passa basso risonante che intercetta due Pulse a bassa frequenza, e CutOff modulato da un UGen LFNoise1 che genera valori random interpolati linearmente a un rate dato dalla frequenza; in questo caso sono due le Ugen in gioco; normalmente l'LFNoise1 genera valori random tra -1 e 1, in questo caso tra 100 e 500; l'rq del filtro è impostato a 0.01, sarebbe il reciproco di q; q è dato dal rapporto tra la CutOff e la larghezza di banda; in questo caso, minore è il valore di rq e più risonanza avra il filtro; il tutto è moltiplicato per 0.1 per attenuare l'ampiezza del segnale in uscita;

RLPF.ar(in: 0.0, freq: 440.0, rq: 1.0, mul: 1.0, add: 0.0)

RLPF.scopeResponse;
























(
{
GVerb.ar((
{
var burstEnv, att = 0, dec = 0.001;
var burst, delayTime, delayDecay = 0.1;
var midiPitch = 37; // A 440
delayTime = midiPitch.midicps.reciprocal;

burstEnv = EnvGen.kr(Env.perc(att, dec), gate: PinkNoise.kr(1/delayDecay));
burst = PinkNoise.ar(burstEnv);
CombL.ar(burst, delayTime, delayTime,delayDecay, add: burst);
}
),270,30,0.7,drylevel:0.5)
}.play
)

p={LFNoise1.kr(freq: 500.0, mul: 1.0, add: 0.0)}.plot(5);





















qui abbiamo un segnale PinkNoise che viene fatto passare attraverso una linea di ritardo a pettine, Comb Filter, con interpolazione lineare; il segnale passando attraverso questa linea di ritardo e subendo delle inversioni di fase per diverse frequenze del suo spettro, una volta sommato al segnale originale produce questo spettro a pettine dovuto alla sovrapposizione del segnale diretto e alla copia del segnale leggermente ritardata e quindi alla cancellazione e il rinforzo di diverse frequenze; la somma tra i due timbri produce quindi rinforzi e annullamenti periodici nell'ampiezza dello spettro passante; il trattamento fornito dal Comb Filter aggiunge al segnale passante una severa componente metallica; l'ampiezza del segnale PinkNoise è modulata da un inviluppo percussivo attivato attraverso il gate da un altro segnale PinkNoise di controllo; il tutto è fatto passare all'interno di una Ugen di riverbero;


p={PinkNoise.ar(10)}.plot;




















i = Image.fromWindow(p.parent, p.interactionView.bounds);
i.write("~/Desktop/pinknoise.png".standardizePath);
i.free




Reverse Engineering SCCode : «Kepler 22-b atmosphere» by vividsnow




(
fork {   
    Ndef(\ttwnd).play; //(d,2,addAction:\addToHead);
    loop {
        var seed = thisThread.randSeed = 100000000.rand.debug('seed');
        Ndef(\ttwnd, {
            var freq = [20, 7500];
            Splay.ar(
                {
                    var bands = 2.rrand(10);
                    var sig = { [BPF,RLPF,RHPF].choose.ar(
                        LFNoise2.ar(freq[0].rrand(freq[1]), LFNoise2.kr(0.1.exprand(10))),
                        Array.rand(bands, freq[0], freq[1]),
                        Array.rand(bands, 0.2, 1.8)
                    ).mean } ! 2;
                    Rotate2.ar(sig[0], sig[1], LFSaw.kr(0.1.exprand(10)));
                } ! 4.rrand(6).debug('source'), // creazione dell'array da passare a Splay
                                0.5.rrand(1) // spread dell'Splay
            );
        }).fadeTime_(1.rrand(4.0)); // fadeTime randomico
        10.0.rrand(40).debug('wait(bts)').wait;
    }
}
)

Struttura del codice, un loop interno a una Routine;
qui una versione semplificata;

(

{

loop {   
    "1*********".postln;
    1.0.wait;   
    "2*********".postln;
    1.0.wait;   
    "3*********".postln;
    1.0.wait;   
    "4*********".postln;
    1.0.wait;   
}
   

}.fork;    

)

UGen :

Ndef è una definizione di un Nodo Proxy;

Ndef registra i Synth attraverso un nome chiave. Tutti gli accessi ai Synth registrati attraverso l'Ndef avvengono tramite quel nome chiave. I Synth registrati possono essere sostituiti con altri Synth durante la riproduzione. I Synth si dissolvono e vengono sostituiti automaticamente e il tempo di sostituzione può essere quantificato.

Ndef è un riferimento in un Proxy, costituisce un'alternativa al ProxySpace. Tutti i metodi sono ereditati da NodeProxy.


thisThread.randSeed = 100000000.rand.debug('seed'); il seed, il seme della distribuzione randomica del thread;


Splay spalma sui canali stereo un array di canali,

Splay.arr(inArray, spread: 1, level: 1, center: 0.0, levelComp: true)

spread = 0, tutti i canali finiscono al centro, 1 massima diffusione, immagino parli del pan?


[BPF,RLPF,RHPF].choose sceglie ogni volta il tipo di filtro, passa band, passa basso risonante, passa alto risonante;


LFNoise2 generatore di rumore, genera valori random, interpolati quadraticamente,

Interpolazione. L'interpolazione consiste nel processo utile a determinare la "migliore" stima dei valori di una funzione f(x) quando ci sono a disposizione solo un numero finito di punti noti. L'Interpolazione lineare può introdurre notevoli errori nella stima dei valori della funzione per l'assenza di curvatura. Ma avendo a disposizione tre punti è possibile introdurre una curvatura del secondo ordine (parabola) per interpolare meglio i dati;

f2(x)=a0+a1x+a2x^2

LFNoise2.ar(freq: 500.0, mul: 1.0, add: 0.0)

Analisi Codice :

Splay.ar(
                {
                    var bands = 2.rrand(10);
                    var sig = { [BPF,RLPF,RHPF].choose.ar(
                        LFNoise2.ar(freq[0].rrand(freq[1]), LFNoise2.kr(0.1.exprand(10))),
                        Array.rand(bands, freq[0], freq[1]),
                        Array.rand(bands, 0.2, 1.8)
                    ).mean } ! 2;
                    Rotate2.ar(sig[0], sig[1], LFSaw.kr(0.1.exprand(10)));
                } ! 4.rrand(6).debug('source'), // creazione dell'array da passare a Splay
                                0.5.rrand(1) // spread dell'Splay
            )


viene prima scelto randomicamente il numero di bands;
il segnale viene creato facendo passare attraverso un filtro (BPF, RLPF o RHPF) un generatore di rumore a interpolazione quadratica

RLPF.ar(in: 0.0, freq: 440.0, rq: 1.0, mul: 1.0, add: 0.0)

in : LFNoise2.ar
freq : Array.rand(bands, freq[0], freq[1])

Array.rand(size, minVal, maxVal) // quindi qui avviene un'espansionzione multicanale a seconda del numero scelto per bands

rq : Array.rand(bands, 0.2, 1.8), la frequenza di risonanza; il reciproco di Q (bandwidth/cutoffFreq)

dopo di che interviene .mean che

collassa tutti i canali su un canale e poi il !2 che li espande su due canali;

{(SinOsc.ar(440)!2).mean}.plot  // verifica del funzionamento di .mean
{(SinOsc.ar(440)!2)}.plot
{(SinOsc.ar(440)!2).mean}.play
{(SinOsc.ar(440)!2)}.play

i due segnali sig[0] e sig[1] vengono passati a Rotate2

Rotate2 prende questi due segnali, in questo caso i due canali stereo, e li ruota spazialmente, in base a un angolo che in questo caso è fornito dall'output dell'UGen LFSaw, che è un oscillatore "dente di sega" non limitato in banda;

! 4.rrand(6).debug('source'); // creazione dell'array da passare a Splay, da 4 a 6 elementi;

che prende questo array di canali e li spalma su i due canali stereo;


0.1.exprand(10); genera valori random da 0.1 a 10 con probabilità esponenziali; dall'osservazione sembrano più probabili i valori bassi; in effetti dal grafico, sono più probabili i valori bassi;




rrand funzione che serve a generare valori random;

1.rrand(4.0) random da 1 a 4

wait(bts) è una stringa di debug






Type the following command to see IPv4 port(s), enter:
# lsof -Pnl +M -i4
Type the following command to see IPv6 listing port(s), enter:
# lsof -Pnl +M -i6

• -P : This option inhibits the conversion of port numbers to port names for network files. Inhibiting the conversion may make lsof run a little faster. It is also useful when port name lookup is not working properly.
• -n : This option inhibits the conversion of network numbers to host names for network files. Inhibiting conversion may make lsof run faster. It is also useful when host name lookup is not working properly.
• -l : This option inhibits the conversion of user ID numbers to login names. It is also useful when login name lookup is working improperly or slowly.
• +M : Enables the reporting of portmapper registrations for local TCP and UDP ports.
• -i4 : IPv4 listing only
• -i6 : IPv6 listing only

Type the command as follows:
# netstat -tulpn
OR
# netstat -npl

$ cat /etc/services
$ grep 110 /etc/services
$ less /etc/services

https://www.cyberciti.biz/faq/find-out-which-service-listening-specific-port/


// 18
// Nathaniel Virgo
(
play{
    p = PinkNoise.ar(1!2);
    BRF.ar(
        p + Blip.ar(p+2,400),
        150,
        2,
        0.1
    )
    +
    LPF.ar( FreeVerb2.ar( *LPF.ar( p + 0.2 * Dust.ar( 0.1 ), 60) ++ [ 1, 1, 0.2, 1e4 ]).tanh, 2000)
}
)





(1!2).postln -> [ 1, 1 ]
PinkNoise *ar (mul: 1.0, add: 0.0)
PinkNoise.ar([1,1])

Genera rumore rosa il cui spettro decade in potenza di 3 dB per ottava, il che fornisce uguale potenza nell'arco di ciascuna ottava. Questa versione ha un limite di banda di 8 ottave.

Al rumore rosa viene aggiunto un segnale

Blip.ar(freq: 440.0,  numharm: 200.0,  mul: 1.0,  add: 0.0)
che è un segnale di impulsi limitato in banda; il numero di armoniche nel nostro caso è settato a 400; la frequenza è data dal doppio PinkNoise; quella specie di rumore di gocce di acqua che cadono che si sente è dovuto all'UGen Blip.ar;

il segnale risultante è fatto passare in un filtro risonante rifiuta banda, BRF.ar(in: 0.0, freq: 440.0, rq: 1.0, mul: 1.0, add: 0.0)



BRF.scopeResponse

a questo segnale è aggiunto un secondo segnale :




















LPF.ar( FreeVerb2.ar( *LPF.ar( p + 0.2 * Dust.ar( 0.1 ), 60) ++ [ 1, 1, 0.2, 1e4 ]).tanh, 2000)

Un "*" prima di un array all'interno di una funzione divide gli elementi dell'array e li passa agli args, nel nostro caso alla UGen FreeVerb2.ar. Diventa più chiaro facendo questo con il metodo Array.with che genera un nuovo array e prevede elementi separati.

Array.with(*LPF.ar (PinkNoise.ar (1! 2) + 0.2 * Dust.ar (0.1), 60) ++ [1, 1, 0.2, 1e4])
-> [ a LPF, a LPF, 1, 1, 0.2, 10000.0 ]

quindi la UGen avra questi args : FreeVerb2.ar(in: LPF,  in2: LPF,  mix: 1,  room: 1,  damp: 0.2,  mul: 10000.0,  add: 0.0)

questo segnale genera un forte boato, 1 volta ogni 10 secondi circa, dovuto all'impulso creato dal Dust moltiplicato per il Rumore Rosa;

La precedenza sinistra-destra di SC provoca l'aggiunta di un offset di 0,2 (al Rumore Rosa stereo) prima della moltiplicazione con l'impulso Dust.
La funzione sigmoide tanh mantiene il segnale tra -1 e + 1;

Per quanto riguarda l'offset di 0,2. Ho solo un presupposto: il file di aiuto di PinkNoise dice:

NOTA: è stato osservato che i valori prodotti da questa UGen sono molto probabilmente tra -0,65 e +0,81 circa (prima di essere moltiplicati per mul).

Quindi potrebbe essere che l'intenzione fosse quella di mantenere il segnale all'incirca al di sotto di 1, con probabilità molto alta.

// Modo per attivare e esplorare le Eccezioni con la GUI

Exception.debug = true;

// Metodo per salvare l'immagine del Plot

p= {BRF.ar( PinkNoise.ar(1!2) + Blip.ar(PinkNoise.ar(1!2)+2,400), 150, 2, 0.1) }.plot(10);
i = Image.fromWindow(p.parent, p.interactionView.bounds);
i.write("~/concat.png".standardizePath);
i.free

// Metodo per tracciare una Synth

(
SynthDef(\resonz, { |out, freq = 440|
    var    sig, ffreq;
    sig = PinkNoise.ar(1!2);
    Out.ar(out, FreeVerb2.ar( *LPF.ar( sig + 0.2 * Dust.ar( 0.1 ), 60) ++ [ 1, 1, 0.2, 1e4 ]).tanh, 0.1)
}).send(s);

)

a = Synth(\resonz);
a.trace;

// Metodo per capire come è composto un segnale

sig = PinkNoise.ar(1 ! 2).postln;
sig = LPF.ar (sig + 0.2 * Dust.ar(0.1), 60).postln;
sig = (sig ++ [1, 1, 0.2, 1e4]).postln;
sig = FreeVerb2.ar(*sig).postln;

Reverse Engineering di un sc-tweet di Rukano

play{a[1,1.01,2,2.02,3.5,4.01,5.501];SinOsc.ar(Duty.kr(0.2,0,Dseq([10,11,0,12.2,0,0,10,0]+39,inf).midicps)*(a++(a*2))).sum!2/10}//DAF #sc

Un Oscillatore Sinusoidale, SinOsc.ar, la cui frequenza è estratta dalla lista di Dseq dall'UGen Duty ogni 0.2 secondi; il tutto è moltiplicato per 14 valori ottenuti concatendando l'array di 7 valori "a" al doppio di se stesso; quindi per ogni elemento estratto ogni 0.2 secondi da Duty.kr abbiamo 14 Sinusoidi che poi vengono sommate in un unico segnale; il segnale ottenuto viene poi duplicato sul canale sinistro e destro dell'uscita; l'ampiezza è divisa per 10;





















SinOsc.ar(freq: 440,  phase: 0.0,  mul: 1.0,  add: 0.0)

Duty.kr(dur: 1.0,  reset: 0.0,  level: 1.0,  doneAction: 0)

ogni "dur" secondi, viene richiesto un valore da ogni Ugen nella lista; nel nostro caso ogni 0.2 secondi, viene richiesto un elemento della lista ([10,11,0,12.2,0,0,10,0]+39).midicps che viene generato dalla Ugen Dseq;





















Dseq.new(list, repeats: 1)

Generatore di sequenze; genera un valore appartenente alla lista, ogni volta che viene interrogato da Ugen tipo Demand, Duty, Drand, ecc.

{a[1,1.01,2,2.02,3.5,4.01,5.501];SinOsc.ar(Duty.kr(0.2,0,Dseq([10,11,0,12.2,0,0,10,0]+39,inf).midicps)*(a++(a*2)))}.plot(10)





















(a++(a*2))
[ 1, 1.01, 2, 2.02, 3.5, 4.01, 5.501, 2, 2.02, 4, 4.04, 7.0, 8.02, 11.002 ]



play{AY.ar((Hasher.ar(Latch.ar(AY.ar((1..3)!2),Impulse.ar([7/3,1])))*337+317).round(73),0,LFNoise2.ar(3,1/3,1/3))/7}//#supercollider

AY.ar(tonea: 1777,  toneb: 1666,  tonec: 1555,  noise: 1,  control: 7,  vola: 15,  volb: 15,  volc: 15,  envfreq: 4,  envstyle: 1,  chiptype: 0,  mul: 1,  add: 0)

Emula lo strumento AY-3-8910 (a.k.a. the Yamaha YM2149) a tre voci, tre suoni chip.

i tre suoni chip :

tonea : (Hasher.ar(Latch.ar(AY.ar((1..3)!2),Impulse.ar([7/3,1])))*337+317).round(73)
toneb : 0
tonec : LFNoise2.ar(3,1/3,1/3)

Latch.ar(in: 0.0,  trig: 0.0)

Il Latch mantiene l'input quando viene triggherato e genera zero all'inizio fino a quando non viene triggherato; nel nostro caso è triggherato da un doppio generatore di impulsi; quindi probabilmente il Latch campiona due valori secondo frequenze diverse;

questo è il segnale che viene campionato sui due canali stereo secondo il trig dei due impulsi;

{AY.ar((1..3))}.plot





































{Latch.ar(AY.ar((1..3)!2),Impulse.ar([7/3,1]))}.plot





















{(Hasher.ar(Latch.ar(AY.ar((1..3)!2),Impulse.ar([7/3,1])))*337+317).round(73)}.plot(10)





















Hasher.ar(in: 0.0,  mul: 1.0,  add: 0.0)

L'Hasher è un generatore Hash, che genera valori tra -1 e 1 a seconda dell'input che riceve secondo una funzione Hash; lo stesso valore di input genererà lo stesso valore hash in output; il segnale di input non ha bisogno di essere nel range di -1 e 1.


Impulse.ar(freq: 440.0,  phase: 0.0,  mul: 1.0,  add: 0.0)

Genera in output impulsi non limitati in banda; in teoria quindi se si superano i 22050 Herz di frequenza avremo un mirror nello spettro in frequenza?

round

round(a, b)
a round: b
a.round(b)

Arrotonda al più vicino multiplo di b;

LFNoise2.ar(freq: 500.0, mul: 1.0, add: 0.0)

{LFNoise2.ar(3,1/3,1/3)}.plot(10)





















Genera valori casuali interpolati quadraticamente ad una velocità data dalla divisione intera più vicina della frequenza di campionamento freq.



















Un ragionamento viene detto deduttivo, quando si conoscono le premesse e le regole (o leggi) e si intende ricavare il risultato o l’esito.Questo tipo di logica (vedi i sillogismi di Aristotele) si applica quando si vuole sapere quali risultati si ottengono applicando delle leggi conosciute. Se tutte le operazioni previste sono state svolte correttamente, le risposte che si ottengono sono sempre certe e sicure e per questo motivo molti sostengono che la logica deduttiva non porta mai a delle novità in quanto i risultati ottenuti sono già impliciti nelle premesse

Premessa, Regola --> Risultato

Premessa: i fagioli provengono dal sacco
Regola: tutti i fagioli del sacco sono bianchi
Risultato:i fagioli sono bianchi (sicuramente)

Il ragionamento deduttivo non aumenta la conoscenza; d'altro canto però le conclusioni sono vere.

Un ragionamento viene detto induttivo quando si conoscono le premesse e i risultati e si intende ricostruire le regole. Questo tipo di logica è tipica di chi, come ad esempio gli scienziati, vuole risalire a una legge naturale osservando quale risultato è stato ottenuto a partire da certe situazioni o premesse iniziali conosciute. La legge che si ottiene non è sicura in assoluto, ma solo probabile (vedi anche Bayes).

Premessa, Risultato --> Regola 

Premessa: i fagioli provengono dal sacco
Risultato verificato: i fagioli sono bianchi
Regola ipotizzata:tutti i fagioli del sacco sono bianchi (probabilmente)

Il ragionamento induttivo permette di allargare la nostra conoscenza mediante un processo di generalizzazione: l'induzione però può essere soggetta ad errori.

Un ragionamento viene detto abduttivo, quando si conoscono regole e risultati e si intende ricostruire le premesse. Questo tipo di logica è propria di chi cerca, come ad esempio un medico o un investigatore, di ricostruire una situazione iniziale, conoscendo il risultato che è stato ottenuto per effetto di una legge nota. Anche in questo caso la situazione iniziale che si ricostruisce non è mai certa ma valida solo con un dato livello di probabilità.

Regola, Risultato --> Premessa

Regola: tutti i fagioli del sacco sono bianchi
Risultato verificato: i fagioli sono bianchi
Fatto ipotizzato:i fagioli provengono dal sacco (forse)

Il ragionamento abduttivo tende a fornire ipotesi esplicative. Ovviamente anche l'abduzione non è esente da errori.

l'abduzione coincide con il metodo ipotetico sperimentale che caratterizza la scienza moderna da Galilei in poi. Le conclusioni a cui arriva l'abduzione non sono mai definitive, ma aprono la strada a nuove ricerche e a nuove conclusioni secondo il modello di approssimazione progressiva alla realtà che caratterizza il metodo scientifico.

La chiave concettuale del reverse engineering si chiama abduzione, uno schema di ragionamento teorizzato dal logico Charles Peirce: partire da un dato risultato, alla luce di leggi note, per ricostruire le cause di quel risultato. È il modo di procedere tipico degli investigatori o della medicina diagnostica.

L'abduzione è il processo di formazione d'ipotesi esplicative. È l'unica operazione logica che introduce una nuova idea, in quanto l'induzione non fa che determinare un valore e la deduzione sviluppa semplicemente le conseguenze necessarie di una pura ipotesi. La deduzione trova che qualcosa deve essere; l'induzione mostra che qualcosa è realmente operativa; l'abduzione meramente suggerisce che qualcosa può essere;

Nella risoluzione di problemi complessi non si ricorre mai ad un solo tipo di logica. In particolare per considerare se determinate ipotesi scaturite da ragionamenti induttivi o abduttivi possono essere considerate attendibili, è necessario sottoporle a dei controlli di tipo deduttivo e a corroborarle mediante seri tentativi di falsificazione;


Con Circuit Bending si indica l'arte di modificare in maniera creativa, attraverso semplici cortocircuiti, apparecchi elettronici a bassa tensione o strumenti elettronici alimentati a pile, come giocattoli (il più famoso tra questi è lo Speak & Spell della Texas Instruments, commercializzato in Italia come Grillo Parlante dalla Clementoni), tastiere, batterie elettroniche e effetti per chitarra, allo scopo di generare suoni inediti e curiosi, creare nuovi strumenti musicali e generici generatori di suono.

Generalmente il Circuit Bending viene associato alla musica elettronica sperimentale, al noise e a musicisti alla ricerca di nuovi suoni e di nuove strumentazioni "aleatorie". I suoni generati da tali apparecchiature sono, infatti, per lo più casuali, caotici o comunque non canonicamente collegabili all'idea di suono emesso da uno strumento musicale.

























Articolo Punto Informatico









2 Timer 555
1 Condesatore ceramico 0.1 uF
1 Condesatore ceramico 0.01 uF
1 Condesantore elettrolitico 100 uF
1 Resistenza 1K Ohm


Il chip CD4093 è composto da quattro porte NAND identiche. Ci sono due porte su ciascun lato del chip, ma a differenza del 74C14, sono disposte in modo simmetrico, specularmente : l'uscita di ciascuna porta fronteggia l'uscita della successiva, piuttosto che essere nella stessa direzione.

Ho giocato con le fotoresistenze, una tra l'uscita e l'ingresso verso il condensatore e la massa della prima porta NAND va a modulare il Gate della seconda porta NAND da cui viene perlevata l'uscita audio; poi ho fatto un po di cambiamenti a caso per arrivare a effetti audio particolari modulando le fotoresistenze con delle luci intermittenti;











L'interferenza dei fili sul sensore ad ultrasuoni ha prodotto questa melodia impazzita di suoni, dovuta alla presenza dei fili e al mio corpo che si avvicinava e allontanava dal sensore;

I sensori ad ultrasuoni non forniscono direttamente la misura della distanza dell’oggetto più vicino, ma misurano il tempo impiegato da un segnale sonoro a raggiungere l’oggetto e ritornare al sensore. L’impulso ad ultrasuoni inviato dal HC-SR04 è di circa 40KHz il tempo viene misurato in microsecondi, la tensione di funzionamento è di 5V

Il sensore HC-SR04 dispone di 4 pin: Vcc (+5V), Trigger, Echo, GND. Si invia un impulso alto sul pin Trigger per almeno 10 microsecondi, a questo punto il sensore invierà il ping sonoro e aspetterà il ritorno delle onde riflesse, il sensore risponderà sul pin Echo con un impulso alto della durata corrispondente a quella di viaggio delle onde sonore, dopo 38 millisecondi si considera che non sia stato incontrato alcun ostacolo. Per sicurezza si aspettano in genere 50-60 millisec per far si che non vi siano interferenze con la misura successiva.

Progetto originale : link

Hardware

330Ω Resistor
470Ω Resistor
Solderless Breadboard
Ultrasonic Distance Sensor
3 x Male to Male Jumper Leads
4 x Male to Female Jumper Leads

Software

sudo apt update && sudo apt upgrade -y
sudo pip3 install python-osc

Python :

from gpiozero import DistanceSensor
from time import sleep

from pythonosc import osc_message_builder
from pythonosc import udp_client

sensor = DistanceSensor(echo=17, trigger=4)
sender = udp_client.SimpleUDPClient('127.0.0.1', 4559)

while True:
        pitch = round(sensor.distance * 100 + 30)
        sender.send_message('/play_this', pitch)
        sleep(0.1)


------

Sonic Pi :


live_loop :listen do
       message = sync "/play_this"
       note = message[:args][0]
       play note
end

























Il CD4049 Hex Inverter.
Il resistore di ingresso, RI, generalmente di 10kOhm.
Il resistore di retroazione, RF, generalmente più grande di RI.
Il condensatore di ingresso, CI, generalmente intorno a 0.1uf.
Il condensatore di uscita, CO, generalmente intorno a 10uf.

Il guadagno, ovvero quanto il circuito amplifica il segnale in ingresso, è determinato dal rapporto RF/RI. Quindi, se RF = 100kOhms e RI = 10kOhms, il guadagno è di 10, il che significa che qualsiasi segnale in input al circuito viene amplificato di 10 volte. Se RF = 10mOhms e RI = 10kOhms il guadagno è di 1000, il che rende il segnale MOLTO più forte. Sostituendo i resistori fissi con un potenziometro (tipo da 1 megOhm) possiamo variare il guadagno del circuito. Per un tipico preamplificatore (come quello che si potrebbe usare per un microfono) si potrebbe desiderare di collegare una resistenza da 10k in serie al potenziometro da 1 megOhm: ciò consente di regolare l'amplificazione in modo fluido dal guadagno unitario (segnale in uscita uguale al segnale in ingresso) a un guadagno di 100 (output = 100 volte l'ingresso).

I condensatori all'ingresso e all'uscita (CI e CO) bloccano le tensioni continue presente nel circuito.  Sono necessari per la stabilità del circuito, e di solito non influenzano molto il suono.




















Inserisci un chiodo o una graffetta in un limone. Poi un pezzo di filo di rame. Assicurati che il filo e il chiodo siano vicini, ma che si non tocchino. Il chiodo è diventato l'elettrodo negativo della batteria e il filo di rame l'elettrodo positivo. Il succo di limone, che è acido, agisce come l'elettrolita. È possibile utilizzare altre cose oltre alla graffetta, al chiodo e al filo di rame, purché costituite da metalli diversi. La batteria al limone fornirà circa un quarto a un terzo di un Volt. Per utilizzare una batteria al limone per alimentare un piccolo dispositivo elettrico, come un LED, è necessario collegarne diverse in serie;



















al posto del Fotoresistore nel simulatore ho messo uno Switch, quando è buio la resistenza è altissima, il valore del Fotoresistore in assenza di luce tende a pochi Ohm, ed è come se lo Switch fosse aperto e quindi il LED si accende; quando invece è giorno, la resistenza è praticamente nulla ed è come se lo Switch fosse chiuso; quando lo Switch è chiuso la base del BJT è a 0 Volt quindi il Transistor è interdetto; quando è aperto la base di trova a circa 0.7 Volt e quindi il Transistor conduce;