Zitat:
Das ist interessant, leider werde ich aus dem C Code nicht schlau. Was meinst du mit "du prüfst ob an den erwarteten Stellen noch Syncwords sind". Ich hatte gedacht der einzige Sync ist am Anfang des Headers...Wäre dir sehr dankbar, wenn du das ein wenig präziser beschreiben könntest.
Vorhin vergessen: Jeder MP3-Frame beginnt mit einem Syncword, darum gibt's auch so viele Matches für dein Pattern
Jeder MP3-Frame hat eine bestimmte Länge, die man auf's Byte genau ausrechnen kann (aus den Daten im Syncword).
Das macht die folgende Routine (sorry, wieder C):
Code:
int
l3f_header_set_syncword (L3F_Header *self, long off, l3f_syncword sw)
{
int sb, spf, bps, freq, kbps;
self->offset = off;
self->syncword.sw_l = sw.sw_l;
sb = sw.sw_b[1];
self->i_version = (sb >> 3) & 1;
self->i_layer = (sb >> 1) & 3;
self->i_no_crc = (char)((sb ) & 1);
sb = sw.sw_b[2];
self->i_bitrate = (sb >> 4) & 15;
self->i_freq = (sb >> 2) & 3;
self->i_padding = (sb >> 1) & 1;
self->i_extension = (char)((sb ) & 1);
sb = sw.sw_b[3];
self->i_mode = (sb >> 6) & 3;
self->i_mode_ext = (sb >> 4) & 3;
self->i_copyright = (char)((sb >> 3) & 1);
self->i_original = (char)((sb >> 2) & 1);
self->i_emphasis = (sb ) & 3;
// Framelänge berechnen
spf = l3f_spframe[self->i_version][self->i_layer];
bps = l3f_bpslot[self->i_layer];
freq = l3f_frequency[self->i_version][self->i_freq];
kbps = 125 * l3f_kbps[self->i_version][self->i_layer][self->i_bitrate];
// Auf irgendwelche ungültigen Indizes testen
if (spf <= 0 || bps <= 0 || freq <= 0 || kbps <= 0)
return 0;
self->length_in_bytes = l3f_umuldiv_trunc(spf, kbps, freq) + bps * self->i_padding;
self->length_in_samples = spf;
return 1;
}
"L3F_Header" ist eine selbstdefinierte Struktur, in der ich die einzelnen Bitfelder aus dem Syncword ablege. Mit Hilfe der Arrays l3f_spframe, l3f_bpslot, l3f_frequency und l3f_kbps errechne ich dann die Länge eines Frames in Samples und in Bytes.
Sofern die MP3-Datei korrekt ist findest du exakt "length_in_bytes" Bytes weiter (ab Beginn des Syncwords) das nächste Syncword - und das muss ja kompatibel sein, also müssen z.B. Layer und Frequenz übereinstimmen.
C/C++ ist für jemanden der Delphi kann gar nicht sooo schwer zu lesen.
Alternativ kannst du dir die vier Felder "version", "layer", "frequency" und "bitrate" aus dem Syncword extrahieren und mit der folgenden Tabelle (die auch in der C++-Datei steht) in die Framelänge umrechnen (ggf. plus 1 Byte "padding", auch aus dem Syncword).
V/L ist version/layer
F ist frequency
die Spalten sind die Bitrate
(-> jeweils die Werte aus dem Syncword)
Code:
// Hier ist eine Tabelle mit den Basislängen (ohne Padding) für alle
// möglichen Werte von h.version, h.layer, h.frequency und h.bitrate.
//
// V/L F | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// === ===+==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
// 0-0 0 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// 1 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// 2 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// 3 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// MPEG 2 Layer 3 ------------------------------------------------------------------------
// 0-1 0 | 0 26 52 78 104 130 156 182 208 261 313 365 417 470 522 -1
// 1 | 0 24 48 72 96 120 144 168 192 240 288 336 384 432 480 -1
// 2 | 0 36 72 108 144 180 216 252 288 360 432 504 576 648 720 -1
// 3 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// MPEG 2 Layer 2 ------------------------------------------------------------------------
// 0-2 0 | 0 52 104 156 208 261 313 365 417 522 626 731 835 940 1044 -1
// 1 | 0 48 96 144 192 240 288 336 384 480 576 672 768 864 960 -1
// 2 | 0 72 144 216 288 360 432 504 576 720 864 1008 1152 1296 1440 -1
// 3 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// MPEG 2 Layer 1 ------------------------------------------------------------------------
// 0-3 0 | 0 69 104 121 139 174 208 243 278 313 348 383 417 487 557 -1
// 1 | 0 64 96 112 128 160 192 224 256 288 320 352 384 448 512 -1
// 2 | 0 96 144 168 192 240 288 336 384 432 480 528 576 672 768 -1
// 3 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// === ===+==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
// 1-0 0 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// 1 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// 2 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// 3 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// MPEG 1 Layer 3 ------------------------------------------------------------------------
// 1-1 0 | 0 104 130 156 182 208 261 313 365 417 522 626 731 835 1044 -1
// 1 | 0 96 120 144 168 192 240 288 336 384 480 576 672 768 960 -1
// 2 | 0 144 180 216 252 288 360 432 504 576 720 864 1008 1152 1440 -1
// 3 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// MPEG 1 Layer 2 ------------------------------------------------------------------------
// 1-2 0 | 0 104 156 182 208 261 313 365 417 522 626 731 835 1044 1253 -1
// 1 | 0 96 144 168 192 240 288 336 384 480 576 672 768 960 1152 -1
// 2 | 0 144 216 252 288 360 432 504 576 720 864 1008 1152 1440 1728 -1
// 3 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// MPEG 1 Layer 1 ------------------------------------------------------------------------
// 1-3 0 | 0 34 69 104 139 174 208 243 278 313 348 383 417 452 487 -1
// 1 | 0 32 64 96 128 160 192 224 256 288 320 352 384 416 448 -1
// 2 | 0 48 96 144 192 240 288 336 384 432 480 528 576 624 672 -1
// 3 | -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
// === ===+==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====