Sample Rate aus Flac File auslesen (Bytes) -> total überfordert
-
Hallo zusammen,
wir haben im dritten Semester nun einen Professor, der uns mit dem an sich spannenden Thema betraut hat aus einer FLAC Datei die Sample Rate auszulesen und das ganze dann noch in einem OpenOFfice Add-in einzubauen.
Leider ist unser Programmieren 2 nie soweit gegangen, so dass ich ziemlich auf dem Schlauch stehe und mit den gefundenen Tutorials im netz nicht wirklich weiterkomme.
Mein Problem ist auch, das die Spezifikation der FLAC Metadaten als Blöcke vorliegt und ich nicht wirklich heisst, was das für mich beim Lesen der Datei bedeutet.
Das ist was ich bisher habe:
#include <iostream> #include <stdio.h> using naespace std; int main() { int sampleRate = 0; FILE * flacFile; flacFile = fopen ("test.flc","r"); char sampleRate [4]; if (flacFile!=NULL) { fseek (flacFile, , SEEK_SET ); fgets (sampleRate, 4, flacFile); fclose (pFile); } else { cout << "File does not exist!!" << endl; } return 0; }Wie ihr set fehlt zb der Parameter, wohin das fseek springen soll.
Ausserdem bin ich mir nicht sicher, ob ich es richtig auslese. Werden denn so wie ich es vorhabe auch wirklich die bytes gespeichert?
-
also:
using naespace std;ist falsch geschrieben ^^
FILE * flacFile;undflacFile = fopen ("test.flc","r");ist C - wir sind im C++ Forum - also schau mal nach std::istream - und nutz das dann auch ^^
ansonsten müsstest du wahrscheinlich mal posten, was du über FLAC-Daten scho rausgefunden hast - ich muss ehrlich zugeben, dass ich gerad zu faul bin, danach zu suchen ^^ also poste einfach mal den aufbau so einer datei...bb
-
hm tja okay dann wohl verscheieben weil die istream reference schnall ich absolut nicht -.-
-
ThaRealMatix schrieb:
hm tja okay dann wohl verscheieben weil die istream reference schnall ich absolut nicht -.-
Voll einfach: http://www.cplusplus.com/doc/tutorial/files.html
PS: "unskilled" meinte wahrscheinlich "ifstream".
-
Badestrand schrieb:
PS: "unskilled" meinte wahrscheinlich "ifstream".
hmm... das f hat sich nur versteckt ^^
hab ich selbst beim durchlesen vorm posten nicht gemerkt gehabt, dass da was fehlt ><bb
-
Hallo,
also ich habs jetzt (doch) nochmal in C++ versucht und habe folgendes:
#include <iostream> // Standardstream-Funktionaliät einbinden #include <fstream> // ofstream und ifstream einbinden using namespace std; int main(void) { char sampleRate[4]; ifstream flacFile; // create new read-stream flacFile.open("test.flac", ios::in, ios::binary); // open flac File öffnen flacFile.seekg( , ios::beg); return 0; }Mein Problem ist, dass ich weder weiss wohin ich mit seekg springen muss, noch wie weit ich lesen muss, weil ich in Programmieren 2 nie gelernt habe mit Blöcken zu arbeiten.
Die Dokumentation findet man hier: http://flac.sourceforge.net/format.html
Leider werde ich draus trotz inzwischen 5-maligem Lesen nicht schlau, weil ich ganz offensichtlich zu doof bin.
Falls ich mit seekg zu einem Block springen kann, wüsste ich nicht wie, weil diereferenz die ich im Internet gefunden habe ganz klar sagt das ich "nur" von anfang oder ende einer datei oder dem derzeitigen Punkt aus Zeichen/bitweise "springen" kann/muss um an die Position zu kommen die ich brauche.
-
Der 5. Wert der METADATA_BLOCK_DATA sollte die Sampling-Rate sein:
<20> Sample rate in Hz. Though 20 bits are available, the maximum sample rate is limited by the structure of frame headers to 655350Hz. Also, a value of 0 is invalid.
Der wiederrum ist der erste Wert der METADATA_BLOCK_DATA und der besteht aus dem Header und dem eigtl Inhalt...
Also würde ich mal auf folgendes tippen:
<32bit müll - iwas mit Flac> <1Bit: 0> <7Bit: metadata-block> <24bit: länge des metadaten-blocks an sich (ohne header) - uns interessiert nur der block, der bei den 7Bit von oben ne 0 stehen hat - also vrmtl der erste> ... <1Bit: 1> //METADATA_BLOCK_STREAMINFO <80Bit Müll> <20Bit - genau die, die wir wollen>Also entweder, du nimmst den stream und liest immer nen stück in nen puffer (am besten) und guckst dir dann die Werte an (z.bsp. mit std::bitset) - oder du versuchst direkt immer nur genau so viel auszulesen, wie du gerade brauchst - wobei ich gerade gleich gar nicht weiß, ob man bitgenau auslesen kann ^^
Ich würd vll am ehesten ne Klasse bauen, die versucht den Stream zu parsen und den intern aufsplittet - die muss ja auch gar nicht alles können - reicht ja, wenn sie alles ignoriert, was sie nicht braucht...
also in etwa so:
enum TmetaData_What { STREAMINFO, //... } //irgendwo braucht man das bestimmt ^^ class TmetaData { TmetaData_What what; virtual ~TmetaData; virtual bool /*again*/ Parse(std::ifstream &stream, TmetaData *object); //virtual ... }; class TmetaDataStreamInfo : public TmetaData { TmetaDataStreamInfo () : what(STREAMINFO) {} unsigned int srate; unsigned int GetSamplingRate() const {return srate;} bool Parse(std::ifstream &stream, TmetaDataStreamInfo *object) { //pseudo-code - wird so niemals funktionieren) stream.readBit(80); srate = reinterpret_cast <unsigned int> (stream.readBit(24)); return stream.readBit(1); } //... }; class TflacData { // private/public: std::ifstream stream; std::vector <TmetaData*> metadata; TflacData(std::ifstream &stream); Parse() { TmetaData* out (nullptr); while (! stream.eof()) { while (Parse (stream, out)) { if (!out) continue; metadata.push_back(out); out = nullptr; }; }; } //hier könnte man noch ne fkt bauen, die anhand des enums TmetaData_What nur die richtigen einträge (also wieder nen vector) des vectors zurückgibt };Irgendwie so in etwa würde ich das wohl anstellen - wobei hier sicherlich noch paar (grobe) Fehler drin sind ^^
bb