7. Formatos AIFF y AIFC

El formato AIFF (Audio Interchange File Format) está muy extendido en plataformas Apple. Se fundamenta en el formato IFF de Electronic Arts, que permite almacenar la información en segmentos (o chunks). El formato AIFC es una extensión que permite la compresión de los datos de audio.

Cabecera IFF

Al tratarse de un fichero de formato IFF, debe contener al comienzo una cabecera con un primer campo de 4 bytes que contiene la palabra "FORM", un segundo campo de 4 bytes que indica la longitud del resto del fichero. Por último para identificar el fichero IFF como contenedor de audio AIFF, los 4 bytes siguientes a la cabecera deben contener la palabra "AIFF":

  		struct {
 			 char id[4];
 			 DWORD len;
 		} iff_hdr; 
		char aiff_id[4]; 

Chunks AIFF

A partir de la cabecera y la identificación el resto del fichero se compone de una secuencia de segmentos. Cada segmento se compone a su vez de una cabecera de segmento compuesta por 4 bytes de identificación y 4 bytes de longitud del campo de datos. Esta longitud no incluye ni la cabecera ni el posible byte que pueda haber para hacer que su longitud total sea par. El orden de estos segmentos es irrelevante.

Sólo existe un segmento obligatorio denominado Segmento Común ("COMM") y en el caso de que la forma de onda tenga longitud mayor que cero, también es obligatoria la existencia del segmento Datos de Sonido ("SSND"). El resto de segmentos son opcionales y los programas de reproducción podrán ignorarlos selectivamente. Sin embargo a la hora de copiar el fichero se deben copiar la totalidad de los segmentos incluidos los que son ignorados en la reproducción.

Generalidades del formato AIFF

La ordenación de los bytes en formato AIFF es de tipo big-endian como en el microprocesador 68000 de Motorola. Las muestras de la señal se almacenan en el menor número entero bytes, rellenando los bits sobrantes con ceros. En cada muestra los bits de información se sitúan en las posiciones de mayor peso, quedando el relleno de 0's en las posiciones menos significativas.

Las reproducciones multicanal se organizan de la siguiente forma: los muestras se agrupan en tramas de muestra, que son un conjunto de muestras, cada una de las cuales corresponde a un canal distinto. Está definido el siguiente orden para las siguientes situaciones:

Las muestras pertenecientes a una trama de muestra se empaquetan una tras otra, sin rellenos, al igual que las tramas de muestra entre sí.

Segmento Común (Common Chunk)

Describe parámetros fundamentales de la forma de onda almacenada como la tasa de muestreo, el número de bits por muestra y el número de canales. Se identifica por la secuencia "COMM".

struct { short numChannels;
unsigned long numSampleFrames;
short sampleSize;
extended sampleRate;
}CommonChunk;
numChannels Especifica el número de canales en el segmento de datos.
numSampleFrames Indica el número de cuadros que contiene el segmento de datos. El número total de muestras es este valor multiplicado por el número de canales.
sampleSize Especifica el número de bits por muestra. Puede tomar un número entre 1 y 32.
sampleRate Indica la tasa a la que las muestras se deben reproducir.

Segmento de datos de sonido (Sound Data chunk)

Contiene todos las muestras, las de todos los canales de sonido. Su identificativo es "SSND". Es un segmento obligatorio salvo que el campo numSampleFrames del segmento común valga cero.

struct { unsigned long offset;
unsigned long blockSize;
unsigned char WaveformData[];
} SoundDataChunk;
offset Indica el comienzo de la primera trama de muestras. En la mayoría de los casos no se empleará y contendrá un valor cero. Su utilización está asociada a la alineación en bloques.
blockSize Tamaño de bloque. Es el número de bytes de los bloques a los que la forma de onda se alinea.
WaveformData Los datos de la forma de onda.

Alineación en bloques de los datos

La alineación de bloques es una necesidad que presentan algunas aplicaciones para poder realizar una reproducción y grabación en tiempo real. Por ello se permite dividir la información en bloques de blockSizeBytes y alinearlos mediante offset. Las aplicaciones que no requieran de esta ordenación, no deben usarla y si operan con un fichero con esta ordenación es conveniente que la mantengan, aunque no es obligatorio.

Segmento Marker

Sirve para indicar determinadas posiciones de la forma de onda contenida en el fichero, para cualquier propósito. Las marcas definidas con este segmento, que se identifica por "MARK", son utilizadas por otros como referencias.

struct { unsigned short numMarkers;
Marker Markers[];
} MarkerChunk;
struct {
short id;
unsigned long position;
pstring markerName;
} Marker;
numMarkers Número de marcas definidas en el segmento.
id Es un número que identifica de forma única a la marca dentro del fichero AIFF. Debe ser un número mayor que cero.
position Indica la posición de la marca. En AIFF las marcas se sitúan entre tramas de muestras, considerando que una marca antes de la primera trama de muestra tiene posición cero.
markerName Es una cadena tipo PASCAL que contiene la descripción de la marca. Estas cadenas tienen como primer elemento la longitud de la cadena, a la que siguen los caracteres.

