spassig
LikeAPolaroid
81 posts
Thoughts halfway between images and sounds. And rumblings of a nerd, occasionally. www.likeapolaroid.com http://www.flickr.com/spassig
Don't wanna be here? Send us removal request.
spassig · 6 years ago
Text
Using wide-angle lenses on Sony A7 II
I recently bought a Sony A7 II moving away from Nikon DSLRs (I owned a D800E) and I am using (with adapters) all my other lenses like the M42s, the Nikons of course and the Leica M-mount lenses I have, made by Voigtlander.
One lens that I simply love is the Voigtlander Color Skopar 21/4. It’s just a marvelous, amazing lens. Sharp (maybe even sharper than the Leica equivalents), great colour rendition, amazing black and white. I have been using it on my Bessa R3A for years now.
I thought I'd share my experience of using this lens on a digital mirrorless camera. In my case, Sony A7 II. Here it is mounted on the camera, via a Commlite close-focus Leica M adapter.
Tumblr media
It's pretty known that wide angle lenses on mirrorless cameras are an issue because their back nodal point gets too close to the sensor and this causes weird color shifts on the left and right sides. This happens on Sony, Fuji or even Leica cameras. The phenomenon is called "lens cast".
What camera manufacturers do is to embed correction in the camera firmware, but the lens must be coded and recognized by the camera. This is what Leica does for their lenses. Unfortunately, Sony A7 II does not have this possibility so we need to think of something else.
First though, let's see what the problem is about.
This is a shot straight off the camera. As you can see, there's a lot of color shift on the left and right sides - and a substantial vignetting. I shot this at f/4 (full aperture) and underexposed to exaggerate the problem.
Tumblr media
I am a Lightroom user so I searched for a solution to this problem. Naturally you can do it manually but it's a bit tricky to correct the color shifts, really. Photoshop is a lot better for this as you can use masks but Lightroom does not have this possibility.
Fortunately, Adobe have released a Lightroom plugin called "DNG Flat Field", which is what I needed. Can be downloaded from here.
It works by using a calibration image, it applies this image as a "negative" layer and removes the vignetting and the cast.
The calibration image is an image shot in the same aperture condition of the original image but with no details. It can be taken by shooting through some white translucent plastic with the lens set to infinity.
So when you're out in the field shooting you take some pictures, take a calibration shot, take some more pictures, take another calibration shot, etc. This is what the plugin recognizes as "interleaved" shots and related correction.
I also did something different. At home, I shot a white wall with the lens set at all the different apertures and focused at infinity. So I basically built my "external" calibration shots to be used at any time with any shot. Naturally, you need to record the aperture used for a certain shot. This is how you make the plugin apply the "external correction".
It works like a charm.
This is the result of applying the external correction to the original image.
Tumblr media
As a final note, the plugin can work only to correct the color shift and leave vignetting as it is, if it serves a purpose. Here is the original shot with just the color cast removed.
Tumblr media
Hope this helped someone.
Let me know what your experience is.
0 notes
spassig · 7 years ago
Text
Rumblings in golang: Variables (part 2)
In my previous post I went through some considerations about variable allocations in Go. One point was about var declaration and zero-value initialization. Let’s see this more in details with this example (a bit silly but it’s just to illustrate the point).
    package main     import "fmt"
    type P struct {         x, y int     }
    func main() {         var foo int         var p P         fmt.Printf("%x\n", foo)         fmt.Printf("%x\n", p)     }
Let’s ask the compiler to emit the assembly code. 
    $ go build -gcflags="-S -N" test.go
-gcflags is used to set specific compiler switches. -N gets rid of any compiler optimization.
(This is go 1.8. Older versions of the language up to 1.5 - before the compiler itself was rewritten in Go - the equivalent command would have been
    $ go tool 6g -S -N test.go
but the 6g 6c etc tools are now deprecated)
This will generate assembly information in the binary code. Let’s look into it:
    $ objdump -dS test > test.S
