Tutti gli articoli di Andrea Tassotti

IMG_4582-1.png

C reflection ?

Da qualche tempo ho ripreso a programmare in puro C per dei miei progetti personali, e quando dico puro intendo utilizzando essenzialmente la libreria standard come unico ausilio e primitive di sistema ove possibile.Non amo appoggiarmi ad API terze parti, per due (credo) ottime ragioni: esiste un tempo di apprendimento della loro logica non sempre nullo, e quasi sempre si adotta solo una minima percentuale delle funzioni date: che spreco di bit!
Poi una ragione diciamo di orgoglio, è che mi piace conoscere e trovare tecniche e soluzioni a problemi per mio conto, quasi sempre cercando (è un istinto della mia generazione) di sprecare pochi bit e pochi cicli CPU! Che noia, eh?!
Certo dopo qualche anno di C++, Java e Objective-C (in ordine cronologico), la mancanza di alcuni costrutti o strumenti si è fatta sentire: ci si vizia facilmente! Però si sopravvive.
In particolare un mio programma, instaurando un dialogo simbolico con un suo client aveva la necessità di cercare nelle sue strutture di memoria mediate il simbolo rappresentante un attributo di struttura: un classico esempio di reflection.
Abituato nell’ultimo periodo al paradigma Key-Value-Coding, la sua assenza mi pesava. Un approccio classico switch-case comportava la codifica numerica dei simboli (siamo in C, non PHP!). Una sequenza di if-else-if con strcmp “a manciate” non mi sembrava elegante: quindi?
Quindi perché non trovare un modo di implementare un abbozzo di reflection istruendo il programma sulla sua struttura?
Occorreva una tabella di meta-dati: nome del membro della struttura, spiazzamento da base di memoria della struttura e una funzione associata che applicasse un qualche algoritmo (a me serviva una comparazione tra i valori della struttura e un parametro di riferimento) tenendo conto del tipo dato.
Soluzione? La vecchia e cara aritmetica degli indirizzi!
Certo, come tutti sappiamo le cose così si complicano e diventano maledettamente illeggibili, ma per fortuna l’ambiente di sviluppo in Linux (a già dimenticavo! stavo implementando per questo specifico sistema) mi è venuto incontro con una macro di pre-processing che ha semplificato e reso leggibile il tutto.
Si tratta di “offsetof” definita in stddef.h e usata in ambito sviluppo kernel (con alcune varianti possibili): ovviamente troverete il file in /usr/src/linux-header-$(uname -r)/include/linux che quindi divrete avere.
Dunque con una struttura formata da 

  • const char *
  • size_t
  • int (*)(void *, void *)

ho potuto così creare una lookup table con cui ispezionare in riflessione la memoria del programma (relativamente a una certa struttura dati).

Ovviamente il size_t popolato dalla macro “offsetof” , mente la funzione nel mio caso doveva essere capace di comparare due argomenti del tipo pari all’attributo considerato, di cui appunto un argomento sarebbe stato proprio l’attributo.
Per accedere al dato nella struttura una volta riconosciuto il nome, la funzione di lookup non doveva fare altro che convertire in char * l’indirizzo base della struttura stessa e sommarci l’offset dato nella riga della lookup table che aveva consentito il riconoscimento, ottenendo un puntatore che convertito in void * e passato assieme al parametro di riferimento alla funzione associata che avrebbe provveduto (conoscendo il tipi originale) ad eseguire quanto voluto in modo coerente.

Basta ?

Forse no in termini assoluti, ma per la mia implementazione avere una struttura con 2 attributi o 50 è stato solo un gioco di riempimento della (o delle) lookup table, dopodiché lo stesso codice ha fatto quanto previsto in tutte le circostanze e in tutti gli aggiornamenti della struttura dati (e lookup table).

Alla prossima!

cocoa_cup

OSX e le risorse dinamiche

Molte applicazioni di piccole dimensioni nascono e muoiono con il solo contributo delle risorse definite nel nib/xib MainMenu contenuto nel bundle dell’applicazione.
Ma la disponibilità di risorse nella programmazione macOS è molto più articolata e al crescere della dimensione e funzionalità di una applicazione questa disponibilità verrà prima o poi a convergere nella nostra applicazione.

Vediamo di dare una guida ragionata all’uso di questa disponibilità di risorse.

Le diverse forme di disponibilità vanno scelte in ragione della tipologia di risorsa che intendiamo dinamizzare ed in ragione di quante istanze di questa abbiamo bisogno.

Una ulteriore scelta potrebbe essere fatta in ragione del budle che contiene le risorse che ci interessa utilizzare: potremmo infatti considerare l’uso di risorse collocate diversamente dal bundle dell’applicazione; ma per ora tralasciamo questa possibilità.