Segmento de instrumento

Define unos parámetros básicos que un instrumento, como uno MIDI, puede utilizar para reproducir la forma de onda. Se identifica por la cadena "INST".

struct { char baseNote;
char detune;
char lowNote;
char highNote;
char lowVelocity;
char highVelocity;
short gain;
Loop sustainLoop;
Loop releaseLoop;
} InstrumentChunk;
baseNote Indica el número de la nota a la que el instrumento reproduce la forma de onda sin modificación de tono. (Esto es, a la misma tasa de muestras a la que fue creado). Las unidades son notas MIDI, de 0 a 127.
detune Determina cuanto debe ser modificado el tono cuando el sonido se reproduce. Se especifica en centésimas de semitono, pudiendo variar entre –50 y +50. Los números negativos indican que el tono debe ser bajado.
lowNote y highNote Especifican el rango de notas recomendado en un teclado para la reproducción de la forma de onda. La forma de onda se debe reproducir si al teclado se le pide una nota dentro de este rango, extremos incluidos. El valor de baseNote no tiene por qué estar en este rango.
lowVelocity y highVelocity Especifica el rango de velocidades a las que se deben reproducir las notas. Aquellas notas que indiquen una velocidad dentro de este rango, extremos incluidos, deben ser reproducidas. Las unidades son valores MIDI: 1 (la más lenta) y 127 (la más rápida).
gain Especifica la ganancia que se debe aplicar al sonido cuando se reproduce. Se mide en dB, con 6 dB se multiplican las muestras por 2 y con –6 dB se dividen por 2.
sustainLoop Especifica un bucle a ser reproducido cuando el instrumento sostiene un sonido.
releaseLoop Especifica un bucle que se reproduce cuando el instrumento está terminando la reproducción de un sonido.

Los bucles utilizados en este segmento se organizan según la siguiente estructura: struct { short PlayMode;
short beginLoop;
short endLoop;
} Loop;
PlayMode Especifica el modo de reproducir el bucle. Hay tres formas:
  • NoLooping: No realiza bucles
  • ForwardLooping: Desde el inicio al final
  • ForwardBackwardLooping: Del inicio al final y del final al inicio.
beginLoop Identifica la marca de comienzo de la forma de onda a reproducir.
endLoop Identifica la marca de final de la forma de onda a reproducir.

Segmento de datos MIDI

Como su nombre indica permite almacenar datos MIDI en el fichero AIFF. Se identifica por la cadena "MIDI". Consta de un único parámetro que es una secuencia de bytes que contiene los datos MIDI. Su presencia es opcional y puede haber más de uno en un fichero AIFF. En el caso de disponer de información relativa a varios instrumentos, se recomienda que exista un segmento "MIDI" por instrumento en lugar de un único segmento para todos.

Su propósito fundamental es contener los denominados MIDI System Exclusive Messages asociados sobre todo a parámetros MIDI que aparezcan después de la especificación de AIFF y que por tanto no están recogidos en el segmento de instrumento o que recogen capacidades exclusivas de algún instrumento que los demás no pueden interpretar.

Segmento de grabación de audio

Se identifica por "AESD". Contiene una tabla de información descrita en el "AES Recommended Practice for Digital Audio Engineering - Serial Transmission Format for Linearly Represented Digital Audio Data".

Su presencia es opcional y no puede haber más de uno en un fichero AIFF. Esa información se incluye en el formato AIFF por conveniencia, al describir parámetros útiles para la grabación del sonido.

Segmento específico de aplicación

Permite introducir datos para cualquier fin tanto a desarrolladores como a creadores de aplicaciones. Se identifica mediante la cadena "APPL".

struct { char applicationSignature[4];
char data[];
} ApplicationSpecificChunk;
applicationSignature Permite distinguir entre diversos segmentos específicos de aplicaciones.
data Datos relacionados con la aplicación.

Segmento de comentarios

El formato IFF define un segmento para la introducción de comentarios que también puede ser usado. El segmento de comentarios AIFF, identificado por "COMT" tiene una estructura más elaborada, su presencia es opcional pero no debe aparecer más de un segmento por fichero.

struct { unsigned long timeStamp;
short marker;
unsigned short count;
char text[];
} Comment;
timeStamp Especifica el momento en el que el comentario se creó. En plataformas Amiga se mide en segundos desde el 1 de Enero de 1978; en Mac, desde el 1 de Enero de 1904.
marker Su su valor es distinto de cero, identifica un marca, permitiendo hacer comentarios sobre marcas en la forma de onda. Si vale cero, el comentario no se asocia a ninguna marca.
count Indica la longitud del texto que forma el comentario. Al ser de 16 bits permite comentario mucho mayores a los que se podrían realizar con una cadena tipo PASCAL.
text Cadena de texto que constituye el comentario.

Segmentos de texto: nombre, autor, copyright y anotación

Este conjunto de segmentos se identifican, respectivamente, por "NAME", "AUTH", "(c) " y "ANNO". Todos tienen la misma estructura. Sólo contienen un elemento, que es la cadena de caracteres que describe lo que el segmento indica en cada caso.