#include #include #include #include #include #include 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); }