Einzelnen Beitrag anzeigen

Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: Wirkliche Position eines mp3headers...nicht mal jedi kan

  Alt 30. Aug 2005, 22:04
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
// === ===+==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat