#include #include #include #define MAXVZORKU 500000 #define KONECOK 0 #define KONECERR -1 #define MAXINDHLAV 57 /* to je posledni index hlavicky waw file */ unsigned char azakon(float vzorek); void prechroustej(unsigned long int co); int mocvelkejvzorek; unsigned char prechr[4]; /* pole pro prechroustavaci proceduru */ main() { float cislo; int vysledek = 1; int i = 0; unsigned long int pocetvzorku = 0; unsigned long int celkovadelka = 0; unsigned char vzazak; unsigned char *pamet; /* to je ukazatel na pamet, tam se budou ukladat vzorky */ unsigned char *ukazovatko; unsigned char wavfile[MAXINDHLAV+2]; /* +2 neni chyba, nebot tam jeste prijde 0 jako konec stringu - inicializuji to pomoci strcpy */ pamet = (char*)malloc(MAXVZORKU + 2); if(pamet == NULL) { printf("Nepodarilo se alokovat %d byte pameti - koncim \n", MAXVZORKU); return KONECERR; } ukazovatko = pamet; mocvelkejvzorek = 0; while((vysledek == 1) &&( pocetvzorku <= MAXVZORKU )&& !mocvelkejvzorek ) { vysledek = scanf(" %f", &cislo); if(vysledek == 1) { pocetvzorku++; } vzazak = azakon(cislo ); printf("Pro hodnotu %f je po prevodu %x hex \n",cislo,vzazak); vzazak = vzazak ^ 0x55; /* invertneme sude bity ^ je XOR, a bit uplne napravo - LSb - je 0., tedy sudy. */ *ukazovatko++ = vzazak; } /* tady jsme vypadli z cteciho cyklu */ if(pocetvzorku == 0 ) { printf("Nebyl precten zadny platny vzorek. WAV file tedy nelze udelat. \n\n"); free(pamet); return KONECERR; /* a koncim s celym programem */ } if(pocetvzorku > MAXVZORKU ) { printf("Bylo zadano prilis mnoho vzorku, vice nez %d\n",MAXVZORKU); printf(" WAV file tedy nelze udelat. \n\n"); free(pamet); return KONECERR ; /* a koncim s celym programem */ } if(mocvelkejvzorek) { printf("Byl zadan prilis velky vzorek (abs.h. > 1). WAV file tedy nelze udelat. \n\n"); free(pamet); return KONECERR ; /* a koncim s celym programem */ } /* no a pokud jsme se dostali sem, tak mame vsechny vstupni vzorky prevedene a ulozene v RAM - pointer, v pocetvzorku je pocet vzorku a tedy muzeme smele vyrabet file *.wav */ strcpy(wavfile,"RIFF****WAVEfmt ----**++****++++**++**fact****++++data****"); celkovadelka = pocetvzorku + 50; /* plati pro Azak, 1 kan. atd. ... */ prechroustej(celkovadelka); for(i=0;i<4;i++) wavfile[4+i] = prechr[i]; wavfile[16] = 0x12; wavfile[17] = 0; wavfile[18] = 0; wavfile[19] = 0; /* delka chunku fmt */ wavfile[20] = 6; /* format - A zakon dle CCITT */ wavfile[21] = 0; wavfile[22] = 1; /* pocet kanalu */ wavfile[23] = 0; wavfile[24] = 0x40; /* vzorku za 1 sec - 8000 */ wavfile[25] = 0x1f; wavfile[26] = 0; wavfile[27] = 0; wavfile[28] = 0x40; /* bytu za 1 sec */ wavfile[29] = 0x1f; wavfile[30] = 0; wavfile[31] = 0; wavfile[32] = 1; /* bytu na vzorek */ wavfile[33] = 0; wavfile[34] = 8; /* bitu na vzorek */ wavfile[35] = 0; wavfile[36] = 0; /* nevim, co to je */ wavfile[37] = 0; wavfile[42] = 4; /* velikos chunku fact */ wavfile[43] = 0; wavfile[44] = 0; wavfile[45] = 0; prechroustej(pocetvzorku); for(i=0;i<4;i++) wavfile[46+i] = prechr[i]; /* tohle neni chyba; pocet vzorku se tam udava dvakrat, jednou v chunku fact a podruhe v chunku data */ for(i=0;i<4;i++) wavfile[54+i] = prechr[i]; /* no a tady to tisknu; nejde pouzit %c, nebot v poli jsou 0 a ty se interpretuji jako konec stringu */ for(i=0;i<= MAXINDHLAV;i++) printf("%c",wavfile[i]); ukazovatko = pamet; while(pocetvzorku-- > 0) { vzazak = *ukazovatko++; printf("%c", vzazak); } free(pamet); return KONECOK; } /* funkce prechrousta cislo do 4 bytu, aby se dalo nacpat do pole wav little endian, tedy LSB ma index 0, MSB 3*/ void prechroustej(unsigned long int co) { unsigned int pom; unsigned long int pomco; unsigned char znak; pom = ( unsigned int ) (co / 16777216); /* to je 256 na 3 - a to bude MSB */ znak = (unsigned char) pom; prechr[3] = znak; pomco = co - (pom * 16777216); pom = ( unsigned int) (pomco / 65536); znak = (unsigned char) pom; prechr[2] = znak; pomco = pomco - (pom * 65536); pom = ( unsigned int) (pomco / 256); znak = (unsigned char) pom; prechr[1] = znak; pomco = pomco - (pom * 256); znak = (unsigned char) pomco; prechr[0] = znak; } /* funkce prevede cislo na jeho representaci v A zakone. cislo musi byt v intervalu <0; 1> 1 odpovida maximum, tedy 127 dec nemo 0x7f a pak se jeste musi zinvertovat sude bity, to se dela az v main */ unsigned char azakon(float vzorek) { unsigned int ivzorek; unsigned int pocposun; int i; int jetozaporne; unsigned char vzazak; jetozaporne = 0; if (vzorek < 0) { vzorek = vzorek * (-1); jetozaporne = 1; } if (vzorek > 1) { mocvelkejvzorek = 1; vzazak = 0x7f; } else { ivzorek = (unsigned int) (vzorek * 2047U); /* 0x7ff - plnych 11 bitu U znamena, ze konstanta bude unsigned */ ivzorek = ivzorek & 0x7ffU; pocposun = 7; while ( (!((ivzorek & 0x400U) == 0x400U)) && ( pocposun > 0) ) { pocposun--; ivzorek = ivzorek << 1; } ivzorek = ivzorek >> 7 ; pocposun = pocposun << 4; vzazak = (unsigned char) ivzorek + (unsigned char) pocposun; } if (jetozaporne) vzazak = vzazak + 0x80; return vzazak; }