Mp3-Header auslesen (nicht die TAGS!)
-
das ist ne berechtigte frage
du kannst davon ausgehen, dass das erste bit des headers immer gesetzt sein wird. "SyncWord" wird also bei nem gültigen header größergleich 0x400 sein.
zusätzlich vielleicht mal paar andere bits angucken. "Bitrate" sollte z.b. kleiner als 0xff sein, da dieser wert reserviert ist.
blockweise durchlaufen kannst du die datei ungefähr so:
int pos = 0; isFileStream.seekg(0); do { isFileStream.read((char*)&mp3core.Mp3Info.BitInfo, MP3_HEADER_SIZE); isFileStream.seekg(pos); ++pos; } while(!isValidHeader(mp3core)) // boole'sche funktion, die den header auf gültigkeit prüft
achtung: dabei kann das ende der datei erreicht werden. ne sinnvolle überprüfung auf eof() einschieben.
was mir an deinem code grad auffällt, wieso sind die bytes und header infos alle rückwärts deklariert? müsste eigentlich andersrum sein.
[hier war ne längere pause, in der der autor sich gedacht hat, er implementiere son reader mal eben fix]
mein beispielprogramm liefert auch nur müll
die meisten meiner mp3s entsprechen offenbar "MPEG 2.5". für manche stimmt die bitrate, für manche nicht... komische sache. das syncword war auch völlig unterschiedlich gesetzt...
ich häng mal meinen code ran, vielleicht hilft er dir weiter.
#include <iostream> #include <fstream> #include <string> using namespace std; union MP3Header { char bytes[4]; struct { unsigned Syncword : 11; unsigned FuzzyBit : 1; unsigned MPEGVersion : 1; unsigned MPEGLayer : 2; unsigned ProtectionBit : 1; unsigned Bitrate : 4; unsigned SamplingFrequency : 2; unsigned Padding : 1; unsigned Private : 1; unsigned Mode : 2; unsigned ModeExtension : 2; unsigned Copyright : 1; unsigned OriginalHome : 1; unsigned Emphasis : 2; } InfoBits; }; bool validHeader(MP3Header &header) { return header.InfoBits.Syncword > 0x400 && header.InfoBits.Bitrate && header.InfoBits.Bitrate < 0xff && header.InfoBits.SamplingFrequency < 0x4; } int main(int argc, char *argv[]) { string file = "foo.mp3"; ifstream fs(file.c_str(), ios::binary); if(!fs) return 1; int pos = 0; fs.seekg(pos); MP3Header header; do { fs.read(header.bytes, 4); // error prone! ++pos; fs.seekg(pos); } while(!fs.eof() && !validHeader(header)); fs.close(); if(!validHeader(header)) { cerr << "invalid header" << endl; return 1; } cout << "found header at block " << pos - 1 << endl; cout << file << endl; if(!header.InfoBits.FuzzyBit) cout << "MPEG 2.5" << endl; else switch(header.InfoBits.MPEGVersion) { case 0 : cout << "MPEG 2" << endl; break; case 1 : cout << "MPEG 1" << endl; break; } cout << "MPEG Layer " << (4 - header.InfoBits.MPEGLayer) << endl; cout << header.InfoBits.Bitrate << endl; system("PAUSE"); return EXIT_SUCCESS; }
-
hi hi,
hab dein proggy mal ausprobiert und festgestellt, das der einen gültigen Header-Block immer bei 0 findet also am anfang :p , ich hab auf vielen seiten schon gelesen, dass am anfang immer der Header steht....
Dann mal ne Frage:
unsigned Syncword : 11; unsigned FuzzyBit : 1; unsigned MPEGVersion : 1;
Wieso hast du denn da ein FuzzyBit eingebaut, bzw den SyncWord auf 11 gekürzt ?
->>Syncword (12 Bit)
Diese 12 Bits werden zur Synchronisierung verwendet und meist auf 0xFFF gesetzt. Beim Betrachten unterschiedlicher MP3 Dateien erkennt man aber auch Abweichungen von diesem Standardwert.auf http://193.23.168.186/pc_pool/lernmodule/multimediadateien/Kapitel32.htm
Ach ja, hab noch ne 'andere' Idee:
Wenn wir über ne funktionierende Funktionauf die Bits der Datei direkt zugreifen könnten, kann man doch (mal von einem gültigem Header ausgehen
) die Bitsets direkt untersuchen oder ? ... Habs nur noch nit aufe Reihe bekommen mir son Ding zu schreiben...
Zählt man eigentlich das 0.te Bit schon mit oder beginnt man bei 1 an zu zählen ?
danke nochmal für dein Posting
-
das fuzzy bit ist für mpeg 2.5. drei formate lassen sich mit einem bit für "MPEGVersion" halt nicht abdecken, also haben sich paar leute ausgedacht, dass sie dafür einfach das letzte bit vom SyncFrame (bzw. Syncword) nehmen. ist das auf 0 gesetzt, so hat man es mit mpeg 2.5 zu tun. deshalb "fuzzy" bit, weils am standard vorbei ist.
dass die header meist am anfang der datei gefunden werden liegt daran, dass man es meist nur mit "intakten" mp3 files zu tun hat. hatte da zuerst den fehler vermutet, aber offensichtlich liegt er doch woanders. möglicherweise einfach daran, dass sich so gut wie niemand an den standard hält.
rein theoretisch kannst du an den anfang ner mp3 datei ne menge bullshit schreiben und das ganze funzt trotzdem noch, da player sich erstmal den ersten gültigen block (frame) suchen und ab da spielen.
rührt, wie erwähnt, vom streaming her. wenn man sich in so einen mp3 stream einklingt, dann fängt der halt irgendwo an und nicht direkt mit nem gültigen frame.
was du mal machen kannst, um deinen code generell auf gültigkeit zu überprüfen, ist eigentlich ganz einfach.
schnapp dir nen hex-editor und bastel dir nen gültigen mp3 header zusammen, speicher das ganze und jag es durch dein programm
-
der Titel sagt alles ....
....wenn ich das mal irg wann raus hab...willse dann ne Funktion haben ?
-
ich komm mir grad bisschen blöd vor *G
das problem ist die endianess
windows systeme arbeiten mit little endian. hab mich durch die verwendung von union wohl blenden lassen
also: stell dir vor dein header sieht so aus: 0xFFF0ABFD
eigentlich erwartet man, dass dann das syncword 0xFFF entspricht. tut es aber nicht, da durch die little endian interpretation die bytes blockweise "vertauscht" werden. ein block entspricht dabei 8 bit und das höchstwertige steht dabei ganz rechts. das syncword wird also mit 0x0FF belegt.
anderes beispiel, das es vielleicht klarer macht:
0xABCD wird in 16 bit word geschaufelt -> word == 0xCDAB
hätte mir eigentlich sofort auffallen sollen, als ich deine umgedrehten member gesehen hab ^^ das umdrehen allein reicht nicht wegen der blockweisen vertauschung
-
Gut wenn das :
hätte mir eigentlich sofort auffallen sollen, als ich deine umgedrehten member gesehen hab ^^ das umdrehen allein reicht nicht wegen der blockweisen vertauschung
'nicht reicht' ^^; was kann ich dann machen um den Schmand aufe Reihe zu bekommen ...irgend wie muss das doch gehen
-
ich hab noch einen funktionierenden VB-Code der genau diesen Kack macht, das problem is nur, das ich kein bisschen VB kann... der is auch gar nit so lang...soll ich den mal posten ?
-
CodeFinder schrieb:
Gut wenn das :
hätte mir eigentlich sofort auffallen sollen, als ich deine umgedrehten member gesehen hab ^^ das umdrehen allein reicht nicht wegen der blockweisen vertauschung
'nicht reicht' ^^; was kann ich dann machen um den Schmand aufe Reihe zu bekommen ...irgend wie muss das doch gehen
indem du auf diesen union krams verzichtest und z.b. nen bitset verwendest.
#include <bitset> // filestream fs öffnen etc. pp unsigned char bytes[4]; fs.read((char*)bytes, 4); // char bytes von hand in nen long schieben unsigned long longbytes = 0; for(int i = 0; i < 3; ++i) { longbytes += bytes[i]; longbytes <<= 8; } longbytes += bytes[3]; std::bitset<32> bits(longbytes); // erzeugt ein bitset von long
und _der_ header ist dann tatsächlich umgedreht
syncframe is also auf bits 31-21 (bits[31] bis bits[21]).
-
muhaha, ok danke nochmal für deine Antwort, ich bin schon weiter...wenn ich ne Fkt fertig hab werde ich die mal posten
-
Also habs jetzt raus, kannst den Code ja mal ausprobieren, bei mir funzt der einwandfrei, is n bissl anders gelößt; aber er läuft und der Rest is mir wurscht
(ich weiß n bissl unschön: C und C++ gemixt aber egal)
ACHTUNG: das ist nur eine Funktion, kein ganzes Proggy
#include <iostream> #include <fstream> using namespace std; /***************************************************/ // ASC - Audio Sound Channel #define ASC_UNKNOWN (0x00) #define ASC_STEREO (0x01) #define ASC_JOINT_STEREO (0x02) #define ASC_DUAL_CHANNEL (0x03) #define ASC_SINGLE_CHANNEL (0x04) // EMPHASIS Modes #define EMPHASIS_UNKNOWN (0x00) #define EMPHASIS_NONE (0x01) #define EMPHASIS_50_15_MS (0x02) #define EMPHASIS_CCITT_J_17 (0x03) typedef struct tagMP3COREHEADER // mp3core { long lFileSize; /* Bytes */ long lFirstFrameOffset; /* Bytes */ long lTotalFrames; /* Frames */ long lTrackLength; /* Sekunden */ long lBitrate; /* kBit/s */ long lFrequence; /* Hz */ long lMPEGVersion; long lMPEGLayer; bool fCRCProtected; bool fPadding; bool fPrivate; bool fCopyright; bool fOriginal; bool fErrorAppeared; UINT uiEmphasis; UINT uiSoundMode; } MP3COREHEADER, *PMP3COREHEADER/*, NEAR *NPMP3COREHEADER, FAR *LPMP3COREHEADER*/; bool GetMp3HeaderInformation(const PSTR pszFilepath, PMP3COREHEADER pMp3CoreHeader) { // => Parameter überprüfen if(pszFilepath == NULL || pMp3CoreHeader == NULL) return (false); // => Lokale Variablen FILE *pfMp3File; int iCharCode; bool fStatusFlag = false; // => noch keine Fehler aufgetreten pMp3CoreHeader->fErrorAppeared = false; // => Datei öffnen pfMp3File = fopen(pszFilepath, TEXT("rb")); if(pfMp3File == NULL) { pMp3CoreHeader->fErrorAppeared = true; return (false); } // => Dateigröße bestimmen: std::ifstream ifsMp3File(pszFilepath, std::ios::binary); if(!ifsMp3File) return (false); ifsMp3File.seekg(0, std::ios::end); pMp3CoreHeader->lFileSize = (long)ifsMp3File.tellg(); ifsMp3File.close(); // => Ersten Frame des MPEG 1 Layer III suchen do { iCharCode = fgetc(pfMp3File); if(iCharCode == 255) { iCharCode = fgetc(pfMp3File); if(tolower(iCharCode / 16) == 15) fStatusFlag = true; } } while(!fStatusFlag); // => Den ersten Frame Header ermitteln fpos_t fpMp3FilePos; fgetpos(pfMp3File, &fpMp3FilePos); fpMp3FilePos -= 2; pMp3CoreHeader->lFirstFrameByteOffset = fpMp3FilePos; // => MPEG Version ermitteln (1/2) int iMPEGVersion = tolower(((iCharCode % 16) / 4) / 2); switch(iMPEGVersion) { case 0: pMp3CoreHeader->lMPEGVersion = 2L; // MPEG-2 break; case 1: pMp3CoreHeader->lMPEGVersion = 1L; // MPEG-1 break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => MPEG Layer ermitteln int iMPEGLayer = tolower((((iCharCode % 16) / 4) % 2) * 2 + (((iCharCode % 16) % 4) / 2)); switch(iMPEGLayer) { case 0: pMp3CoreHeader->lMPEGLayer = 0; // Reserved break; case 1: pMp3CoreHeader->lMPEGLayer = 3; // Layer III break; case 2: pMp3CoreHeader->lMPEGLayer = 2; // Layer II break; case 3: pMp3CoreHeader->lMPEGLayer = 1; // Layer I break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } if(iMPEGLayer != 1) return (true); // => CRC-Protection ermitteln int iProtectionBit = tolower(((iCharCode % 16) % 4) % 2); switch(iProtectionBit) { case 1: pMp3CoreHeader->fCRCProtected = false; // CRC-Protection: No break; case 0: pMp3CoreHeader->fCRCProtected = true; // CRC-Protection: Yes break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => Das nächste Byte einlesen, um das 3. des Frame-Headers zu analysieren iCharCode = fgetc(pfMp3File); // => Bitrate ermitteln int iBitrateTable[2][16] = { 0x000,0x008,0x010,0x018, 0x020,0x040,0x050,0x038, 0x040,0x080,0x0A0,0x070, 0x080,0x100,0x140,0x000, 0x000,0x020,0x028,0x030, 0x038,0x040,0x050,0x060, 0x070,0x080,0x0A0,0x0C0, 0x0E0,0x100,0x140,0x000 }; pMp3CoreHeader->lBitrate = iBitrateTable[iMPEGVersion][(tolower(iCharCode / 16))]; // in Kbps // => Frequenz ermitteln long lFrequencyTable[2][4] = { 0x05622,0x05DC0,0x03E80,0x00000, 0x0AC44,0x0BB80,0x07D00,0x00000 }; pMp3CoreHeader->lFrequence = lFrequencyTable[pMp3CoreHeader->lMPEGVersion][(tolower((iCharCode % 16) / 4))]; // in Hz // => Padding ermitteln int iPaddingBit = tolower(((iCharCode % 16) % 4) / 2); switch(iPaddingBit) { case 0: pMp3CoreHeader->fPadding = false; // Padding: No break; case 1: pMp3CoreHeader->fPadding = true; // Padding: Yes break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => Private Bit ermitteln int iPrivateBit = tolower(((iCharCode % 16) % 4) % 2); switch(iPrivateBit) { case 0: pMp3CoreHeader->fPrivate = false; // Private: No break; case 1: pMp3CoreHeader->fPrivate = true; // Private: Yes break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => Das nächste Byte einlesen, um das 4. des Frame-Headers zu analysieren iCharCode = fgetc(pfMp3File); // Sound Channel ermitteln int iChannelMode = tolower((iCharCode / 16) / 4); switch(iChannelMode) { case 0: pMp3CoreHeader->uiSoundMode = ASC_STEREO; // Stereo break; case 1: pMp3CoreHeader->uiSoundMode = ASC_JOINT_STEREO; // Joint Stereo break; case 2: pMp3CoreHeader->uiSoundMode = ASC_DUAL_CHANNEL; // Dual Channel break; case 3: pMp3CoreHeader->uiSoundMode = ASC_SINGLE_CHANNEL; // Single Channel break; default: pMp3CoreHeader->uiSoundMode = ASC_UNKNOWN; // Unknown pMp3CoreHeader->fErrorAppeared = true; break; } // => Copyright ermitteln int iCopyrightBit = tolower(((iCharCode % 16) / 4) / 2); switch(iCopyrightBit) { case 0: pMp3CoreHeader->fCopyright = false; // Copyrighted: No break; case 1: pMp3CoreHeader->fCopyright = true; // Copyrighted: Yes break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => Originale Mp3 Datei int iOriginalBit = tolower(((iCharCode % 16) / 4) % 2); switch(iOriginalBit) { case 0: pMp3CoreHeader->fOriginal = false; // Original: No break; case 1: pMp3CoreHeader->fOriginal = true; // Original: Yes break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => Emphasis ermitteln int iEmphasis = tolower((iCharCode % 16) % 4); switch(iEmphasis) { case 0: pMp3CoreHeader->uiEmphasis = EMPHASIS_NONE; // Emphasis: None break; case 1: pMp3CoreHeader->uiEmphasis = EMPHASIS_50_15_MS; // Emphasis: 50/15 ms break; case 3: pMp3CoreHeader->uiEmphasis = EMPHASIS_CCITT_J_17; // Emphasis: CCITT J.17 break; default: pMp3CoreHeader->uiEmphasis = EMPHASIS_UNKNOWN; // Unknown pMp3CoreHeader->fErrorAppeared = true; break; } // => Frame-Size berechnen long lFrameSize = (144000 * pMp3CoreHeader->lBitrate / pMp3CoreHeader->lFrequence) + iPaddingBit; // => Anzahl der Frames pMp3CoreHeader->lTotalFrames = (pMp3CoreHeader->lFileSize - pMp3CoreHeader->lFirstFrameByteOffset) / lFrameSize; // => Track Länge in Sekunden pMp3CoreHeader->lTrackLength = toupper(pMp3CoreHeader->lTotalFrames * 26 / 1000); // => Datei Handle wieder schließen fclose(pfMp3File); return (!pMp3CoreHeader->fErrorAppeared); } /***************************************************/
PS: Hab das ganze jetzt mal mit Flags gelößt; Also Emphasis und Sound-Modi, dann is das ganze n bissl universeller
hmm vll. was für die FAQ ?
-
Hab noch 2 kleine Bugs gefunden:
Das...
// => Dateigröße bestimmen: std::ifstream ifsMp3File(pszFilepath, std::ios::binary); if(!ifsMp3File) return (false); ifsMp3File.seekg(0, std::ios::end); pMp3CoreHeader->lFileSize = (long)ifsMp3File.tellg(); ifsMp3File.close();
wird zu...
// => Dateigröße bestimmen: std::ifstream ifsMp3File(pszFilepath, std::ios::binary); if(!ifsMp3File) { fclose(pfMp3File); return (false); } ifsMp3File.seekg(0, std::ios::end); pMp3CoreHeader->lFileSize = (long)ifsMp3File.tellg(); ifsMp3File.close();
-------------------------------------
Das...
if(iMPEGLayer != 1) return (true);
wird zu...
if(iMPEGLayer != 1) { fclose(pfMp3File); return (true); }
Bitte vielmals um Entschuldigung
-
öhm kann das sein dass du irgendwelche eigenen typen verwendet hast?
bekomme ne tonne fehler!
UINT = unsigned int? (UINT uiEmphasis;)
PSTR = ? (const PSTR pszFilepath)
und dann gibts ne tonne weiterer fehler. ein paar davon kommen sicher von dem hier, habe aber nicht alle angeschaut.
-
UINT und PSTR sind afaik WinAPI-typedefs für unsigned int bzw. char*.
-
soweit binich mittlerweile auch gekommen leider bekomm ich n crash wenn ich da stattdessen einfach unsigned int und char * schreibe.
habe diese typedefs ausserdem in der winnt.h gefunden.
da drin steht auch wo was von TEXT("rb"), sehe aber den sinn davon nicht.
das TEXT... habich auch weggelassen und einfach "rb" geschrieben.
die winnt.h kannich nicht inkludieren weil 1. muss das unter linux und windows funzen und 2. kommt dann noch n neuer fehler.
schaut bei mir jetzt so aus:
*.h:
#pragma once #ifndef MP3_HEADER #define MP3_HEADER #include <iostream> #include <fstream> using namespace std; /***************************************************/ // ASC - Audio Sound Channel #define ASC_UNKNOWN (0x00) #define ASC_STEREO (0x01) #define ASC_JOINT_STEREO (0x02) #define ASC_DUAL_CHANNEL (0x03) #define ASC_SINGLE_CHANNEL (0x04) // EMPHASIS Modes #define EMPHASIS_UNKNOWN (0x00) #define EMPHASIS_NONE (0x01) #define EMPHASIS_50_15_MS (0x02) #define EMPHASIS_CCITT_J_17 (0x03) typedef struct tagMP3COREHEADER // mp3core { long lFileSize; /* Bytes */ long /*lFirstFrameOffset;*/ lFirstFrameByteOffset; /* Bytes */ long lTotalFrames; /* Frames */ long lTrackLength; /* Sekunden */ long lBitrate; /* kBit/s */ long lFrequence; /* Hz */ long lMPEGVersion; long lMPEGLayer; bool fCRCProtected; bool fPadding; bool fPrivate; bool fCopyright; bool fOriginal; bool fErrorAppeared; unsigned int /* UINT */ uiEmphasis; unsigned int /* UINT */ uiSoundMode; } MP3COREHEADER, *PMP3COREHEADER/*, NEAR *NPMP3COREHEADER, FAR *LPMP3COREHEADER*/; bool GetMp3HeaderInformation(const char /*PSTR*/ *pszFilepath, PMP3COREHEADER pMp3CoreHeader); /***************************************************/ #endif
.cpp
#include "includes.h" bool GetMp3HeaderInformation(const char /*PSTR*/ *pszFilepath, PMP3COREHEADER pMp3CoreHeader) { // => Parameter überprüfen if(pszFilepath == NULL || pMp3CoreHeader == NULL) return (false); // => Lokale Variablen FILE *pfMp3File; int iCharCode; bool fStatusFlag = false; // => noch keine Fehler aufgetreten pMp3CoreHeader->fErrorAppeared = false; // => Datei öffnen pfMp3File = fopen(pszFilepath, /*TEXT(*/"rb"/*)*/); if(pfMp3File == NULL) { pMp3CoreHeader->fErrorAppeared = true; return (false); } // => Dateigröße bestimmen: std::ifstream ifsMp3File(pszFilepath, std::ios::binary); if(!ifsMp3File) { fclose(pfMp3File); return (false); } ifsMp3File.seekg(0, std::ios::end); pMp3CoreHeader->lFileSize = (long)ifsMp3File.tellg(); ifsMp3File.close(); // => Ersten Frame des MPEG 1 Layer III suchen do { iCharCode = fgetc(pfMp3File); if(iCharCode == 255) { iCharCode = fgetc(pfMp3File); if(tolower(iCharCode / 16) == 15) fStatusFlag = true; } } while(!fStatusFlag); // => Den ersten Frame Header ermitteln fpos_t fpMp3FilePos; fgetpos(pfMp3File, &fpMp3FilePos); fpMp3FilePos -= 2; pMp3CoreHeader->lFirstFrameByteOffset = fpMp3FilePos; // => MPEG Version ermitteln (1/2) int iMPEGVersion = tolower(((iCharCode % 16) / 4) / 2); switch(iMPEGVersion) { case 0: pMp3CoreHeader->lMPEGVersion = 2L; // MPEG-2 break; case 1: pMp3CoreHeader->lMPEGVersion = 1L; // MPEG-1 break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => MPEG Layer ermitteln int iMPEGLayer = tolower((((iCharCode % 16) / 4) % 2) * 2 + (((iCharCode % 16) % 4) / 2)); switch(iMPEGLayer) { case 0: pMp3CoreHeader->lMPEGLayer = 0; // Reserved break; case 1: pMp3CoreHeader->lMPEGLayer = 3; // Layer III break; case 2: pMp3CoreHeader->lMPEGLayer = 2; // Layer II break; case 3: pMp3CoreHeader->lMPEGLayer = 1; // Layer I break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } if(iMPEGLayer != 1) { fclose(pfMp3File); return (true); } // => CRC-Protection ermitteln int iProtectionBit = tolower(((iCharCode % 16) % 4) % 2); switch(iProtectionBit) { case 1: pMp3CoreHeader->fCRCProtected = false; // CRC-Protection: No break; case 0: pMp3CoreHeader->fCRCProtected = true; // CRC-Protection: Yes break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => Das nächste Byte einlesen, um das 3. des Frame-Headers zu analysieren iCharCode = fgetc(pfMp3File); // => Bitrate ermitteln int iBitrateTable[2][16] = { 0x000,0x008,0x010,0x018, 0x020,0x040,0x050,0x038, 0x040,0x080,0x0A0,0x070, 0x080,0x100,0x140,0x000, 0x000,0x020,0x028,0x030, 0x038,0x040,0x050,0x060, 0x070,0x080,0x0A0,0x0C0, 0x0E0,0x100,0x140,0x000 }; pMp3CoreHeader->lBitrate = iBitrateTable[iMPEGVersion][(tolower(iCharCode / 16))]; // in Kbps // => Frequenz ermitteln long lFrequencyTable[2][4] = { 0x05622,0x05DC0,0x03E80,0x00000, 0x0AC44,0x0BB80,0x07D00,0x00000 }; pMp3CoreHeader->lFrequence = lFrequencyTable[pMp3CoreHeader->lMPEGVersion][(tolower((iCharCode % 16) / 4))]; // in Hz // => Padding ermitteln int iPaddingBit = tolower(((iCharCode % 16) % 4) / 2); switch(iPaddingBit) { case 0: pMp3CoreHeader->fPadding = false; // Padding: No break; case 1: pMp3CoreHeader->fPadding = true; // Padding: Yes break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => Private Bit ermitteln int iPrivateBit = tolower(((iCharCode % 16) % 4) % 2); switch(iPrivateBit) { case 0: pMp3CoreHeader->fPrivate = false; // Private: No break; case 1: pMp3CoreHeader->fPrivate = true; // Private: Yes break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => Das nächste Byte einlesen, um das 4. des Frame-Headers zu analysieren iCharCode = fgetc(pfMp3File); // Sound Channel ermitteln int iChannelMode = tolower((iCharCode / 16) / 4); switch(iChannelMode) { case 0: pMp3CoreHeader->uiSoundMode = ASC_STEREO; // Stereo break; case 1: pMp3CoreHeader->uiSoundMode = ASC_JOINT_STEREO; // Joint Stereo break; case 2: pMp3CoreHeader->uiSoundMode = ASC_DUAL_CHANNEL; // Dual Channel break; case 3: pMp3CoreHeader->uiSoundMode = ASC_SINGLE_CHANNEL; // Single Channel break; default: pMp3CoreHeader->uiSoundMode = ASC_UNKNOWN; // Unknown pMp3CoreHeader->fErrorAppeared = true; break; } // => Copyright ermitteln int iCopyrightBit = tolower(((iCharCode % 16) / 4) / 2); switch(iCopyrightBit) { case 0: pMp3CoreHeader->fCopyright = false; // Copyrighted: No break; case 1: pMp3CoreHeader->fCopyright = true; // Copyrighted: Yes break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => Originale Mp3 Datei int iOriginalBit = tolower(((iCharCode % 16) / 4) % 2); switch(iOriginalBit) { case 0: pMp3CoreHeader->fOriginal = false; // Original: No break; case 1: pMp3CoreHeader->fOriginal = true; // Original: Yes break; default: pMp3CoreHeader->fErrorAppeared = true; // Unknown break; } // => Emphasis ermitteln int iEmphasis = tolower((iCharCode % 16) % 4); switch(iEmphasis) { case 0: pMp3CoreHeader->uiEmphasis = EMPHASIS_NONE; // Emphasis: None break; case 1: pMp3CoreHeader->uiEmphasis = EMPHASIS_50_15_MS; // Emphasis: 50/15 ms break; case 3: pMp3CoreHeader->uiEmphasis = EMPHASIS_CCITT_J_17; // Emphasis: CCITT J.17 break; default: pMp3CoreHeader->uiEmphasis = EMPHASIS_UNKNOWN; // Unknown pMp3CoreHeader->fErrorAppeared = true; break; } // => Frame-Size berechnen long lFrameSize = (144000 * pMp3CoreHeader->lBitrate / pMp3CoreHeader->lFrequence) + iPaddingBit; // => Anzahl der Frames pMp3CoreHeader->lTotalFrames = (pMp3CoreHeader->lFileSize - pMp3CoreHeader->lFirstFrameByteOffset) / lFrameSize; // => Track Länge in Sekunden pMp3CoreHeader->lTrackLength = toupper(pMp3CoreHeader->lTotalFrames * 26 / 1000); // => Datei Handle wieder schließen fclose(pfMp3File); return (!pMp3CoreHeader->fErrorAppeared); }
-
sry hab meinen Beitrag lange nicht beachtet, dachte das hatte sich erledigt...
ALSO:
eigentlich solltest du durch folgenden Code das auch ohne Windows.h compilieren können#define UINT unsigned int #define PSTR char*
PS: wenn nicht dann mach noch mal n post (mit Fehlermeldungen büdde
)
MfG CodeFinder
-
hm kompilieren ging schon aber es is gecrasht.
hat sich eh erledigt habs jetzt so:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-145320-and-postdays-is-0-and-postorder-is-asc-and-start-is-0.html
-
HiHi,
Hassu ne Funktion geschrieben, kannst die mal posten ?...würd mich mal interessieren^^...wär cool...!!
MfG CodeFinder
-
1. habich die net selbst geschrieben sondern nur überarbeitet und 2. habich ja link gepostet wo ich den code gepostet hab