Iniziano con il distinguere in base alla dimensione della astrazione che intendiamo recuperare dinamicamente: una intera finestra o una vista custom.

All’interno di questa distinzione possiamo trovare una ulteriore dicotomia in relazione al numero di controller collegati alle viste: un solo controller o più controller.

Pur potendo il nib/xib contenere istanze di oggetti controller, quello che a noi interessa è l’istanza (o istanze) di controller che richiedano il caricamento dinamico di risorsa, e non quindi controller che subiscano essi stessi il meccanismo di caricamento dinamico stesso.

Dal punto di vista del nib/xib esiste un riferimento speciale ad un oggetto che è inteso sempre disponibile per le viste ivi contenute perché responsabile del caricamento dell’intero nib/xib: questo riferimento è il File’s Owner. Si può considerarlo spesso un oggetto di tipo controller o comunque un proxy di qualche genere a modello o azioni (a cui collegare le viste).

In virtù di questo il framework AppKit provvede a fornirci due implementazioni di controller con cui governare (prima delle altre cose accessorie in grado di fare) il caricamento dinamico di una intera finestra o di una specifica vista; sono: NSWindowController e NSViewController. L’implementazione di base è spesso sufficiente allo scopo del caricamento dinamico, comunque non è infrequente che si possa necessitare di una loro estensione per compiti poi specifici.
Perché le viste all’interno del nib/xib abbiano accesso ad un controller o model validi è sufficiente fare affidamento al File’s Owner, definendolo nel nib/xib come di classe scelta per il controllo del caricamento della risorsa rappresentata nel nib/xib (quindi NSWindowController o NSViewController, oppure loro derivazioni).
A questo punto una istanza di NSWindowController potrà tramite -(id)initWithWindowNibName:(NSString *)windowNibName
consentire il recupero di una intera finestra da un nib/xib (indicato per nome) con tutte le azioni, outlet o binding collegate a File’s Owner (e quindi NSWindowController) o suoi elementi.
La finestra stessa è ottenibile dall’istanza di NSWindowController mediante metodo -window, così come sono ottenibili altri strumenti propri del controller.

Esempio

NSWindowController * aWindowController = [[NSWindowController alloc] initWithWindowNibName:@"myWindow"];

[aWindowController showWindow: self];

Allo stesso modo un NSViewController potrà farsi carico del caricamento di un nib/xib che definisce una vista attraverso il metodo:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

L’idea di questo controller (contrariamente al precedente, orientata alla finestra/documento) è maggiormente sviluppata al supporto per le viste contenute nel nib/xib nella definizione di legami con il modello; a tale scopo fornisce una proprietà generica representedObject per consentire un facile collegamento tra il nib e un oggetto (modello) che ancora non è noto in fase di caricamento del nib/xib.

Esempio

NSViewController *viewCtlr = [[[NSViewController alloc] initWithNibName:@"myView" bundle:nil] autorelease];

[[window contentView] addSubview: [viewCtlr view]];

Questi due controller risolvono il problema di una vista più o meno complessa governata da un proprio controller. Ma come poter gestire istanze multiple di viste custom afferenti al medesimo controller?

Una derivazione da NSView può implementare la seguente:

- (BOOL)loadFromNib:(NSString *)nibName bundle:(NSBundle *)bundle controller:(id)controller
{
/*
 * Codice liberamente tratto da "Resource Programming Guide" di Apple
 *
 */

    NSNib *		aNib = [[NSNib alloc] initWithNibNamed:@"ReusableView" bundle:bundle];

    NSArray *	topLevelObjs;

    if (![aNib instantiateNibWithOwner:controller topLevelObjects:&topLevelObjs]) {

     NSLog(@"Warning! Could not load nib file.\n");

     return NO;

    }

    // Ricerca delle viste

   for(id obj in topLevelObjs) {

     if ( [obj isKindOfClass: [NSView class]] )

        [self addSubview: obj];

}

   // Release the raw nib data.

    [aNib release];

    // Release the top-level objects so that they are just owned by the array.

    [topLevelObjs makeObjectsPerformSelector:@selector(release)];

   // Do not autorelease topLevelObjs.

    return YES;

}

Esempio

ReusableView * reusable1  = [[ReusableView alloc] initWithFrame:NSMakeRect(0, 0, 100, 95)];

[reusable1 loadFromNib:@"ReusableView" bundle:nil controller: controller];

[reusable2 loadFromNib:@"ReusableView" bundle:nil controller: controller];