and locate the main function. This is on a 64-bit Intel machine, Fedora Core 26.
    func main() {       401dd7: 4c 8d 9c 24 d8 fe ff   lea    -0x128(%rsp),%r11       [...removed...]        401dfd: 48 89 e5                     mov    %rsp,%rbp       401e00: 41 57                         push   %r15       401e02: 41 56                         push   %r14       401e04: 41 55                         push   %r13       401e06: 41 54                         push   %r12       401e08: 53                              push   %rbx       401e09: 48 81 ec f8 00 00 00 sub    $0xf8,%rsp
    var foo int       401e10: 48 c7 45 c8 00 00 00 movq   $0x0,-0x38(%rbp)       401e17: 00     var p P       401e18: 48 c7 85 e0 fe ff ff     movq   $0x0,-0x120(%rbp)       401e1f: 00 00 00 00       401e23: 48 c7 85 e8 fe ff ff     movq   $0x0,-0x118(%rbp)       401e2a: 00 00 00 00
The bold section is where variables are intitalized on the stack. And as we can see, they are initialized with their default zero-value. movq assigns zero to a quad word (64 bits). For the foo integer, this is set to zero. For the structure p which is made of two ints, every member is set to its default zero-value, which is zero again as they are ints.
It’s always interesting to look into what the compiler does. Fortunately, the go build system helps do that.
0 notes
spassig · 7 years ago
Text
Rumblings in golang: Variables
I am part of a Go study group at work and we have started discussing various topics periodically. I thought I’d use this opportunity to write a few short essays on what we discuss. This is not meant to build yet another Go tutorial but is rather a brain dump. This is the first issue of a series so stay tuned.
In this issue, a few things and considerations about variables. 
Variables can be “created” in different ways: with the var keyword, with the idiomatic := operator, with the new and make built-ins.
The only way to make sure a variable is initialized with its native zero-value (e.g. zero for ints, false for bool, etc) is to declare it with the var keyword:
    var anInt int
This is equivalent to
    anInt := 0
Go infers variable type by looking at the assigned value.
If T is a type struct{} then
    var aT T
also initializes each member of T to their default zero-value.
The new built-in is a shortcut to return a pointer to a zero-valued initialized memory. So
    t := new(T)
it a shortcut to:
    var temp T     var t = &temp
make is used to create slices, channels and maps and returns the actual value not a pointer. Slices, channels and maps are actually references to data structures so make is creating those structures in memory and returns them initialized (not zeroed) for immediate use. So make and new have different behaviours. A couple of examples:
    a := make([]int, 10) 
creates a slice. So make creates an array, and then returns a slice referencing the array. This is different from
    p := new([]int) // *p is actually a nil value so useless
Another example. 
    m := make(map[string]bool) 
creates a map, so you can do things like m[”foo”] = true and m[”bar”] = false.
Doing instead
    p := new(map[string]bool) // p is now a pointer to a nil map
will make it impossible to do e.g. (*p)[”foo”] = true, as this will panic.
0 notes
spassig · 7 years ago
Text
avr-gcc, inline assembly, local and global variables (part 2)
In my previous post I described some of the nice features of gcc inline assembly.
In this episode I want to better explain the access to local variables.
Say we need to implement these functions:
     static void c_func()      {           uint8_t volatile a;
          a = 1;      }
    static void b_func()     {          uint8_t volatile a;         
         a = 1;     }
     #define COUNT 10      static void a_func()      {          static uint8_t volatile local_static = COUNT;          static uint8_t volatile b_or_c = 0
         if (- -count == 0) {              count = COUNT;              b_or_c ^= 1;              if (b_or_c) b_func();              else c_func();          }      }
If we use the same approach we saw last time, we could start with:
   static void a_func()    {         static uint8_t volatile count = COUNT;         static uint8_t volatile b_or_c = 0;
        asm volatile (                "subi %[cnt], 1\n"                "brne 1f\n"                "ldi %[cnt], %[CNT]\n"                "ldi r16, 1\n"                "eor %[bc], r16\n"                "breq 2f\n"                "call b_func\n"                "rjmp 1f\n"        "2:\n"                 "call c_func()\n"        "1:\n"                 : [cnt] "+r" (count), [bc] "+r" (b_or_c) ��               : [CNT] "I" (COUNT)                 : "r16"         );    }
