On Fri, Mar 29, 2002 at 01:04:58AM -0800, Rob Leslie wrote:
On Tuesday, March 26, 2002, at 12:23 AM, Dirk Nehring wrote:
I'm writing a program to correct bad MP3 files (by dropping bad frames, dropping IDv2 tags on demand, etc.) by using libmad. One point is that I want to add an CRC-16 checksum to the header. Can I use the libmad low level interface for this (i.e. set protection bit, and call mad_frame_decode(), get crc-checksum from header->crc_target)?
You probably can't add a checksum easily if there isn't one already because it involves adding a 16-bit field to the audio data region, and you may not have enough room for it in every frame.
I haven't understand it fully: if I use a CRC check field, I loose 2 bytes from the data field. If this is true, I think it is impossible to add a CRC field afterward.
If you can overcome that problem, your strategy might work. If you mark the protection bit in the frame header, make sure you call mad_frame_decode() with the CRC field present or it will compute the wrong CRC.
The computed CRC is in header->crc_check.
I developed the following lines:
---------------------------------------------------------- unsigned short crc_check; struct mad_bitptr crc_buffer; unsigned int nch, si_len;
ptr = (unsigned char *) Stream.this_frame; ptr2 = (unsigned char *) Stream.next_frame;
crc_check = 0xffff; mad_bit_init(&crc_buffer, ptr + 2); crc_check = mad_bit_crc(crc_buffer, 16, crc_check);
nch = MAD_NCHANNELS(&Frame.header); si_len = (Frame.header.flags & MAD_FLAG_LSF_EXT) ? (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32);
if (Frame.header.flags & MAD_FLAG_PROTECTION) { mad_bit_init(&crc_buffer, ptr + 6); crc_check = mad_bit_crc(crc_buffer, si_len * 8, crc_check); if (crc_check != Frame.header.crc_target) { fprintf(stderr, "%s: Correct wrong crc16 checksum, expected 0x%x, got 0x%x.\n", ProgName, crc_check, Frame.header.crc_target); ptr[4] = crc_check >> 8; ptr[5] = crc_check & 255; } } else { unsigned char ch;
mad_bit_init(&crc_buffer, ptr + 4); crc_check = mad_bit_crc(crc_buffer, si_len * 8, crc_check); ptr[1] -= 1; /* set protection_bit */ } ----------------------------------------------------------
Is it theoretically possible to add an CRC checksum to a frame without reencoding?
Dirk