Also ich habe das in einem Framescanner mal so gemacht (C-Code)
Code:
//======================================================================
//
// Aufbau des MPEG Audio Synchronisationswort
//
// ========0======== ========1======== ========2======== ========3======== Byte
// 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 Bit
//
// 1 1 1 1 1 1 1 1 1 1 1 1 ~0-0 ~1-1-1-1 1-1~ Valid
// X x x x x x x X X 1-1 Compatible
//
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
// |1 1 1 1 1 1 1 1| |1 1 1 1| | | | | | | | | | | | | | |
// +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
// | | | | | | | | | | | |
// | | | | | | | | | | | +-- emphasis
// | | | | | | | | | | +----- original
// | | | | | | | | | +------- copyright
// | | | | | | | | +---------- mode extension
// | | | | | | | +-------------- mode
// | | | | | | +------------------- extension
// | | | | | +--------------------- padding
// | | | | +------------------------ frequency (0,1,2)
// | | | +------------------------------ bitrate (1-14)
// | | +------------------------------------- no crc check
// | +---------------------------------------- layer (1,2,3)
// +------------------------------------------- version (0,1)
//
//======================================================================
union l3f_syncword {
unsigned char sw_b[4];
unsigned long sw_l;
};
#define L3F_SYNC_VALID(sw) \
( (sw).sw_b[0] == 0xff \
&& ((sw).sw_b[1] & 0xf0) == 0xf0 \
&& ((sw).sw_b[1] & 0x06) != 0x00 \
&& ((sw).sw_b[2] & 0xf0) != 0xf0 \
&& ((sw).sw_b[2] & 0x0c) != 0x0c)
#define L3F_SYNC_COMPATIBLE(s1, s2) \
( ((s1).sw_b[1] & 0x0e) == ((s2).sw_b[1] & 0x0e) \
&& ((s1).sw_b[2] & 0xfc) == ((s2).sw_b[2] & 0xfc) \
&& (((s1).sw_b[3] & 0xc0) == 0xc0) == (((s2).sw_b[3] & 0xc0) == 0xc0))
Ich teste also auf (1111 1111 1111 .aa. bbbb
cc..).
aa muss ungleich "00" sein
bbbb muss ungleich "1111" sein
cc muss ungleich "11" sein
(binär)
Damit habe ich noch nie einen falschen Frame erwischt.
[Nachtrag]
Also in Pascal (falls Syncword ein Cardinal ist)
Delphi-Quellcode:
ok := ((syncword and $0000f0ff) = $0000f0ff) and
((syncword and $00000600) <> $00000000) and
((syncword and $00f00000) <> $00f00000) and
((syncword and $000c0000) <> $000c0000);
Ein bisschen aufwendiger ist der Test doch noch gewesen (hab gerade noch mal durch die Sourcen geschaut):
Nachdem ich ein gültiges Syncword gefunden habe prüfe ich dann außerdem noch ob an den erwarteten Stellen (anhand der Framegröße berechnet) noch mindestens 7 weitere gültige Syncwords folgen und mit dem Makro L3F_SYNC_COMPATIBLE zusätzlich noch, ob diese zum ersten gefundenen kompatibel sind.
Ich hab' die C++-Datei mal angehängt falls du was damit anfangen kannst (die drei Header-Dateien braucht man nicht).