home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / ModBass / c / Dsptest.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-18  |  5.9 KB  |  214 lines

  1. /* BASS simple DSP test, copyright (c) 2000 Ian Luck.
  2. =====================================================
  3. Imports: bass.lib, kernel32.lib, user32.lib, comdlg32.lib
  4. */
  5.  
  6. #include <windows.h>
  7. #include <stdio.h>
  8. #include <math.h>
  9. #include "bass.h"
  10. #include "dsptest.h"
  11.  
  12. static HWND win=NULL;
  13. static HINSTANCE inst;
  14.  
  15. static DWORD chan;    // the channel... HMUSIC (mod) or HSTREAM (wav/mp3)
  16.  
  17. static OPENFILENAME ofn;
  18. static char path[MAX_PATH];
  19.  
  20. /* display error messages */
  21. static void Error(char *es)
  22. {
  23.     char mes[200];
  24.     sprintf(mes,"%s\n(error code: %d)",es,BASS_ErrorGetCode());
  25.     MessageBox(win,mes,"Error",0);
  26. }
  27.  
  28.  
  29. #define clip(a) (short)((a<=-32768)?-32768:((a>=32767)?32767:a))
  30.  
  31. /* "rotate" */
  32. static HDSP rotdsp=0;    // DSP handle
  33. static float rotpos;    // cur.pos
  34. void CALLBACK Rotate(HSYNC handle, DWORD channel, void *buffer, DWORD length, DWORD user)
  35. {
  36.     short *d=buffer;
  37.     for (;length;length-=4,d+=2) {
  38.         d[0]=(short)((float)d[0]*fabs(sin(rotpos)));
  39.         d[1]=(short)((float)d[1]*fabs(cos(rotpos)));
  40.         rotpos=fmod(rotpos+0.00003f,3.1415927);
  41.     }
  42. }
  43.  
  44. /* "echo" */
  45. static HDSP echdsp=0;    // DSP handle
  46. #define ECHBUFLEN 1200    // buffer length
  47. static short echbuf[ECHBUFLEN][2];    // buffer
  48. static int echpos;    // cur.pos
  49. void CALLBACK Echo(HSYNC handle, DWORD channel, void *buffer, DWORD length, DWORD user)
  50. {
  51.     short *d=buffer;
  52.     for (;length;length-=4,d+=2) {
  53.         int l=d[0]+(echbuf[echpos][1]/2);
  54.         int r=d[1]+(echbuf[echpos][0]/2);
  55. #if 1 // 0=echo, 1=basic "bathroom" reverb
  56.         echbuf[echpos][0]=d[0]=clip(l);
  57.         echbuf[echpos][1]=d[1]=clip(r);
  58. #else
  59.         echbuf[echpos][0]=d[0];
  60.         echbuf[echpos][1]=d[1];
  61.         d[0]=clip(l);
  62.         d[1]=clip(r);
  63. #endif
  64.         echpos++;
  65.         if (echpos==ECHBUFLEN) echpos=0;
  66.     }
  67. }
  68.  
  69. /* "flanger" */
  70. static HDSP fladsp=0;    // DSP handle
  71. #define FLABUFLEN 350    // buffer length
  72. static short flabuf[FLABUFLEN][2];    // buffer
  73. static int flapos;    // cur.pos
  74. static float flas,flasmin,flasinc;    // sweep pos/min/max/inc
  75. void CALLBACK Flange(HSYNC handle, DWORD channel, void *buffer, DWORD length, DWORD user)
  76. {
  77.     short *d=buffer;
  78.  
  79.     for (;length;length-=4,d+=2) {
  80.         int p1=(flapos+(int)flas)%FLABUFLEN;
  81.         int p2=(p1+1)%FLABUFLEN;
  82.         float f=fmod(flas,1.0);
  83.         int s;
  84.  
  85.         s=d[0]+(int)(((1.0-f)*(float)flabuf[p1][0])+(f*(float)flabuf[p2][0]));
  86.         flabuf[flapos][0]=d[0];
  87.         d[0]=clip(s);
  88.  
  89.         s=d[1]+(int)(((1.0-f)*(float)flabuf[p1][1])+(f*(float)flabuf[p2][1]));
  90.         flabuf[flapos][1]=d[1];
  91.         d[1]=clip(s);
  92.             
  93.         flapos++;
  94.         if (flapos==FLABUFLEN) flapos=0;
  95.         flas+=flasinc;
  96.         if (flas<0.0 || flas>FLABUFLEN)
  97.             flasinc=-flasinc;
  98.     }
  99. }
  100.  
  101.  
  102. #define MESS(id,m,w,l) SendDlgItemMessage(win,id,m,(WPARAM)w,(LPARAM)l)
  103.  
  104. BOOL CALLBACK dialogproc(HWND h,UINT m,WPARAM w,LPARAM l)
  105. {
  106.     switch (m) {
  107.         case WM_COMMAND:
  108.             switch (LOWORD(w)) {
  109.                 case IDCANCEL:
  110.                     DestroyWindow(h);
  111.                     return 1;
  112.                 case ID_OPEN:
  113.                     {
  114.                         char file[MAX_PATH]="";
  115.                         ofn.lpstrFilter="playable files\0*.mo3;*.xm;*.mod;*.s3m;*.it;*.mtm;*.mp3;*.wav\0All files\0*.*\0\0";
  116.                         ofn.lpstrFile=file;
  117.                         if (GetOpenFileName(&ofn)) {
  118.                             memcpy(path,file,ofn.nFileOffset);
  119.                             path[ofn.nFileOffset-1]=0;
  120.                             // free both MOD and stream, it must be one of them! :)
  121.                             BASS_MusicFree(chan);
  122.                             BASS_StreamFree(chan);
  123.                             if (!(chan=BASS_StreamCreateFile(FALSE,file,0,0,0))
  124.                                 && !(chan=BASS_MusicLoad(FALSE,file,0,0,BASS_MUSIC_LOOP|BASS_MUSIC_RAMP))) {
  125.                                 // not a WAV/MP3 or MOD
  126.                                 MESS(ID_OPEN,WM_SETTEXT,0,"click here to open a file...");
  127.                                 Error("Can't play the file");
  128.                                 break;
  129.                             }
  130.                             if (BASS_ChannelGetFlags(chan)&(BASS_SAMPLE_MONO|BASS_SAMPLE_8BITS)) {
  131.                                 /* not 16-bit stereo */
  132.                                 MESS(ID_OPEN,WM_SETTEXT,0,"click here to open a file...");
  133.                                 BASS_MusicFree(chan);
  134.                                 BASS_StreamFree(chan);
  135.                                 Error("16-bit stereo sources only");
  136.                                 break;
  137.                             }
  138.                             MESS(ID_OPEN,WM_SETTEXT,0,file);
  139.                             // setup DSPs on new channel
  140.                             SendMessage(win,WM_COMMAND,ID_ROTA,0);
  141.                             SendMessage(win,WM_COMMAND,ID_ECHO,0);
  142.                             SendMessage(win,WM_COMMAND,ID_FLAN,0);
  143.                             // play both MOD and stream, it must be one of them! :)
  144.                             BASS_MusicPlay(chan);
  145.                             BASS_StreamPlay(chan,0,BASS_SAMPLE_LOOP);
  146.                         }
  147.                     }
  148.                     return 1;
  149.                 case ID_ROTA:
  150.                     if (MESS(ID_ROTA,BM_GETCHECK,0,0)) {
  151.                         rotpos=0.7853981f;
  152.                         rotdsp=BASS_ChannelSetDSP(chan,&Rotate,0);
  153.                     } else
  154.                         BASS_ChannelRemoveDSP(chan,rotdsp);
  155.                     break;
  156.                 case ID_ECHO:
  157.                     if (MESS(ID_ECHO,BM_GETCHECK,0,0)) {
  158.                         memset(echbuf,0,sizeof(echbuf));
  159.                         echpos=0;
  160.                         echdsp=BASS_ChannelSetDSP(chan,&Echo,0);
  161.                     } else
  162.                         BASS_ChannelRemoveDSP(chan,echdsp);
  163.                     break;
  164.                 case ID_FLAN:
  165.                     if (MESS(ID_FLAN,BM_GETCHECK,0,0)) {
  166.                         memset(flabuf,0,sizeof(flabuf));
  167.                         flapos=0;
  168.                         flas=FLABUFLEN/2;
  169.                         flasinc=0.002f;
  170.                         fladsp=BASS_ChannelSetDSP(chan,&Flange,0);
  171.                     } else
  172.                         BASS_ChannelRemoveDSP(chan,fladsp);
  173.                     break;
  174.             }
  175.             break;
  176.  
  177.         case WM_INITDIALOG:
  178.             win=h;
  179.             GetCurrentDirectory(MAX_PATH,path);
  180.             memset(&ofn,0,sizeof(ofn));
  181.             ofn.lStructSize=sizeof(ofn);
  182.             ofn.hwndOwner=h;
  183.             ofn.hInstance=inst;
  184.             ofn.nMaxFile=MAX_PATH;
  185.             ofn.lpstrInitialDir=path;
  186.             ofn.Flags=OFN_HIDEREADONLY|OFN_EXPLORER;
  187.             // setup output - default device, 44100hz, stereo, 16 bits, no syncs (not used)
  188.             if (!BASS_Init(-1,44100,BASS_DEVICE_NOSYNC,win)) {
  189.                 Error("Can't initialize device");
  190.                 DestroyWindow(win);
  191.             } else
  192.                 BASS_Start();
  193.             return 1;
  194.     }
  195.     return 0;
  196. }
  197.  
  198. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
  199. {
  200.     inst=hInstance;
  201.  
  202. // Check that BASS 0.8 was loaded
  203.     if (BASS_GetVersion()!=MAKELONG(0,8)) {
  204.         Error("BASS version 0.8 was not loaded");
  205.         return 0;
  206.     }
  207.  
  208.     DialogBox(inst,1000,0,&dialogproc);
  209.  
  210.     BASS_Free();
  211.  
  212.     return 0;
  213. }
  214.