Pliki wave - naglowek do bufora - problem

0

Witam:) Mam nastepujacy problem. Dosc dlugo nie poslugiwalam sie umiejetnoscia pisania w C++:-) A teraz musze napisac filtr dolnoprzepustowy. W tym celu chce otworzyc plik wave i wrzucic jego zawartosc do bufora. Fragment kodu wyglada tak (pisze napredce, dlatego moga byc jakies bledy):

FILE *WaveFile;
WaveFile=fopen(FileName,"rb");
char buffer[FileSize];
fread(buffer,sizeof(char),FileSize,WaveFile); - gdzie FileSize to rozmiar pliku, a FileName sciezka. wszystko juz lezy w buforze i teraz chce z tego bufora wylowic potrzebne mi informacje: np. sprawdzam czy zgadza sie naglowek - porownuje po kolei czy zgadzaja sie znaki na okreslonych bajtach (np dla 0-4 powinien byc napis "RIFF", itd.)

char temp2[5]={0};
int position=0;
strncpy(temp2,(char *)buffer+position,4);
if (strncmp(temp2,"RIFF",4)!=0) return false;

i z tym jest OK. Natomiast problem mam, jesli chodzi o odczytanie np. liczby kanałów pliku wave. Informacja o tym jest umieszczona na pozycji 22 w 2 bajtach i wynosi - jak wyczytałam w internecie - 0x01 dla pliku mono (liczba kanałów=1), 0x02 dla stereo (liczba kanałów=2). Jak mam "przeliczyć" informacje zawarta w pliku (0x01, 0x02) na integera (1,2)? Mam następujący fragment kodu, mam z tzw. gotowca (juz napisanego przez kogos programu):

int temp[4]={0};
position=22;
temp[0]=buffer[position];
temp[1]=buffer[position+1];
Liczba_kanalow=temp[0]+16*temp[1];

ale zupelnie nie wiem dlaczego tak to ma wygladac (a wylicza sie dobrze). Tak samo sprawa ma sie z odczytaniem częstotliwości (na 24 pozycji, 4 bajty):

position=24;
for (int i=0;i<4;i++) {if((temp[i]=buffer[position+i]) <0 ) temp[i]+=256;}
Czestotliwosc=temp[0]+temp[1]*256;

oraz z dalszymi wielkosciami charakteryzujacymi plik wave (byte/sec, bytes_per_sample).
Może ktoś mi da jakas wskazowke, jesli chodzi o ten temat?
Z gory dziekuje i pozdrawiam:-))

0

A nie prościej rzutować wskaźnik char* na WORD* (unsigned short*) lub DWORD* (unsigned int*)??? Czyli:

WORD   Liczba_kanalow=*((WORD*)&buffer[22]);
DWORD Czestotliwosc=*((DWORD*)&buffer[24]);
0

generalnie plik wave składa się z chunk'ów gdzie każdy taki chunk ma z góry podany rozmiar i tylko dwa są ważne dla szarych programistów: 'fmt ' oraz 'data'

pierwsze dwordy wave to: 'RIFF', filelen-8, 'WAVE'
teraz masz same chunk'i:
pobierasz dword - to nazwa chunka, następny dword to jego rozmiar.
Jeśli nazwa == 'fmt ' // ze spacją!
to jest to WAVEFORMATEX bez ostatniego .cbSize
if 'data' - masz tutaj muzyczkę
if inny - po prostu ignorujesz, przesuwasz swój pointer na następny chunk (o chunk_size)
Aby było jasno: chunk składa się z: FOURCC nazwa, DWORD size {, size-bajtów jakichś danych}; więc 'size' nie zawiera +8 bajtów tylko rozmiar danych chunka

Możesz się 'podpisać' w każdym pliku wav dodając chunk:
'TATO', sizeof("mój plik"), "mój plik" :D

przykładzik z CWaveFile:

db "RIFF"
dd 0           ; <-filesize-8
db "WAVE"
db "fmt "
dd 16          ;   size
dw 1           ;   wFormatTag
dw 0           ; <-nChannels
dd 0           ; <-nSamplesPerSec
dd 0           ; <-nAvgBytesPerSec
dw 0           ; <-nBlockAlign
dw 0           ; <-nBitsPerSample
db "data"
dd 0           ; <-size of raw data
               ; <--- raw data ----
0
0x666 napisał(a)

A nie prościej rzutować wskaźnik char* na WORD* (unsigned short*) lub DWORD* (unsigned int*)??? Czyli:

WORD   Liczba_kanalow=*((WORD*)&buffer[22]);
DWORD Czestotliwosc=*((DWORD*)&buffer[24]);

Wyskakuje mi error przy deklaracji jednego i drugiego, cyt. 'WORD: first use of this function'. Uzywam Dev-Cpp, bo nie mam u siebie Visuala. na czym polega problem?
dzieki za odpowiedzi:-) ale moze jednak wiecie dlaczego tak sie przelicza jak to podalam w przykladzie w pierwszym poscie (zwykla ciekawosc:)) pozdrawiam

0

Wyskakuje mi error przy deklaracji jednego i drugiego, cyt. 'WORD: first use of this function'. Uzywam Dev-Cpp, bo nie mam u siebie Visuala. na czym polega problem?

Ehh to daj tak:

unsigned short   Liczba_kanalow=*((unsigned short*)&buffer[22]);
unsigned int Czestotliwosc=*((unsigned int*)&buffer[24]);
0

No tak, nie pomyslalam:/
Dzieki wielkie, pomoglo:-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1