Position eines Zeichens im Ascii/Ansii-Code
-
Hallo
Ich versuche das Signal aus einem WAVE-File grafisch darzustellen. Im WAVE-File sind die Daten mit 8 Bit Genauigkeit in Zeichen dargestellt, das heist, jedes Zeichen im WAVE-File entspricht einem Samplewert.Mittels einem anderen C++-Programm, welches funktioniert, habe ich ein Sinussignal aufgenommen und als .wav gespeichert. Die Daten sehen nach dem Header so aus: (angefangen beim 1. Samplewert, das File ist natürlich länger, weil ich nicht ein einzelner Durchlauf aufnehmen kann)
€€€€€€€€€€€€€}„oAGJUaq‚’¡¬µ¹¸³ªŽ}m^RIEEJR_nžª´¸¹µ¬ ‘paTKEDHP\k{‹›¨²¸¹¶
¢”„tdVLFDGNZhxˆ˜¦°·Die € und
betrachte ich mal als Einschwingen oder so, danach widerholen sich die Zeichen nach einer Periode.der vereinfachte C++-Code sieht ungefähr so aus:
//Unterprogramm dataconvert unsigned int dataconvert(char data){ unsigned int MSB; MSB=int(data); return MSB; } //Unterprogramm laden void laden(void){ for(i=0;i<2048;i++){ fscanf(f,"%c",&data); decresultarrayleft[i]=dataconvert(data); } for(i=0;i<2048;i++){ if(i==0){Form1->Image1->Canvas->MoveTo(20,height/2);} else Form1->Image1->Canvas->LineTo(20+i*3,((decresultarrayleft[i]/4)+height/2)); } }Das Resultat (Image1) sieht so aus: http://www.horgenberghammers.ch/sine
Der Sinus ist erkennbar, jedoch springt die Amplitude nach jeder Halbwelle. Mein Verdacht ist nun, dass der Befehl MSB=int(data); mit dem ASCII statt dem ANSII-Code arbeitet, oder dass beim Konvertieren von einer Variabel in die andere irgendwelche Vorzeichenfehler auftreten.
Habt ihr auch schon solche Probleme gehabt und habt ihr Lösungsansätze?
Danke im Voraus!
-
Der Link funktioniert nicht.
Habe keine Ahnung vom wav-Format, aber kannst du nicht gleich als (unsigned) int einlesen? Wozu der Umweg über char?
-
Hallo Jansen
Danke für deine Antwort!
Bist du sicher, dass der Link nicht funktioniert? bei mier gehts...
Zu deinem Vorschlag: Die Idee währe super, jedoch habe ich keine Ahnung wie so etwas gehen soll. Ich kenne für das Auslesen von Daten aus Textdateien nur den Befehl 'fscanf'. Kann man damit auch int einlesen? Und weiter habe ich das Gefühl, dass das nicht funktionieren würde, denn die Samplewerte sind ja in Zeichen gespeichert, nicht in int-Werten. (oben dargestellt)
-
Kann es sein, dass du die Datei nicht binär öffnest?
-
Danke für deine Antwort.
Nein, ich öffne die Datei nicht Binär, da im Dateiheader auch noch Zeichen enthalten sind, die ich nicht umwandeln muss. Allerdings könnte ich das vorerst einfach mal weglassen...
Also, gehen wir mal davon aus, dass ich die Datei nun Binär öffne:
f=fopen("C:/test.wav","r+b"); fseek(f,48,SEEK_SET);Vor dem ersten Sample-Wert im Dateiheader stehen 48 Zeichen (8-Bit). Die gillt es nun zu überspringen. Funktioniert das so? Irgendwie müsste ich doch dem fseek noch sagen, das er 48 mal 8 Bit überspringen muss. Eigentich müsste das ganze aber auch so funktionieren, oder:
int nichts,i,data; f=fopen("C:/test.wav","r+b"); for(i=0;i<48;i++) fread(&nichts, sizeof(nichts),1,f);Dan währe ich auch an der Position des ersten Sample-Wertes, oder?
Und danach der Lesebefehl:
fread(&data, sizeof(data),1,f);Müsste dan nicht die Variabel 'data' genau 8 Bit lang sein, dass das Programm auch nur 8 Bit ausliest und der Zeiger für den nächsten Lesebefehl an der richtigen Position steht?
Und wie definiert man eine genau 8-Bit grosse Variabel?
Danke für eure Hilfe!
-
es gibt noch mehr Filehandling FUnktionen fseek zum Beispiel ist hier auch klar dein Freund.
Was die Variablengrösse betrifft: nein, sie müsste nicht 8 Bit gross sein. Datentypengrössen sind entweder abhängig von der Maschinengrösse oder fix breit. Niemals jedoch variabel.
char ist eine 8-Bit Variabel. Das ist jedoch irelevant, denn du bestimmst ja wie viel aus der Datei ausgelesen wird. Benutz dafür vielleicht eher fread als fscanf.
-
Danke für deine Antwort.
Deinen Informationen zufolge interpretiere ich, dass ich den Zeiger nun folgendermassen auf das 48. Bit setze:fread(&data, sizeof(data),384,SEEK_SET);die 384 beziehen sich auf die 48*8Bit, die als Offset angegeben werden. Ich gehe hier mal davon aus, das man den Offset in Bits angiebt.
und wenn 'data' nun irgendeine int-variabel ist, funktioniert das wirklich, dass danach nach jedem Lesebefehl immer genau den Wert eines Zeichens in der Int-Variabel steht?
Binär-File: 01111000 1110100001110000001111100001110111.... ¦1.Zeichen¦ ¦2.Z ¦ 3.Z ¦Wiso habe ich nun den Wert von genau 8 Bits in meiner 32-Bit Int-Variabel?
Funktioniert das wirklich?
-
Schon mal die Dokumentation zu fseek und fread gelesen? Sieht jedenfalls nciht danach aus.