Un limite di questa implementazione è l’assenza di un meccanismo automatico per definire la catena dei risponditori sommando il contributo di ciascuna vista (e poter passare da una a l’altra, che detengono così catene indipendenti).
Per semplificare rapporto con model implementare una proprietà representedObject similmente a NSViewController.

Va da se che applicare questa forma di caricamento quando si collegano poi alle viste istanze di controller differenti è una inutile ripetizione della implementazione già in essere con NSViewController.
Con questa ultima osservazione chiudiamo la nostra guida al caricamento dinamico delle risorse in macOS.

Alla prossima.

osx-vb-cpuid

OSX+VirtualBox+cpuid

Il mondo degli smanettoni è a volte omissivo, a volte ignorante. L’omissivo lo ammetto quando serve ad impedire a giovani sprovveduti di replicare tecniche pericolose o illegali; l’ignoranza è altra cosa. Ma nel chiacchiericcio internet, persa la fonte originale (forse solo omissiva), dopo molti “copia e incolla” molti post diventano un crogiolo di ignoranza.

Non so se questo sia il caso, ma non si trova molto in giro che spieghi le relazioni profonde tra le cose oggetto di questo post.

Cpuid è una istruzione assembly Intel che consente di determinare tipo e caratteristiche della cpu (ovviamente solo per architetture Intel/AMD).

L’insieme di informazioni risultanti è usato da sistemi operativi e software applicativi per determinare certi comportamenti.

Nel caso di  Oracle VirtualBox vengono utilizzate per determinare se il sistema host può eseguire il codice del sistema guest; ma VirtualBox usa una versione “edulcorata” di queste informazioni anche per mostrare al guest la CPU virtuale che intende fornire. Tipicamente fa questo clonando le informazioni cpuid della CPU reale modificando alcune caratteristiche (per ragioni di isolamento e protezione).

VirtualBox fornisce uno strumento per interrogare la CPU host rispetto al cpuid:

VBoxManage list hostcpuids

Consente anche un certo grado di intervento nell’immagine virtuale di queste informazioni che fornirà al sistema guest:

VBoxManage modifyvm --cpuidset

ma attenzione: potranno essere arbitrariamente alterate da VirtualBox per le ragioni di isolamento e protezione di cui sopra.

Come si relaziona tutto questo con OSX?

Parliamoci chiaro: su internet la maggior parte dei post che trattano questi argomenti lo fanno spiegando di installazioni OSX su hardware e OS “non Apple“: questo non è consentito dalle licenze d’uso.

Nessuno tratta argomenti più “Apple” come la sperimentazione di nuove versioni di OSX prima in virtuale (tipico approccio conservativo per chi personalizza pesantemente il sistema e deve sapere se tutto funzionerà correttamente, se software particolari e magari costosi funzioneranno ancora, ecc). Nessuno parla mai dello sviluppo “legacy”, quindi della necessità di avere una vecchia versione di OSX su cui sperimentare il software.

VirtualBox per OSX è lo strumento ideale per tutte queste cose.

Grazie alla manipolazione delle informazioni cpuid Potremo testare anche per hardware differente (sempre Apple, ma meno recente).

Ma OSX non ha uno strumento nativo per leggere il cpuid; quindi se non vogliamo installare VirtualBox su tutte le macchine da cui estrarre le informazioni cpuid  ci serve uno strumento alternativo.

È quello che propongo con questa mia semplice implementazione in C:

http://www.github.com/andrea-tassotti/cpuid

Il codice deriva da un sorgente open source di Apple (con licenza non GPL), e produce un output come quello di VBoxManage.

Il vantaggio di questo codice è che potrà essere eseguito all’interno del sistema guest per verificare che le informazioni impostate in configurazione della VM siano come previste (salvo modifiche applicate da VirtualBox).

Spero possa esserVi di qualche aiuto per comprendere certi meccanismi.

Alla prossima

IMG_3426.PNG

Big-G consuma risorse sul vostro Mac? 

Era un po’ di tempo che avevo notato che il mio Mac, quando non online, faticava a completare l’avvio della sessione utente.
Mi sono risposto troppe volte che forse avevo esagerato con software e servizi installati.

Troppe volte.

Cosè ieri sera ho deciso di fare il sistemista (a casa si evita sempre di farlo, chissà perchè) e ho guardato il log di sistema appena avviato ed entrato in sessione utente: sorpresa!

Scoperto il colpevole.

Non tutti sanno (e anche io lo ignoravo) ma dovrebbero sapere che quando si installa una qualche applicazione Google (Chrome, Earth, ecc) viene installato in sordina un altro software: GoogleSoftwareUpdate. E io avevo installato Chrome !!!

