[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