// sndview.c // (c) Perry R. Cook, 1987-2008 // You're free to use this except for evil // Perry's horrible non-secret for well over 20 years now // Use some variant of these, depending on architecture and OS // link with glut32.lib or whatever (Frameworks on MacOSX) // or just use -lglut in compiler/linker line // Use these includes for LINUX: // #include // #include // #include // Use these includes for Mac OS X: #include #include #include // June08: Just hacked this for intel arch. Had to do some // byte-swap fixing so it's possible I broke it for m@tr@la // machines, so if you need it for your NeXT machine or ppcMac, // then change the define from LITTLEENDIAN to BIGENDIAN, and // hold on to your hat. // Rules of thumb: if data looks funny, try with -s or -b #define LITTLEENDIAN #include #include #include // #include // for getch() function on some compilers // #include // for malloc on some compilers #include char file_name[1024]; #define RAW 0 #define WAV 1 #define SND 2 #define AIF 3 /* unsupported */ #define FLT 4 #define BYTE 1 #define WORD 2 #define MIN_WIN 16 #define MAX_WIN 262144 #define MAX_WIN_TYPE 5 int Size=64; int Beginning=0; int WinType=3; int FileType = 0; // RAW, WAV, SND, or FLT int SwapMode=0; // 0 = don't swap int WordSize=0; long HdrLength=0; long Srate=0; long Location=0; long CursorPos=0; float FreqScale=0; FILE *MyFile,*TempFile; int CalcSpectrum=0; int ByteMode=0; long MySize=0; float drawC[4] = {0,1,0,0}; float clearC[4] = {0,0,0,0}; short data[MAX_WIN*2]; // moved these to here so we float fdata[MAX_WIN*2]; // can see them for playback void swaplong(long *along) { unsigned char *temp,temp2; temp = (unsigned char *) along; temp2 = temp[0]; temp[0] = temp[3]; temp[3] = temp2; temp2 = temp[1]; temp[1] = temp[2]; temp[2] = temp2; } void swapshort(short *ashort) { unsigned char *temp,temp2; temp = (unsigned char *) ashort; temp2 = temp[0]; temp[0] = temp[1]; temp[1] = temp2; } void Redraw(void); SndView(int InitLocation, int InitSize, char *InitFileName) { long i = 0; int k = 1; short data[256]; Size = InitSize; FreqScale = 1.0; // Location = InitLocation; CalcSpectrum = 1; // ByteMode = InitByteMode; // SwapMode = InitSwapMode; if (WordSize==BYTE) { while(k) { k = fread(&data,1,256,MyFile); i += k; } } else if (WordSize==WORD) { while(k) { k = fread(&data,2,256,MyFile); i += k; } } else if (WordSize==FLT) { while(k) { k = fread(&data,4,256,MyFile); i += k; } } MySize = i; CursorPos = 32; Srate = -1; WinType = 3; Beginning = 0; if (file_name[strlen(InitFileName)-4] == '.' && file_name[strlen(InitFileName)-3] == 'w') { // .wav FileType = WAV; HdrLength = 44; Beginning = HdrLength; fseek(MyFile,24,0); fread(&Srate,4,1,MyFile); #ifdef BIGENDIAN swaplong(&Srate); #endif } else if (file_name[strlen(InitFileName)-4] == '.' && file_name[strlen(InitFileName)-3] == 's') { // .snd FileType = SND; fseek(MyFile,4,0); fread(&HdrLength,4,1,MyFile); fseek(MyFile,16,0); fread(&Srate,4,1,MyFile); #ifdef LITTLEENDIAN SwapMode = 1; swaplong(&HdrLength); swaplong(&Srate); #endif Beginning = HdrLength; } else if (file_name[strlen(InitFileName)-3] == '.' && file_name[strlen(InitFileName)-2] == 'a') { // .au, same as .snd FileType = SND; fseek(MyFile,4,0); fread(&HdrLength,4,1,MyFile); fseek(MyFile,16,0); fread(&Srate,4,1,MyFile); #ifdef LITTLEENDIAN SwapMode = 1; swaplong(&HdrLength); swaplong(&Srate); #endif Beginning = HdrLength; } return 1; }; #define PI 3.141592654782 #define SQRT_TWO 1.414213562 #define TWO_PI 6.283185309564 // #define MAX_WIN 5 void rectangle(int size,float* array) { // Dummy, don't do anything ; } void triangle(int size,float* array) { int i; float w = 0.0, delta; delta = 2.0 / size; for (i=0;i0.0) { if (array[0] > t1) t1 = array[0]; } for (i=1;i0.0) { if (t>t1) t1 = t; } } // printf("%f\n",t1); if (t1>0.0) { for (i=0;i0.0) { t = log10(array[i]/t1); if (t MySize) Location = MySize - Size; if (Location MySize) Location = MySize - Size; if (Location MySize) Location = MySize - Size; if (Location>1); SetLocation(loc); loc = YourLocation(); } else if (key==GLUT_KEY_LEFT) { loc -= (size>>1); SetLocation(loc); loc = YourLocation(); } else if (key==GLUT_KEY_HOME) { loc = 0; SetLocation(loc); loc = YourLocation(); } else if (key==GLUT_KEY_END) { loc = MySize; SetLocation(loc); loc = YourLocation(); } } #include "waveio.h" // Added new for 2008 to support file snip playback struct soundhdr myhdr = {"RIF",88244,"WAV","fmt",16,1,1, 44100,88200,2,16,"dat",88200}; void KeyFunc(unsigned char key, int x, int y) { char tempString[2048]; if (key==0x1b) { fclose(MyFile); exit(0); } if (key=='q') { fclose(MyFile); exit(0); } else if (key=='+') { size *= 2; if (size>MAX_WIN) size = MAX_WIN; else { CursorPos *= 2; if (CursorPos >= (FreqScale * Size / 2)) CursorPos = FreqScale * Size / 2; } SetSize(size); } else if (key=='-') { size /= 2; if (size=1.0/fscale-1.0) floc = 1.0/fscale-1.0; SetFreqScale(fscale); } else if (key=='>') { fscale *= 2.0; if (fscale>1.0) fscale=1.0; if (floc>=1.0/fscale-1.0) floc = 1.0/fscale-1.0; SetFreqScale(fscale); } else if (key==',') { floc = floc - fscale/2; if (floc < 0) floc = 0; SetFreqScale(fscale); } else if (key=='.') { if (fscale < 1.0) { floc = floc + fscale/2; if (floc>=1.0/fscale-1.0) floc = 1.0/fscale-1.0; } SetFreqScale(fscale); } else if (key=='P') { // play displayed buffer from temp file #ifdef LITTLEENDIAN if (Srate>0) fillheader(&myhdr,Srate); // use actual file sample rate else fillheader(&myhdr,22050.0); // best compromise? on sample rate TempFile = opensoundout("sndviewTemp.wav",&myhdr); fwrite(data,Size,2,TempFile); // short tempdata = 0; // for some players, you need // int i; // to add silence to the end // for (i=0;i= (FreqScale * Size / 2)) CursorPos = FreqScale * Size / 2; glutPostRedisplay(); } else if (key=='[') { CursorPos -= Size / 100; if (CursorPos < 0) CursorPos = 0; glutPostRedisplay(); } else if (key=='}') { CursorPos += 1; if (CursorPos >= (FreqScale * Size / 2)) CursorPos = FreqScale * Size / 2; glutPostRedisplay(); } else if (key=='{') { CursorPos -= 1; if (CursorPos < 0) CursorPos = 0; glutPostRedisplay(); } else if (key=='S') { ToggleSpectrum(); glutPostRedisplay(); } else if (key=='W') { WinType += 1; if (WinType > MAX_WIN_TYPE) WinType = 0; SetSize(size); } else if (key=='C') { if (clearC[0]==0) { clearC[0]=1; clearC[1]=1; clearC[2]=1; clearC[3]=1; drawC[0]=0; drawC[1]=0; drawC[2]=0; drawC[3]=0; } else { clearC[0]=0; clearC[1]=0; clearC[2]=0; clearC[3]=0; drawC[0]=0; drawC[1]=1; drawC[2]=0; drawC[3]=0; } glColor4f(drawC[0],drawC[1],drawC[2],drawC[3]); glClearColor(clearC[0],clearC[1],clearC[2],clearC[3]); glutPostRedisplay(); } } void Redraw(void) { long i,tempi; int k,pow2,siz2; int x,y,xL,yL; unsigned char bdata[MAX_WIN*2]; char out_string[256],temp_string[20]; int xoffset=0.0,morexoffset=0.0,xright = 630; int yoffset = 128,yoffset3 = yoffset*3.3,yfscale=160; float xscale,temp,temp2; int maxLoc = 0; // printf("FileType= %i, SwapMode= %i, ByteMode = %i\n",FileType, SwapMode, ByteMode); if (ByteMode) { k = fseek(MyFile,Location,0); k = fread(&bdata,BYTE,Size,MyFile); for (i=0;i>8); for (i=1;i>8); line(xL,yL,x,y); xL=x; yL=y; } if (CalcSpectrum) { siz2 = 64; pow2 = 6; while (siz2Size) for (i=Size;i fdata[j+1]) j++; // for (i=j;itemp) { // temp = fdata[i]; // maxLoc = i; // } // } // temp = maxLoc + fitParabola(fdata[maxLoc-1],fdata[maxLoc],fdata[maxLoc+1]); // sprintf(temp_string,"Peak Location = %f ",temp); // outtext(0,440,temp_string); temp = 90.0 * (fdata[CursorPos + (int) (floc * fscale * Size/2.0)] - 1.0); temp2 = (float) (CursorPos + (floc * fscale * (float) Size / 2.0)) / (float) Size; if (FileType==RAW) { sprintf(temp_string,"%3.2f dB",temp); outtext(xscale * CursorPos + 20,445,temp_string); sprintf(temp_string,"%5.2f SRATE ",temp2); outtext(xscale * CursorPos + 20 ,455,temp_string); } else { temp2 *= Srate; sprintf(temp_string,"%3.2f dB",temp); outtext(xscale * CursorPos + 20 ,445,temp_string); sprintf(temp_string,"%5.2f Hz.",temp2); outtext(xscale * CursorPos + 20 ,455,temp_string); } // outtext(300,435,temp_string); if (strlen(file_name) < 80) outtext(470,477,file_name); else outtext(470,477,&file_name[strlen(file_name)-40]); if (Srate > -1.0) sprintf(temp_string,"SRATE=%li",Srate); else sprintf(temp_string,"SRATE=??"); outtext(360,467,temp_string); if (WinType == 0) sprintf(temp_string,"Rectangular Window"); else if (WinType == 1) sprintf(temp_string,"Triangular Window"); else if (WinType == 2) sprintf(temp_string,"Hanning Window"); else if (WinType == 3) sprintf(temp_string,"Hamming Window"); else if (WinType == 4) sprintf(temp_string,"Blackman3 Window"); else if (WinType == 5) sprintf(temp_string,"Blackman4 Window"); outtext(360,477,temp_string); } else { outtext(200,340,"SPECTRUM DISPLAY DISABLED"); } outtext(0,467," Wave Size=+/- Loc=L/R arrow Spectrum: Y/N=S Size=<> Pos.= , / ."); outtext(0,477," Spectral Cursor L/R={ } (fast=[ ]) Window=W Color=C Exit: ESC"); } main(int ac, char *av[] ) { int k; char titleString[512]; // int graphdriver = DETECT, graphmode; long loc = 0; if (ac>1) { strcpy(file_name,av[1]); MyFile = fopen(file_name,"rb"); WordSize = WORD; if (MyFile) { k = 2; while(k