Questo software si pone come demone all’avvio di sessione e contatta i server Google per cercare nuove versioni dei software. Nulla di male se non per due cose:

  • non è chiaramente visibile all’utente
  • non contempla il non essere online

Proprio questo ultimo punto causa il maggior fastidio.

Infatti l’aggressività del software in configurazione base è tale per cui il fallimento nel contattare i server Google si riverbera nel sistema con forti rallentamenti dello stesso per continua ed intensa attività su disco. Troverete in rete molte fonti citare strani rallentamenti causati da tale software.

Ora una semplice alea di rete può rallentare temporaneamente, ma la non connessione permanente causa molto secondi di rallentamento ogni volta che il processo di controllo aggiornamenti viene schedulato (e questo avviene alla partenza e ogni 5 ore).
Questo è quanto ho rilevato nel log:

19/07/16 22.07.22	GoogleSoftwareUpdateAgent[240]	2016-07-19 22:07:21.899 GoogleSoftwareUpdateAgent[240/0xa0cce540] [lvl=2] -[KSAgentApp setupLoggerOutput] Agent settings: <KSAgentSettings:0x20d280 bundleID=com.google.Keystone.Agent lastCheck=2016-06-15 23:04:48 +0200 checkInterval=18000.000000 uiDisplayInterval=604800.000000 sleepInterval=1800.000000 jitterInterval=900 maxRunInterval=0.000000 isConsoleUser=1 ticketStorePath=/Users/andrea/Library/Google/GoogleSoftwareUpdate/TicketStore/Keystone.ticketstore runMode=3 daemonUpdateEngineBrokerServiceName=com.google.Keystone.Daemon.UpdateEngine daemonAdministrationServiceName=com.google.Keystone.Daemon.Administration logEverything=0 logBufferSize=2048 alwaysPromptForUpdates=0 productIDToUpdate=(null) lastUIDisplayed=(null) alwaysShowStatusItem=0 updateCheckTag=(null) printResults=NO userInitiated=NO>

...

19/07/16 22.08.06	GoogleSoftwareUpdateAgent[240]	2016-07-19 22:08:06.993 GoogleSoftwareUpdateAgent[240/0xb0207000] [lvl=3] -[KSOutOfProcessFetcher(PrivateMethods) helperDidTerminate:] KSOutOfProcessFetcher helper tool failure. [com.google.UpdateEngine.CommonErrorDomain:1501 - 'KSOutOfProcessFetcher.m:783']

...

19/07/16 22.08.09	GoogleSoftwareUpdateAgent[240]	2016-07-19 22:08:09.938 GoogleSoftwareUpdateAgent[240/0xa0cce540] [lvl=2] -[KSAgentApp checkForUpdates] Finished update check.

47 secondi di attivitˆà per un singolo processo quando l’intero sistema esegue bootstrap in meno tempo?

Intollerabile.

Come risolvere ?
Si può pensare di modificare la configurazione di schedulazione, oppure (e questo ho fatto io) rimuovere dall’avvio in sessione. Ci si può facilmente spingere oltre rimuovendo l’intero software.

Consigurazioni e cache le troviamo in:

  • ~/Library/LaunchAgents/com.google.keystone.agent.plist
  • ~/Library/Preferences/com.google.keystone.Agent.plist
  • ~/Library/Caches/com.google.keystone.Agent

Il vero e proprio software in:

  • ~/Library/Google/GoogleSoftwareUpdate [Directory]


Rimuovere
com.google.keystone.agent.plist
è sufficiente per fermare l’avvio del demone.

Se volete spingervi oltre (rimuovere), liberi di farlo: basta buttare tutto nel cestino; non accade nulla di strano: semplicemente non avrete più aggiornamenti automatici.

Ma attenti!

Se installerete nuovamente qualche altro software Google, la storia potrebbe ripetersi.

Alla prossima

IMG_3419.PNG

“Nerditudine” che avanza

Il nostro blog non può rimanere insensibile ai temi nerd.
Quindi in questa occasione, dopo altri argomenti nerdissimi trattati nei post precedenti, vogliamo proporre una altra cosa da Nerd che ci viene dai nostri amici (nerd anche loro) del blog http://www.brilliantbeaver.com.
Si tratta di un plugin per WordPress che consente di avere nel proprio sito un calendario nerd, ossia uno strumento che ci indichi se il giorno corrente è una data legata a qualche saga o a qualche numero notevole: insomma se la data è nerd!
Potevamo rimanerne senza? No. Quindi lo abbiano adottato nel nostro blog.
Naturalmente questo è solo un pretesto per presentare una speriamo proficua collaborazione tra nerdammer e brilliantbeaver che inizia da oggi.

Maggiori dettagli su:

