//Plays a sound once at a specific volume void SoundManager::PlayOneShotSound(char* soundName, float volume) { int _groupIndex = -1, _soundIndex = -1; FindSoundIndex(soundName, _groupIndex, _soundIndex); //If the sound was found, play it! if (_groupIndex != -1 && _soundIndex != -1) { m_result = m_system->playSound(FMOD_CHANNEL_FREE, m_sounds[_groupIndex][_soundIndex], false, &m_soundChannels[_groupIndex][_soundIndex]); m_soundChannels[_groupIndex][_soundIndex]->setVolume(m_effectVolume); FMODErrorCheck(m_result); } else if (_groupIndex != -1) { //Play random sound from the group int _randomInt = rand() % m_sounds[_groupIndex].size(); m_result = m_system->playSound(FMOD_CHANNEL_FREE, m_sounds[_groupIndex][_randomInt], false, &m_soundChannels[_groupIndex][_randomInt]); m_soundChannels[_groupIndex][_randomInt]->setVolume(m_effectVolume); FMODErrorCheck(m_result); } else { MessageBox(NULL, "Couldn't find sound name handle", "Sound Playing Error", MB_ICONERROR | MB_OK); exit(-1); } }
string AudioDevice::registerSound(ci::fs::path pathToSound, bool looping, bool is3d, bool asStream) { if ( !boost::filesystem::exists( pathToSound ) ) { app::console() << "[NOTICE] " << pathToSound << " doesn't exist" << endl; return ""; } std::stringstream namestream; namestream << deviceName << "-" << pathToSound.filename().string() << "-" << mSounds.size(); string name = namestream.str(); app::console() << "Adding " << name << endl; if(mSounds.find(name)!=mSounds.end()) { app::console() << "[WARNING] " << name << " already exists on this device. Re-adding." << endl; } if( asStream ) { FMODErrorCheck( mSystem->createStream( pathToSound.string().c_str(), FMOD_DEFAULT, NULL, &mSounds[name]) ); } else { FMODErrorCheck( mSystem->createSound( pathToSound.string().c_str(), FMOD_DEFAULT, NULL, &mSounds[name]) ); } FMOD_MODE mode; mode = is3d ? FMOD_3D|FMOD_3D_LINEARSQUAREROLLOFF : FMOD_2D; mode |= looping ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF; FMODErrorCheck( mSounds.at(name)->setMode( mode ) ); return name; }
/** * Create a map where the keys are the names of the devices * and the values are the id (0-x where x = num of devices) */ map<string,int> AudioDevice::getDeviceMap() { FMOD_RESULT result; FMOD::System* sys; result = FMOD::System_Create( &sys ); FMODErrorCheck(result); int numDrivers; result = sys->getNumDrivers(&numDrivers); FMODErrorCheck(result); map<string,int> deviceMap; //app::console() << "===========================" << endl; //app::console() << "Listing audio devices:" << endl; for(int i=0; i<numDrivers; i++) { FMOD_GUID guid; char deviceName[256]; sys->getDriverInfo(i, deviceName, 256, &guid); //app::console() << "(" << i << ") " << deviceName << endl; deviceMap[string(deviceName)] = i; } //app::console() << "===========================" << endl; FMODErrorCheck( sys->close() ); FMODErrorCheck( sys->release() ); return deviceMap; }
AudioDevice::~AudioDevice() { for(auto& sound : mSounds) { FMODErrorCheck(sound.second->release()); } FMODErrorCheck( mSystem->close() ); FMODErrorCheck( mSystem->release() ); }
void SoundManager::LoadMusic(char * fileName) { m_result = m_system->createSound(fileName, FMOD_SOFTWARE, 0, &m_musicSound); FMODErrorCheck(m_result); m_musicSound->getLength(&m_musicLength, FMOD_TIMEUNIT_PCM); //Weird stuff from french code https://www.youtube.com/watch?v=jZoQ1S73Bac void* _ptr1; void* _ptr2; unsigned int _length1; unsigned int _length2; if (m_dataLeftChannel != nullptr) { delete m_dataLeftChannel; m_dataLeftChannel = nullptr; } if (m_dataRightChannel != nullptr) { delete m_dataRightChannel; m_dataRightChannel = nullptr; } m_dataLeftChannel = new int[m_musicLength]; m_dataRightChannel = new int[m_musicLength]; m_musicSound->lock(0, m_musicLength, &_ptr1, &_ptr2, &_length1, &_length2); for (int i = 0; i < m_musicLength; i++) { m_dataLeftChannel[i] = ((int*)_ptr1)[i] >> 16; m_dataRightChannel[i] = (((int*)_ptr1)[i] << 16) >> 16; } m_musicSound->unlock(&_ptr1, &_ptr2, _length1, _length2); }
Sound::Sound() { system = fmodSetup(); FMODErrorCheck(FMOD_System_CreateChannelGroup(system, NULL, &channelGroup)); FMOD_Channel_SetChannelGroup(channel, channelGroup); loaded = false; volume = 1.f; mode = FMOD_LOOP_OFF; }
SoundClass::SoundClass(FMOD::System** mainSystemRef, FMOD::ChannelGroup* channelGroup, FMOD_VECTOR position, const char* filePath) : m_FModSysRef(mainSystemRef), m_channelGroupRef(channelGroup) { SetDefaultValues(); result = (*m_FModSysRef)->createSound( filePath, FMOD_CREATESTREAM | FMOD_3D, 0, &m_audioClip); FMODErrorCheck(); numOfBars = 32; barVals = new float[numOfBars]; }
void SoundManager::LoadSound(char* fileName, char* soundName, char* groupName, SoundFlags flags) { FMOD::Sound* audio; //Either load into memory or as a stream if (flags & LOAD_MEMORY) { if (flags & LOAD_SOFTWARE) m_result = m_system->createSound(fileName, FMOD_SOFTWARE, 0, &audio); else m_result = m_system->createSound(fileName, FMOD_DEFAULT, 0, &audio); } else if (flags & LOAD_STREAM) if (flags & LOAD_SOFTWARE) m_result = m_system->createStream(fileName, FMOD_SOFTWARE, 0, &audio); else m_result = m_system->createStream(fileName, FMOD_DEFAULT, 0, &audio); else //No mode set { MessageBox(NULL, "No Loadmode Set", "Sound Loading Error", MB_ICONERROR | MB_OK); exit(-1); } FMODErrorCheck(m_result); //Add audio, sound name and channel to their vectors FMOD::Channel* channel; int _groupIndex = FindGroupIndex(groupName); if (_groupIndex != -1) { m_soundChannels[_groupIndex].push_back(channel); m_sounds[_groupIndex].push_back(audio); m_soundIndexes[_groupIndex].push_back(soundName); } else { std::vector<FMOD::Channel*> _newChannelVec; std::vector<FMOD::Sound*> _newSoundVec; std::vector<char*> _newIndexVec; _newChannelVec.push_back(channel); _newSoundVec.push_back(audio); _newIndexVec.push_back(soundName); m_soundChannels.push_back(_newChannelVec); m_sounds.push_back(_newSoundVec); m_soundIndexes.push_back(_newIndexVec); m_soundGroupIndexes.push_back(groupName); } }
void AudioDevice::setup(int deviceID, int nChannels) { mNumChannels = nChannels; if(deviceID >= 0 && deviceID <= deviceMap.size()-1) { mSystem->setDriver(deviceID); mSystem->getDriverInfo(deviceID, deviceName, 256, &guid); // Get the capabilities of the sound card "mDeviceID" int controlpaneloutputrate; FMOD_SPEAKERMODE speakerMode; FMOD_CAPS caps; // capabilities FMODErrorCheck(mSystem->getDriverCaps(deviceID, &caps, &controlpaneloutputrate, &speakerMode)); cout << FMODSpeakerModeDescription(speakerMode) << endl; cout << "Num speakers: " << FMODGetNumSpeakers(speakerMode) << endl; FMODErrorCheck(mSystem->setSpeakerMode(speakerMode)); } else { app::console() << "Error initializing FMOD Audio Device. Device ID (" << deviceID << ") not in range." << endl; FMODErrorCheck(mSystem->setOutput(FMOD_OUTPUTTYPE_NOSOUND)); } FMOD_RESULT result; FMOD_INITFLAGS flags = FMOD_INIT_NORMAL; result = mSystem->init( mNumChannels, flags, NULL ); // If the selected speaker mode isn't supported by this sound card, switch it back to stereo if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) { app::console() << "WARNING: Falling back to basic stereo" << endl; FMODErrorCheck(mSystem->setSpeakerMode(FMOD_SPEAKERMODE_STEREO)); FMODErrorCheck(mSystem->init(100, FMOD_INIT_NORMAL, 0)); } FMODErrorCheck(mSystem->getMasterChannelGroup(&mMasterChannelGroup)); FMOD_VECTOR up = { 0.0f, 1.0f, 0.0f }; FMOD_VECTOR forward = { 0.0f, 0.0f, 1.0f }; FMOD_VECTOR listenerpos = { 0.0f, 0.0f, 0.0f }; FMOD_VECTOR vel = {0, 0, 0}; FMODErrorCheck(mSystem->set3DListenerAttributes(0, &listenerpos, &vel, &forward, &up)); }
//Initializes FMOD and makes the system handle void SoundManager::InitFMOD() { //Create FMOD Interface Object m_result = FMOD::System_Create(&m_system); FMODErrorCheck(m_result); //Check version m_result = m_system->getVersion(&m_version); FMODErrorCheck(m_result); //If the user has an old version of FMOD, shut the program down if (m_version < FMOD_VERSION) { //Makes an stringstream with error message and send to messagebox function std::stringstream _ss; _ss << "Error! You are using an old version of FMOD " << m_version << ". This program requires " << FMOD_VERSION << "\nGame Shutting Down"; MessageBoxAndShutDown(&_ss); } //Get number of sound cards m_result = m_system->getNumDrivers(&m_numDrivers); FMODErrorCheck(m_result); //If no sound cards, disable sound if(m_numDrivers == 0) { m_result = m_system->setOutput(FMOD_OUTPUTTYPE_NOSOUND); FMODErrorCheck(m_result); } else //If at least one sound card { //Get the capabilities of the default (0) sound card (stereo, 5.1, 7.1 etc) m_result = m_system->getDriverCaps(0, &m_caps, 0, &m_speakerMode); FMODErrorCheck(m_result); //Set the speaker mode to match that in Control Panel m_result = m_system->setSpeakerMode(m_speakerMode); FMODErrorCheck(m_result); //Increase the buffer size if user has hardware acceleration disabled to guard agains skipping and stuttering if (m_caps & FMOD_CAPS_HARDWARE_EMULATED) { m_result = m_system->setDSPBufferSize(1024, 10); FMODErrorCheck(m_result); } //Get name of driver m_result = m_system->getDriverInfo(0, m_name, 256, 0); FMODErrorCheck(m_result); // SigmaTel sound devices crackle for some reason if the format is PCM 16-bit. // PCM floating point output seems to solve it. if (strstr(m_name, "SigmaTel")) { m_result = m_system->setSoftwareFormat(48000, FMOD_SOUND_FORMAT_PCMFLOAT, 0, 0, FMOD_DSP_RESAMPLER_LINEAR); FMODErrorCheck(m_result); } } //Actually initialize the FMOD system m_result = m_system->init(100, FMOD_INIT_NORMAL, 0); //100 is number of virtual channel, won't probably use more than 5 //If the selected speaker mode isn't supported by this sound card, switch it back to stereo if (m_result == FMOD_ERR_OUTPUT_CREATEBUFFER) { m_result = m_system->setSpeakerMode(FMOD_SPEAKERMODE_STEREO); FMODErrorCheck(m_result); m_result = m_system->init(100, FMOD_INIT_NORMAL, 0); } FMODErrorCheck(m_result); }
unsigned int AudioDevice::getNumChannelsPlaying() { int n; FMODErrorCheck( mSystem->getChannelsPlaying(&n) ); return n; }
AudioDevice::AudioDevice() { FMODErrorCheck(FMOD::System_Create( &mSystem )); }
FMOD_SYSTEM *Sound::fmodSetup() { FMOD_SYSTEM *system; FMOD_RESULT result; unsigned int version; int numDrivers; FMOD_SPEAKERMODE speakerMode; FMOD_CAPS caps; char name[256]; result = FMOD_System_Create(&system); FMODErrorCheck(result); result = FMOD_System_GetVersion(system, &version); FMODErrorCheck(result); result = FMOD_System_GetNumDrivers(system, &numDrivers); FMODErrorCheck(result); if (numDrivers == 0) { result = FMOD_System_SetOutput(system, FMOD_OUTPUTTYPE_NOSOUND); FMODErrorCheck(result); } else { result = FMOD_System_GetDriverCaps(system, 0, &caps, 0, &speakerMode); FMODErrorCheck(result); result = FMOD_System_SetSpeakerMode(system, speakerMode); FMODErrorCheck(result); if (caps & FMOD_CAPS_HARDWARE_EMULATED) { result = FMOD_System_SetDSPBufferSize(system, 1024, 10); FMODErrorCheck(result); } result = FMOD_System_GetDriverInfo(system, 0, name, 256, 0); FMODErrorCheck(result); if (strstr(name, "SigmaTel")) { result = FMOD_System_SetSoftwareFormat(system, 48000, FMOD_SOUND_FORMAT_PCMFLOAT, 0, 0, FMOD_DSP_RESAMPLER_LINEAR); FMODErrorCheck(result); } } result = FMOD_System_Init(system, 100, FMOD_INIT_NORMAL, 0); if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) { result = FMOD_System_SetSpeakerMode(system, FMOD_SPEAKERMODE_STEREO); FMODErrorCheck(result); result = FMOD_System_Init(system, 100, FMOD_INIT_NORMAL, 0); } FMODErrorCheck(result); return system; }
int main() { // ================================================================================================ // Application-independent initialization // ================================================================================================ FMOD::System *system; FMOD_RESULT result; unsigned int version; int numDrivers; FMOD_SPEAKERMODE speakerMode; FMOD_CAPS caps; char name[256]; // Create FMOD interface object result = FMOD::System_Create(&system); FMODErrorCheck(result); // Check version result = system->getVersion(&version); FMODErrorCheck(result); if (version < FMOD_VERSION) { std::cout << "Error! You are using an old version of FMOD " << version << ". This program requires " << FMOD_VERSION << std::endl; return 0; } // Get number of sound cards result = system->getNumDrivers(&numDrivers); FMODErrorCheck(result); // No sound cards (disable sound) if (numDrivers == 0) { result = system->setOutput(FMOD_OUTPUTTYPE_NOSOUND); FMODErrorCheck(result); } // At least one sound card else { // Get the capabilities of the default (0) sound card result = system->getDriverCaps(0, &caps, 0, &speakerMode); FMODErrorCheck(result); // Set the speaker mode to match that in Control Panel result = system->setSpeakerMode(speakerMode); FMODErrorCheck(result); // Increase buffer size if user has Acceleration slider set to off if (caps & FMOD_CAPS_HARDWARE_EMULATED) { result = system->setDSPBufferSize(1024, 10); FMODErrorCheck(result); } // Get name of driver result = system->getDriverInfo(0, name, 256, 0); FMODErrorCheck(result); // SigmaTel sound devices crackle for some reason if the format is PCM 16-bit. // PCM floating point output seems to solve it. if (strstr(name, "SigmaTel")) { result = system->setSoftwareFormat(48000, FMOD_SOUND_FORMAT_PCMFLOAT, 0, 0, FMOD_DSP_RESAMPLER_LINEAR); FMODErrorCheck(result); } } // Initialise FMOD result = system->init(100, FMOD_INIT_NORMAL, 0); // If the selected speaker mode isn't supported by this sound card, switch it back to stereo if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) { result = system->setSpeakerMode(FMOD_SPEAKERMODE_STEREO); FMODErrorCheck(result); result = system->init(100, FMOD_INIT_NORMAL, 0); } FMODErrorCheck(result); // ================================================================================================ // Application-specific code // ================================================================================================ bool quit = false; bool fading = false; int fadeLength = 3000; int fadeStartTick; // Open music as a stream FMOD::Sound *song1, *song2, *effect; result = system->createStream("Song1.mp3", FMOD_DEFAULT, 0, &song1); FMODErrorCheck(result); result = system->createStream("Song2.mp3", FMOD_DEFAULT, 0, &song2); FMODErrorCheck(result); // Load sound effects into memory (not streaming) result = system->createSound("Effect.mp3", FMOD_DEFAULT, 0, &effect); FMODErrorCheck(result); // Assign each song to a channel and start them paused FMOD::Channel *channel1, *channel2; result = system->playSound(FMOD_CHANNEL_FREE, song1, true, &channel1); FMODErrorCheck(result); result = system->playSound(FMOD_CHANNEL_FREE, song2, true, &channel2); FMODErrorCheck(result); // Songs should repeat forever channel1->setLoopCount(-1); channel2->setLoopCount(-1); // Print instructions std::cout << "FMOD Simple Demo - (c) Katy Coe 2012 - www.djkaty.com" << std::endl << "=====================================================" << std::endl << std::endl << "Press:" << std::endl << std::endl << " 1 - Toggle song 1 pause on/off" << std::endl << " 2 - Toggle song 2 pause on/off" << std::endl << " F - Fade from song 1 to song 2" << std::endl << " S - Play one-shot sound effect" << std::endl << " Q - Quit" << std::endl; while (!quit) { // Per-frame FMOD update FMODErrorCheck(system->update()); // Q - Quit if (GetAsyncKeyState('Q')) quit = true; // 1 - Toggle song 1 pause state if (GetAsyncKeyState('1')) { bool isPaused; channel1->getPaused(&isPaused); channel1->setPaused(!isPaused); while (GetAsyncKeyState('1')); } // 2 - Toggle song 2 pause state if (GetAsyncKeyState('2')) { bool isPaused; channel2->getPaused(&isPaused); channel2->setPaused(!isPaused); while (GetAsyncKeyState('2')); } // F - Begin fade from song 1 to song 2 if (GetAsyncKeyState('F')) { channel1->setVolume(1.0f); channel2->setVolume(0.0f); channel1->setPaused(false); channel2->setPaused(false); fading = true; fadeStartTick = GetTickCount(); while (GetAsyncKeyState('F')); } // Play one-shot sound effect (without storing channel handle) if (GetAsyncKeyState('S')) { system->playSound(FMOD_CHANNEL_FREE, effect, false, 0); while (GetAsyncKeyState('S')); } // Fade function if fade is in progress if (fading) { // Get volume from 0.0f - 1.0f depending on number of milliseconds elapsed since fade started float volume = min(static_cast<float>(GetTickCount() - fadeStartTick) / fadeLength, 1.0f); // Fade is over if song 2 has reached full volume if (volume == 1.0f) { fading = false; channel1->setPaused(true); channel1->setVolume(1.0f); } // Translate linear volume into a smooth sine-squared fade effect volume = static_cast<float>(sin(volume * M_PI / 2)); volume *= volume; // Fade song 1 out and song 2 in channel1->setVolume(1.0f - volume); channel2->setVolume(volume); } } // Free resources FMODErrorCheck(song1->release()); FMODErrorCheck(song2->release()); FMODErrorCheck(effect->release()); FMODErrorCheck(system->release()); }
// FMOD_PRESET_OFF, FMOD_PRESET_UNDERWATER, FMOD_PRESET_STONEROOM, FMOD_PRESET_ARENA, etc. void AudioDevice::setAmbientReverb(FMOD_REVERB_PROPERTIES prop1) { FMODErrorCheck(mSystem->setReverbAmbientProperties(&prop1)); }
void AudioDevice::setVolume(float vol) { FMODErrorCheck(mMasterChannelGroup->setVolume(vol)); }
Sound::~Sound(void) { FMODErrorCheck(sound->release()); FMODErrorCheck(sys->release()); }
int main(int argc, char* argv[]) { // Args if(argc > 1) { if(!strcmp(argv[1], "-r")) { printf("Record mode, will use default recording device.\n\n"); record = true; } else { record = false; printf("Going to play %s\n\n", argv[1]); sound_file = argv[1]; } if(argc > 2) { if(!strcmp(argv[2], "-f")) { fullscreen = true; } if(argc > 4) { WINDOW_WIDTH = atoi(argv[3]); WINDOW_HEIGHT = atoi(argv[4]); } } } else { printf("Usage: visualizer -r [-f width height]\n visualizer <filename> [-f width height]\n\n -r: record from default audio source\n filename: audio file to play\n\n -f width height: fullscreen at width*height resolution.\n", argv[0]); return 0; } // Intialize SDL, OpenGL context, etc. if (init() == false) { return -1; } printf("\nInitialization complete. Enjoy!\n"); shader_init(); // Uniform locations GLint time_loc = glGetUniformLocation(p, "time"); GLint amplitude_loc = glGetUniformLocation(p, "amplitude"); GLint high_freq_loc = glGetUniformLocation(p, "high_freq"); GLint low_freq_loc = glGetUniformLocation(p, "low_freq"); GLint texture_loc = glGetUniformLocation(p, "texture"); GLint low_freq_max_loc = glGetUniformLocation(p, "low_freq_max"); // Scene // // Sphere GLUquadric* quadric = gluNewQuadric(); gluQuadricNormals(quadric, GLU_SMOOTH); gluQuadricTexture(quadric, GL_TRUE); gluQuadricOrientation(quadric, GLU_OUTSIDE); // Lights GLfloat light_0_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f}; GLfloat light_0_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; GLfloat light_0_position[] = {0.0f, 0.0f, 1.0f, 0.0f}; glLightfv(GL_LIGHT0, GL_AMBIENT, light_0_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_0_diffuse); glLightfv(GL_LIGHT0, GL_POSITION, light_0_position); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); // Textures and FBOs glGenTextures(1, &fbo_texture_id); glBindTexture(GL_TEXTURE_2D, fbo_texture_id); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap generation included in OpenGL v1.4 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, FBO_TEXTURE_WIDTH, FBO_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); glGenFramebuffersEXT(1, &fbo_id); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id); glGenRenderbuffersEXT(1, &rbo_id); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo_id); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, FBO_TEXTURE_WIDTH, FBO_TEXTURE_HEIGHT); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo_texture_id, 0); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo_id); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); bool quit = false; unsigned int length; bool playing = false; bool recording = false; bool looping = true; unsigned int recordpos = 0; unsigned int playpos = 0; int i; float instant_spectrum[256]; float instant_spectrum_l[256]; float instant_spectrum_r[256]; float rot_angle; while (quit == false) { // Grab spectrums result = channel->getSpectrum(instant_spectrum_l, 256, 0, FMOD_DSP_FFT_WINDOW_RECT); if(!record) { result = channel->getSpectrum(instant_spectrum_r, 256, 1, FMOD_DSP_FFT_WINDOW_RECT); } FMODErrorCheck(result); // Merge stereo for(i = 0; i < 256; i++) { if(record) { instant_spectrum[i] = 10.0f * (float)log10(instant_spectrum_l[i]/2.0f) * 2.0f; } else { instant_spectrum[i] = 10.0f * (float)log10((instant_spectrum_l[i] + instant_spectrum_r[i])/2.0f) * 2.0f; } } //instant_spectrum[255] = 0; // Rolling spectrum average for(i = 7; i >= 1; i = i - 1) { arrayCopy(256, spectrum[i-1], spectrum[i]); } arrayCopy(256, instant_spectrum, spectrum[0]); int j; for(j = 0; j < 256; j++) { rolling_spectrum[j] = 0; for(i = 0; i < 8; i++) { rolling_spectrum[j] += spectrum[i][j]; } rolling_spectrum[j] = rolling_spectrum[j] / 8.0f; } float max = -100.0f; int max_index = 0; for(i = 0; i < 256; i++) { if(rolling_spectrum[i] > max) { max = rolling_spectrum[i]; max_index = i; } } // Normalize float low_avg = 0; float low_mid_avg = 0; float mid_avg = 0; float high_avg = 0; float low_max = 0; float low_mid_max = 0; float mid_max = 0; float high_max = 0; int low_max_index = 0; int low_mid_max_index = 0; int mid_max_index = 0; int high_max_index = 0; for(i = 0; i < 256; i++) { processed_spectrum[i] = (rolling_spectrum[i] + 100)/(100); if(i < 64) { low_avg += processed_spectrum[i]; if(processed_spectrum[i] > low_max) { low_max = processed_spectrum[i]; low_max_index = i; } } else if(i < 128 && i >= 64) { low_mid_avg += processed_spectrum[i]; if(processed_spectrum[i] > low_mid_max) { low_mid_max = processed_spectrum[i]; low_mid_max_index = i; } } else if(i < 196 && i >= 128) { mid_avg += processed_spectrum[i]; if(processed_spectrum[i] > mid_max) { mid_max = processed_spectrum[i]; mid_max_index = i; } } else if(i < 256 && i >= 196 ) { high_avg += processed_spectrum[i]; if(processed_spectrum[i] > high_max) { high_max = processed_spectrum[i]; high_max_index = i; } } } low_avg = low_avg/64.0f; low_mid_avg = low_mid_avg/64.0f; mid_avg = mid_avg/64.0f; high_avg = high_avg/64.0f; float high_freq_avg = 0; float low_freq_avg = 0; float high_freq_max = spectrum_freq*(low_mid_max_index+1); float low_freq_max = spectrum_freq*(low_max_index+1); for(i = 63; i >= 1; i = i-1) { low_freq_samples[i] = low_freq_samples[i-1]; high_freq_samples[i] = high_freq_samples[i-1]; } high_freq_samples[0] = high_freq_max; low_freq_samples[0] = low_freq_max; for(i = 0; i < 64; i++) { high_freq_avg += high_freq_samples[i]; low_freq_avg += low_freq_samples[i]; } high_freq_avg = high_freq_avg / 64.0f; low_freq_avg = low_freq_avg / 64.0f; //printf("dominant high freq: %f dominant low freq: %f\n", high_freq_avg, low_freq_avg); // OpenGL // Uniforms for shaders glUniform1f(time_loc, (GLfloat)SDL_GetTicks()*0.001); //glUniform1f(amplitude_loc, 8.0f*smoothstep(-1, 1, log(low_mid_max/low_mid_avg))); glUniform1f(amplitude_loc, 0.5/normalize(low_avg, low_max)); glUniform1f(high_freq_loc, high_freq_avg); glUniform1f(low_freq_loc, low_freq_avg); glUniform1f(low_freq_max_loc, low_freq_max); printf("low: %f high: %f midmax-mid %f\n", low_freq_avg, high_freq_avg, 1/normalize(low_avg, low_max)); // Into the FBO glViewport(0, 0, FBO_TEXTURE_WIDTH, FBO_TEXTURE_HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, (float)(FBO_TEXTURE_WIDTH)/FBO_TEXTURE_HEIGHT, 1.0f, 100.0f); glMatrixMode(GL_MODELVIEW); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id); glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glTranslatef(0.0f, 0.0f, -50.0f); glColor4f(0.4f, 0.2f, 1.0f, 1.0f); gluSphere(quadric, 8.0f, 64, 64); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glBindTexture(GL_TEXTURE_2D, fbo_texture_id); glGenerateMipmapEXT(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // Normal render glViewport(0, 0, (GLsizei) WINDOW_WIDTH, (GLsizei) WINDOW_HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, (GLfloat)WINDOW_WIDTH/(GLfloat)WINDOW_HEIGHT, 0.1f, 100.0f); glMatrixMode (GL_MODELVIEW); glLoadIdentity(); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity (); glBindTexture(GL_TEXTURE_2D, fbo_texture_id); glUniform1f(texture_loc, fbo_texture_id); rot_angle += 0.9f; glTranslatef(0.0f, 0.0f, -40.0f); glRotatef(rot_angle,0.0f,1.0f,0.0f); glRotatef(20,0.0f,0.0f,1.0f); glColor4f(0.4f, 0.2f, 1.0f, 1.0f); gluSphere(quadric, 8.0f, 64, 64); glFlush(); glFinish(); SDL_GL_SwapBuffers(); // FMOD fmod_system->update(); result = sound->getLength(&length, FMOD_TIMEUNIT_PCM); FMODErrorCheck(result); result = fmod_system->isRecording(0, &recording); FMODErrorCheck(result); result = fmod_system->getRecordPosition(0, &recordpos); FMODErrorCheck(result); if (channel) { result = channel->isPlaying(&playing); FMODErrorCheck(result); result = channel->getPosition(&playpos, FMOD_TIMEUNIT_PCM); FMODErrorCheck(result); } //printf("State: %-19s. Record pos = %6d : Play pos = %6d : Loop %-3s\r", recording ? playing ? "Recording / playing" : "Recording" : playing ? "Playing" : "Idle", recordpos, playpos, looping ? "On" : "Off"); // SDL while (SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) { quit = true; } else if(event.type == SDL_KEYDOWN) { switch(event.key.keysym.sym) { case SDLK_ESCAPE: quit = true; break; case SDLK_f: break; } } } } fmod_system->release(); SDL_Quit(); return 0; }
float AudioDevice::getVolume() { float vol; FMODErrorCheck(mMasterChannelGroup->getVolume(&vol)); return vol; }
bool init() { // SDL Init int error; error = SDL_Init(SDL_INIT_EVERYTHING); if (error == -1) { return false; } // Set attributes of the context SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); // Initialize context SDL_Surface* drawContext; Uint32 flags = SDL_OPENGL | SDL_DOUBLEBUF; if(fullscreen) { flags = flags | SDL_FULLSCREEN; } drawContext = SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BIT_DEPTH, flags); if (drawContext == NULL) { return false; } // OpenGL Setup glViewport(0, 0, (GLsizei) WINDOW_WIDTH, (GLsizei) WINDOW_HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, (GLfloat)WINDOW_WIDTH/(GLfloat)WINDOW_HEIGHT, 0.1f, 100.0f); glMatrixMode (GL_MODELVIEW); glLoadIdentity(); glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE); // GLEW glewInit(); if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader) printf("GLSL Supported\n"); else { printf("No GLSL! Are you from 1990?"); return false; } if (glewIsSupported("GL_VERSION_2_0")) printf("OpenGL 2.0 Supported\n"); else { printf("OpenGL 2.0 not supported\n"); return false; } // Misc SDL_WM_SetCaption( "Lovin it!", NULL ); // FMOD int num_drivers; int count; // Create the main system object. result = FMOD::System_Create(&fmod_system); FMODErrorCheck(result); //result = fmod_system->setOutput(FMOD_OUTPUTTYPE_NOSOUND); //FMODErrorCheck(result); // Enumerate drivers result = fmod_system->getNumDrivers(&num_drivers); FMODErrorCheck(result); printf("\nOutput drivers: %i\n", num_drivers); for (count=0; count < num_drivers; count++) { char name[256]; result = fmod_system->getDriverInfo(count, name, 256, 0); FMODErrorCheck(result); printf("%d : %s\n", count + 1, name); } result = fmod_system->setDriver(0); FMODErrorCheck(result); result = fmod_system->getRecordNumDrivers(&num_drivers); FMODErrorCheck(result); printf("\nRecording drivers: %i\n", num_drivers); for (count=0; count < num_drivers; count++) { char name[256]; result = fmod_system->getRecordDriverInfo(count, name, 256, 0); FMODErrorCheck(result); printf("%d : %s\n", count + 1, name); } result = fmod_system->setDSPBufferSize(512, 4); FMODErrorCheck(result); // Initialize FMOD. result = fmod_system->init(32, FMOD_INIT_NORMAL, 0); FMODErrorCheck(result); memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); exinfo.numchannels = 1; exinfo.format = FMOD_SOUND_FORMAT_PCM16; exinfo.defaultfrequency = output_rate; exinfo.length = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels * 3; if(record == false) { result = fmod_system->createSound(sound_file, FMOD_2D | FMOD_SOFTWARE, 0, &sound); FMODErrorCheck(result); } else { result = fmod_system->createSound(0, FMOD_2D | FMOD_SOFTWARE | FMOD_OPENUSER, &exinfo, &sound); FMODErrorCheck(result); result = fmod_system->recordStart(0, sound, true); FMODErrorCheck(result); SDL_Delay(latency); } sound->setMode(FMOD_LOOP_NORMAL); result = fmod_system->playSound(FMOD_CHANNEL_REUSE, sound, false, &channel); FMODErrorCheck(result); if(record) { result = channel->setMute(true); FMODErrorCheck(result); } // Check latencies unsigned int blocksize; int numblocks; float ms; int frequency; result = fmod_system->getDSPBufferSize(&blocksize, &numblocks); result = fmod_system->getSoftwareFormat(&frequency, 0, 0, 0, 0, 0); ms = (float)blocksize * 1000.0f / (float)frequency; printf("\nMixer blocksize = %.02f ms\n", ms); printf("Mixer Total buffersize = %.02f ms\n", ms * numblocks); printf("Mixer Average Latency = %.02f ms\n", ms * ((float)numblocks - 1.5f)); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); return true; }
void Sound::Init() { // Create FMOD interface object result = FMOD::System_Create(&sys); FMODErrorCheck(result); // Check version result = sys->getVersion(&version); FMODErrorCheck(result); if (version < FMOD_VERSION) { std::cout << "Error! You are using an old version of FMOD " << version << ". This program requires " << FMOD_VERSION << std::endl; exit(0); } // Get number of sound cards result = sys->getNumDrivers(&numDrivers); FMODErrorCheck(result); // No sound cards (disable sound) if (numDrivers == 0) { result = sys->setOutput(FMOD_OUTPUTTYPE_NOSOUND); FMODErrorCheck(result); } // At least one sound card else { // Get name of driver result = sys->getDriverInfo(0, name, sizeof(name), NULL, NULL, &speakerMode,NULL); FMODErrorCheck(result); // SigmaTel sound devices crackle for some reason if the format is PCM 16-bit. // PCM floating point output seems to solve it. if (strstr(name, "SigmaTel")) { result = sys->setSoftwareFormat(48000, speakerMode, FMOD_SOUND_FORMAT_PCMFLOAT); FMODErrorCheck(result); } } // Initialise FMOD result = sys->init(100, FMOD_INIT_NORMAL, 0); FMODErrorCheck(result); //Open music as a stream :song1 main song result = sys->createStream("backgroundTest.mp3", FMOD_LOOP_NORMAL | FMOD_DEFAULT, 0, &song1); FMODErrorCheck(result); result = sys->createSound("hit.mp3", FMOD_DEFAULT, 0, &sound); FMODErrorCheck(result); // Assign each song to a channel and start them paused result = sys->playSound(song1, 0, false, &channel); FMODErrorCheck(result); // Assign each song to a channel and start them paused result = sys->playSound(sound, 0, true, &channel1); FMODErrorCheck(result); // Songs should repeat forever channel->setLoopCount(-1); // Songs should repeat forever channel1->setLoopCount(-1); }