Para comprender por qué se usan enteros seguros de sincronización, es útil comprender un poco sobre el formato de los datos MP3, así como también cómo un reproductor de MP3 reproduce un archivo. Los datos MP3 se almacenan en un archivo como una serie de marcos. Cada cuadro contiene un pequeño fragmento de música digital codificada en formato MP3, así como algunos metadatos sobre el propio cuadro. Al comienzo de cada fotograma de MP3 hay 11 bits (a veces 12) todos configurados en 1. Esto se llama sincronización, y es el patrón que busca un reproductor de medios cuando intenta reproducir un archivo o transmisión MP3. Si el jugador encuentra esta secuencia de 11 bits, entonces sabe que encontró un cuadro de MP3 que puede decodificarse y reproducirse.
Ver: www.id3.org/mp3Frame
Como sabe una etiqueta ID3 contiene datos acerca de la pista en su conjunto. Una etiqueta ID3, en la versión 2.xy posterior, se encuentra al principio de un archivo, o incluso se puede incrustar en una transmisión de MP3 (aunque esto no suele hacerse). El encabezado de una etiqueta ID3 contiene un campo de tamaño de 32 bits, que indica cuántos bytes hay en la etiqueta. El valor máximo que un entero sin signo de 32 bits puede contener es 0xFFFFFFFF. Entonces, si escribimos 0xFFFFFFFF en el campo de tamaño, estamos reclamando una etiqueta realmente grande (pragmáticamente demasiado grande). Cuando el jugador intenta reproducir el archivo o la transmisión, busca la secuencia de 11 bits de un fotograma de datos MP3, pero en su lugar encuentra el campo de tamaño en el encabezado de etiqueta ID3 e intenta reproducir la etiqueta, ya que el campo de tamaño tiene los primeros 11 bits establecidos Por lo general, esto no suena tan bien, dependiendo de tus gustos musicales. La solución es crear un formato entero que no contenga secuencias de 11 bits de todos los 1. De ahí el formato entero seguro de sincronización.
Un número entero de sincronización de fallos se puede convertir en un número entero en C/C++ usando algo como el siguiente:
int ID3_sync_safe_to_int(uint8_t* sync_safe)
{
uint32_t byte0 = sync_safe[0];
uint32_t byte1 = sync_safe[1];
uint32_t byte2 = sync_safe[2];
uint32_t byte3 = sync_safe[3];
return byte0 << 21 | byte1 << 14 | byte2 << 7 | byte3;
}
Hope esto ayuda.
Gracias, mucho. Pensé que nunca lo conseguiría. –
¡Explicación impresionante, hombre! +1! – jwueller
Explicación muy clara. gracias amigo :) –