http://www.brilliantbeaver.com/2016/05/14/beavernerdholidays/

Un saluto ai nostri colleghi di nerditudine!

tux-banner

Come consentire la scrittura di un file di sistema ad un utente ordinario

Più che di svelare chissà quale segreto, l’intento di questo post è di costituire un quasi memorandum per amministratori (e non solo).

Parliamo di scrittura, non necessariamente di condivisione della proprietà del file: pertanto sono esclusi gruppi più o meno esoterici, ACL o altri sistemi basati su privilegi su filesystem.

Ovviamente la soluzione residua è un’assegnazione di diritti amministrativi al processo di scrittura, e quindi una soluzione basata su sudoers.

Naturalmente occorre trovare una mediazione tra rispetto della sicurezza del resto del sistema e una certa flessibilità del meccanismo.

La sicurezza la imponiamo fissando nella lista comandi della regola sudoers il nome assoluto del particolare file di sistema su cui delegare il privilegio di scrittura.

La flessibilità del meccanismo la otteniamo considerando la sorgente dei dato non originante da altro argomento di un comando da attivare con sudo (vedi cp), ma invero dallo standard input del comando da attivare, implicando quindi un ulteriore processo di delega.

Per ragioni di opportunità e di semplicità di realizzazione in termini di sintassi sudoers la scelta del comando ricade su /usr/bin/tee.

Ponendo in /etc/sudoers la seguente:

utente ALL = (root) NOPASSWD: /usr/bin/tee /file/protetto

l’utente ordinario potrà modificare il file di sistema (protetto) assumendo temporaneamente i privilegi amministrativi; dovrà  quindi scrivere:

cat /file/sorgente | sudo '/usr/bin/tee /file/protetto' >/dev/null

Ovviamente la cosa potrà estendersi oltre il contesto locale con:

cat /file/sorgente/locale | ssh -t utente@host.remoto sudo /usr/bin/tee /file/protetto/su/host/remoto

dove opzione -t è fondamentale perché ssh possa lavorare in pipe eseguendo un sudo remotamente.

Speriamo di aver fornito un contributo per risolvere uno dei più  classici problemi di sicurezza di un sistema.

videogame80

Strike and ball NG

Come promesso iniziamo con la prima proposta per la relizzazione del gioco che vi avevamo descritto nell’articolo Amarcord e nuove sfide.

Per sfida e ricerca Nerdammer vi offre sempre soluzioni non banali, poco frequentate o innovative.
Questa volta, pur con lo stesso spirito, seguiamo una soluzione “mainstream”.

Volendo sviluppare il nostro gioco con tecnologie per il web abbiamo fatto ricadere la nostra scelta su una tecnologia che ci offrisse qualche spunto di interesse e ci portasse un minimo di agio nel modellare il progetto con quegli strumenti (tra paradigmi e astrazioni) ai quale siamo abituati nella nostra esperienza di sviluppo software.

Abbiamo scelto il framework (Google) AngularJS.

La realizzazione del nostro gioco (nella versione che proponiamo) non é compito arduo in generale, pertanto un simile progetto non potrà investire tutte le potenzialità di AngularJS, e ce ne dogliamo con voi, ma la semplicità ci consente di descrivere gioco e tecnologie in un unico momento.

L’algoritmo di valutazione della risposta utente impone di verificare dapprima le cifre giuste nella corretta posizione escludendole dalla successiva valutazione delle cifre giusta nella posizione errata. Per procedere a tali valutazioni occorre modificare la risposta utente eliminando via via quanto rilevato. Nel voler far questo sulla risposta utente cosi come ci arriva dalla view ci troviamo ad affrontare il limite del tipo String in EMCA script, che è Immutable.
Per rendere il tipo String Mutable provvediamo alla modifica del suo prototype introducendo un metodo replaceAt() che pur generando una copia modifcata dell’oggetto originale riesce a mimare il comportamento mutable.

Armati di questo nuove strumento implementiamo nel controller il metodo di verifica che sarà innescato da evento click (ng-click) su un pulsante della vista.

Le valutazioni (una stringa di X e O) verranno accodate in un array del controller collegato (one-way-binding) ad un elemento <Ii > della vista: questo verrà gestito dalla direttiva ng-repeat che iterando all’array a cui è collegato provvederà dinamicamente all’aggiornamento di una vista delle risposte date dall’utente.

Questo è essenzialmente il cuore del programma.

Il resto é solo per gestire gli stati di vittoria, sconfitta e resa, le relative statistiche e qualche opzione, il tutto reso attraverso le direttive proprie di AngulaJS, qualche stile e poco altro.

