Newsgroup: it.comp.lang.visual-basic
Titolo: [scansione binaria file] [lungo ma veloce] file mpeg

salve
sto realizzando un programmino che legga la struttura di un file mp3 e ne
restituisca le caratteristiche (n° frame, bitrate e altre cosine), come fa
WINAMP quando restituisce le info file.
PREMESSA:
un file mpeg è costituito da una serie di FRAME di lunghezza variabile
(questo permette di riprodurre anche file spezzati). Ogni frame ha un header
di 4 byte:
AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
per indicare che il blocco è un frame header tutti i bit A devono essere
settati a valore 1 quindi
byte 1 = 11111111  --> quindi valore = 255
byte 2 = 111xxxxx  --> quindi 223 < valore < 256
1° quesito
----------
CODICE:
per cercare gli header opro il file in modalità binaria e scorro tutto il
file byte per byte avanzando di un byte per volta. memorizzo ogni coppia di
byte in un array (frameSync) e ne verifico i valori.
ho provato con un piccolo file, winamp mi dice che ha 990 frames, il mio
programma ne trova 3696!!!
sono sicuro che il file venga letto completamente perchè scrivo in un file
di testo il contenuto di ogni singolo byte.
dim numFrame        'conteggio frame
numFrame = 0
For i = 1 To mp3FileDim Step 1
    If Asc(frameSync(0)) = 255 And (Asc(frameSync(1)) > 223 And
Asc(frameSync(1)) < 256) Then
        'conto i frame header
        numFrame = numFrame + 1
    End If
next
2° quesito
----------
perchè con un file di 403kb winamp restitiuisce  tutte le info in modo
istantaneo e invece il mio sw impiega 2 min e 14 sec?
3° quesito
----------
come faccio a sapere il valore di un singolo bit all'interno di un byte?
ex.:
nel byte 2 gli ultimi 5 bit indicano:
BB --> la versione del compressore mpeg
CC --> il layer utilizzato
D  --> la presenza di altri 4 byte di CRC
mica dovrò calcolare e verificare singolarmente ogni combinazione
possibile!!!
tnx in advance
TaTo

 mica dovrò calcolare e verificare singolarmente ogni combinazione
possibile!!!
La funzione logica AND serve a quanto richiesto
la relativa tabella della verità indica quanto segue:
U=A AND B
A B   U
0  0    0
0  1    1
1  0    1
1  1    1
ovvero il risultato è 1 quando almeno uno dei bit è a 1
ne consegue che se vuoi sapere lo stato del bit nr.3 devi eseguire un AND
con un numero con il solo bit 3 attivato
es. byte da testare 01101100
richiesta stato bit 3 (da destra verso sinistra iniziando il conteggio con
zero)
numero con bit 3 attivato 00001000
01101100 AND 00001000 = 00001000 (cioè bit 3 attivato)
es. byte da testare 11010011
richiesta stato bit 3 (da destra verso sinistra iniziando il conteggio con
zero)
numero con bit 3 attivato 00001000
11010011 AND 00001000 = 00000000 (cioè bit 3 disattivato)
naturalmente spesso non trattiamo numeri binari ma decimali quindi:
es. byte da testare 108
richiesta stato bit 3 (da destra verso sinistra iniziando il conteggio con
zero)
numero con bit 3 attivato 8 (cioè 2 ^ 3)
108 AND 8 = 8 (cioè bit 3 attivato)
ovvero
108 AND (2^3) = 8
es. byte da testare 211
richiesta stato bit 3 (da destra verso sinistra iniziando il conteggio con
zero)
numero con bit 3 attivato 8
211 AND 8 = 0 (cioè bit 3 disattivato)
ovvero
211 AND (2^3) = 0
se ne deduce che se l'esigenza e unicamente quella di verificare lo stato di
un bit
si esegue un AND con (2^bit)
se il risultato è 0 il bit è spento
altrimenti è acceso
Altre volte la necessità è quella di rilevare un numero indicato da alcuni
bit
in questo caso si svolge la stessa funzione descritta sopra
di seguito di divide il risultato per 2 un certo numero di volte:
Es.
in un ipotetico file di un'immagine il terzo byte contiene il numero di
colori
precisamente (nell'ambito del byte) i bit 5°, 4° e 3°
byte estratto: 10101010 ovvero 170
estrazione bit: 10101010 AND 00111000 = 00101000 ovvero 170 AND (2^5 OR 2^4
OR 2^3) = 40
per ottenere il numero è necessario shiftare (spostare) i bit a destra di
tre posizioni
ovvero dividere per 2 un numero di volte pari a 3
00101000 shift a destra 3 volte = 00000101
ovvero 40 / (2^3) = 5
Tutto chiaro ?
--
Mauro
www.cerretosoft.it


penso di si
proverň
tnx!!!
TaTo


L'esempio e' sbagliato perche' si tratta del'operatore OR non AND.
La tabella per L'operatore AND e' questa.
X = A and B
A B  X
0 0  0
0 1  0
1 0  0
1 1  1
------------
X = A or B
A B  X
0 0  0
0 1  1
1 0  1
1 1  1
------------
X = A xor B
A B  X
0 0  0
0 1  1
1 0  1
1 1  0
CIAnO

 istantaneo e invece il mio sw impiega 2 min e 14 sec?
Perchè se il file ha un rate costante legge solo il primo pacchetto dati...
se invece è variabile ne fa una stima... leggendone alcuni... suppongo...
Ciao

 CIAnO
Hai ragione !!! Troppe chiacchere ad ora tarda fanno male !! Scusate !
--
Mauro
www.cerretosoft.it

 wrote in message
news:abof8e$2rt6$1...@half.spin.it...

mi spiace ma.... supponi male.
la struttura mpeg consiste nel creare un file unico unendo una serie di
frame consecutivi totalmente indipendenti l'uno dall'altro.
questa caratteristica permette, come già detto in precedenza, di riprodurre
un file anche se incompleto.
nello specifico, per gli mp3 so che (quello che ho trovato in rete perchè
tale codifica è copyrighted) _per_ogni_frame_ viene indicato nell'header (4
byte) il bitrate del singolo frame.
quindi se è un file di tipo VBR in ogni frame sono indicati valori
differenti di bitrate, nel caso invece di NON VBR in ogni singolo frame è
indicato lo stesso valore di bitrate (ma cmq indicato in ogni singolo frame)
ciaz

 singolo frame)
E io che avevo detto? :?

 wrote in message
news:abqfgr$265o$1...@half.spin.it...

1) il fatto di winamp sulla durata del file non la sapevo...
2) per quel che ne so in ogni header sono indicate le caratteristiche del
frame a cui fanno riferimento. sempre per quanto ne so io non esistono
indicazioni riguardo il frame al difuori del proprio header
3) magari ne so male ;-((

 esistono indicazioni riguardo il frame al difuori del proprio header
Appunto tu hai un file a rate costante; rate costante significa che TUTTI i
pacchetti avranno le STESSE caratteristiche (bit rate, dimensione ecc...):
cambierà SOLO il contenuto (la descrizione dell'onda). Dati i presupposti se
ti metti a leggere l'header di ogni pacchetto troverai sempre le stesse
informazioni quindi non serve a nulla farlo: basta leggere tali dati dal
primo pacchetto. Come ho anche cercato di spiegarti per ottenere poi il
numero dei pacchetti basta prendere la dimensione del file e dividerla per
la dimensione del primo pacchetto... :)
Nel caso di rate variabile l'unica è leggersi tutto il file per avere il
dato accurato oppure ricavarsi una media su n pacchetti...
Ciao