[Tech] Domanda di C

Franco Bagnoli bagnoli@dma.unifi.it
Gio 27 Maggio 2004 15:52:58 CEST


On Thu, 27 May 2004, Valerio Montagnani wrote:

> > a questo punto sono io che non capisco. Se i dati sono signed char perché 
> > li converti a short? Sei tu che li converti? e che te ne frega se sono 
> > little endian in memoria? 
> 
> Ho un sensore acustico che acquisisce dati. La scheda audio di un
> computer opera da ADC (convertitore analogico-digitale) e mi restituisce
> un vettore signed char. Il vettore signed char viene decimato,
> eliminando il segnale del canale dx. A questo punto trasformato in un
> vettore di dati float per l'elaborazione numerica e le varie misure da
> fare.


> 
> Se vado a rappresentare con un programma di elaborazione di tracce
> musicali, come audacity, il vettore acquisito,

intendi prima della conversione a float? quando sono ancora signed char?

>  scopro che ha livelli
> molto bassi. Ciò che mi è venuto in mente di fare, quindi è di aumentare
> i livelli del segnale, moltiplicando i campioni per un valore di
> amplificazione. Tuttavia i dati signed char possono rappresentare valori
> compresi tra -128 e 127, quindi se voglio dei valori maggiori per i
> campioni, senza incorrere negli errori di rappresentazione in modulo 2,
> devo per forza trasformare i dati di partenza in qualcosa che mi
> permetta di rappresentare numeri più grossi. Visto che successivamente
> lovorerò con valori float, sicuramente trasformerò i dati di partenza in
> float prima di fare l'elaborazione numerica.
> 
> Il problema del little-endian era nato ieri quando leggevo dei documenti
> relativi alla rappresentazione dei dati audio, perchè mi piaceva vedere
> l'andamento del segnale dopo l'amplificazione (usando audacity).
> Tuttavia come vi dicevo oggi, mi sembra inutile disassemblare il dato
> little-endian amplificarlo singolarmente e riassemblarlo, basta
> moltiplicare tutto per il fattore di amplificazione, e automaticamente
> sia la parte low che la high del dato saranno opportunamente
> amplificate. Si incorre in un errore di rappresentazione solo se
> tratterò il dato secondo un formato NON little-endian.

assolutamente no. Se i dati sono signed char non c'è nessun little o 
big-endian. Sono char e basta. Se, supponiamo, prendi uno short 
little-endian su una macchina big-endian e lo moltiplichi per qualcosa, 
ottieni un numero che ha poco a che fare con quello di partenza, dato che 
i bit delle due parti si sono rimescolati. Peggio che mai se lo converti 
in float. 

diciamo che ti funziona perché i processori intel sono little-endian e 
quindi non fai nessuna cornversione. 


> 
> Ora, se io volessi rivedere l'effetto di questa elaborazione su
> audacity, devo far capire a audacity che ha a che fare con una serie di
> dati little-endian a 32 bit (float), impostare il numero dei canali e la
> freq di campionamento giusti, e non più little-endian 16 bit; così
> facendo mi aspetto di poter vedere opportunamente il mio nuovo segnale.

little-endian sono solo per interi (o meglio: parole), non esistono 
little-endian per i float (anche se ovviamente, dato che i float sono 
memorizzati su delle parole è differente memorizzare un float in una 
parola little-endian o big-endian). Ma per i float ci sono anche altri 
problemi, sul tipo di rappresentazione. 

> 
> Lascia stare il fatto che nella mail precedente dicevo di trattare il
> dato come double. Parliamo in termini di float. I float sono
> rappresentati come dati in virgola mobile, quindi come mantissa e
> esponente, a differenza dei dati int, char....
> 
> Non capisco che cosa significa che il dato ha poco a che fare con il
> numero originario: vuoi dirmi che è diversa la rappresentazione in
> macchina, vero?

Supponiamo di lavorare con un computer big-endian (ovvero di scrivere i 
dati come siamo abituati: 

a = 03 10 (in esadecimale per fare prima) = (0*16+3)*256+(1*16+0) = 784
Se il dato viene da un file little-endian invece diventa, quando lo stampi 
per esempio: (1*16+0)*256+(0*16+3)=4099.

Chiaramente se converti a float ottieni li stessi numeri (con la virgola): 
a=784.0 in un caso, a=4099.0 nell'altro. Non mi sembrano la stessa cosa. 

Se  moltiplichi gli interi per 16 per esempio (shiftando il numero di 4 
bit), ottieni nel primo caso 31 00 = 4864, nel secondo 
00 30 (l'1 si perde) = 48

Se invece moltiplichi i float ottieni 12544.0 nel primo caso, 65584.0 nel 
secondo. Ma quando poi li riconveri a interi ottieni il valore di cui 
sopra, in nessun caso "è uguale" moltiplicare i numeri con una 
rappresentazione diversa da quella della macchina, perché la macchina fa 
le operazioni seguendo le regole sue. 


-- 
Franco Bagnoli (franchino) <bagnoli@dma.unifi.it> 
virtual location: Dipartimento di Energetica "S. Stecco"
ultra-virtual affiliation: Centro Dinamiche Complesse (CSDC-Firenze)
real location: Dip. Matematica Applicata "G. Sansone", Universita' Firenze,
Via S. Marta, 3 I-50139 Firenze, Italy. Tel. +39 0554796422, fax: +39 055471787




Maggiori informazioni sulla lista flug-tech