Il sorgente completo lo trovate in https://github.com/andrea-tassotti/sbjs .

osxbeep

Beep OS X, Beep!

Nell’implementazione dello strato BSD, OSX omette alcuni comandi; poco male se una alternativa è data da un comando nativo: verosimilmente l’astrazione BSD non era in grado di realizzare a pieno il compito. Ma questo non é evidentemente l’unico motivo.

Tra i vari “ports” BSD, Apple ne seleziona solo alcuni, mantenendoli spesso ad una versione “vecchia” (vedi il caso di bash, ancora rimasta alla 3).

Non dovrebbe dunque sorprendere l’assenza del port del comando beep, sebbene sia difficilmente spiegabile in termini tecnologici; al piú si spiega in termini di conformità alle metafore della interfaccia che prevedono altro per la segnalazione di eventi ad utente.

L’ironia del caso vuole che mentre il mondo Linux evolve la sua implementazione del comando beep, anche il port per FreeBSD è stato rimosso in quanto obsoleto, alla buona faccia di chi voglia ancora utilizzarlo.
Ovviamente il nostro interesse per il comando beep nel mondo OS X è indotto dalle cose espresse nei nostri precedenti articoli, ma andiamo per gradi.
Ricercando nella documentazione di sviluppo si trova la disponibilità della funzione beep() nella libreria ncurses (https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/beep.3x.html): questa peró esegue il suono di avviso configurato negli effetti sonori nelle preferenze di sistema.
Quindi, almeno per conformità alle metafore dell’interfaccia, il comando beep poteva essere implementato semplicemente utilizzando questa funzione di ncurses.

Ricercando in Internet (come è nostro solito) una soluzione per implementare un beep su OS X troviamo tante risposte ovvie, ma non quella che cercavamo (ovvio anche questo!)

E’ ovvio che un comando echo (o print) in shell riproduca con un suono il carattere audible alert (\a=ASCII 0x7, carattere di controllo
che deve i suoi natali alla Teletype Model 33 ASR):

echo -e "\a"

ma é anche ovvio che si comporti come prevede l’implementazione della libreria ncurses, come per l’equivalente:

tput bel

con cui si attiva la capability del terminale (che dipendono dalla solita libreria)

Ovvio (benchè meno diretto) la possibilitá di eseguire un beep come istruzione AppleScript:

osascript -e beep

e non ci si può stupire se anche questo metodo (piú che mai OS X) esegue Il suono di sistema previsto per gli avvisi.

Il suggerimento piú esilarante è certamente il seguente:

say beep

benchè abbia un suo fascino.
Dunque è giunto il momento di trovare una risposta in stile Nerdammer e dotare il nostro OS X del comando beep.
Volevamo scegliere come modello la piú evoluta implementazione Linux (di Johnathan Nightingale) invece di quella del port FreeBSD:
questioni pratiche e di tempo ci impongono al momento di implementare la versione FreeBSD: ritorneremo sulla implementazione per evolverla accessivamente.

Questa scelta ci consentirà comunque di utilizzare le nostre “beepsongs” come prodotte dal software descritto nel
precedente articolo (ponendo in modo FreeBSD l’output dello script). Alla fine in realtà è questo che cercavamo!

Per realizzare il nostro progetto ci avvaliamo del framework Core Audio, ed in particolare utilizziamo una Audio Unit di tipo output con definita una funzione callback per il rendering del buffer audio, il che ci consentirà di definire algoritmicamente (dunque dinamicamente) la forma d’onda emessa.

Vogliamo con questo simulare al meglio il circuito analogico del beeper delle schede madri di pc e server, evitando i limiti e la complessità che altri metodi imporrebbero volendo ottenere campo di frequenze e durata di emissione molto ampi.

Come al solito la nostra implementazione é una guida: ci si perdoni quindi l’assenza di ricerca di ottimizzazioni nelle prestazioni (ad esempio l’algoritmo di generazione dell’onda sinusoidale non é il piú efficiente in assoluto).

Potete scaricare il codice sorgente da Git Hub e compilarlo sul vostro OS X come indicato nella documentazione.

Ancora una volta buon ascolto!

diversamenteArte

Diversamente Arte (Parte II)

Partendo dalle specifiche del formato file per la trascrizione musicale dettate nel precedente post costruire un programma (script) capace di trasformare la nostra partitura in sequenze di comandi beep (o sequenza di argomenti per lo stesso) é cosa assai semplice.

La scelta del linguaggio di programmazione é ovviamente orientata alla omogeneità con l’ambiente di utilizzo del risultato, ovvero shell (in particolare bash >4.0), ma nulla vieta di realizzare il nostro programma per BeepMusic con altra tecnologia.

