VOID CSoundSystemFMod::Initial(LPCTSTR szSndPath, LPCTSTR szDBCFile) { assert(szSndPath); assert(szDBCFile); if (FSOUND_GetVersion() < FMOD_VERSION) { throw("FMOD: You are using the wrong DLL version! Should be %.2f", FMOD_VERSION); } FSOUND_SetOutput(FSOUND_OUTPUT_WINMM); FSOUND_SetDriver(0); FSOUND_SetMixer(FSOUND_MIXER_AUTODETECT); FSOUND_3D_SetRolloffFactor(0); if(!FSOUND_Init(44100, 32, 0)) { throw("Failed to create the FMod driver object"); } m_strSoundPath = szSndPath; m_strSndDBCFile = szDBCFile; //查询资源定义 static DBC::DBCFile fileSnd(0); BOOL fileOpened = fileSnd.OpenFromTXT(m_strSndDBCFile.c_str()); if (!fileOpened) { throw("Failed to open config file!"); } INT nLineNum = (INT)fileSnd.GetRecordsNum(); for(INT i=0; i<nLineNum; i++) { const _DBC_SOUND_INFO* pDefine = (const _DBC_SOUND_INFO*)fileSnd.Search_Posistion(i, 0); if(!pDefine) continue; SOUND_BUFFER newSound; newSound.pDefine = pDefine; newSound.pSoundBuf = NULL; //加入列表 m_listSoundBuffer.push_back(newSound); //加入索引 m_mapSoundID[pDefine->nID] = &(m_listSoundBuffer.back()); m_mapSoundFile[pDefine->pSoundFile] = &(m_listSoundBuffer.back()); } }
bool CSoundManager::InitFMOD(SOUNDMANAGER_PARAMETERS smpp) { Protokoll.WriteText ("Initializing FMOD\n", false); FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND); // Output-Mode setzen FSOUND_SetDriver(0); // Default-Soundkarte setzen FSOUND_SetMixer(FSOUND_MIXER_QUALITY_AUTODETECT); // Mixer-Quality setzen InitSuccessfull = (TRUE == FSOUND_Init(smpp.Mixrate, smpp.MaxSoftwareChannels, smpp.Flags)); if (false == InitSuccessfull) { Protokoll.WriteText ("\n->", false); Protokoll.WriteText (GetFMODErrorString(FSOUND_GetError()), false); return false; } MaxChannels = FSOUND_GetMaxChannels(); Protokoll.WriteText ("Successfull\n", false); return true; } // InitFMOD
bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) { LLAudioEngine::init(num_channels, userdata); // Reserve one extra channel for the http stream. if (!FSOUND_SetMinHardwareChannels(num_channels + 1)) { LL_WARNS("AppInit") << "FMOD::init[0](), error: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; } LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() initializing FMOD" << LL_ENDL; F32 version = FSOUND_GetVersion(); if (version < FMOD_VERSION) { LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version << ")! You should be using FMOD " << FMOD_VERSION << LL_ENDL; //return false; } U32 fmod_flags = 0x0; #if LL_WINDOWS // Windows needs to know which window is frontmost. // This must be called before FSOUND_Init() per the FMOD docs. // This could be used to let FMOD handle muting when we lose focus, // but we don't actually want to do that because we want to distinguish // between minimized and not-focused states. if (!FSOUND_SetHWND(userdata)) { LL_WARNS("AppInit") << "Error setting FMOD window: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; return false; } // Play audio when we don't have focus. // (For example, IM client on top of us.) // This means we also try to play audio when minimized, // so we manually handle muting in that case. JC fmod_flags |= FSOUND_INIT_GLOBALFOCUS; fmod_flags |= FSOUND_INIT_DSOUND_HRTF_FULL; #endif #if LL_LINUX // initialize the FMOD engine // This is a hack to use only FMOD's basic FPU mixer // when the LL_VALGRIND environmental variable is set, // otherwise valgrind will fall over on FMOD's MMX detection if (getenv("LL_VALGRIND")) /*Flawfinder: ignore*/ { LL_INFOS("AppInit") << "Pacifying valgrind in FMOD init." << LL_ENDL; FSOUND_SetMixer(FSOUND_MIXER_QUALITY_FPU); } // If we don't set an output method, Linux FMOD always // decides on OSS and fails otherwise. So we'll manually // try ESD, then OSS, then ALSA. // Why this order? See SL-13250, but in short, OSS emulated // on top of ALSA is ironically more reliable than raw ALSA. // Ack, and ESD has more reliable failure modes - but has worse // latency - than all of them, so wins for now. bool audio_ok = false; if (!audio_ok) { if (NULL == getenv("LL_BAD_FMOD_ESD")) /*Flawfinder: ignore*/ { LL_DEBUGS("AppInit") << "Trying ESD audio output..." << LL_ENDL; if(FSOUND_SetOutput(FSOUND_OUTPUT_ESD) && FSOUND_Init(44100, num_channels, fmod_flags)) { LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY" << LL_ENDL; audio_ok = true; } else { LL_WARNS("AppInit") << "ESD audio output FAILED to initialize: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; } } else { LL_DEBUGS("AppInit") << "ESD audio output SKIPPED" << LL_ENDL; } } if (!audio_ok) { if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/ { LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL; if(FSOUND_SetOutput(FSOUND_OUTPUT_OSS) && FSOUND_Init(44100, num_channels, fmod_flags)) { LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL; audio_ok = true; } else { LL_WARNS("AppInit") << "OSS audio output FAILED to initialize: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; } } else { LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL; } } if (!audio_ok) { if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/ { LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; if(FSOUND_SetOutput(FSOUND_OUTPUT_ALSA) && FSOUND_Init(44100, num_channels, fmod_flags)) { LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; audio_ok = true; } else { LL_WARNS("AppInit") << "ALSA audio output FAILED to initialize: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; } } else { LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL; } } if (!audio_ok) { LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; return false; } // On Linux, FMOD causes a SIGPIPE for some netstream error // conditions (an FMOD bug); ignore SIGPIPE so it doesn't crash us. // NOW FIXED in FMOD 3.x since 2006-10-01. //signal(SIGPIPE, SIG_IGN); // We're interested in logging which output method we // ended up with, for QA purposes. switch (FSOUND_GetOutput()) { case FSOUND_OUTPUT_NOSOUND: LL_DEBUGS("AppInit") << "Audio output: NoSound" << LL_ENDL; break; case FSOUND_OUTPUT_OSS: LL_DEBUGS("AppInit") << "Audio output: OSS" << LL_ENDL; break; case FSOUND_OUTPUT_ESD: LL_DEBUGS("AppInit") << "Audio output: ESD" << LL_ENDL; break; case FSOUND_OUTPUT_ALSA: LL_DEBUGS("AppInit") << "Audio output: ALSA" << LL_ENDL; break; default: LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break; }; #else // LL_LINUX // initialize the FMOD engine if (!FSOUND_Init(44100, num_channels, fmod_flags)) { LL_WARNS("AppInit") << "Error initializing FMOD: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; return false; } #endif // set up our favourite FMOD-native streaming audio implementation if none has already been added if (!getStreamingAudioImpl()) // no existing implementation added setStreamingAudioImpl(new LLStreamingAudio_FMOD()); LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL; mInited = true; return true; }
int main(int argc, char *argv[]) { FSOUND_SAMPLE *samp1; signed char key; int driver, i, channel, originalfreq; if (FSOUND_GetVersion() < FMOD_VERSION) { printf("Error : You are using the wrong DLL version! You should be using FMOD %.02f\n", FMOD_VERSION); return 0; } /* 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 - NoSound\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("---------------------------------------------------------\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_NOSOUND); 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 default : return 0; } /* SELECT OUTPUT 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; case FSOUND_OUTPUT_WINMM: printf("Windows Multimedia Waveout"); break; case FSOUND_OUTPUT_DSOUND: printf("Direct Sound"); break; 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; }; 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 */ } printf("---------------------------------------------------------\n"); /* print driver names */ printf("Press a corresponding number or ESC to quit\n"); do { key = getch(); if (key == 27) { FSOUND_Close(); return 0; } driver = key - '1'; } while (driver < 0 || driver >= FSOUND_GetNumDrivers()); FSOUND_SetDriver(driver); /* Select sound card (0 = default) */ /* SELECT MIXER */ FSOUND_SetMixer(FSOUND_MIXER_QUALITY_AUTODETECT); /* INITIALIZE */ if (!FSOUND_Init(44100, 64, FSOUND_INIT_ACCURATEVULEVELS)) { printf("Error!\n"); printf("%s\n", FMOD_ErrorString(FSOUND_GetError())); return 0; } /* SELECT INPUT DRIVER (can be done before or after init) */ /* The following list are the drivers for the output method selected above. */ printf("---------------------------------------------------------\n"); switch (FSOUND_GetOutput()) { case FSOUND_OUTPUT_NOSOUND: printf("NoSound"); break; case FSOUND_OUTPUT_WINMM: printf("Windows Multimedia Waveout"); break; case FSOUND_OUTPUT_DSOUND: printf("Direct Sound"); break; 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; }; printf(" Recording device driver list\n"); printf("---------------------------------------------------------\n"); for (i=0; i < FSOUND_Record_GetNumDrivers(); i++) { printf("%d - %s\n", i+1, FSOUND_Record_GetDriverName(i)); /* print driver names */ } 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_Record_GetNumDrivers()); if (!FSOUND_Record_SetDriver(driver)) /* Select input sound card (0 = default) */ { printf("Error!\n"); printf("%s\n", FMOD_ErrorString(FSOUND_GetError())); FSOUND_Close(); return 0; } /* 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_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 : %s\n", FSOUND_GetDriverName(FSOUND_GetDriver())); printf("FSOUND Record Driver : %s\n", FSOUND_Record_GetDriverName(FSOUND_Record_GetDriver())); /* RECORD INTO A STATIC SAMPLE */ /* Create a sample to record into */ samp1 = FSOUND_Sample_Alloc(FSOUND_UNMANAGED, RECORDLEN, FSOUND_STEREO | FSOUND_16BITS , RECORDRATE, 255, 128, 255); if (!samp1) { printf("Error!\n"); printf("%s\n", FMOD_ErrorString(FSOUND_GetError())); FSOUND_Close(); return 0; } printf("\n"); printf("=========================================================================\n"); printf("Press a key to start recording 5 seconds worth of data\n"); printf("=========================================================================\n"); getch(); if (!FSOUND_Record_StartSample(samp1, FALSE)) /* it will record into this sample for 5 seconds then stop */ { printf("Error!\n"); printf("%s\n", FMOD_ErrorString(FSOUND_GetError())); FSOUND_Close(); return 0; } do { printf("Recording position = %d\r", FSOUND_Record_GetPosition()); Sleep(50); } while (FSOUND_Record_GetPosition() < RECORDLEN && !kbhit()); FSOUND_Record_Stop(); /* it already stopped anyway */ printf("\n=========================================================================\n"); printf("Press a key to play back recorded data\n"); printf("=========================================================================\n"); getch(); channel = FSOUND_PlaySound(FSOUND_FREE, samp1); printf("Playing back sound...\n"); do { printf("Playback position = %d\r", FSOUND_GetCurrentPosition(channel)); Sleep(50); } while (FSOUND_IsPlaying(channel) && !kbhit()); if (FSOUND_GetOutput() == FSOUND_OUTPUT_OSS) { FSOUND_Sample_Free(samp1); FSOUND_Close(); return 0; } /* REALTIME FULL DUPLEX RECORD / PLAYBACK! */ printf("\n=========================================================================\n"); printf("Press a key to do some full duplex realtime recording!\n"); printf("(with reverb for mmx users)\n"); printf("=========================================================================\n"); getch(); FSOUND_Sample_SetMode(samp1, FSOUND_LOOP_NORMAL); /* make it a looping sample */ if (!FSOUND_Record_StartSample(samp1, TRUE)) /* start recording and make it loop also */ { printf("Error!\n"); printf("%s\n", FMOD_ErrorString(FSOUND_GetError())); FSOUND_Close(); return 0; } /* Increase this value if the sound sounds corrupted or the time between recording and hearing the result is longer than it should be.. */ #define RECORD_DELAY_MS 25 #define RECORD_DELAY_SAMPLES (RECORDRATE * RECORD_DELAY_MS / 1000) /* Let the record cursor move forward a little bit first before we try to play it (the position jumps in blocks, so any non 0 value will mean 1 block has been recorded) */ while (!FSOUND_Record_GetPosition()) { Sleep(1); } #ifdef ENABLEREVERB SetupReverb(); #endif channel = FSOUND_PlaySound(FSOUND_FREE, samp1); /* play the sound */ originalfreq = FSOUND_GetFrequency(channel); /* printf("initial delay = %d\n", FSOUND_GetCurrentPosition(channel) - FSOUND_Record_GetPosition()); */ do { int playpos, recordpos, diff; static int oldrecordpos = 0, oldplaypos = 0; playpos = FSOUND_GetCurrentPosition(channel); recordpos = FSOUND_Record_GetPosition(); /* NOTE : As the recording and playback frequencies arent guarranteed to be exactly in sync, we have to adjust the playback frequency to keep the 2 cursors just enough apart not to overlap. (and sound corrupted) This code tries to keep it inside a reasonable size window just behind the record cursor. ie [........|play window|<-delay->|<-Record cursor.............] */ /* Dont do this code if either of the cursors just wrapped */ if (playpos > oldplaypos && recordpos > oldrecordpos) { diff = playpos - recordpos; if (diff > -RECORD_DELAY_SAMPLES) { FSOUND_SetFrequency(channel, originalfreq - 1000); /* slow it down */ } else if (diff < -(RECORD_DELAY_SAMPLES * 2)) { FSOUND_SetFrequency(channel, originalfreq + 1000); /* speed it up */ } else { FSOUND_SetFrequency(channel, originalfreq); } } oldplaypos = playpos; oldrecordpos = recordpos; /* Print some info and a VU meter (vu is smoothed) */ { char vu[19]; float vuval, l, r; static float smoothedvu = 0; FSOUND_GetCurrentLevels(channel, &l, &r); vuval = (l+r) * 0.5f; vuval *= 18.0f; #define VUSPEED 0.2f if (vuval > smoothedvu) { smoothedvu = vuval; } smoothedvu -= VUSPEED; if (smoothedvu < 0) { smoothedvu = 0; } memset(vu, 0, 19); memset(vu, '=', (int)(smoothedvu)); printf("Play=%6d Rec=%6d (gap=%6d, freqchange=%6d hz) VU:%-15s\r", playpos, recordpos, diff, FSOUND_GetFrequency(channel) - originalfreq, vu); } Sleep(10); } while (!kbhit()); getch(); FSOUND_StopSound(channel); FSOUND_Record_Stop(); #ifdef ENABLEREVERB CloseReverb(); #endif /* CLEANUP AND SHUTDOWN */ FSOUND_Sample_Free(samp1); FSOUND_Close(); return 0; }