Wave-File auslesen



  • 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();
    	}
    }
    


  • schaue auf Zeile 8 und diesen Beitrag von Michael

    schaue auf Zeile 23, 28, 33, usw, und auf die Bemerkung von MFK



  • cpp_freak schrieb:

    schaue auf Zeile 8 und diesen Beitrag von Michael

    schaue auf Zeile 23, 28, 33, usw, und auf die Bemerkung von MFK

    Ok das mit 23, 28, 33 ist mir klar, aber trotzdem müssten ja die anderen Werte dann korrekt sein, die beeinflussen sich ja nicht. Wenn die stimmen wollte ich da weiter machen. Zeile 8 schaue ich mir jetzt mal an.



  • Das kann man ja gar nicht mit ansehen!
    Du liest aus einer Datei mit binärem Inhalt doch nur Zeichenketten und uint23_t und uint16_t-Werte. Schreibe Dir doch zunächst mal dafür jeweils eine kleine Funktion, die das erledigt.

    Es gibt sicher schöneres, als das was ich Dir hier vorschlage - siehe ibinstream, aber ich will das mal auf Deinem Programm aufbauen.

    Also mit den drei Funktionen ...

    #include <string>
    #include <istream>
    #include <cstdint>
    
    void readbin( std::istream& in, std::string& str, std::size_t n )
    {
        const std::size_t N = 100;
        char buf[N]; // hier mal ganz anfängermäßig!
        if( n > N )
            in.setstate( std::ios_base::failbit );
        if( in.read( buf, n ) )
            str.assign( buf, buf + n );
    }
    void readbin( std::istream& in, std::uint32_t& x )
    {   // ACHTUNG: Dein OS muss Little Endian haben (z.B.: Windows), nur dann ist dies ok!
        in.read( (char*)&x, sizeof(x) );
    }
    void readbin( std::istream& in, std::uint16_t& x )
    {
        in.read( (char*)&x, sizeof(x) );
    }
    

    .. geht alles viel einfacher.

    Hier in Deine Methode eingebaut, unter Berücksichtigung dessen, was hier bereits erwähnt wurde.

    void WaveFormat::readFileVersuchen (Steinberg::String samplePath)
    {
        using namespace std;
        ifstream fileStream(samplePath.c_str(), ios_base::binary ); // ios_base::binary MUSS sein
        if (!fileStream.is_open())
            return;
    
        string tag;
        readbin( fileStream, tag, 4 );
        if( !fileStream || tag != "RIFF" ) // mChunkID
        {
            cerr << "keine RIFF-Datei" << endl;
            return;
        }
        readbin( fileStream, mChunkSize );
        readbin( fileStream, tag, 4 );
        if( !fileStream || tag != "WAVE" ) // mFormat
        {
            cerr << "keine WAVE-Datei" << endl;
            return;
        }
    
        for( uint32_t len; ; )
        {
            // --   Header des jeweiligen Chunks einlesen: tag + len
            readbin( fileStream, tag, 4 );
            readbin( fileStream, len );
            if( !fileStream )
                break; // EOF
    
            cout << "Chunk: " << tag << " Len:" << len << endl;
            if( tag == "fmt " ) // abhängig vom Chunk-Typ die Details lesen
            {
                readbin( fileStream, mAudioFormat );
                readbin( fileStream, mNumChannels );
                readbin( fileStream, mSampleRate );
                readbin( fileStream, mByteRate );
                readbin( fileStream, mBlockAlign );
                readbin( fileStream, mBitsPerSample );
                if( fileStream )
                    cout << "fmt ohne Fehler gelesen" << endl; 
            }
            // else if( tag == "data" ) // hier kommt der Ton
            // {}
            else
            {
                fileStream.ignore( len ); // unbekannten Chunk überspringen
            }
        }
    }
    

    und schon sind es nur noch 50 Zeilen statt 90 und die Methode tut auch noch mehr.

    Gruß
    Werner



  • Werner Salomon schrieb:

    Das kann man ja gar nicht mit ansehen!
    Du liest aus einer Datei mit binärem Inhalt doch nur Zeichenketten und uint23_t und uint16_t-Werte. Schreibe Dir doch zunächst mal dafür jeweils eine kleine Funktion, die das erledigt.

    Es gibt sicher schöneres, als das was ich Dir hier vorschlage - siehe ibinstream, aber ich will das mal auf Deinem Programm aufbauen.

    Also mit den drei Funktionen ...

    #include <string>
    #include <istream>
    #include <cstdint>
    
    void readbin( std::istream& in, std::string& str, std::size_t n )
    {
        const std::size_t N = 100;
        char buf[N]; // hier mal ganz anfängermäßig!
        if( n > N )
            in.setstate( std::ios_base::failbit );
        if( in.read( buf, n ) )
            str.assign( buf, buf + n );
    }
    void readbin( std::istream& in, std::uint32_t& x )
    {   // ACHTUNG: Dein OS muss Little Endian haben (z.B.: Windows), nur dann ist dies ok!
        in.read( (char*)&x, sizeof(x) );
    }
    void readbin( std::istream& in, std::uint16_t& x )
    {
        in.read( (char*)&x, sizeof(x) );
    }
    

    .. geht alles viel einfacher.

    Hier in Deine Methode eingebaut, unter Berücksichtigung dessen, was hier bereits erwähnt wurde.

    void WaveFormat::readFileVersuchen (Steinberg::String samplePath)
    {
        using namespace std;
        ifstream fileStream(samplePath.c_str(), ios_base::binary ); // ios_base::binary MUSS sein
        if (!fileStream.is_open())
            return;
    
        string tag;
        readbin( fileStream, tag, 4 );
        if( !fileStream || tag != "RIFF" ) // mChunkID
        {
            cerr << "keine RIFF-Datei" << endl;
            return;
        }
        readbin( fileStream, mChunkSize );
        readbin( fileStream, tag, 4 );
        if( !fileStream || tag != "WAVE" ) // mFormat
        {
            cerr << "keine WAVE-Datei" << endl;
            return;
        }
    
        for( uint32_t len; ; )
        {
            // --   Header des jeweiligen Chunks einlesen: tag + len
            readbin( fileStream, tag, 4 );
            readbin( fileStream, len );
            if( !fileStream )
                break; // EOF
    
            cout << "Chunk: " << tag << " Len:" << len << endl;
            if( tag == "fmt " ) // abhängig vom Chunk-Typ die Details lesen
            {
                readbin( fileStream, mAudioFormat );
                readbin( fileStream, mNumChannels );
                readbin( fileStream, mSampleRate );
                readbin( fileStream, mByteRate );
                readbin( fileStream, mBlockAlign );
                readbin( fileStream, mBitsPerSample );
                if( fileStream )
                    cout << "fmt ohne Fehler gelesen" << endl; 
            }
            // else if( tag == "data" ) // hier kommt der Ton
            // {}
            else
            {
                fileStream.ignore( len ); // unbekannten Chunk überspringen
            }
        }
    }
    

    und schon sind es nur noch 50 Zeilen statt 90 und die Methode tut auch noch mehr.

    Gruß
    Werner

    vielen dank, aber habe trotzdem nochmal weiter versucht selber das hinzukiregen.
    Hat auch endlich halbwegs geklappt! Ich kriege jetzt die richtigen Werte heraus, allerdings nur in hexadezimal, und manche muss man davon noch umdrehen. Bei der Samplerate steht zum Beispiel: 0080bb00. Dreht man das um steht dort bb80 und das sind 48000! Und das ist ja bekanntlich nen passender Wert für ne Samplerate. Ich denkee das liegt dann wohl an little und Big Endian. Werde jetzt mal versuchen das komplett hinzukriegen.
    Code:

    void WaveFormat::readFileVersuchen (Steinberg::String samplePath)
    {
    	bool dump = true;
    	wofstream ftest("C:\\Users\\Otto\\waveDaten.txt", ios::out);
    	std::string fmtMarker;
    	std::string fmtString = "fmt ";
    	int chunkState = kChunkDescriptor;
    	fstream fileStream;
    	fileStream.open(samplePath.text (), ios::in);
    	int byteCounter = 0;
    	bool isSignalSounded = false;			// Gibt true an, wenn fmt erreicht wurde
    	int8 oneByte = 0;
    	if (fileStream.is_open())
    	{
    		while (!fileStream.eof())
    		{
    			//int au = sizeof(Steinberg::uint8);
    			fileStream.read(&oneByte, sizeof(Steinberg::uint8)); 
    			if (dump)
    			{
    				ftest << oneByte << std::hex;
    			}
    
    			if (chunkState == kChunkDescriptor)
    			{
    				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;
    					if (byteCounter == 11)
    					{
    						chunkState = kFmtSubChunk;
    					}
    				}
    			}
    			else if (chunkState == kFmtSubChunk)
    			{
    				static const string kFmtMarker = "";
    				if (oneByte == 0)
    				{
    					fmtMarker.push_back (' ');
    				}
    				else
    				{
    					fmtMarker.push_back (oneByte);
     					int hmmmm = fmtMarker.find(fmtString);
    					if (hmmmm > 0 && !isSignalSounded)		// && !isSignalSounded entfernen um die Sachen nach fmt in die Datei mitzuschreiben
    					{
    						fileStream.read(&oneByte, sizeof(Steinberg::uint8));			// ???
    						isSignalSounded = true;											// Da fmt erreicht wurde, wird hier nicht mehr reingesprungen
    						byteCounter = 17;												// Setze den ByteCounter auf 17 zurück, damit die Schleifen unterhalb durchlaufen werden.
    						ofstream ftest("C:\\Users\\Otto\\waveDaten.txt", ios::out);		// Schreibt zum Testen eine
    						ftest << fmtMarker;												// Textdatei mit den Daten. (Noch keine umgewandelten)
    						//turnHex(0xccbb3344);											// Test ob das umdrehen klappt
    					}
    				}
    /*				if (byteCounter>=12 && byteCounter <=15 && isSignalSounded == true)
    				{
    					mSubChunk1ID <<= sizeof(Steinberg::uint8) * 8;				                     
    					mSubChunk1ID |= oneByte & 0xFF;
    				}				*/   
    				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++;
    		}
    	}
    }
    


  • AsterixderGallier schrieb:

    vielen dank, aber habe trotzdem nochmal weiter versucht selber das hinzukiregen.
    Hat auch endlich halbwegs geklappt! Ich kriege jetzt die richtigen Werte heraus, allerdings nur in hexadezimal, und manche muss man davon noch umdrehen. Bei der Samplerate steht zum Beispiel: 0080bb00. Dreht man das um steht dort bb80 und das sind 48000! Und das ist ja bekanntlich nen passender Wert für ne Samplerate. Ich denkee das liegt dann wohl an little und Big Endian.

    Nö - das liegt an Dir.

    Ändere an Deinem Programm folgendes:
    - Zeile 9 Daten BINÄR lesen

    fileStream.open(samplePath.text (), ios::in | ios::binary);
    

    wenn Du das nicht tust, wird spätestens das Lesen der Audiodaten fehlschlagen!

    - Zeile 57 >= 0

    if (hmmmm >= 0 && !isSignalSounded)
    

    wird der fmt_-String gefunden, so kann ' hmmmm ' auch den Wert 0 annehmen, falls der erste Chunk bereits der 'fmt_'-Chunk ist.

    - Zeile 61

    byteCounter = 16;
    

    - Zeile 89 und 90
    ersetze diese beiden Zeilen bitte durch

    if( byteCounter == 24 )
                            mSampleRate = 0;
                        mSampleRate |= (oneByte & 0xFF) << 8*(byteCounter - 24);
    

    Du wirst sehen, dass hilft 😉 - auch wenn Du danach noch nicht am Ziel bist.

    Gruß
    Werner



  • Hallo AsterixDerGallier,

    kennst du schon das for-case Antipattern? Dein Code ist also ein Paradebeispiel dafür.
    Auch wenn der Code von Werner dir vllt. jetzt noch etwas zu hoch vorkommt, so solltest du doch unsere Ratschläge annehmen...



  • Werner Salomon schrieb:

    AsterixderGallier schrieb:

    vielen dank, aber habe trotzdem nochmal weiter versucht selber das hinzukiregen.
    Hat auch endlich halbwegs geklappt! Ich kriege jetzt die richtigen Werte heraus, allerdings nur in hexadezimal, und manche muss man davon noch umdrehen. Bei der Samplerate steht zum Beispiel: 0080bb00. Dreht man das um steht dort bb80 und das sind 48000! Und das ist ja bekanntlich nen passender Wert für ne Samplerate. Ich denkee das liegt dann wohl an little und Big Endian.

    Nö - das liegt an Dir.

    Ändere an Deinem Programm folgendes:
    - Zeile 9 Daten BINÄR lesen

    fileStream.open(samplePath.text (), ios::in | ios::binary);
    

    wenn Du das nicht tust, wird spätestens das Lesen der Audiodaten fehlschlagen!

    - Zeile 57 >= 0

    if (hmmmm >= 0 && !isSignalSounded)
    

    wird der fmt_-String gefunden, so kann ' hmmmm ' auch den Wert 0 annehmen, falls der erste Chunk bereits der 'fmt_'-Chunk ist.

    - Zeile 61

    byteCounter = 16;
    

    - Zeile 89 und 90
    ersetze diese beiden Zeilen bitte durch

    if( byteCounter == 24 )
                            mSampleRate = 0;
                        mSampleRate |= (oneByte & 0xFF) << 8*(byteCounter - 24);
    

    Du wirst sehen, dass hilft 😉 - auch wenn Du danach noch nicht am Ziel bist.

    Gruß
    Werner

    Danke ich glaube das hilft mir schonmal weiter!! Aber muss erstmal etwas sehen



  • Th69 schrieb:

    Hallo AsterixDerGallier,

    kennst du schon das for-case Antipattern? Dein Code ist also ein Paradebeispiel dafür.
    Auch wenn der Code von Werner dir vllt. jetzt noch etwas zu hoch vorkommt, so solltest du doch unsere Ratschläge annehmen...

    Ja versuche ich ja, aber ich will halt soweit wie möglich auf den code selber kommen. Wenn er erstmal läuft ist es doch auch einfacher ihn zu verbessern, weil dann kann man immer testen wenn etwas verändert wurde ob es noch läuft.
    Das ist eigentlich meine erste (für mich) ziemlich komplexe Sache die ich versuche zu machen. Hab mir vorgenommen ganz am Ende vllt nen Drumcomputer daraus zu machen, aber das ist sicher noch lange hin.



  • So mein Code funktioniert:

    void WaveFormat::readFileVersuchen (Steinberg::String samplePath)
    {
    	std::string fmtMarker;
    	std::string fmtString = "fmt ";
    	int chunkState = kChunkDescriptor;
    	fstream fileStream;
    	fileStream.open(samplePath.text (), ios::in | ios::binary);
    	int byteCounter = 0;
    	bool isSignalSounded = false;			// Gibt true an, wenn fmt erreicht wurde
    	int8 oneByte = 0;
    	if (fileStream.is_open())
    	{
    		while (!fileStream.eof())
    		{
    			fileStream.read(&oneByte, sizeof(Steinberg::uint8)); 
    			if (chunkState == kChunkDescriptor)
    			{
    				if (byteCounter>=0 && byteCounter <= 3)					// Liest die ChunkID ein (RIFF)
    				{
    					if (byteCounter == 0)
    						mChunkID = "";
    					mChunkID.push_back (oneByte);
    				}
    				else if (byteCounter>=4 && byteCounter <=7)				// Liest die Größe des Data-Blocks ein (etwas kleiner als die Datei)
    				{
    					if( byteCounter == 4 )
    						mChunkSize = 0;
                        mChunkSize |= (oneByte & 0xFF) << 8*(byteCounter - 4);
    				}
    				else if (byteCounter>=8 && byteCounter <=11)			// Liest das Format ein (WAVE), push_back hängt jeweils oneByte an den String ran			
    				{
    					if (byteCounter == 8)
    						mFormat = "";
    					mFormat.push_back(oneByte);
    					if (byteCounter == 11)
    					{
    						chunkState = kFmtSubChunk;
    					}
    				}
    			}
    			else if (chunkState == kFmtSubChunk)
    			{
    				static const string kFmtMarker = "";
    				if (oneByte == 0)
    				{
    					fmtMarker.push_back (' ');
    				}
    				else
    				{
    					fmtMarker.push_back (oneByte);
     					int hmmmm = fmtMarker.find(fmtString);
    					if (hmmmm >= 0 && !isSignalSounded)		// && !isSignalSounded entfernen um die Sachen nach fmt in die Datei mitzuschreiben
    					{
    						fileStream.read(&oneByte, sizeof(Steinberg::uint8));			// ???
    						isSignalSounded = true;											// Da fmt erreicht wurde, wird hier nicht mehr reingesprungen
    						byteCounter = 16;												// Setze den ByteCounter auf 17 zurück, damit die Schleifen unterhalb durchlaufen werden.
    						mSubChunk1ID = "fmt ";
    						ofstream ftest("C:\\Users\\Otto\\waveDaten.txt", ios::out);		// Schreibt zum Testen eine
    						ftest << fmtMarker;												// Textdatei mit den Daten. (Noch keine umgewandelten)
    					}
    				}
    				if (byteCounter>=16 && byteCounter <=19 && isSignalSounded == true)
    				{
    				   	if( byteCounter == 22 )		// Ist dafür da, dass auch eine zweite Datei danach eingelesen werden kann, und der alte Wert vorher wieder auf 0 gesetzt wird
    						mSubChunk1Size = 0;
                        mSubChunk1Size |= (oneByte & 0xFF) << 8*(byteCounter - 16);
    				}
    				else if (byteCounter>=20 && byteCounter <=21 && isSignalSounded == true)
    				{
    				 	if( byteCounter == 20 )
                            mAudioFormat = 0;
                        mAudioFormat |= (oneByte & 0xFF) << 8*(byteCounter - 20);
    				}
    				else if (byteCounter>=22 && byteCounter <=23 && isSignalSounded == true)
    				{
    					if( byteCounter == 22 )
                            mNumChannels = 0;
                        mNumChannels |= (oneByte & 0xFF) << 8*(byteCounter - 22);
    				}
    				else if (byteCounter>=24 && byteCounter <=27 && isSignalSounded == true)
    				{
    					if( byteCounter == 24 )				
                            mSampleRate = 0;	
                        mSampleRate |= (oneByte & 0xFF) << 8*(byteCounter - 24);
    				}
    				else if (byteCounter>=28 && byteCounter <=31 && isSignalSounded == true)
    				{						   
    					if( byteCounter == 28 )
                            mByteRate = 0;
                        mByteRate |= (oneByte & 0xFF) << 8*(byteCounter - 28);
    				}
    				else if (byteCounter>=32 && byteCounter <=33 && isSignalSounded == true)
    				{
    					if( byteCounter == 32 )
                            mBlockAlign = 0;
                        mBlockAlign |= (oneByte & 0xFF) << 8*(byteCounter - 32);
    				}
    				else if (byteCounter>=34 && byteCounter <=35 && isSignalSounded == true)
    				{
    					if( byteCounter == 34 )
                            mBitsPerSample = 0;
                        mBitsPerSample |= (oneByte & 0xFF) << 8*(byteCounter - 34);
    				}	
    				else if (byteCounter>=36 && byteCounter <=39 && isSignalSounded == true)
    				{
    					if( byteCounter == 36 )
                            mSubChunks2ID = 0;
                        mSubChunks2ID |= (oneByte & 0xFF) << 8*(byteCounter - 36);
    				}
    				else if (byteCounter>=40 && byteCounter <=43 && isSignalSounded == true)
    				{
    					if( byteCounter == 40 )
                            mSubchunck2Size = 0;
                        mSubchunck2Size |= (oneByte & 0xFF) << 8*(byteCounter - 40);
    				}
    				else if (byteCounter >=44)
    				{
    					// Data-Block einlesen	
    				}
    			}			
    			byteCounter++;
    		}
    	}
    		fileStream.close();
    }
    

    Muss man dieses auf 0 setzen der Werte

    if( byteCounter == 20 )
                            mAudioFormat = 0;
                        mAudioFormat |= (oneByte & 0xFF) << 8*(byteCounter - 20);
    

    in jedem Block machen oder besser einfach am Anfang bei byteCounter == 0 alle zurück setzen. Wie sollte ich den Code noch verbessern, bzw. aufräumen? Vielen Dank schonmal bishierhin.


  • Mod

    Mach doch bitte endlich das for-case Pattern raus! Das wurde dir schon in der allerersten Antwort gesagt! Überhaupt wurden dir schon ganz viele wichtige Fehler genannt, von denen du nicht eine Sache auch nur angeguckt hast. Z.B. das while(!eof) ist immer noch drin. Lies am besten den ganzen Thread nochmal langsam und genau und setz alles um ,was dir genannt wurde.


Anmelden zum Antworten