II nostro prototipo é capace di produrre varie forme di BeepMusic secondo la compatibilità con le possibili implementazioni del comando beep (Linux e FreeBSD).

Il cuore del software è il calcolo della durata delle note in ragione delle impostazioni metriche della partitura:

duration_in_millisec = n * 60000 / BPM / x;

dove n è il numeratore della frazione che indica la divisione di tempo (time signature) ed x è il denominatore della frazione che rappresenta la singola durata della nota. Questo viene calcolato per tutte le possibili durate di nota, ossia 1 2 4 8 16 32 64 128.

Le frequenze per le note sono semplicemente estratte da un array
pre-calcolato e posto in un file accessorio (potete “accordare” a piacimento lo “strumento” beep).

Qualche accorgimento per produrre output compatibile con le differenti implementazioni di beep ed il gioco é fatto!

Il software completo é scaricabile da GitHub (https://github.com/andrea-tassotti/beepmusic).

Buon ascolto!

diversamenteArte

Diversamente Arte (prima parte)

Arte ed Informatica si sono incontrate piú volte dalla nascita di quest’ultima.

L’Informatica ha creato nel tempo strumenti a supporto dell’Arte parlando la lingua dell’Arte (dalla conservazione per via digitale di capolavori alla creazione di nuovi strumenti); ma ha saputo dare all’Arte (o meglio agli artisti) anche nuovi linguaggi (e i conseguenti strumenti).

Molti strumenti sono divenuti di uso quotidiano in molte realtà ove l’Arte é anche industria (si pensi agli strumenti di fotoritocco, di modellazione 3D o per la produzione audio-video); altri sono rimasti pura sperimentazione o passatempo per informatici estrosi (e con molto tempo libero).

Di questa “diversa Arte” o “Arte diversa” vogliamo parlare in questo post.

Avrete certo visto forme di ASCII Art, ossia immagini create in documenti testo da caratteri la cui forma e posizione fanno credere a differenti livelli di tono tanto da illudere a sufficienza l’osservatore. Per lo più realizzate con carattere tipografo a corpo fisso (come nella “old school” in voga nel mondo Amiga) o nelle forme piú estreme con corpo variabile e colori (addirittura video con la AAlib di Linux), queste forme d’arte hanno abbellito, decorato o commentato manuali, programmi e quant’altro.

Da notare che anche gli emoticons noti ai piú nascono come forma minimalista di Ascii Art:

:-)

Su YouTube potreste trovare “composizioni per aghi e carta” (avete letto bene!): c’é chi ha “accordato” la propria stampante a matrice di aghi per eseguire composizioni musicali.

Ci sono artisti che amano creare Photographic Mosaic (o Photomosaic), ossia usare immagini come punti per una immagine piú grande frutto di questa composizione; oppure ce ne sono altri un po’ retro’ che si cimentano nella Pixel Art (puntillismo), ossia disegnano un pixel alla volta, con pazienza infinita.

