Wave-File auslesen
-
Hallo ich versuche grade den Header eines Wave-Files auszulesen. Irgendwie kommen aber falsche Werte raus. Ich blicke aber nicht durch warum. Habe schon im Internet gesucht, aber finde irgendwie nichts.
Code:void WaveFormat::readFileVersuchen (Steinberg::String samplePath) { //fstream f; //f.open("testNeu2.txt", ios::out); //f << "Dieser Text geht in die Datei" << endl; //f.close(); fstream fileStream; fileStream.open(samplePath.text (), ios::in); int byteCounter = 0; uint8 oneByte = 0; if (fileStream.is_open()) { while (!fileStream.eof()) { fileStream.read(&oneByte, sizeof(Steinberg::uint8)); //mChunkID = oneByte & 0xFFFF; if (byteCounter>=0 && byteCounter <= 3) { mChunkID <<= sizeof(Steinberg::uint8); mChunkID += oneByte; //char oneByteChar = oneByte; //stringstream allByte << oneByteChar; //allByte >> CString a; } else if (byteCounter>=4 && byteCounter <=7) { mChunkSize <<= sizeof(Steinberg::uint8); mChunkSize += oneByte; } else if (byteCounter>=8 && byteCounter <=11) { //mFormat <<= sizeof(Steinberg::uint8); char oneByteChar = oneByte; mFormat = mFormat + oneByteChar; } else if (byteCounter>=12 && byteCounter <=15) { mSubChunk1ID <<= sizeof(Steinberg::uint8); mSubChunk1ID += oneByte; } else if (byteCounter>=16 && byteCounter <=19) { mSubChunk1Size <<= sizeof(Steinberg::uint8); mSubChunk1Size += oneByte; } else if (byteCounter>=20 && byteCounter <=21) { mAudioFormat <<= sizeof(Steinberg::uint8); mAudioFormat += oneByte; } else if (byteCounter>=22 && byteCounter <=23) { mNumChannels <<= sizeof(Steinberg::uint8); mNumChannels += byteCounter; } else if (byteCounter>=24 && byteCounter <=27) { mSampleRate <<= sizeof(Steinberg::uint8); mSampleRate += oneByte; } else if (byteCounter>=28 && byteCounter <=31) { mByteRate <<= sizeof(Steinberg::uint8); mByteRate += oneByte; } else if (byteCounter>=32 && byteCounter <=33) { mBlockAlign <<= sizeof(Steinberg::uint8); mBlockAlign += oneByte; } else if (byteCounter>=34 && byteCounter <=35) { mBitsPerSample <<= sizeof(Steinberg::uint8); mBitsPerSample += oneByte; } else if (byteCounter>=36 && byteCounter <=39) { mSubChunks2ID <<= sizeof(Steinberg::uint8); mSubChunks2ID += oneByte; } else if (byteCounter>=40 && byteCounter <=43) { mSubchunck2Size <<= sizeof(Steinberg::uint8); mSubchunck2Size += oneByte; } else if (byteCounter >=44) { } byteCounter++; } fileStream.close(); } }Dass das mit den ganzen If-Abfragen sicher nicht grade optimal ist ist mir klar, aber will erstmal erreichen, dass der Code funktioniert.
Will das ganze in einem Insert-Effekt in Cubase benutzen, also benutze die SKD von Steinberg, aber ich glaube das müsste auch gehen ohne die zu kennen.
-
Dann geh doch mal mit dem Debugger durch und guck wann und warum du die falschen Werte bekommst.
AsterixderGallier schrieb:
Dass das mit den ganzen If-Abfragen sicher nicht grade optimal ist ist mir klar, aber will erstmal erreichen, dass der Code funktioniert.
Keine gute Idee, denn wenn man nicht sauber arbeitet, erreicht man gerade eben das Gegenteil und es funktioniert nicht. Siehe dein eigener Code. Abgesehen von deinem verkappten for-switch-Pattern scheinst du das Dateieinlesen in C++ nicht zu beherrschen. Das sieht bei dir nämlich so aus wie wenn jemand C nach C++ übersetzt hätte, ohne die Unterschiede zu kennen. Da musst du mal die Grundlagen nochmal lernen, besonders wie das mit der Abbruchlogik funktioniert.
-
Aber wie soll ich das denn ohne die If-Abfragen lösen? Case-Swich geht ja nicht in dem Fall. C habe ich noch nie gemacht, nur JAVA. Ich finde die Abbruchbedingung eigentlich ok, er macht das ganze solange bis die Datei zu ende ist:
while (!fileStream.eof())oder was meinst du?
Ich habe natürlich schon debuggt, der erste Wert ist richtig, der zweite ist aber komischerweise negativ also mChunkSize. Nur hilft mir das nicht weiter um zu erkennen warum die falsch sind ab dann..
-
SeppJ schrieb:
Dann geh doch mal mit dem Debugger durch und guck wann und warum du die falschen Werte bekommst.
AsterixderGallier schrieb:
Dass das mit den ganzen If-Abfragen sicher nicht grade optimal ist ist mir klar, aber will erstmal erreichen, dass der Code funktioniert.
Keine gute Idee, denn wenn man nicht sauber arbeitet, erreicht man gerade eben das Gegenteil und es funktioniert nicht. Siehe dein eigener Code. Abgesehen von deinem verkappten for-switch-Pattern scheinst du das Dateieinlesen in C++ nicht zu beherrschen. Das sieht bei dir nämlich so aus wie wenn jemand C nach C++ übersetzt hätte, ohne die Unterschiede zu kennen. Da musst du mal die Grundlagen nochmal lernen, besonders wie das mit der Abbruchlogik funktioniert.
Ich lese doch lediglich einen Pfad ein, aber den bekomme ich auch ner anderen Klasse. Und mit dem fstream habe ich im Internet desöfteren gefunden.
-
AsterixderGallier schrieb:
Aber wie soll ich das denn ohne die If-Abfragen lösen?
Einfach hintereinander lesen?
Case-Swich geht ja nicht in dem Fall. C habe ich noch nie gemacht, nur JAVA. Ich finde die Abbruchbedingung eigentlich ok, er macht das ganze solange bis die Datei zu ende ist:
while (!fileStream.eof())oder was meinst du?
Das heißt es eben gerade nicht. Das was du gemacht hast heißt "solange wie die letzte Leseaktion nicht am Dateiende gescheitert ist". Jetzt guck mal, wo die letzte Leseaktion vor dieser Überprüfung war und was zwischen dieser Leseaktion und der Prüfung noch so alles passiert ist.
Ich habe natürlich schon debuggt, der erste Wert ist richtig, der zweite ist aber komischerweise negativ also mChunkSize. Nur hilft mir das nicht weiter um zu erkennen warum die falsch sind ab dann..
Da brauchst du doch gar nicht weiter zu debuggen. Wenn der zweite Wert schon falsch ist, ist der Rest doch uninteressant. Guck, was du einliest, vergleiche was du erwarten würdest. Guck was bei deiner Berechnung in der if-Abfrage herauskommt, vergleiche wieder was du erwarten würdest.
Und mit dem fstream habe ich im Internet desöfteren gefunden.
Im Internet findet man so einiges...
-
Da brauchst du doch gar nicht weiter zu debuggen. Wenn der zweite Wert schon falsch ist, ist der Rest doch uninteressant. Guck, was du einliest, vergleiche was du erwarten würdest. Guck was bei deiner Berechnung in der if-Abfrage herauskommt, vergleiche wieder was du erwarten würdest.
Was meinst du habe ich gemacht? Ich habe doch schon am Anfang geschrieben das meine Werte nicht stimmen, genau deshalb habe ich doch hier reingeschrieben weil vielleicht jemand ne Idee hat warum sie nicht stimmen. Nur weil ich sehe, dass sie falsch sind heißt das ja nicht unbedingt, dass ich weiß warum.
-
Wenn in der ChunkID RIFF steht, sind die Zahlenwerte Little-Endian. Dann funktioniert deine <<=-Logik nicht, weil das niederwertigste Byte zuerst kommt.
-
MFK schrieb:
Wenn in der ChunkID RIFF steht, sind die Zahlenwerte Little-Endian. Dann funktioniert deine <<=-Logik nicht, weil das niederwertigste Byte zuerst kommt.
Da hast du Recht, das guck ich mir mal eben an.
-
mChunkID <<= sizeof(Steinberg::uint8);ist doch sowieso falsch, denn sizeof(uint8) wird wohl auf den meisten Systemen 1 ergeben...
P.S. Außerdem macht es wenig Sinn, die Daten byteweise zu lesen.
-
Zu jedem Chunk gibt es doch auch die Info, wie lang der Chunk ist. Du könntest Dich also einfach von Chunk zu Chunk hangeln.
-
Tachyon schrieb:
Zu jedem Chunk gibt es doch auch die Info, wie lang der Chunk ist. Du könntest Dich also einfach von Chunk zu Chunk hangeln.
ja ich weiß, das versuche ich ja auch. Mit den If-Abfragen schaue ich ja wo grade der byteCounter ist. Und jenachdem wie lang der jeweilige Chunk gerade ist, frage ich in dem If verschieden ab. Aber es haut einfach nicht hin. Habe auch schon << mal umgedreht trotzdem falsche Werte. Habe jetzt gerade versucht
mChunkSize += oneByte;mal durch
mChunkSize |= oneByte & 0xFF;zu ersetzen, weil ich dachte vielleicht klappt da irgendwie das shiften nicht. Aber bringt nichts.
-
Th69 schrieb:
mChunkID <<= sizeof(Steinberg::uint8);ist doch sowieso falsch, denn sizeof(uint8) wird wohl auf den meisten Systemen 1 ergeben...
P.S. Außerdem macht es wenig Sinn, die Daten byteweise zu lesen.
Es soll doch auch 1 ergeben?
Warum nicht bitweise, wie dann?
-
AsterixderGallier schrieb:
Es soll doch auch 1 ergeben?
Nein. Damit verschiebst du um 1 Bit.
AsterixderGallier schrieb:
Warum nicht bitweise, wie dann?
Du liest nicht bitweise, du liest byteweise.
Daten mit fester Größe liest man üblicherweise am Stück in eine entsprechende Struktur.
-
Hier steht es beschrieben: How to Load a Wave File
-
Super werde ich mir gleich anschauen, ich habe aber gerade gemerkt, dass in einem wavefile nicht zwingend die ersten 44 bits ausgelesen werden müssen, sondern erst nachdem fmt kommt angefangen werden muss. Also kann vor dem FMT-Block noch etwas anderes stehen, wodurch dann bei mir alles durcheinander gekommen ist. Dadurch konnten meine werte auf jeden fall schonmal nicht stimmen.
Ich dachte, dass zwingend in den ersten 44 Bits die Daten stehen, aber das ist definitiv nicht so.
-
Den Unterschied zwischen Bit und Byte solltest du dir nochmal ansehen.
-
Th69 schrieb:
Hier steht es beschrieben: How to Load a Wave File
Bäh - oben steht ganz groß C++ und unten ist reiner C-Code drin. Dann geht auch das: http://www.codeproject.com/Articles/1325/Wave-Class-for-Playing-and-Recording-Wave-Files oder im Code-Project nach 'WAVE' suchen.
-
Nebenbei hast du die Datei nicht mit ios::binary geöffnet.
-
cpp_freak schrieb:
Th69 schrieb:
Hier steht es beschrieben: How to Load a Wave File
Bäh - oben steht ganz groß C++ und unten ist reiner C-Code drin. Dann geht auch das: http://www.codeproject.com/Articles/1325/Wave-Class-for-Playing-and-Recording-Wave-Files oder im Code-Project nach 'WAVE' suchen.
Ich hatte mir die Seite auch angesehen, aber diesen Link: http://www.codeproject.com/Articles/29676/CWave-A-Simple-C-Class-to-Manipulate-WAV-Files
-
Hier mal mein aktueller Code, leider geht es immernoch nicht, aber das Problem was ich vorhin geschrieben habe müsste damit eigentlich gelöst sein. Habe jetzt auch ne * 8 dahinter gemacht. Aber klappt trotzdem nicht..
void WaveFormat::readFileVersuchen (Steinberg::String samplePath) { //fstream f; //f.open("testNeu2.txt", ios::out); //f << "Dieser Text geht in die Datei" << endl; //f.close(); fstream fileStream; fileStream.open(samplePath.text (), ios::in); int byteCounter = 0; bool isSignalSounded = false; // Gibt true an, wenn fmt erreicht wurde int8 oneByte = 0; char kp[5000] = ""; int oneByteIndex = 0; if (fileStream.is_open()) { while (!fileStream.eof()) { //int au = sizeof(Steinberg::uint8); fileStream.read(&oneByte, sizeof(Steinberg::uint8)); if (byteCounter>=0 && byteCounter <= 3) { mChunkID <<= sizeof(Steinberg::uint8) * 8; mChunkID |= oneByte & 0xFF; } else if (byteCounter>=4 && byteCounter <=7) { mChunkSize <<= sizeof(Steinberg::uint8) * 8; mChunkSize |= oneByte & 0xFF; } else if (byteCounter>=8 && byteCounter <=11) { mFormat <<= sizeof(Steinberg::uint8) * 8; mFormat |= oneByte & 0xFF; } else if (byteCounter>=12 && isSignalSounded == false) // Wird ausgeführt, wenn fmt noch nicht erreicht wurde. { char oneByteChar = oneByte; if (oneByte != 0) { kp[oneByteIndex] = oneByteChar; } else if (oneByte == 0) { kp[oneByteIndex] = ' '; } for (int i = 0; i < 4997; i++) { if (kp[i] == 'f' && kp[i+1] == 'm' && kp[i+2] == 't') // Wenn fmt erreicht wurde.. { fileStream.read(&oneByte, sizeof(Steinberg::uint8)); // Weiß nicht genau ob das nicht weg muss. isSignalSounded = true; byteCounter = 11; // Setze den ByteCounter auf 15 zurück, damit die Schleifen unterhalb durchlaufen werden. ofstream ftest("C:\\Users\\Otto\\waveDaten.txt", ios::out); // Schreibt zum Testen eine ftest << kp; // Textdatei mit den Daten. } } oneByteIndex++; } else if (byteCounter>=12 && byteCounter <=15 && isSignalSounded == true) { mSubChunk1ID <<= sizeof(Steinberg::uint8) * 8; mSubChunk1ID |= oneByte & 0xFF; } else if (byteCounter>=16 && byteCounter <=19 && isSignalSounded == true) { mSubChunk1Size <<= sizeof(Steinberg::uint8) * 8; mSubChunk1Size |= oneByte & 0xFF; } else if (byteCounter>=20 && byteCounter <=21 && isSignalSounded == true) { mAudioFormat <<= sizeof(Steinberg::uint8) * 8; mAudioFormat |= oneByte & 0xFF; } else if (byteCounter>=22 && byteCounter <=23 && isSignalSounded == true) { mNumChannels <<= sizeof(Steinberg::uint8) * 8; mNumChannels |= oneByte & 0xFF; } else if (byteCounter>=24 && byteCounter <=27 && isSignalSounded == true) { mSampleRate <<= sizeof(Steinberg::uint8) * 8; mSampleRate |= oneByte & 0xFF; } else if (byteCounter>=28 && byteCounter <=31 && isSignalSounded == true) { mByteRate <<= sizeof(Steinberg::uint8) * 8; mByteRate |= oneByte & 0xFF; } else if (byteCounter>=32 && byteCounter <=33 && isSignalSounded == true) { mBlockAlign <<= sizeof(Steinberg::uint8) * 8; mBlockAlign |= oneByte & 0xFF; } else if (byteCounter>=34 && byteCounter <=35 && isSignalSounded == true) { mBitsPerSample <<= sizeof(Steinberg::uint8) * 8; mBitsPerSample |= oneByte & 0xFF; } else if (byteCounter>=36 && byteCounter <=39 && isSignalSounded == true) { mSubChunks2ID <<= sizeof(Steinberg::uint8) * 8; mSubChunks2ID |= oneByte & 0xFF; } else if (byteCounter>=40 && byteCounter <=43 && isSignalSounded == true) { mSubchunck2Size <<= sizeof(Steinberg::uint8) * 8; mSubchunck2Size |= oneByte & 0xFF; } else if (byteCounter >=44) { } byteCounter++; } fileStream.close(); } }