rendered paste body#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <libavutil/crc.h>
int main(int argc, char *argv[])
{
int fd = open(argv[1], O_RDONLY);
uint8_t buffer[38];
unsigned int offset = 0;
AVCRC crc_2D[1024];
int rate = 0;
int substreams = 0;
/* search for major sync header first to align */
memset(buffer, 0, sizeof(buffer));
while(read(fd, buffer + 4, 1) == 1) {
++offset;
uint32_t syncword = ((((buffer[0] << 8 | buffer[1]) << 8) | buffer[2]) << 8) | buffer[3];
if (syncword == 0xf8726fba)
{
offset -= 9;
lseek(fd, -9, SEEK_CUR);
break;
}
memmove(buffer, buffer + 1, 4);
}
av_crc_init(crc_2D, 0, 16, 0x2D, sizeof(crc_2D));
/* read the access units */
while(read(fd, buffer, sizeof(buffer)) == sizeof(buffer)) {
int valid = 1;
uint16_t length = ((buffer[0] & 0x0F) << 8 | buffer[1]) << 1;
uint32_t syncword = ((((buffer[4] << 8 | buffer[5]) << 8) | buffer[6]) << 8) | buffer[7];
printf("offset: 0x%08x, length: %3d, ", offset, length);
/* check for a major audio unit */
if (syncword == 0xf8726fba)
{
rate = (buffer[8] & 0xF0) >> 4;
if (rate == 0xF)
{
rate = 0;
valid = 0;
}
else
rate = (rate & 8 ? 44100 : 48000) << (buffer[8] & 7);
/* verify the CRC */
if (valid)
{
uint16_t crc = av_crc(crc_2D, 0, buffer + 4, 24);
crc ^= (buffer[29] << 8) | buffer[28];
valid = ((buffer[31] << 8) | buffer[30]) == crc;
}
substreams = (buffer[20] & 0xF0) >> 4;
}
else
{
/* verify the parity */
int p = 0;
uint8_t check = 0;
for(int i = -1; i < substreams; ++i)
{
check ^= buffer[p++];
check ^= buffer[p++];
if (i == -1 || buffer[p - 2] & 0x80)
{
check ^= buffer[p++];
check ^= buffer[p++];
}
}
valid = ((((check >> 4) ^ check) & 0xF) == 0xF);
}
printf("%s, %dHz, %d substreams\n", valid ? "Valid" : "Invalid", rate, substreams);
lseek(fd, length - sizeof(buffer), SEEK_CUR);
offset += length;
if (!valid)
{
printf("Lost Sync\n");
break;
}
}
close(fd);
}