Esistono programmi che consentono a musicisti di generare suoni o musiche a partire da una immagine, o consentono di imprimere il  volto dell’autore nello spettro audio di una composizione (in modo cioé che uno spettrogramma riproduca una immagine di tale volto: è un vezzo questo che si è concesso I’artista Aphex Twin (al secolo Richard David James).

Molti piú dettagli e molte altri modi di fare arte con i computer possono essere approfonditi cercando il termine “demoscene” su Wikipedia.

E veniamo all’esempio di “diversa arte” di cui vogliamo ampliare la conoscenza.

Non tutti sanno che le motherboard di PC e Server sono dotate di beeper (emettitore acustico tipicamente piezoelettrico). Spesso la sua presenza è rilevabile solo nelle fasi pre-boot, nell’accesso al BIOS, e altre “fasi hardware”.

Per sistemisti (o utenti) UNIX il “beep” è una presenza immanente, sin dai tempi dei terminali “telescriventi”: ma anche tra questi sono pochi a conoscere che il beeper può essere “accordato” ad emettere suono di altezza e lunghezza differenti dal classico “beep” (tipicamente 750Hz per 200msec).

Pochi non vuol dire nessuno: utilizzando il comando beep, sia su sistemi FreeBSD, sia su sistemi Linux (con differenti implementazioni), “diversamente artisti” hanno potuto sequenziare l’emissione sonora e temporale del beeper per eseguire musica, benché monofonica (una sola voce) e monotimbrica (un solo colore).

Tra questi artisti, molti lavorano direttamente sui parametri del comando beep (frequenza in Hz e tempo in msec (o cent sec nel caso FreeBSD).
I piú raffinati tentano un approccio con convertitori da MIDI SMF a sequenza di comandi beep (o sequenza di suoi parametri nella implementazione Linux).

Entrambi gli approcci hanno dei problemi: il primo è certamente un metodo “innaturale” e “complicato”; il secondo si deve scontrare con il limite monofonico (innaturale nelle trascrizioni MIDI di musica) e con i problemi della quantizzazione del tempo che può tradursi in una caotica quantità di esecuzioni di comandi beep (o suoi parametri) per mimare il timing degli eventi MIDI.

Il sistema MIDI si basa infatti sulla successione di eventi note on e note off, nell’ottica di una meccanica key pressed (on) e key released (off): questo metodo é perfetto per “registrare” esattamente l’esecuzione di un brano da parte di un musicista su uno strumento di input MIDI (come una keyboard): la riproduzione sarà esattamente uguale (con precisione molto, molto elevata): in questo é cruciale il riferimento temporale (relativo tra due eventi o assoluto).

Il comando beep non ha un sistema di riferimento temporale: il suono viene emesso nel momento di esecuzione del comando e per il tempo indicato (durata): nella versione Linux in cui si può istruire un solo comando ad eseguire piú note e si può indicare anche una latenza temporale tra due note (pausa), ma sempre in termini di durata.

Per i piú ferrati in musica si riconoscerà in questo un approccio più simile al metodo musicale della divisione del tempo, in cui è fondamentale il concetto di durata (e altezza) della nota.
Vogliamo quindi fornire un nuovo strumento per questa Beep Art (o meglio Beep Music), che sia semplice e piú”musicale” possibile.
Proponiamo di scrivere in un semplice file testo una nota per riga (come un “rullo musicale”), espressa con altezza, durata naturale e modificatori, tre campi separati da carattere colon (:). Questo file testo sarà la nostra partitura che un software (che andremo a costruire) provvederà a convertire in una sequenze di comandi beep.

Esistono sistemi di Music Engraving che si basano su file testo molto semplice (vedi abc),
quindi non si consideri banale questo metodo: solo prototipale.

L’altezza sarà espressa in notazione anglosassone e con estensione come dettata anche dallo standard MIDI dalla MMA (da C-2 a G8, ossia dal Do ben 2 ottave sotto la nota piú bassa del pianoforte, fino a 127 semitoni sopra).
La durata sarà espressa in termini di divisione musicale, esprimendo la componente a denominatore. Come modificatori saranno supportati il punto (singolo, doppio e triplo, e i gruppi (irregolari) espressi da un semplice numero.
Le pause saranno espresse da note con altezza “P”, con durata e modificatori come per le note.

E’ evidente che in questo modo la durata e posizione delle note nel tempo musicale é garantita dalla divisione del tempo tra note e pause (come é nelle notazione classica e come é pure per il comando beep.

A completare la sintassi introduciamo indicazioni sulla divisione con il metadato tsig (indicata in modo canonico con una frazione), ed indicazione sul tempo (velocità di esecuzione), con un numero che esprima i bpm (beat for measure) ossia il numero di pulsazioni (note di lunghezza indicate dal denominatore delle tsig: per un 3/4 una nota di 1/4) al minuto.
Questi parametri altro non fanno che produrre il rapporto tra le durate di note e pause in termini di tempo assoluto (secondi o frazionamenti).

Se volessimo realizzare un metronomo per una divisione 4/4 avremo:

A5:4:
A4:4:
A4:4:
A4:4:

Ma questo andrebbe bene se il generatore di toni fosse di natura impulsiva e le note poste all’inizio dei quarti della misura decadessero in ampiezza prima di esaurire la loro durata (caso tipico di una partitura MIDI per un drum kick).

Questo non é quasi mai valido in generale, e non é assolutamete vero nel caso di beep ché si comporta come un generatore di tono ideale (potendo assumere altezza e durata arbitrari).

Per questo la giusta partitura potrebbe essere:

A5:16:
A4:16:
A4:16:
A4:16:

Dato che questo è poco intuitivo per un musicista, introduciamo un meccanismo di “umanizzazione” indicando nella “partitura” i portamenti “legato” (comportamanto naturale) e “staccato” (meccanismo per emulare suoni di natura impulsiva). Questo sintatticamente verrà collocato all’interno di una riga di commento. La riga di commento potrà essere inoltre utilizzata per indicare l’inizio della “misura” (o battuta). Questo potrà essere d’ausilio nella verifica (anche automatica) della trascrizione.

Come si può intuire trascrivere musica da spartito originale con questa notazione risulta assai facile.

Vedremo nel prossimo post come anche la trasformazione in Beep Music sia altrettanto facile.

(Fine prima parte)