[cnt] and [bc] represents the read-write ("+r") variables. [CNT] represents the constant ("I") value defined by the macro. "r16" is the clobbered register.
Let's see the generated code:
 d2: 0f 93            push r16  d4: 90 91 00 01 lds r25, 0x0100 ; 0x800100 <__data_start>  d8: 80 91 02 01 lds r24, 0x0102 ; 0x800102 <__data_end>  dc: 91 50           subi r25, 0x01   ; 1  de: 49 f4            brne .+18          ; 0xf2 <a_func+0x20>  e0: 9a e0           ldi r25, 0x0A      ; 10  e2: 01 2d           ldi r16, 1  e4: 80 27           eor r24, r16  e6: 19 f0            breq .+6             ; 0xee <a_func+0x1c>  e8: 0e 94 5e 00 call 0xbc             ; 0xbc <b_func>  ec: 02 c0            rjmp .+4             ; 0xf2 <a_func+0x20>  ee: 0e 94 53 00 call 0xa6            ; 0xa6 <c_func>  f2: 90 93 00 01  sts 0x0100, r25  ; 0x800100 <__data_start>  f6: 80 93 02 01  sts 0x0102, r24  ; 0x800102 <__data_end> 102: 0f 91           pop r16 104: 08 95          ret
First, the clobber instruction translated into a push/pop of r16. This is good, so the content of r16 will be preserved. That was not necessary though: as function a_func() is a C called function, registers r2-r17 and r28-r29 can be freely used. This is very well referenced in Atmel Application Note AT1886[1].
Then, the compiler correctly generates (on our behalf) lds instructions to load the variables into registers r24 (for variable b_or_c) and r25 (for variable count), and the corresponding sts instructions are at the end of the function. In the meanwhile, either b_func or c_func are called. Let's see the disassembly of those functions:
000000a6 <c_func>:  a6: cf 93       push r28  a8: df 93       push r29  aa: 1f 92       push r1  ac: cd b7       in r28, 0x3d ; 61  ae: de b7      in r29, 0x3e ; 62  b0: 81 e0      ldi r24, 0x01 ; 1  b2: 89 83      std Y+1, r24 ; 0x01  b4: 0f 90       pop r0  b6: df 91       pop r29  b8: cf 91       pop r28  ba: 08 95      ret
static void __attribute((used)) b_func() {  bc: cf 93       push r28  be: df 93       push r29  c0: 1f 92       push r1  c2: cd b7      in r28, 0x3d ; 61  c4: de b7      in r29, 0x3e ; 62 uint8_t volatile a; a = 1;  c6: 81 e0       ldi r24, 0x01 ; 1  c8: 89 83       std Y+1, r24 ; 0x01 }  ca: 0f 90        pop r0  cc: df 91        pop r29  ce: cf 91        pop r28  d0: 08 95       ret
Both functions modify register r24. Therefore the value that will eventually be stored into b_or_c won't be the expected one.
So, how can we do?
An easy solution is to push and then pop the values of those variables. Like this:
     asm volatile (           "subi %[cnt], 1\n"           "brne 3f\n"           "ldi %[cnt], %[CNT]\n"           "ldi r16, 1\n"           "eor %[bc], r16\n"           "push %[cnt]\n"           "push %[bc]\n"           "breq 2f\n"           "call b_func\n"           "rjmp 1f\n"      "2:\n"            "call c_func\n"      "1:\n"            "pop %[bc]\n"            "pop %[cnt]\n"      “3:\n”             : [cnt] "+r" (count), [bc] "+r" (b_or_c)             : [CNT] "I" (COUNT)             : "r16"
The compiler will reuse the registers already allocated for variables count and b_or_c:
 c2: 90 91 01 01 lds r25, 0x0101 ; 0x800101 <count.1534>  c6: 80 91 00 01 lds r24, 0x0100 ; 0x800100 <__data_start>  ca: 91 50           subi r25, 0x01   ; 1  cc: 69 f4            brne .+26           ; 0xe8 <a_func+0x26>  ce: 9a e0           ldi r25, 0x0A      ; 10  d0: 01 e0           ldi r16, 0x01      ; 1  d2: 80 27           eor r24, r16  d4: 9f 93            push r25  d6: 8f 93            push r24  d8: 19 f0            breq .+6             ; 0xe0 <a_func+0x1e>  da: 0e 94 56 00 call 0xac             ; 0xac <b_func>  de: 04 c0           rjmp .+4              ; 0xe4 <a_func+0x26>  e0: 0e 94 4b 00 call 0x96             ; 0x96 <c_func>  e4: 8f 91            pop r24  e6: 9f 91            pop r25  e8: 90 93 01 01 sts 0x0101, r25   ; 0x800101 <count.1534>  ec: 80 93 00 01 sts 0x0100, r24   ; 0x800100 <__data_start>  f0: 08 95            ret
This is necessary, as explained in [1], because it's assembly code calling a C function, and therefore it needs to save/restore registers r18-r27, r0 and r31.
Further improvements
It is quick to see that there's no easy way to force the sts instructions to happen. In case you want to do that, you may need to code them manually. This is how is done:
      asm volatile (            "lds r15, %[cnt]            "subi r15, 1\n"            "sts %[cnt], r15            : [cnt] "+m" (count)            :            :       );
The special "m" (memory) constraint will tell the compiler to replace the %[cnt] parameter with the address of variable count.
[1] http://ww1.microchip.com/downloads/en/appnotes/doc42055.pdf
0 notes
spassig · 8 years ago
Text
avr-gcc, inline assembly, local and global variables
I was working on a set of routines that I had to implement as inline assembly (the reasons behind this are beyond the scope of this blog post), and I had to work through the quirks of the AVR-GCC inline assembly notation. For those who have never seen what I am talking about, please go here: http://www.nongnu.org/avr-libc/user-manual/inline_asm.html to get a primer on the subject before carrying on with the below.
To make things easier, let's say we have this piece of C code that we want to translate into an inline assembly code. Noone really wants to do this and with this particular code, but I thought this would be a nice and simple example to explain a few things.
    #include <avr/io.h>
    static uint8_t global_static;
    static void a_func(uint8_t n)     {          static uint8_t local_static;
         local_static += n;     }
    int main()     {          for (;;) {               global_static += 1;               a_func(global_static);          }
        return 0;     }
First of all, let's translate the for(;;) loop inside the main() function. The first question we have is: how can we refer to the global_static variable in inline assembly? There are several ways and we could use the sophisticated avr-gcc inline assembly syntax, but the easiest is: with its name! Global variables have a unique name (you can't have two global variables with the same name infact), and the linker will not make any effort to mangle their names. So we can do something like:
     int main()      {           asm volatile(                   ".loop:\n"                   "lds r24, global_static\n"                   "subi r24, -1\n"                   "sts global_static, r24\n"                   "rcall a_func\n"                   "rjmp .loop           );
          return 0;      }
What we do is: load from data space (lds) the value of global_static register r24, add 1 (AVR don't have an add immediate operation, so we subtract immediate (subi) -1), store the updated value back into data space (sts), call the a_func() function, go back and loop. Pretty much what we would have done with a standard assembly function stored in a .S file.
That was easy.
Now, on to the a_func() function. Here we have a problem: what's the best way to refer to the local_static variable? There may be another function implementing another local_static variable, so the linker needs to do something to cope with this problem, and typically what it does is to mangle the name to make it unique. The mangled name is linker/compiler dependent, and there's no standard. For example, this is how avr-ld mangles the name:
$ avr-nm main.elf (...other stuff...) 00800100 d local_static.1530 (...other stuff...)
The thing is, if we add another local static variable, even in another function, this name will change (try it yourself). In any case, we won't be able to do the inline assembly implementation as:
    static void a_func(uint8_t n)     {         asm volatile(                 "lds r25, local_static\n"                 "add r25, r24\n"                 "sts local_static, r25\n"         );      }
because local_static is not a recognized name. If we used local_static.1530 in the lds and sts instructions, it would work, but is not a viable solution as we saw before.
To solve this, we need to exploit avr-gcc inline assembly input, output and clobbers parameters. In our function,  local_static is both an input and an output variable: we need to load its value (input), add n, and store it back (output). We know the other input parameter is n.
When using this inline assembly constructs, you need to think more in terms of what you mainly need to do (in this case: add to the value of local_function the value of parameter n) rather than thinking about how this would be written in assembly. The actual implementation is indeed very simple:
    static void a_func(uint8_t n)     {           static uint8_t local_static;
          asm volatile(                   "add %[ls], %1\n" [1]              : [ls] "+r" (local_static) [2]              : "r" (n) [3]              :           ); }
We don’t care about loading/storing from/to data space, we leave that duty to the compiler. We just tell gcc that we need to add 1 to the local_static variable. And to do this, we use the avr-gcc kind of cryptic notation. Here’s what that piece of code means: Line [1] defines mnmemonic [ls] (used in place of %0) as the variable local_static, as the input/output parameter (”+“), and that we can use any registry (”r”) to work on it. Line [2] tells the compiler that parameter %1 (input) must be associated to parameter n Line [3] tells the compiler that we don't work on any register that may be used for input/output parameters (no clobbers).
This is the generated assembly code (avr-gcc -Os):
     b2: 80 91 00 01 lds r25, 0x0100 ; 0x800100 <__data_start>      b8: 98 0f            add r25, r24      ba: 90 93 00 01 sts 0x0100, r25 ; 0x800100 <__data_start>
As expected, avr-gcc generated the needed lds and sts instructions.
Another way of coding the former assembly routine is as follows, when we make output and input contraints separate and explicit:
     static void a_func(uint8_t n)      {            static uint8_t local_static;
           asm volatile(                    "add %[ls], %1\n"                    : [ls] "=r" (local_static)                    : "r" (local_static), "r" (n)                    :            );     }
0 notes
spassig · 8 years ago
Video
New York, 2004
0 notes
spassig · 8 years ago
Text
avr-gcc and a look at the generated code
I am working on a project based on ATMel MCUs, and this implies  I’mwriting C code. Since I used to write assembly code with the 8051 and similar, I wanted to take a look at how the avr-gcc generates code, and especially at how it uses optimization techniques.
I’ll give you a couple of examples here.
First, is an easy one, and is related to instructions like
DDRD |= (1 << PORTB2) | (1 << PORTB3) | (1 << PORTB5)
or in general when you need to use bitwise operations on Data Registers and I/O ports. Well, for the above expression, the compiler is recognizing that we are working on I/O ports and generates just two instructions:
100: 84 b1 in r24, 0x04 102: 8c 62 ori r24, 0x2C
No left shifts and multiple ori. Takes the address in memory for DDRD (0x04), already offset in case the bootloader is on or not, and it is or’d with the precomputed string of shifts and ors. This would be roughly equivalent to the following C code:
*DDRD = 0x2C
Second, and quite more complex, is branch instructions optimization.
I have the following C code:
void M7219_sendNumber(uint8_t digit, uint8_t singledigitnum) { if ((digit < 1) ||(digit > 8)) return; if (singledigitnum > 9) return; sendData(digit, g_segNum[singledigitnum]); }
(Yes, you guessed it right: I am interfacing Maxim’s MAX7219 to drive 7-segments displays)
Let’s see the first “if” condition in the generated assembly code:
// if ((digit < 1) || (digit > 8)) return; 180: 9f ef ldi r25, 0xFF 182: 98 0f add r25, r24 184: 98 30 cpi r25, 0x08 186: 48 f4 brcc .+18
Let’s examine what’s happening:
// Load 0XFF (-1) in r25 (a generic I/O register) 180: 9f ef ldi r25, 0xFF // Add the digit to be compared (parameter digit sits in r24) 182: 98 0f add r25, r24 // cpi Rd, K is Compare Register with Immediate. It will set the // C(arry) flag if the absolute value of K is larger than the // absolute value of Rd; cleared otherwise 184: 98 30 cpi r25, 0x08 // Branch out if the C(arry) flag is set* 186: 48 f4 brcc .+18
The compiler is applying the following[1]
THEOREM. If a and b are signed integers and a ≤ b, then
a <= x <= b is equivalent to x-a <= b-a
Applying to our case, we want to test
1 <= digit <= 8
that is equivalent, for the above theorem, to
digit - 1 <= 7
which is the test executed by the above instructions.
This is all interesting and smart.
Basically, the test can be executed with just one branch instruction instead of two.
Branch instructions are costly because they break the instructions pipelining mechanism, the CPU needs to stall and cannot preload the next instruction until the branch is resolved in real time, therefore slowing down the program execution flow.
Unless the CPU implements some sort of Branch Prediction algorithms, but these 8-bit MCUs don't.
[1] Hacker’s Delight (2nd Edition), by Henry S. Warren, ISBN 0321842685
0 notes
spassig · 8 years ago
Text
Slew rate, SID e THD
Un po’ di divertimento con SPICE.
Questa è la valutazione dello slew rate di un amplificatore - ossia quanto sia “veloce” a rispondere ai segnali in ingresso. Se un amplificatore ha uno slew rate basso, segnali oltre una certa frequenza provocano distorsione perché l'ampli non riesce a stare dietro a ciò che gli viene dato in pasto. Per valutarlo si offre una onda quadra in ingresso (traccia blu) e si valuta l'uscita (traccia verde). Come si vede, ha i bordi arrotondati indice di una limitazione dello slew rate. Per calcolare il suo valore, si mettono due cursori distanziati di 1 microsecondo sulla retta in salita e si osserva la differenza di potenziale. In questo caso, lo slew rate è di 3V/microsecondo.
3V/us è uno slew rate insufficiente. Un segnale a 20kHz con 30V di picco (tipico di un amplificatore audio a circa 50W di uscita) ha uno slew rate di 5V/us. In genere si punta ad avere uno slew rate in grado di sostenere un segnale a 50kHz a piena potenza.
Questa distorsione viene comunemente chiamata SID: Slew-rate Induced Distortion.
Tumblr media
L'effetto della limitazione dello slew rate comporta la creazione, nel segnale di uscita, di armoniche secondarie rispetto al segnale di ingresso. L'ammontare delle armoniche e rispetto al segnale principale produce quella che viene chiamata Total Harmonic Distortion, THD.
Con SPICE si può calcolare la THD passando il segnale di uscita attraverso un filtro FFT (trasformata di Fourier veloce) che evidenzia le armoniche prodotte. La foto di sotto mostra la decomposizione FFT del segnale a 20kHz in uscita dall'amplificatore. Come si nota, c'è la frequenza dominante a 20kHz, ossia il segnale puro in ingresso, con guadagno di circa 23dB. Ma ci sono anche armoniche ad ogni ottava successiva (40kHz, 60kHz etc).
Tumblr media
Il calcolo della THD è una media quadratica delle potenze delle armoniche rispetto al segnale principale. SPICE, per nostra fortuna, fa il calcolo da solo. In questo caso la THD è 0.5%, un valore abbastanza altino. Un buon amplificatore audio ha la THD inferiore allo 0.01% a 20kHz.
Queste le direttive SPICE per l’analisi spettrale a 20kHz (vout è il nodo di uscita dell’amplificatore):
.tran 400us .option plotwinsize=0 .options maxstep=0.02441555u .four 20khz v(vout)
1 note · View note
spassig · 8 years ago
Text
OpenDNS, Vodafone & iptables
Per varie ragioni, ho deciso di usare OpenDNS sul laptop che usano i ragazzi.
Nulla di più semplice, mi dico, basta cambiare /etc/resolv.conf e mettere i nameserver forniti da OpenDNS.
Col caschio, col fischio.
Ho scoperto che Vodafone implementa il Transparent DNS Proxy imponendo i suoi DNS anche se tu ne vuoi usare altri. Alla faccia della net neutrality.
Questo è facilmente verificabile eseguendo il test presente su https://www.dnsleaktest.com/.
Ecco il mio risultato.
Tumblr media
/etc/resolv.conf punta ai nameserver OpenDNS mentre in realtà alla fine usiamo questi:
Come fare dunque?
Il protocollo DNS viaggia sulla porta 53 ed è molto probabile Vodafone filtri solo quella. Se OpenDNS ascoltasse anche su altre porte avremmo la soluzione a portata di mano.
Questi provider DNS forniscono in genere ascolto anche su porte alternative come la 443 (SSL, aperta sempre da tutti) e 5353 (facile da ricordare). Verifichiamo:
$ dig @208.67.220.220 -p 443 www.repubblica.it ; DiG 9.10.4-P2-RedHat-9.10.4-1.P2.fc24 @208.67.220.220 -p 443 www.repubblica.it ; (1 server found) ;; global options: +cmd ;; Got answer: ;;HEADER;- opcode: QUERY, status: NOERROR, id: 24440 ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;www.repubblica.it. IN A ;; ANSWER SECTION: www.repubblica.it. 52 IN CNAME www.repubblica.it.edgekey.net. www.repubblica.it.edgekey.net. 18887 IN CNAME e7047.e12.akamaiedge.net. e7047.e12.akamaiedge.net. 20 IN A 23.40.162.106 ;; Query time: 65 msec ;; SERVER: 208.67.220.220#443(208.67.220.220) ;; WHEN: Sat Oct 01 22:21:54 CEST 2016 ;; MSG SIZE  rcvd: 140
Stesso risultato per la porta 5353. Perfetto.
Altra vittoria dei nerd. Perché i nerd non si arrendono mai.
Il gioco è fatto. Ora dobbiamo reindirizzare qualsiasi richiesta ai server OpenDNS con destinazione porta 53 standard sulla porta 443. Banalità:
$ sudo iptables -t nat -A OUTPUT -p udp --dport 53 -j NAT --to 208.67.220.220:443 $ sudo iptables -t nat -A OUTPUT -p tcp --dport 53 -j NAT --to 208.67.220.220:443
0 notes
spassig · 9 years ago
Text
Miusikette
Qualche pezzo che mi ha recentemente entusiasmato. Sto ascoltando più musica di recente e la cosa non può che fare bene.
Ordunque:
Andrew Bird - Roma Fade
youtube
Lui dice che il pezzo "is about the wordless dialogue between the watcher and the watched and the fine line between romance and creepiness". Vabbè. OK. Ci credo. Molto romantica in effetti con questo ritmo in levare, il pizzicato degli archi, il fischiettìo, un pezzo un pò d'altri tempi, ma che se ti entra in testa non esce più. Black Mountain - Florian Saucer Attack
youtube
Dal Canada. Un po' Blondie, un po' psycho, un po' hippie, un po’ Futurama, comunque molto sixties/seventies, quindi yeah yeah, adatta per i veci come me/noi/voi. Vi sfido a non dondolare su e giù con la testa. Motta - Sei Bella Davvero
youtube
Anche qui atmosfere deja vu beatlesiane, mescolate a sonorità tipicamente italiane ma non (grazie a dio) sanremesi e arrangiamenti un po' new wave un po' (ma proprio poco) prog. Dai, per essere itaGliano non è proprio ‘accio. Michael Kiwanuka - Black Man In A White World
youtube
E qua ci spostiamo su altre timbriche, vocali soprattutto, tra (parecchio) Marvin Gaye, i Traffic, le chitarre da sigle polizieschi anni 70 unite ad anime afro, soul e jazz. Gajarda. Super Gajarda. Parov Stelar - The Sun
youtube
E ricambiamo timbriche, anche qui vocali, soprattutto. La voce è maschile, ad esempio. Ve lo avevo detto che avremmo cambiato timbriche, no? Un pezzo per finire il venerdì lavorativo, spensieratamente e magari con un birrozzo a cercare/guardare il sole, e sperando ci sia anche nel weekend.
0 notes
spassig · 9 years ago
Text
And all the fat, skinny people And all the tall, short people And all the nobody people And all the somebody people I never thought I'd need so many people
0 notes
spassig · 9 years ago
Video
Perugia
flickr
Perugia Exactly two years ago.
1 note · View note
spassig · 9 years ago
Video
A.  This is why I love film.
3 notes · View notes
spassig · 9 years ago
Photo
Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media
Goodbye, Holga
La fabbrica della Holga ha chiuso. Qualche scatto fatto con quella macchina di plastica, una delle cose fotograficamente più divertenti che mi siano mai capitate tra le mani.
0 notes
spassig · 9 years ago
Photo
Tumblr media
Prague
1 note · View note
spassig · 9 years ago
Photo
Tumblr media
Somewhere in Greece, last year.
0 notes
spassig · 9 years ago
Photo
Tumblr media Tumblr media Tumblr media
Somewhere in Greece.
Shot last year, developed and scanned one year later.
1 note · View note