Tutti gli articoli di Andrea Tassotti

core_midi_devel

Come mostrare il tempo di una MusicSequence come nel display LCD di GarageBand

Con un nostro precedente post abbiamo già accennato a questo problema: ora approfondiamo le motivazioni tecnico/teoriche che sono alla base.

Il formato ha 4 valori:

– la misura (bar)
– la battuta (beat)
– la nota di sedicesimo nella battuta
– sottodivisioni della battuta (subbeatdivision)

Il framefork AudioToolbox (Core Audio) offre alcuni strumenti per gestire la divisione del tempo a
supporto di una MusicSequence: i principali sono le seguenti:

  • MusicTimeStamp
  • CABarBeatTime

Il primo è un valore temporale la cui unità è la misura musicale (bar): quindi posto 1 il tempo di durata di una misura, tutto è multiplo o sottomultiplo di questo: ne consegue che MusicTimeStamp è un valore in virgola mobile con la necessità di una certa precisione.

La seconda è una struttura utilizzata per le conversioni (vedi le funzioni MusicSequenceBeatsToBarBeatTime e MusicSequenceBarBeatTimeToBeats), ma la scarsa documentazione non fornisce quanto serve a che queste funzioni facciano a pieno il loro dovere.

Il lato oscuro di queste funzione è il parametro inSubbeatDivisor (per la funzione MusicSequenceBeatsToBarBeatTime) o il campo subbeatDivisor nella struttura CABarBearTime (da passare alla funzione MusicSequenceBarBeatTimeToBeats).

Nella soluzione proposta nel precedente post utilizzavamo la risoluzione della sequenza (ppq) come parametro, e sembrava funzionare egregiamente: invero su divisioni di tempo differenti avremmo potuto avere problemi di rappresentazione.

Infatti il subbeatDivisor è un valore in relazione non solo alla risoluzione (in ppq), ma anche alla divisione del tempo corrente (time signature) e per la precisione al denominatore della divisione del tempo, secondo la sequente relazione:

subbeatDivisor = ( (ppq >> 2) << sig_denominator )

dove sig_denominator è espresso come l’esponente di una potenza di 2 che determina il denominatore della divisione temporale corrente. Una breve nota: il memorizzare l’esponente è un meccanismo utilizzato anche nel meta evento di una SMF o di una MusicTrack: la Tempo Track di una MusicSequence è una MusicTrack, pertanto la divisione è registrata in questa mediante meta eventi (di tipo kMIDIMetaEvent_Time_Signature).

La risoluzione è espressa in parti (tick o pulse) di una nota di quarto (ppq o ppqn), ma quando cambia il denominatore della divisione temporale, allora per avere medesima “precisione” occorre ampliare o ridurre questo valore quando esprimiamo una posizione nel tempo al fine di consentire di avere lo stesso numero di parti nel beat (che ha cambiato dimensione per il diverso denominatore della divizione del tempo).

Dato la divisione di 6/8 e una risoluzinone di 240 ppq:

UInt8    tsig_num = 6;
UInt8    tsig_den = 3;        // 2^3 = 8
UInt16    resolution = 240;    // PPQ

allora avremo:

UInt16  subbeatDivisor = ( (resolution >> 2) << tsig_den );

Le dimensioni delle variabili sono conformi a quanto atteso dalle strutture o funzioni in AudioToolbox.

Il penultimo valore da mostrare è il numero della nota di sedicesimo corrente, e come abbiamo visto l’altra volta è ottenibile mediante la seguente:

subbeat / (subbeatDivisor / 4) + 1

dove subbeat rappresente il “pulse” corrente di una nota di quarto, quindi rapportanto alla divisione corrente (subbeatDivisore) se ne prende la quarta parte: 4 * 4 = 16 !

Per eseguire qualche esperimento ecco come scrivere un beat di tanti eventi quanti i tick indicati dalla risoluzione prescelta.

MusicTrack outTrack;
UInt8    tsig_num = 6;
UInt8    tsig_den = 3;
UInt16    resolution = 240;    // PPQ
UInt16  subbeatDivisor = ( (resolution >> 2) << tsig_den );
CABarBeatTime inBarBeatTime;
MIDINoteMessage aNoteMessage;
MusicTimeStamp       outBeats ;

MusicSequenceNewTrack (mainSequence, &outTrack);

aNoteMessage.channel = 1;
aNoteMessage.note = 23 & 0x0f;
aNoteMessage.velocity = 80 & 0x0f;
aNoteMessage.releaseVelocity = 0;
aNoteMessage.duration = 1/960;

for(int i = 0; i < resolution; i++){
inBarBeatTime.bar = 1;
inBarBeatTime.beat = 1;
inBarBeatTime.subbeat = i;
inBarBeatTime.subbeatDivisor = subbeatDivisor;

MusicSequenceBarBeatTimeToBeats(mainSequence, &inBarBeatTime, &outBeats);
MusicTrackNewMIDINoteEvent (outTrack, outBeats, &aNoteMessage);
}

Ovviamente non abbiamo detto della cosa più importante: come leggere il denominatore della divisione in relazione al tempo corrente di riproduzione (o visualizzazione).

Questo sarà oggetto di un altro post che introdurrà la descrizione di un mio progetto di ampliamento del framework AudioToolkit che presto pubblicherò su github.

Per ora basta.

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!