//=============================================================================================== // 3D.EXE // Copyright (c), Firelight Technologies Pty, Ltd, 1999-2003. // // This test shows EAX, DS3D and Software all being used together and the simple commands needed // to set up some 3d audio. // This application also displays the use of FSOUND_GetDriverCaps to get information on the // 3D capabilities of the selected driver //=============================================================================================== #include #include #include #if defined(WIN32) || defined(__WATCOMC__) #include #include #else #include "../../api/inc/wincompat.h" #endif #include "../../api/inc/fmod.h" #include "../../api/inc/fmod_errors.h" // optional #define INTERFACE_UPDATETIME 50 // 50ms update for interface /* [ [DESCRIPTION] [PARAMETERS] [RETURN_VALUE] [REMARKS] [SEE_ALSO] ] */ void Close(FSOUND_SAMPLE *samp1, FSOUND_SAMPLE *samp2, FSOUND_SAMPLE *samp3) { // you dont need to free samples if you let fsound's sample manager look after samples, as // it will free them all for you. FSOUND_Sample_Free(samp1); FSOUND_Sample_Free(samp2); FSOUND_Sample_Free(samp3); FSOUND_Close(); } /* [ [DESCRIPTION] [PARAMETERS] [RETURN_VALUE] [REMARKS] [SEE_ALSO] ] */ int main() { FSOUND_SAMPLE *samp1 = NULL, *samp2 = NULL, *samp3 = NULL; char key, listenerflag = 1; int driver, i = 0, channel1 = -1, channel2 = -1; float listenerpos[3] = { 0,0,0 }; if (FSOUND_GetVersion() < FMOD_VERSION) { printf("Error : You are using the wrong DLL version! You should be using FMOD %.02f\n", FMOD_VERSION); return 1; } // ========================================================================================== // SELECT OUTPUT METHOD // ========================================================================================== printf("---------------------------------------------------------\n"); printf("Output Type\n"); printf("---------------------------------------------------------\n"); #if defined(WIN32) || defined(__CYGWIN32__) || defined(__WATCOMC__) printf("1 - Direct Sound\n"); printf("2 - Windows Multimedia Waveout\n"); printf("3 - ASIO\n"); #elif defined(__linux__) printf("1 - OSS - Open Sound System\n"); printf("2 - ESD - Elightment Sound Daemon\n"); printf("3 - ALSA 0.9 - Advanced Linux Sound Architecture\n"); #endif printf("4 - NoSound\n"); printf("---------------------------------------------------------\n"); // print driver names printf("Press a corresponding number or ESC to quit\n"); do { key = getch(); } while (key != 27 && key < '1' && key > '4'); switch (key) { #if defined(WIN32) || defined(__CYGWIN32__) || defined(__WATCOMC__) case '1' : FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND); break; case '2' : FSOUND_SetOutput(FSOUND_OUTPUT_WINMM); break; case '3' : FSOUND_SetOutput(FSOUND_OUTPUT_ASIO); break; #elif defined(__linux__) case '1' : FSOUND_SetOutput(FSOUND_OUTPUT_OSS); break; case '2' : FSOUND_SetOutput(FSOUND_OUTPUT_ESD); break; case '3' : FSOUND_SetOutput(FSOUND_OUTPUT_ALSA); break; #endif case '4' : FSOUND_SetOutput(FSOUND_OUTPUT_NOSOUND); break; default : return 1; } // ========================================================================================== // SELECT DRIVER // ========================================================================================== // The following list are the drivers for the output method selected above. printf("---------------------------------------------------------\n"); switch (FSOUND_GetOutput()) { case FSOUND_OUTPUT_NOSOUND: printf("NoSound"); break; #if defined(WIN32) || defined(__CYGWIN32__) || defined(__WATCOMC__) case FSOUND_OUTPUT_WINMM: printf("Windows Multimedia Waveout"); break; case FSOUND_OUTPUT_DSOUND: printf("Direct Sound"); break; case FSOUND_OUTPUT_ASIO: printf("ASIO"); break; #elif defined(__linux__) case FSOUND_OUTPUT_OSS: printf("Open Sound System"); break; case FSOUND_OUTPUT_ESD: printf("Enlightment Sound Daemon"); break; case FSOUND_OUTPUT_ALSA: printf("Alsa"); break; #endif }; printf(" Driver list\n"); printf("---------------------------------------------------------\n"); for (i=0; i < FSOUND_GetNumDrivers(); i++) { printf("%d - %s\n", i+1, FSOUND_GetDriverName(i)); // print driver names { unsigned int caps = 0; FSOUND_GetDriverCaps(i, &caps); if (caps & FSOUND_CAPS_HARDWARE) printf(" * Driver supports hardware 3D sound!\n"); if (caps & FSOUND_CAPS_EAX2) printf(" * Driver supports EAX 2 reverb!\n"); if (caps & FSOUND_CAPS_EAX3) printf(" * Driver supports EAX 3 reverb!\n"); } } printf("---------------------------------------------------------\n"); // print driver names printf("Press a corresponding number or ESC to quit\n"); do { key = getch(); if (key == 27) return 0; driver = key - '1'; } while (driver < 0 || driver >= FSOUND_GetNumDrivers()); FSOUND_SetDriver(driver); // Select sound card (0 = default) { unsigned int caps = 0; FSOUND_GetDriverCaps(FSOUND_GetDriver(), &caps); printf("---------------------------------------------------------\n"); printf("Driver capabilities\n"); printf("---------------------------------------------------------\n"); if (!caps) printf("- This driver will support software mode only.\n It does not properly support 3D sound hardware.\n"); if (caps & FSOUND_CAPS_HARDWARE) printf("- Driver supports hardware 3D sound!\n"); if (caps & FSOUND_CAPS_EAX2) printf("- Driver supports EAX 2 reverb!\n"); if (caps & FSOUND_CAPS_EAX3) printf("- Driver supports EAX 3 reverb!\n"); printf("---------------------------------------------------------\n"); } FSOUND_SetMixer(FSOUND_MIXER_AUTODETECT); // ========================================================================================== // INITIALIZE // ========================================================================================== if (!FSOUND_Init(44100, 32, 0)) { printf("Init: %s\n", FMOD_ErrorString(FSOUND_GetError())); return 1; } // ========================================================================================== // LOAD SAMPLES // ========================================================================================== // ========================================================================================== // 3D MONO // ========================================================================================== samp1 = FSOUND_Sample_Load(FSOUND_UNMANAGED, "../../media/drumloop.wav", FSOUND_HW3D | FSOUND_LOOP_NORMAL, 0, 0); if (!samp1) { printf("samp1: %s\n", FMOD_ErrorString(FSOUND_GetError())); Close(samp1, samp2, samp3); return 1; } // increasing mindistance makes it louder in 3d space FSOUND_Sample_SetMinMaxDistance(samp1, 4.0f, 10000.0f); // ========================================================================================== // 3D MONO // ========================================================================================== samp2 = FSOUND_Sample_Load(FSOUND_UNMANAGED, "../../media/jungle.wav", FSOUND_HW3D, 0, 0); if (!samp2) { printf("samp2: %s\n", FMOD_ErrorString(FSOUND_GetError())); Close(samp1, samp2, samp3); return 1; } // increasing mindistance makes it louder in 3d space FSOUND_Sample_SetMinMaxDistance(samp2, 4.0f, 10000.0f); FSOUND_Sample_SetMode(samp2, FSOUND_LOOP_NORMAL); // ========================================================================================== // 2D STEREO // ========================================================================================== samp3 = FSOUND_Sample_Load(FSOUND_UNMANAGED, "../../media/chimes.wav", FSOUND_HW2D, 0, 0); if (!samp3) { printf("samp3: %s\n", FMOD_ErrorString(FSOUND_GetError())); Close(samp1, samp2, samp3); return 1; } // ========================================================================================== // DISPLAY HELP // ========================================================================================== printf("FSOUND Output Method : "); switch (FSOUND_GetOutput()) { case FSOUND_OUTPUT_NOSOUND: printf("FSOUND_OUTPUT_NOSOUND\n"); break; case FSOUND_OUTPUT_WINMM: printf("FSOUND_OUTPUT_WINMM\n"); break; case FSOUND_OUTPUT_DSOUND: printf("FSOUND_OUTPUT_DSOUND\n"); break; case FSOUND_OUTPUT_ASIO: printf("FSOUND_OUTPUT_ASIO\n"); break; case FSOUND_OUTPUT_OSS: printf("FSOUND_OUTPUT_OSS\n"); break; case FSOUND_OUTPUT_ESD: printf("FSOUND_OUTPUT_ESD\n"); break; case FSOUND_OUTPUT_ALSA: printf("FSOUND_OUTPUT_ALSA\n"); break; }; printf("FSOUND Mixer : "); switch (FSOUND_GetMixer()) { case FSOUND_MIXER_BLENDMODE: printf("FSOUND_MIXER_BLENDMODE\n"); break; case FSOUND_MIXER_MMXP5: printf("FSOUND_MIXER_MMXP5\n"); break; case FSOUND_MIXER_MMXP6: printf("FSOUND_MIXER_MMXP6\n"); break; case FSOUND_MIXER_QUALITY_FPU: printf("FSOUND_MIXER_QUALITY_FPU\n"); break; case FSOUND_MIXER_QUALITY_MMXP5: printf("FSOUND_MIXER_QUALITY_MMXP5\n"); break; case FSOUND_MIXER_QUALITY_MMXP6: printf("FSOUND_MIXER_QUALITY_MMXP6\n"); break; }; printf("FSOUND Driver : "); printf("%s\n", FSOUND_GetDriverName(FSOUND_GetDriver())); int num2d, num3d; FSOUND_GetNumHWChannels(&num2d, &num3d, NULL); printf("Hardware 2D channels : %d\n", num2d); printf("Hardware 3D channels : %d\n", num3d); printf("=========================================================================\n"); printf("Press 1 Pause/Unpause 16bit 3D sound at any time\n"); printf(" 2 Pause/Unpause 8bit 3D sound at any time\n"); printf(" 3 Play 16bit STEREO 2D sound at any time\n"); printf(" 4 Change to EAX Reverb mode CONCERTHALL (DirectSound/SBLive only)\n"); printf(" 5 Change to EAX Reverb mode SEWERPIPE (DirectSound/SBLive only)\n"); printf(" 6 Change to EAX Reverb mode PSYCHOTIC (DirectSound/SBLive only)\n"); printf(" < Move listener left (in still mode)\n"); printf(" > Move listener right (in still mode)\n"); printf(" SPACE Stop/Start listener automatic movement\n"); printf(" ESC Quit\n"); printf("=========================================================================\n"); // ========================================================================================== // PLAY 2 LOOPING SOUNDS // ========================================================================================== { float pos[3] = { -10.0f, -0.0f, 0.0f }; float vel[3] = { 0,0,0 }; channel1 = FSOUND_PlaySoundEx(FSOUND_FREE, samp1, NULL, TRUE); FSOUND_3D_SetAttributes(channel1, pos, vel); if (!FSOUND_SetPaused(channel1, FALSE)) { printf("%s\n", FMOD_ErrorString(FSOUND_GetError())); } } { float pos[3] = { 15.0f, -0.0f, -0.0f }; float vel[3] = { 0,0,0 }; channel2 = FSOUND_PlaySoundEx(FSOUND_FREE, samp2, NULL, TRUE); FSOUND_3D_SetAttributes(channel2, pos, vel); FSOUND_SetVolume(channel2, 128); if (!FSOUND_SetPaused(channel2, FALSE)) { printf("%s\n", FMOD_ErrorString(FSOUND_GetError())); } } // ========================================================================================== // MAIN LOOP // ========================================================================================== do { if (kbhit()) { key = getch(); if (key == '1') { FSOUND_SetPaused(channel1, !FSOUND_GetPaused(channel1)); } if (key == '2') { FSOUND_SetPaused(channel2, !FSOUND_GetPaused(channel2)); } if (key == '3') { FSOUND_PlaySound(FSOUND_FREE, samp3); } if (key == '4') { FSOUND_REVERB_PROPERTIES props = FSOUND_PRESET_CONCERTHALL; FSOUND_Reverb_SetProperties(&props); } if (key == '5') { FSOUND_REVERB_PROPERTIES props = FSOUND_PRESET_SEWERPIPE; FSOUND_Reverb_SetProperties(&props); } if (key == '6') { FSOUND_REVERB_PROPERTIES props = FSOUND_PRESET_PSYCHOTIC; FSOUND_Reverb_SetProperties(&props); } if (key == ' ') { listenerflag = !listenerflag; } if (!listenerflag) { if (key == '<') { listenerpos[0] -= 1.0f; if (listenerpos[0] < -35) { listenerpos[0] = -35; } } if (key == '>') { listenerpos[0] += 1.0f; if (listenerpos[0] > 30) { listenerpos[0] = 30; } } } } // ========================================================================================== // UPDATE THE LISTENER // ========================================================================================== { static float t = 0; static float lastpos[3] = { 0,0,0 }; float vel[3]; if (listenerflag) { listenerpos[0] = ((float)sin(t*0.05f) * 33.0f); // left right pingpong } // ********* NOTE ******* READ NEXT COMMENT!!!!! // vel = how far we moved last FRAME (m/f), then time compensate it to SECONDS (m/s). vel[0] = (listenerpos[0]-lastpos[0]) * (1000 / INTERFACE_UPDATETIME); vel[1] = (listenerpos[1]-lastpos[1]) * (1000 / INTERFACE_UPDATETIME); vel[2] = (listenerpos[2]-lastpos[2]) * (1000 / INTERFACE_UPDATETIME); // store pos for next time lastpos[0] = listenerpos[0]; lastpos[1] = listenerpos[1]; lastpos[2] = listenerpos[2]; FSOUND_3D_Listener_SetAttributes(&listenerpos[0], &vel[0], 0, 0, 1.0f, 0, 1.0f, 0); t += (30 * (1.0f / (float)INTERFACE_UPDATETIME)); // t is just a time value .. it increments in 30m/s steps in this example // print out a small visual display { char s[80]; sprintf(s, "%d|.......................<1>......................<2>....................|",FSOUND_GetChannelsPlaying()); s[(int)(listenerpos[0])+35] = 'L'; printf("%s\r", s); } } FSOUND_Update(); Sleep(INTERFACE_UPDATETIME-1); // -1 for time taken for printf etc } while (key != 27); printf("\n"); // ========================================================================================== // CLEANUP AND SHUTDOWN // ========================================================================================== Close(samp1, samp2, samp3); return 0; }