FMOD_RESULT F_CALLBACK myDSPCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels) { FMOD_RESULT result; char name[256]; unsigned int userdata; FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; /* This redundant call just shows using the instance parameter of FMOD_DSP_STATE to call a DSP information function. */ result = thisdsp->getInfo(name, 0, 0, 0, 0); ERRCHECK(result); result = thisdsp->getUserData((void **)&userdata); ERRCHECK(result); if (delayBuffer == NULL) delayBuffer = (float*)malloc(bufferSize * sizeof(float)); /* This loop assumes inchannels = outchannels, which it will be if the DSP is created with '0' as the number of channels in FMOD_DSP_DESCRIPTION. Specifying an actual channel count will mean you have to take care of any number of channels coming in, but outputting the number of channels specified. Generally it is best to keep the channel count at 0 for maximum compatibility. */ for (unsigned int samp = 0; samp < length; samp++) { /* Feel free to unroll this. */ for (int chan = 0; chan < *outchannels; chan++) { /* This DSP filter just halves the volume! Input is modified, and sent to output. */ //outbuffer[(samp * *outchannels) + chan] = inbuffer[(samp * inchannels) + chan] * 0.2f; delayBuffer[((sampleCount * *outchannels) + chan) % bufferSize] = inbuffer[(samp * inchannels) + chan]; int delayBufferPosition = (((sampleCount - delay) * inchannels) + chan) % bufferSize; if (delayBufferPosition >= 0) { outbuffer[(samp * *outchannels) + chan] = delayBuffer[delayBufferPosition]; } else { outbuffer[(samp * *outchannels) + chan] = 0; } } sampleCount++; } return FMOD_OK; }
//---------------------------------------------------------------------- FMOD_RESULT F_CALLBACK dspReset( FMOD_DSP_STATE* dsp_state ) { CustomDSPImpl* customDSP = nullptr; FMOD::DSP* thisDSP = (FMOD::DSP*)dsp_state->instance; thisDSP->getUserData( (void**)&customDSP ); return customDSP->reset( dsp_state ); }
//---------------------------------------------------------------------- FMOD_RESULT F_CALLBACK dspRead( FMOD_DSP_STATE * dsp_state, float * inBuffer, float* outBuffer, unsigned int length, int inChannels, int outChannels ) { CustomDSPImpl* customDSP = nullptr; FMOD::DSP* thisDSP = (FMOD::DSP*)dsp_state->instance; thisDSP->getUserData( (void**)&customDSP ); return customDSP->read( dsp_state, inBuffer, outBuffer, length, inChannels, outChannels ); }
GMexport double FMODGMS_Effect_Get_Parameter(double e, double p) { int effectIndex = (int)round(e); if ((effectIndex < 0) || (effectIndex >= (int)effectList.size())) { errorMessage = "Invalid effect index"; return GMS_error; } FMOD::DSP* effect = effectList[effectIndex]; int param = (int)round(p); FMOD_DSP_PARAMETER_DESC* desc = NULL; if (effect->getParameterInfo(param, &desc) != FMOD_OK) { errorMessage = "Could not get effect parameter info, probably invalid param index"; return GMS_error; } if (desc->type == FMOD_DSP_PARAMETER_TYPE_FLOAT) { float value; if (effect->getParameterFloat(param, &value, NULL, 0) == FMOD_OK) return (double)value; } else if (desc->type == FMOD_DSP_PARAMETER_TYPE_INT) { int value; if (effect->getParameterInt(param, &value, NULL, 0) == FMOD_OK) return (double)value; } else if (desc->type == FMOD_DSP_PARAMETER_TYPE_BOOL) { bool value; if (effect->getParameterBool(param, &value, NULL, 0) == FMOD_OK) return (double)value; } else { errorMessage = "Unsupported effect parameter type"; return GMS_error; } errorMessage = "Could not get effect parameter"; return GMS_error; }
void FMOD_Sound::addEffect(int module_id, int type, float value) { float normalized_value = value / 100.0f; switch(type) { case Reverb: FMOD::DSP * reverb; system->createDSPByType(FMOD_DSP_TYPE_REVERB, &reverb); channelMap[module_id]->addDSP(reverb, 0); reverb->setParameter(FMOD_DSP_REVERB_ROOMSIZE, normalized_value); reverbMap[module_id] = reverb; break; case Pitch: FMOD::DSP * pitch; system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &pitch); channelMap[module_id]->addDSP(pitch, 0); pitch->setParameter(0, normalized_value); pitchMap[module_id] = pitch; break; case Distortion: FMOD::DSP * distortion; system->createDSPByType(FMOD_DSP_TYPE_DISTORTION, &distortion); channelMap[module_id]->addDSP(distortion, 0); distortion->setParameter(0, normalized_value); distortionMap[module_id] = distortion; break; case Echo: FMOD::DSP * echo; system->createDSPByType(FMOD_DSP_TYPE_ECHO, &echo); channelMap[module_id]->addDSP(echo, 0); echo->setParameter(0, normalized_value); echoMap[module_id] = echo; break; case Flange: FMOD::DSP * flange; system->createDSPByType(FMOD_DSP_TYPE_FLANGE, &flange); channelMap[module_id]->addDSP(flange, 0); flange->setParameter(0, normalized_value); flangeMap[module_id] = flange; break; default: break; } }
//Frees an effect from the memory GMexport double FMODGMS_Effect_Remove(double e) { int effectIndex = (int)round(e); if ((effectIndex < 0) || (effectIndex >= (int)effectList.size())) { errorMessage = "Invalid effect index"; return GMS_error; } FMOD::DSP* effect = effectList[effectIndex]; if (effect->release() == FMOD_OK) { effectList[effectIndex] = NULL; return FMODGMS_Util_ErrorChecker(); } errorMessage = "Could not remove effect, is it still attached to some audio?"; return GMS_error; }
//Sets a parameter a of effect e to value v. For parameters of different effects, see fmod_dsp_effects.h GMexport double FMODGMS_Effect_Set_Parameter(double e, double p, double v) { int effectIndex = (int)round(e); if ((effectIndex < 0) || (effectIndex >= (int)effectList.size())) { errorMessage = "Invalid effect index"; return GMS_error; } FMOD::DSP* effect = effectList[effectIndex]; int param = (int)round(p); int value = (int)round(v); FMOD_DSP_PARAMETER_DESC* desc = NULL; if (effect->getParameterInfo(param, &desc) != FMOD_OK) { errorMessage = "Could not get effect parameter info, probably invalid param index"; return GMS_error; } if (desc->type == FMOD_DSP_PARAMETER_TYPE_FLOAT) { if (effect->setParameterFloat(param, (float)value) == FMOD_OK) return FMODGMS_Util_ErrorChecker(); } else if (desc->type == FMOD_DSP_PARAMETER_TYPE_INT) { if (effect->setParameterInt(param, (int)round(value)) == FMOD_OK) return FMODGMS_Util_ErrorChecker(); } else if (desc->type == FMOD_DSP_PARAMETER_TYPE_BOOL) { if (effect->setParameterBool(param, (bool)(value > 0.5)) == FMOD_OK) return FMODGMS_Util_ErrorChecker(); } else { errorMessage = "Unsupported effect parameter type"; return GMS_error; } errorMessage = "Could not set effect parameter"; return GMS_error; }
FMOD_RESULT F_CALLBACK myDSPCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels) { unsigned int count, userdata; int count2; char name[256]; FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; /* This redundant call just shows using the instance parameter of FMOD_DSP_STATE and using it to call a DSP information function. */ thisdsp->getInfo(name, 0, 0, 0, 0); thisdsp->getUserData((void **)&userdata); /* This loop assumes inchannels = outchannels, which it will be if the DSP is created with '0' as the number of channels in FMOD_DSP_DESCRIPTION. Specifying an actual channel count will mean you have to take care of any number of channels coming in, but outputting the number of channels specified. Generally it is best to keep the channel count at 0 for maximum compatibility. */ for (count = 0; count < length; count++) { /* Feel free to unroll this. */ for (count2 = 0; count2 < outchannels; count2++) { /* This DSP filter just halves the volume! Input is modified, and sent to output. */ outbuffer[(count * outchannels) + count2] = inbuffer[(count * inchannels) + count2] * 0.2f; } } return FMOD_OK; }
//Get current level/loudness of audio (RMS value) GMexport double FMODGMS_Chan_Get_Level(double channel) { int c = (int)round(channel); int chanListSize = channelList.size(); if (chanListSize > c && c >= 0) { FMOD::DSP* headDSP; channelList[c]->getDSP(FMOD_CHANNELCONTROL_DSP_TAIL, &headDSP); //enable channel metering if it isn't already bool meteringEnabled = 0; if (headDSP->getMeteringEnabled(NULL, &meteringEnabled) != FMOD_OK) return FMODGMS_Util_ErrorChecker(); if (!meteringEnabled) headDSP->setMeteringEnabled(true, false); //get level using metering on head dsp FMOD_DSP_METERING_INFO meteringInfo; if (headDSP->getMeteringInfo(&meteringInfo, NULL) != FMOD_OK) return FMODGMS_Util_ErrorChecker(); double level = 0; short numChannels = meteringInfo.numchannels; for (int i = 0; i < numChannels; i++) level += (double)meteringInfo.rmslevel[i]; level /= numChannels; if (FMODGMS_Util_ErrorChecker() == GMS_true) return level; else return GMS_error; } else { errorMessage = "Index out of bounds."; return GMS_error; } }
int main(int argc, char *argv[]) { int numSounds = 1; FMOD::System *system; FMOD::Sound *sound[numSounds]; FMOD::Sound *applause; FMOD::Channel *channel[numSounds]; FMOD::Channel *applauseChannel; FMOD::DSP *dsppitch; FMOD::DSP *dsplowpass = 0; FMOD::DSP *dsphighpass = 0; FMOD::DSP *dspecho = 0; FMOD::DSP *dspflange = 0; FMOD::DSP *dspdistortion = 0; FMOD::DSP *dspchorus = 0; FMOD::DSP *dspparameq = 0; FMOD_RESULT result; int key; unsigned int version; float pan = 0; float volume; float frequency; int tempFrequency = 0; int tempPitch = 0; int frequencyCount = 0; int pitchCount = 0; int tempoChange = 0; float speed; float pitch = 1; float originalFrequency; string line; int lineCount = 0; int inc = 0; int count; float frequencyArray[numSounds]; float frequencyCountArray[numSounds]; float pitchfArray[numSounds]; float volumeArray[numSounds]; float panArray[numSounds]; float pitchf = 1.0f; /* Create a System object and initialize. */ result = FMOD::System_Create(&system); ERRCHECK(result); result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { printf("Error! You are using an old version of FMOD %08x. This program requires %08x\n", version, FMOD_VERSION); return 0; } result = system->init(32, FMOD_INIT_NORMAL, 0); ERRCHECK(result); result = system->createSound("../Config/Seven Nation Army Drum.mp3", FMOD_SOFTWARE | FMOD_LOOP_NORMAL | FMOD_2D, 0, &sound[0]); ERRCHECK(result); printf("===============================================================================\n"); printf(" Maestro \n"); printf("===============================================================================\n"); printf("Press '1' to play left speaker only\n"); printf("Press '2' to play right speaker only\n"); printf("Press '3' to play from both speakers\n"); printf("Press '[' to pan sound left\n"); printf("Press ']' to pan sound right\n"); printf("Press 'v/V' to increase volume\n"); printf("Press 'd/D' to decrease volume\n"); printf("Press '6' pitch octave down\n"); printf("Press '7' pitch semitone down\n"); printf("Press '8' pitch semitone up\n"); printf("Press '9' pitch octave up\n"); printf("Press 'Esc' to quit\n"); printf("Press 'n' pitch scale down\n"); printf("Press 'm' pitch scale up\n"); printf("\n"); for (count = 0; count < numSounds; count++) { result = system->playSound(FMOD_CHANNEL_FREE, sound[count], false, &channel[count]); ERRCHECK(result); bool paused; channel[0]->getPaused(&paused); ERRCHECK(result); paused = !paused; result = channel[0]->setPaused(paused); ERRCHECK(result); } //Create the DSP effects. result = system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsppitch); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &dsplowpass); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_HIGHPASS, &dsphighpass); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dspecho); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_FLANGE, &dspflange); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_DISTORTION, &dspdistortion); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_CHORUS, &dspchorus); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_PARAMEQ, &dspparameq); ERRCHECK(result); for (count = 0; count < numSounds; count++) { channel[count]->getVolume(&volume); channel[count]->setVolume(.3); channel[count]->getVolume(&volume); } printf("Initial Volume: %f \n", volume); channel[0]->getFrequency(&frequency); channel[0]->getFrequency(&originalFrequency); printf("Initial Frequency: %f \n", frequency); /* Main loop. */ do { ifstream myfile; myfile.open("../../Config/groupb.txt"); while ( myfile.good() ) { //printf("Line Count: %d \n", lineCount); for(int i = 0; i < lineCount; i++){ getline (myfile,line); } getline (myfile,line); if (line.compare("start") == 0){ bool paused; channel[0]->getPaused(&paused); ERRCHECK(result); paused = !paused; result = channel[0]->setPaused(paused); ERRCHECK(result); lineCount++; //printf("Line Count: %d \n", lineCount); break; } if (line.compare("iVol") == 0){ channel[0]->getVolume(&volume); channel[0]->setVolume(1.0f); lineCount++; //printf("Line Count: %d \n", lineCount); break; } if (line.compare("dVol") == 0){ channel[0]->getVolume(&volume); channel[0]->setVolume(.1); lineCount++; //printf("Line Count: %d \n", lineCount); break; } if (line.compare("iPitch") == 0){ result = dsppitch->remove(); ERRCHECK(result); result = system->addDSP(dsppitch, 0); ERRCHECK(result); inc++; pitch = pow(1.059f,inc); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, pitch); ERRCHECK(result); lineCount++; //printf("Line Count: %d \n", lineCount); break; } if (line.compare("dPitch") == 0){ result = dsppitch->remove(); ERRCHECK(result); result = system->addDSP(dsppitch, 0); ERRCHECK(result); inc--; pitch = pow(1.059,inc); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, pitch); ERRCHECK(result); lineCount++; //printf("Line Count: %d \n", lineCount); break; } if (line.compare("left") == 0){ result = channel[0]->setSpeakerMix(1.0f, 0, 0, 0, 0, 0, 0, 0); ERRCHECK(result); lineCount++; //printf("Line Count: %d \n", lineCount); break; } if (line.compare("right") == 0){ result = channel[0]->setSpeakerMix(0, 1.0f, 0, 0, 0, 0, 0, 0); ERRCHECK(result); lineCount++; //printf("Line Count: %d \n", lineCount); break; } if (line.compare("forward") == 0){ result = channel[0]->setSpeakerMix(1.0f, 1.0f, 0, 0, 0, 0, 0, 0); ERRCHECK(result); lineCount++; //printf("Line Count: %d \n", lineCount); break; } if (line.compare("pitch") == 0){ bool active; result = dsppitch->getActive(&active); ERRCHECK(result); if (active) { result = dsppitch->remove(); ERRCHECK(result); } else { result = system->addDSP(dsppitch, 0); ERRCHECK(result); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, 1.2f); ERRCHECK(result); } lineCount++; break; } if (line.compare("pause") == 0){ bool paused; channel[0]->getPaused(&paused); ERRCHECK(result); paused = !paused; result = channel[0]->setPaused(paused); ERRCHECK(result); lineCount++; break; } if (line.compare("lowpass") == 0){ bool active; result = dsplowpass->getActive(&active); ERRCHECK(result); if (active) { result = dsplowpass->remove(); ERRCHECK(result); } else { result = system->addDSP(dsplowpass, 0); ERRCHECK(result); } lineCount++; break; } if (line.compare("highpass") == 0){ bool active; result = dsphighpass->getActive(&active); ERRCHECK(result); if (active) { result = dsphighpass->remove(); ERRCHECK(result); } else { result = system->addDSP(dsphighpass, 0); ERRCHECK(result); } lineCount++; break; } if (line.compare("echo") == 0){ bool active; result = dspecho->getActive(&active); ERRCHECK(result); if (active) { result = dspecho->remove(); ERRCHECK(result); } else { result = system->addDSP(dspecho, 0); ERRCHECK(result); result = dspecho->setParameter(FMOD_DSP_ECHO_DELAY, 50.0f); ERRCHECK(result); } lineCount++; break; } if (line.compare("flange") == 0){ bool active; result = dspflange->getActive(&active); ERRCHECK(result); if (active) { result = dspflange->remove(); ERRCHECK(result); } else { result = system->addDSP(dspflange, 0); ERRCHECK(result); } lineCount++; break; } if (line.compare("distortion") == 0){ bool active; result = dspdistortion->getActive(&active); ERRCHECK(result); if (active) { result = dspdistortion->remove(); ERRCHECK(result); } else { result = system->addDSP(dspdistortion, 0); ERRCHECK(result); result = dspdistortion->setParameter(FMOD_DSP_DISTORTION_LEVEL, 0.8f); ERRCHECK(result); } lineCount++; break; } if (line.compare("chorus") == 0){ bool active; result = dspchorus->getActive(&active); ERRCHECK(result); if (active) { result = dspchorus->remove(); ERRCHECK(result); } else { result = system->addDSP(dspchorus, 0); ERRCHECK(result); } lineCount++; break; } if (line.compare("parameq") == 0){ bool active; result = dspparameq->getActive(&active); ERRCHECK(result); if (active) { result = dspparameq->remove(); ERRCHECK(result); } else { result = system->addDSP(dspparameq, 0); ERRCHECK(result); result = dspparameq->setParameter(FMOD_DSP_PARAMEQ_CENTER, 5000.0f); ERRCHECK(result); result = dspparameq->setParameter(FMOD_DSP_PARAMEQ_GAIN, 0.0f); ERRCHECK(result); } lineCount++; break; } if (line.compare("iTempo") == 0){ //44100 //62366.816406 channel[0]->getFrequency(&frequency); float base = 2.0f; float newTempo = frequency * pow(base,(6.0f/12.0f)); float pitchf = 1.0f; pitchf = pow(.9438f,6); result = dsppitch->remove(); ERRCHECK(result); result = system->addDSP(dsppitch, 0); ERRCHECK(result); channel[0]->setFrequency(newTempo); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, pitchf); ERRCHECK(result); channel[0]->getFrequency(&frequency); lineCount++; break; } if (line.compare("dTempo") == 0){ channel[0]->getFrequency(&frequency); float base = 2.0f; float newTempo = frequency * pow(base,(-6.0f/12.0f)); float pitchf = 1.0f; result = dsppitch->remove(); ERRCHECK(result); result = system->addDSP(dsppitch, 0); ERRCHECK(result); channel[0]->setFrequency(newTempo); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, pitchf); ERRCHECK(result); channel[0]->getFrequency(&frequency); lineCount++; break; } if (line.compare("quit") == 0){ key = 27; lineCount++; //printf("Line Count: %d \n", lineCount); break; } } myfile.close(); if (kbhit()) { key = getch(); switch (key) { case 's' : { bool paused; channel[0]->getPaused(&paused); ERRCHECK(result); paused = !paused; result = channel[0]->setPaused(paused); ERRCHECK(result); break; } case '1' : { // Play Sound From Left Speakers for (count = 0; count < numSounds; count++) { channel[count]->getVolume(&volume); result = channel[count]->setSpeakerMix(1.0f, 0, 0, 0, 0, 0, 0, 0); ERRCHECK(result); } break; } case '2' : { // Play Sound From Right Speakers for (count = 0; count < numSounds; count++) { channel[count]->getVolume(&volume); printf("Volume: %f\n", volume); result = channel[count]->setSpeakerMix(0, 1.0f, 0, 0, 0, 0, 0, 0); ERRCHECK(result); } break; } case '3' : { // Play Sound From Both Speakers for (count = 0; count < numSounds; count++) { channel[count]->getVolume(&volume); result = channel[count]->setSpeakerMix(1.0f, 1.0f, 0, 0, 0, 0, 0, 0); ERRCHECK(result); } break; } case '4' : { // Decrmenent Tempo //if(frequencyCount > -12){ //if (tempoChange + pitchCount > -12 && abs(pitchCount) < 12 && tempoChange > -12) { if (pitchf < 1.98f) { frequencyCount--; tempoChange++; printf("Pitch Count: %d\n", pitchCount); printf("Tempo Count: %d\n", tempoChange); channel[0]->getFrequency(&frequency); //printf("Z Initial Frequency: %f \n", frequency); float base = 2.0f; //printf("inc by: %f \n", pow(base,(-1.0f/12.0f))); float newTempo = frequency * pow(base,(-1.0f/12.0f)); //float pitchf = 1.0f; //if (pitchCount == 0 && tempoChange == 0) { // pitchf = 1.0f; //} if (pitchf == 1.0f) { pitchf = pow(1.059f,abs(tempoChange + pitchCount)); } else if (pitchf > 1.0f) { pitchf = pow(1.059f,abs(tempoChange + pitchCount)); } else if (pitchf < 1.0f) { pitchf = pow(.9438f,abs(tempoChange + pitchCount)); } printf("pitchf: %f\n", pitchf); printf("Frequency: %f \n", newTempo); result = dsppitch->remove(); ERRCHECK(result); result = system->addDSP(dsppitch, 0); ERRCHECK(result); channel[0]->setFrequency(newTempo); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, pitchf); ERRCHECK(result); } else { printf("Reached Min Tempo\n"); } break; } case '5' : { // Incrmenent Tempo if (pitchf > 0.52f) { frequencyCount++; tempoChange--; printf("Pitch Count: %d\n", pitchCount); printf("Tempo Count: %d\n", tempoChange); channel[0]->getFrequency(&frequency); //printf("Z Initial Frequency: %f \n", frequency); float base = 2.0f; float newTempo = frequency * pow(base,(1.0f/12.0f)); if (pitchf == 1.0f) { //printf("tempo one\n"); pitchf = pow(.9438f,abs(tempoChange + pitchCount)); } else if (pitchf > 1.0f) { //printf("tempo inc\n"); pitchf = pow(1.059f,abs(tempoChange + pitchCount)); } else if (pitchf < 1.0f) { //printf("tempo dec\n"); pitchf = pow(.9438f,abs(tempoChange + pitchCount)); } printf("pitchf: %f\n", pitchf); printf("Frequency: %f \n", newTempo); result = dsppitch->remove(); ERRCHECK(result); result = system->addDSP(dsppitch, 0); ERRCHECK(result); channel[0]->setFrequency(newTempo); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, pitchf); ERRCHECK(result); } else { printf("Reached Max Tempo\n"); } break; } case '6' : { // Pitch Shift Down Octave bool active; result = dsppitch->getActive(&active); ERRCHECK(result); if (active) { result = dsppitch->remove(); ERRCHECK(result); } else { result = system->addDSP(dsppitch, 0); ERRCHECK(result); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, 0.5f); ERRCHECK(result); } break; } case '7' : { // Pitch Shift Down One Note bool active; result = dsppitch->getActive(&active); ERRCHECK(result); if (active) { result = dsppitch->remove(); ERRCHECK(result); } else { result = system->addDSP(dsppitch, 0); ERRCHECK(result); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, .9438f); ERRCHECK(result); } break; } case '8' : { // Pitch Shift Up One Note bool active; result = dsppitch->getActive(&active); ERRCHECK(result); if (active) { result = dsppitch->remove(); ERRCHECK(result); } else { result = system->addDSP(dsppitch, 0); ERRCHECK(result); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, 1.059f); ERRCHECK(result); } break; } case '9' : { // Pitch Shift Up Octave bool active; result = dsppitch->getActive(&active); ERRCHECK(result); if (active) { result = dsppitch->remove(); ERRCHECK(result); } else { result = system->addDSP(dsppitch, 0); ERRCHECK(result); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, 2.0f); ERRCHECK(result); } break; } case 'v' : case 'V' : { // Increment Volume for (count = 0; count < numSounds; count++) { channel[count]->getVolume(&volume); volume += 0.1f; if (volume > 1) { volume = 1; } //printf("Volume: %f \n", volume); channel[count]->setVolume(volume); } break; } case 'd' : case 'D' : { // Decrement Volume for (count = 0; count < numSounds; count++) { channel[count]->getVolume(&volume); volume -= 0.1f; if (volume < 0) { volume = 0; } //printf("Volume: %f \n", volume); channel[count]->setVolume(volume); } break; } case '[' : { // Pan Left for (count = 0; count < numSounds; count++) { channel[count]->getPan(&pan); pan -= 0.1f; if (pan < -1) { pan = -1; } channel[count]->setPan(pan); } break; } case ']' : { // Pan Right for (count = 0; count < numSounds; count++) { channel[count]->getPan(&pan); pan += 0.1f; if (pan > 1) { pan = 1; } channel[count]->setPan(pan); } break; } case 'n' : { // Decremental Pitch if (pitchf > 0.52f) { frequencyCount--; pitchCount--; printf("Pitch Count: %d\n", pitchCount); printf("Tempo Count: %d\n", tempoChange); if (pitchf == 1.0f) { pitchf = pow(.9438f,abs(tempoChange + pitchCount)); } else if (pitchf > 1.0f) { pitchf = pow(1.059f,tempoChange + pitchCount); } else if (pitchf < 1.0f) { pitchf = pow(.9438f,abs(tempoChange + pitchCount)); } printf("pitchf: %f\n", pitchf); result = dsppitch->remove(); ERRCHECK(result); result = system->addDSP(dsppitch, 0); ERRCHECK(result); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, pitchf); ERRCHECK(result); } else { printf("Reached Min Pitch\n"); } break; } case 'm' : { // Incremental Pitch if (pitchf < 1.98f) { frequencyCount++; pitchCount++; printf("Pitch Count: %d\n", pitchCount); printf("Tempo Count: %d\n", tempoChange); if (pitchf == 1.0f) { pitchf = pow(1.059f,abs(tempoChange + pitchCount)); } else if (pitchf > 1.0f) { pitchf = pow(1.059f,tempoChange + pitchCount); } else if (pitchf < 1.0f) { pitchf = pow(.9438f,abs(tempoChange + pitchCount)); } printf("pitchf: %f\n", pitchf); result = dsppitch->remove(); ERRCHECK(result); result = system->addDSP(dsppitch, 0); ERRCHECK(result); result = dsppitch->setParameter(FMOD_DSP_PITCHSHIFT_PITCH, pitchf); ERRCHECK(result); } else { printf("Reached Max Pitch\n"); } break; } case 'r' : { // Lowpass bool active; result = dsplowpass->getActive(&active); ERRCHECK(result); if (active) { result = dsplowpass->remove(); ERRCHECK(result); } else { result = system->addDSP(dsplowpass, 0); ERRCHECK(result); } break; } case 't' : { // Highpass bool active; result = dsphighpass->getActive(&active); ERRCHECK(result); if (active) { result = dsphighpass->remove(); ERRCHECK(result); } else { result = system->addDSP(dsphighpass, 0); ERRCHECK(result); } break; } case 'y' : { // Echo bool active; result = dspecho->getActive(&active); ERRCHECK(result); if (active) { result = dspecho->remove(); ERRCHECK(result); } else { result = system->addDSP(dspecho, 0); ERRCHECK(result); result = dspecho->setParameter(FMOD_DSP_ECHO_DELAY, 50.0f); ERRCHECK(result); } break; } case 'u' : { // Flange bool active; result = dspflange->getActive(&active); ERRCHECK(result); if (active) { result = dspflange->remove(); ERRCHECK(result); } else { result = system->addDSP(dspflange, 0); ERRCHECK(result); } break; } case 'i' : { // Distortion bool active; result = dspdistortion->getActive(&active); ERRCHECK(result); if (active) { result = dspdistortion->remove(); ERRCHECK(result); } else { result = system->addDSP(dspdistortion, 0); ERRCHECK(result); result = dspdistortion->setParameter(FMOD_DSP_DISTORTION_LEVEL, 0.8f); ERRCHECK(result); } break; } case 'o' : { // Chorus bool active; result = dspchorus->getActive(&active); ERRCHECK(result); if (active) { result = dspchorus->remove(); ERRCHECK(result); } else { result = system->addDSP(dspchorus, 0); ERRCHECK(result); } break; } case 'p' : { // Parameq bool active; result = dspparameq->getActive(&active); ERRCHECK(result); if (active) { result = dspparameq->remove(); ERRCHECK(result); } else { result = system->addDSP(dspparameq, 0); ERRCHECK(result); result = dspparameq->setParameter(FMOD_DSP_PARAMEQ_CENTER, 5000.0f); ERRCHECK(result); result = dspparameq->setParameter(FMOD_DSP_PARAMEQ_GAIN, 0.0f); ERRCHECK(result); } break; } } } system->update(); { int channelsplaying = 0; bool dsppitch_active; dsppitch ->getActive(&dsppitch_active); system->getChannelsPlaying(&channelsplaying); } fflush(stdout); Sleep(10); } while (key != 27); { for (count = 0; count < numSounds; count++) { //channel[count]->getFrequency(&frequency); channel[count]->getVolume(&volume); int count; //float initFreq = frequency; float initVol = volume; for (count = 0; count < 200; count++) { //printf("Volume: %f \n", volume); //channel[count]->setFrequency(frequency); channel[count]->setVolume(volume); volume -= (initVol / 200.0f); //frequency -= (initFreq / 200.0f); Sleep(2); } } } printf("\n"); /* Shut down */ channel[0]->setFrequency(originalFrequency); result = dsppitch->remove(); ERRCHECK(result); result = dspparameq->remove(); ERRCHECK(result); result = dspchorus->remove(); ERRCHECK(result); result = dspdistortion->remove(); ERRCHECK(result); result = dspflange->remove(); ERRCHECK(result); result = dspecho->remove(); ERRCHECK(result); result = dsplowpass->remove(); ERRCHECK(result); result = dsphighpass->remove(); ERRCHECK(result); for (count = 0; count < numSounds; count++) { result = sound[count]->release(); ERRCHECK(result); } result = system->createSound("../../Config/Recital Crowd Applause.aif", FMOD_SOFTWARE, 0, &applause); ERRCHECK(result); wait(.5); result = system->playSound(FMOD_CHANNEL_FREE, applause, false, &applauseChannel); ERRCHECK(result); wait(10); result = applause->release(); ERRCHECK(result); result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); return 0; }
int FMOD_Main() { FMOD::System *system; FMOD::Sound *sound; FMOD::Channel *channel; FMOD::DSP *mydsp; FMOD::ChannelGroup *mastergroup; FMOD_RESULT result; unsigned int version; void *extradriverdata = 0; Common_Init(&extradriverdata); /* Create a System object and initialize. */ result = FMOD::System_Create(&system); ERRCHECK(result); result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION); } result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); ERRCHECK(result); result = system->createSound(Common_MediaPath("drumloop.wav"), FMOD_SOFTWARE | FMOD_LOOP_NORMAL, 0, &sound); ERRCHECK(result); result = system->playSound(sound, 0, false, &channel); ERRCHECK(result); /* Create the DSP effect. */ { FMOD_DSP_DESCRIPTION dspdesc; memset(&dspdesc, 0, sizeof(dspdesc)); strncpy(dspdesc.name, "My first DSP unit", sizeof(dspdesc.name)); dspdesc.version = 0x00010000; dspdesc.numinputbuffers = 1; dspdesc.numoutputbuffers = 1; dspdesc.read = myDSPCallback; dspdesc.userdata = (void *)0x12345678; result = system->createDSP(&dspdesc, &mydsp); ERRCHECK(result); } /* Attach the DSP, inactive by default. */ result = mydsp->setBypass(true); ERRCHECK(result); result = system->getMasterChannelGroup(&mastergroup); ERRCHECK(result); result = mastergroup->addDSP(0, mydsp, 0); ERRCHECK(result); /* Main loop. */ do { bool bypass; Common_Update(); result = mydsp->getBypass(&bypass); ERRCHECK(result); if (Common_BtnPress(BTN_ACTION1)) { bypass = !bypass; result = mydsp->setBypass(bypass); ERRCHECK(result); } result = system->update(); ERRCHECK(result); Common_Draw("=================================================="); Common_Draw("Custom DSP Example."); Common_Draw("Copyright (c) Firelight Technologies 2004-2014."); Common_Draw("=================================================="); Common_Draw(""); Common_Draw("Press %s to toggle filter bypass", Common_BtnStr(BTN_ACTION1)); Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); Common_Draw(""); Common_Draw("Filter is %s", bypass ? "inactive" : "active"); Common_Sleep(50); } while (!Common_BtnPress(BTN_QUIT)); /* Shut down */ result = sound->release(); ERRCHECK(result); result = mastergroup->removeDSP(mydsp); ERRCHECK(result); result = mydsp->release(); ERRCHECK(result); result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); Common_Close(); return 0; }
FMOD_RESULT F_CALLBACK DSPCallback(FMOD_DSP_STATE* dsp_state, f32* inbuffer, f32* outbuffer, u32 length, s32 inchannels, s32* outchannels){ assert(*outchannels >= 2); FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; void* ud = nullptr; cfmod(thisdsp->getUserData(&ud)); s32 samplerate = 0; cfmod(dsp_state->callbacks->getsamplerate(dsp_state, &samplerate)); f64 inc = 1.0/samplerate; auto dud = static_cast<DSPUserdata*>(ud); auto& phase = dud->phase; for(u32 i = 0; i < length; i++){ f32 out = 0.f; f32 outl = 0.f; f32 outr = 0.f; sched.PlayNotes([&](const NoteTimePair& n){ constexpr f32 attack = 0.1; auto pos = (sched.time-n.begin)/n.length; f32 env; if(pos < attack){ env = pos/attack; }else{ env = (1.0-pos)/(1.0-attack); } f32 o = 0.0; // o += Wave::sin(n.freq*phase*0.5) * env * 0.2; // o += Wave::sin(n.freq*phase*2.0) * env; f32 mod = Wave::sin(phase*10.f) * .02f; f32 ph = n.freq*phase + mod; f32 a = std::min(1.f, std::max(env*env*env * .5f, 0.f)); //Wave::sin(phase*1.f)*.5f + .5f; env *= n.volume; o += (Wave::sin(ph) * (1-a) + Wave::sqr(ph*2.f) * a) * env; // o += Wave::sin((n.freq + Wave::tri(phase*6.f) * .01f)*phase) * env; // o += Wave::sin((n.freq + 0.5)*phase) * env; out += o/3.0; }); chords.PlayNotes([&](const NoteTimePair& n){ constexpr f32 attack = 0.005; auto pos = (chords.time-n.begin)/n.length; f32 env; if(pos < attack){ env = pos/attack; }else{ env = (1.0-pos)/(1.0-attack); } f32 mod = Wave::sin(phase*10.f) * .02f; f32 ph = n.freq*phase + mod; f32 a = env*env * .3f + .3f + Wave::sin(phase*6.f) * 0.2f; a = std::min(1.f, std::max(a, 0.f)); f32 phaseShift = 0.2f + Wave::sin(phase*3.f) * .2f + .5f; //phase / 6.f; outl += (Wave::sin(ph) * (1-a) + Wave::tri(ph) * a) * env * n.volume; outr += (Wave::sin(ph + phaseShift) * (1-a) + Wave::tri(ph * 1.01) * a) * env * n.volume; }); perc.PlayNotes([&](const NoteTimePair& n){ constexpr f32 attack = 0.1; auto pos = (perc.time-n.begin)/n.length; f32 env = 0; if(pos < attack){ env = pos/attack; }else{ env = (1.0-pos)/(1.0-attack); } env *= n.volume; f32 o = 0; o += Wave::sin(n.freq*phase) * env; o += Wave::tri(n.freq*phase) * env; out += o; }); outbuffer[i**outchannels+0] = out + outl/3.f; outbuffer[i**outchannels+1] = out + outr/3.f; phase += inc; chords.Update(inc/60.0* tempo); sched.Update(inc/60.0* tempo); perc.Update(inc/60.0* tempo); } return FMOD_OK; }
void InitFmod(){ cfmod(FMOD::System_Create(&fmodSystem)); u32 version = 0; cfmod(fmodSystem->getVersion(&version)); if(version < FMOD_VERSION){ std::cerr << "FMOD version of at least " << FMOD_VERSION << " required. Version used " << version << std::endl; throw "FMOD Error"; } cfmod(fmodSystem->init(100, FMOD_INIT_NORMAL, nullptr)); FMOD::DSP* dsp; FMOD::DSP* compressor; { FMOD_DSP_DESCRIPTION desc; memset(&desc, 0, sizeof(desc)); // strncpy(desc.name, "Fuckyou", sizeof(desc.name)); desc.numinputbuffers = 0; desc.numoutputbuffers = 1; desc.read = DSPCallback; desc.userdata = new DSPUserdata{/*sched, */0.0}; cfmod(fmodSystem->createDSP(&desc, &dsp)); cfmod(dsp->setChannelFormat(FMOD_CHANNELMASK_STEREO,2,FMOD_SPEAKERMODE_STEREO)); } cfmod(fmodSystem->createDSPByType(FMOD_DSP_TYPE_COMPRESSOR, &compressor)); cfmod(compressor->setParameterFloat(FMOD_DSP_COMPRESSOR_THRESHOLD, -13)); cfmod(compressor->setParameterFloat(FMOD_DSP_COMPRESSOR_ATTACK, 1)); cfmod(compressor->setBypass(false)); cfmod(dsp->setBypass(false)); FMOD::ChannelGroup* mastergroup; cfmod(fmodSystem->getMasterChannelGroup(&mastergroup)); cfmod(mastergroup->addDSP(0, compressor)); cfmod(fmodSystem->playDSP(dsp, mastergroup, false, &channel)); cfmod(channel->setMode(FMOD_2D)); cfmod(channel->setVolume(0.7f)); FMOD::Reverb3D* reverb; cfmod(fmodSystem->createReverb3D(&reverb)); // http://www.fmod.org/docs/content/generated/FMOD_REVERB_PROPERTIES.html FMOD_REVERB_PROPERTIES rprops = { .DecayTime = 8000.0, //1500.0, /* Reverberation decay time in ms */ .EarlyDelay = 7.0, //7.0, /* Initial reflection delay time */ .LateDelay = 11.0, //11.0, /* Late reverberation delay time relative to initial reflection */ .HFReference = 5000.0, /* Reference high frequency (hz) */ .HFDecayRatio = 50.0, /* High-frequency to mid-frequency decay time ratio */ .Diffusion = 60.0, /* Value that controls the echo density in the late reverberation decay. */ .Density = 100.0, //100.0, /* Value that controls the modal density in the late reverberation decay */ .LowShelfFrequency = 250.0, /* Reference low frequency (hz) */ .LowShelfGain = 0.0, /* Relative room effect level at low frequencies */ .HighCut = 10000.0, /* Relative room effect level at high frequencies */ .EarlyLateMix = 50.0, /* Early reflections level relative to room effect */ .WetLevel = -12.0, //-6.0, /* Room effect level (at mid frequencies) */ }; cfmod(reverb->setProperties(&rprops)); }
int main(int argc, char *argv[]) { FMOD::System *system = 0; FMOD::Sound *sound = 0; FMOD::Channel *channel = 0; FMOD::DSP *dsplowpass = 0; FMOD::DSP *dsphighpass = 0; FMOD::DSP *dspecho = 0; FMOD::DSP *dspflange = 0; FMOD::DSP *dspdistortion = 0; FMOD::DSP *dspchorus = 0; FMOD::DSP *dspparameq = 0; FMOD_RESULT result; int key; unsigned int version; /* Create a System object and initialize. */ result = FMOD::System_Create(&system); ERRCHECK(result); result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { printf("Error! You are using an old version of FMOD %08x. This program requires %08x\n", version, FMOD_VERSION); return 0; } result = system->init(32, FMOD_INIT_NORMAL, 0); ERRCHECK(result); result = system->createSound("../media/drumloop.wav", FMOD_SOFTWARE, 0, &sound); ERRCHECK(result); printf("=================================================================\n"); printf("Effects Example. Copyright (c) Firelight Technologies 2004-2011.\n"); printf("=================================================================\n"); printf("\n"); printf("Press SPACE to paused/unpause sound.\n"); printf("Press 1 to toggle dsplowpass effect.\n"); printf("Press 2 to toggle dsphighpass effect.\n"); printf("Press 3 to toggle dspecho effect.\n"); printf("Press 4 to toggle dspflange effect.\n"); printf("Press 5 to toggle dspdistortion effect.\n"); printf("Press 6 to toggle dspchorus effect.\n"); printf("Press 7 to toggle dspparameq effect.\n"); printf("Press 'Esc' to quit\n"); printf("\n"); result = system->playSound(FMOD_CHANNEL_FREE, sound, false, &channel); ERRCHECK(result); /* Create some effects to play with. */ result = system->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &dsplowpass); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_HIGHPASS, &dsphighpass); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dspecho); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_FLANGE, &dspflange); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_DISTORTION, &dspdistortion); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_CHORUS, &dspchorus); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_PARAMEQ, &dspparameq); ERRCHECK(result); /* Main loop. */ do { if (kbhit()) { key = getch(); switch (key) { case ' ' : { bool paused; channel->getPaused(&paused); ERRCHECK(result); paused = !paused; result = channel->setPaused(paused); ERRCHECK(result); break; } case '1' : { bool active; result = dsplowpass->getActive(&active); ERRCHECK(result); if (active) { result = dsplowpass->remove(); ERRCHECK(result); } else { result = system->addDSP(dsplowpass, 0); ERRCHECK(result); } break; } case '2' : { bool active; result = dsphighpass->getActive(&active); ERRCHECK(result); if (active) { result = dsphighpass->remove(); ERRCHECK(result); } else { result = system->addDSP(dsphighpass, 0); ERRCHECK(result); } break; } case '3' : { bool active; result = dspecho->getActive(&active); ERRCHECK(result); if (active) { result = dspecho->remove(); ERRCHECK(result); } else { result = system->addDSP(dspecho, 0); ERRCHECK(result); result = dspecho->setParameter(FMOD_DSP_ECHO_DELAY, 50.0f); ERRCHECK(result); } break; } case '4' : { bool active; result = dspflange->getActive(&active); ERRCHECK(result); if (active) { result = dspflange->remove(); ERRCHECK(result); } else { result = system->addDSP(dspflange, 0); ERRCHECK(result); } break; } case '5' : { bool active; result = dspdistortion->getActive(&active); ERRCHECK(result); if (active) { result = dspdistortion->remove(); ERRCHECK(result); } else { result = system->addDSP(dspdistortion, 0); ERRCHECK(result); result = dspdistortion->setParameter(FMOD_DSP_DISTORTION_LEVEL, 0.8f); ERRCHECK(result); } break; } case '6' : { bool active; result = dspchorus->getActive(&active); ERRCHECK(result); if (active) { result = dspchorus->remove(); ERRCHECK(result); } else { result = system->addDSP(dspchorus, 0); ERRCHECK(result); } break; } case '7' : { bool active; result = dspparameq->getActive(&active); ERRCHECK(result); if (active) { result = dspparameq->remove(); ERRCHECK(result); } else { result = system->addDSP(dspparameq, 0); ERRCHECK(result); result = dspparameq->setParameter(FMOD_DSP_PARAMEQ_CENTER, 5000.0f); ERRCHECK(result); result = dspparameq->setParameter(FMOD_DSP_PARAMEQ_GAIN, 0.0f); ERRCHECK(result); } break; } } } system->update(); { bool paused = 0; bool dsplowpass_active; bool dsphighpass_active; bool dspecho_active; bool dspflange_active; bool dspdistortion_active; bool dspchorus_active; bool dspparameq_active; dsplowpass ->getActive(&dsplowpass_active); dsphighpass ->getActive(&dsphighpass_active); dspecho ->getActive(&dspecho_active); dspflange ->getActive(&dspflange_active); dspdistortion->getActive(&dspdistortion_active); dspchorus ->getActive(&dspchorus_active); dspparameq ->getActive(&dspparameq_active); if (channel) { result = channel->getPaused(&paused); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } } printf("%s : lowpass[%c] highpass[%c] echo[%c] flange[%c] dist[%c] chorus[%c] parameq[%c]\r", paused ? "Paused " : "Playing", dsplowpass_active ? 'x' : ' ', dsphighpass_active ? 'x' : ' ', dspecho_active ? 'x' : ' ', dspflange_active ? 'x' : ' ', dspdistortion_active ? 'x' : ' ', dspchorus_active ? 'x' : ' ', dspparameq_active ? 'x' : ' '); fflush(stdout); } Sleep(10); } while (key != 27); printf("\n"); /* Shut down */ result = sound->release(); ERRCHECK(result); result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); return 0; }
int FMOD_Main() { FMOD::System *system = 0; FMOD::Sound *sound = 0; FMOD::Channel *channel = 0; FMOD::ChannelGroup *mastergroup = 0; FMOD::DSP *dsplowpass = 0; FMOD::DSP *dsphighpass = 0; FMOD::DSP *dspecho = 0; FMOD::DSP *dspflange = 0; FMOD_RESULT result; unsigned int version; void *extradriverdata = 0; Common_Init(&extradriverdata); /* Create a System object and initialize */ result = FMOD::System_Create(&system); ERRCHECK(result); result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION); } result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); ERRCHECK(result); result = system->getMasterChannelGroup(&mastergroup); ERRCHECK(result); result = system->createSound(Common_MediaPath("drumloop.wav"), FMOD_DEFAULT, 0, &sound); ERRCHECK(result); result = system->playSound(sound, 0, false, &channel); ERRCHECK(result); /* Create some effects to play with */ result = system->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &dsplowpass); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_HIGHPASS, &dsphighpass); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dspecho); ERRCHECK(result); result = system->createDSPByType(FMOD_DSP_TYPE_FLANGE, &dspflange); ERRCHECK(result); /* Add them to the master channel group. Each time an effect is added (to position 0) it pushes the others down the list. */ result = mastergroup->addDSP(0, dsplowpass); ERRCHECK(result); result = mastergroup->addDSP(0, dsphighpass); ERRCHECK(result); result = mastergroup->addDSP(0, dspecho); ERRCHECK(result); result = mastergroup->addDSP(0, dspflange); ERRCHECK(result); /* By default, bypass all effects. This means let the original signal go through without processing. It will sound 'dry' until effects are enabled by the user. */ result = dsplowpass->setBypass(true); ERRCHECK(result); result = dsphighpass->setBypass(true); ERRCHECK(result); result = dspecho->setBypass(true); ERRCHECK(result); result = dspflange->setBypass(true); ERRCHECK(result); /* Main loop */ do { Common_Update(); if (Common_BtnPress(BTN_MORE)) { bool paused; result = channel->getPaused(&paused); ERRCHECK(result); paused = !paused; result = channel->setPaused(paused); ERRCHECK(result); } if (Common_BtnPress(BTN_ACTION1)) { bool bypass; result = dsplowpass->getBypass(&bypass); ERRCHECK(result); bypass = !bypass; result = dsplowpass->setBypass(bypass); ERRCHECK(result); } if (Common_BtnPress(BTN_ACTION2)) { bool bypass; result = dsphighpass->getBypass(&bypass); ERRCHECK(result); bypass = !bypass; result = dsphighpass->setBypass(bypass); ERRCHECK(result); } if (Common_BtnPress(BTN_ACTION3)) { bool bypass; result = dspecho->getBypass(&bypass); ERRCHECK(result); bypass = !bypass; result = dspecho->setBypass(bypass); ERRCHECK(result); } if (Common_BtnPress(BTN_ACTION4)) { bool bypass; result = dspflange->getBypass(&bypass); ERRCHECK(result); bypass = !bypass; result = dspflange->setBypass(bypass); ERRCHECK(result); } result = system->update(); ERRCHECK(result); { bool paused = 0; bool dsplowpass_bypass; bool dsphighpass_bypass; bool dspecho_bypass; bool dspflange_bypass; dsplowpass ->getBypass(&dsplowpass_bypass); dsphighpass ->getBypass(&dsphighpass_bypass); dspecho ->getBypass(&dspecho_bypass); dspflange ->getBypass(&dspflange_bypass); if (channel) { result = channel->getPaused(&paused); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } } Common_Draw("=================================================="); Common_Draw("Effects Example."); Common_Draw("Copyright (c) Firelight Technologies 2004-2015."); Common_Draw("=================================================="); Common_Draw(""); Common_Draw("Press %s to pause/unpause sound", Common_BtnStr(BTN_MORE)); Common_Draw("Press %s to toggle dsplowpass effect", Common_BtnStr(BTN_ACTION1)); Common_Draw("Press %s to toggle dsphighpass effect", Common_BtnStr(BTN_ACTION2)); Common_Draw("Press %s to toggle dspecho effect", Common_BtnStr(BTN_ACTION3)); Common_Draw("Press %s to toggle dspflange effect", Common_BtnStr(BTN_ACTION4)); Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); Common_Draw(""); Common_Draw("%s : lowpass[%c] highpass[%c] echo[%c] flange[%c]", paused ? "Paused " : "Playing", dsplowpass_bypass ? ' ' : 'x', dsphighpass_bypass ? ' ' : 'x', dspecho_bypass ? ' ' : 'x', dspflange_bypass ? ' ' : 'x'); } Common_Sleep(50); } while (!Common_BtnPress(BTN_QUIT)); /* Shut down */ result = mastergroup->removeDSP(dsplowpass); ERRCHECK(result); result = mastergroup->removeDSP(dsphighpass); ERRCHECK(result); result = mastergroup->removeDSP(dspecho); ERRCHECK(result); result = mastergroup->removeDSP(dspflange); ERRCHECK(result); result = dsplowpass->release(); ERRCHECK(result); result = dsphighpass->release(); ERRCHECK(result); result = dspecho->release(); ERRCHECK(result); result = dspflange->release(); ERRCHECK(result); result = sound->release(); ERRCHECK(result); result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); Common_Close(); return 0; }
int main(int argc, char *argv[]) { FMOD::System *system = 0; FMOD::Sound *sound = 0; FMOD::Channel *channel = 0; FMOD::DSP *dsp = 0; FMOD_RESULT result; FMOD_CREATESOUNDEXINFO exinfo; FMOD_SPEAKERMODE speakermode; FMOD_CAPS caps; int key, numdrivers; unsigned int version; unsigned int datalength = 0, soundlength; char name[256]; unsigned int adjustedlatency; /* Create a System object and initialize. */ result = FMOD::System_Create(&system); ERRCHECK(result); result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { printf("Error! You are using an old version of FMOD %08x. This program requires %08x\n", version, FMOD_VERSION); return 0; } /* System initialization (recommended startup sequence) */ result = system->getNumDrivers(&numdrivers); ERRCHECK(result); if (numdrivers == 0) { result = system->setOutput(FMOD_OUTPUTTYPE_NOSOUND); ERRCHECK(result); } else { result = system->getDriverCaps(0, &caps, 0, &speakermode); ERRCHECK(result); result = system->setSpeakerMode(speakermode); /* Set the user selected speaker mode. */ ERRCHECK(result); if (caps & FMOD_CAPS_HARDWARE_EMULATED) /* The user has the 'Acceleration' slider set to off! This is really bad for latency!. */ { /* You might want to warn the user about this. */ result = system->setDSPBufferSize(1024, 10); ERRCHECK(result); } #ifdef LOWLATENCY else { result = system->setDSPBufferSize(256, 4); } #endif result = system->getDriverInfo(0, name, 256, 0); ERRCHECK(result); if (strstr(name, "SigmaTel")) /* Sigmatel sound devices crackle for some reason if the format is PCM 16bit. PCM floating point output seems to solve it. */ { result = system->setSoftwareFormat(48000, FMOD_SOUND_FORMAT_PCMFLOAT, 0,0, FMOD_DSP_RESAMPLER_LINEAR); ERRCHECK(result); } } result = system->init(100, FMOD_INIT_NORMAL, 0); if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) /* Ok, the speaker mode selected isn't supported by this soundcard. Switch it back to stereo... */ { result = system->setSpeakerMode(FMOD_SPEAKERMODE_STEREO); ERRCHECK(result); result = system->init(100, FMOD_INIT_NORMAL, 0);/* ... and re-init. */ ERRCHECK(result); } /* System initialization complete (recommended startup sequence) */ /* Create user sound to record into. Set it to loop for playback. */ memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); exinfo.numchannels = 1; exinfo.format = FMOD_SOUND_FORMAT_PCM16; exinfo.defaultfrequency = RECORDRATE; exinfo.length = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels * 5; /* 5 second buffer, doesnt really matter how big this is, but not too small of course. */ result = system->createSound(0, FMOD_2D | FMOD_SOFTWARE | FMOD_LOOP_NORMAL | FMOD_OPENUSER, &exinfo, &sound); ERRCHECK(result); printf("========================================================================\n"); printf("Record with realtime playback example.\n"); printf("Copyright (c) Firelight Technologies 2004-2014.\n"); printf("\n"); printf("Try #define LOWLATENCY to reduce latency for more modern machines!\n"); printf("========================================================================\n"); printf("\n"); printf("Press a key to start recording. Playback will start %d samples (%d ms) later.\n", LATENCY, LATENCY * 1000 / RECORDRATE); printf("\n"); _getch(); printf("Press 'E' to toggle an effect on/off.\n"); printf("Press 'Esc' to quit\n"); printf("\n"); result = system->recordStart(0, sound, true); ERRCHECK(result); result = sound->getLength(&soundlength, FMOD_TIMEUNIT_PCM); ERRCHECK(result); /* Create a DSP effect to play with. */ result = system->createDSPByType(FMOD_DSP_TYPE_FLANGE, &dsp); ERRCHECK(result); result = dsp->setParameter(FMOD_DSP_FLANGE_RATE, 4.0f); ERRCHECK(result); result = dsp->setBypass(true); ERRCHECK(result); adjustedlatency = LATENCY; /* This might change depending on record block size. */ /* Main loop. */ do { static unsigned int lastrecordpos = 0, samplesrecorded = 0; unsigned int recordpos = 0, recorddelta; key = 0; if (_kbhit()) { key = _getch(); } if (key == 'e' || key == 'E') { bool bypass; dsp->getBypass(&bypass); dsp->setBypass(!bypass); if (bypass) { FMOD_REVERB_PROPERTIES prop = FMOD_PRESET_CONCERTHALL; system->setReverbProperties(&prop); } else { FMOD_REVERB_PROPERTIES prop = FMOD_PRESET_OFF; system->setReverbProperties(&prop); } printf("\n\n *** TURN DSP EFFECT %s ** \n\n", bypass ? "ON" : "OFF"); } system->getRecordPosition(0, &recordpos); ERRCHECK(result); recorddelta = recordpos >= lastrecordpos ? recordpos - lastrecordpos : recordpos + soundlength - lastrecordpos; samplesrecorded += recorddelta; if (samplesrecorded >= adjustedlatency && !channel) { result = system->playSound(FMOD_CHANNEL_FREE, sound, 0, &channel); ERRCHECK(result); result = channel->addDSP(dsp, 0); ERRCHECK(result); } if (channel && recorddelta) { unsigned int playrecorddelta; unsigned int playpos = 0; int adjusting = 0; float smootheddelta; float dampratio = 0.97f; static unsigned int minrecorddelta = (unsigned int)-1; /* If the record driver steps the position of the record cursor in larger increments than the user defined latency value, then we should increase our latency value to match. */ if (recorddelta < minrecorddelta) { minrecorddelta = recorddelta; if (adjustedlatency < recorddelta) { adjustedlatency = recorddelta; } } channel->getPosition(&playpos, FMOD_TIMEUNIT_PCM); playrecorddelta = recordpos >= playpos ? recordpos - playpos : recordpos + soundlength - playpos; /* Smooth total */ { static float total = 0; total = total * dampratio; total += playrecorddelta; smootheddelta = total * (1.0f - dampratio); } if (smootheddelta < adjustedlatency - DRIFTTHRESHOLD || smootheddelta > soundlength / 2) /* if play cursor is catching up to record (or passed it), slow playback down */ { channel->setFrequency(RECORDRATE - (RECORDRATE / 50)); /* Decrease speed by 2% */ adjusting = 1; } else if (smootheddelta > adjustedlatency + DRIFTTHRESHOLD) /* if play cursor is falling too far behind record, speed playback up */ { channel->setFrequency(RECORDRATE + (RECORDRATE / 50)); /* Increase speed by 2% */ adjusting = 2; } else { channel->setFrequency(RECORDRATE); /* Otherwise set to normal rate */ adjusting = 0; } printf("REC %5d (REC delta %5d) : PLAY %5d, PLAY/REC diff %5d %s\r", recordpos, recorddelta, playpos, (int)smootheddelta, adjusting == 1 ? "DECREASE SPEED" : adjusting == 2 ? "INCREASE SPEED" : " "); } lastrecordpos = recordpos; system->update(); Sleep(10); } while (key != 27); printf("\n"); /* Shut down */ result = sound->release(); ERRCHECK(result); result = system->release(); ERRCHECK(result); return 0; }
void AnalyzerToolUtils::getSpectrum(SoundAnalyzer* soundAnalyzer) { //FMod variable boost::thread_group threadpool; FMOD::DSP* dspSpectrum; FMOD::ChannelGroup* masterChannel; FMOD::Channel* chan; FMOD_RESULT res; //Variable int sampleRate, musicSpectrumSize; unsigned int soundTime; float niquistRate, i = 0; //sound time in MS soundAnalyzer->Sound->getLength(&soundTime, FMOD_TIMEUNIT_MS); //DSP / FFT / Window soundAnalyzer->sys->createDSPByType(FMOD_DSP_TYPE_FFT, &dspSpectrum); dspSpectrum->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, soundAnalyzer->GetWindowSize()); dspSpectrum->getParameterInt(FMOD_DSP_FFT_WINDOWSIZE, &musicSpectrumSize, 0, 0); dspSpectrum->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_TRIANGLE); //Master Channel -> Add Dsp soundAnalyzer->sys->getMasterChannelGroup(&masterChannel); masterChannel->addDSP(0, dspSpectrum); soundAnalyzer->sys->setOutput(FMOD_OUTPUTTYPE_NOSOUND_NRT); //FMOD_OUTPUTTYPE_NOSOUND_NRT soundAnalyzer->sys->playSound(soundAnalyzer->Sound, masterChannel, false, &chan); soundAnalyzer->sys->setDSPBufferSize(SPECTRUM_BUFFER_SIZE, 0); soundAnalyzer->sys->update(); //Get Samplerate soundAnalyzer->sys->getSoftwareFormat(&sampleRate, 0, 0); niquistRate = sampleRate / 2.0f; soundAnalyzer->data.SpectrumData.resize(static_cast<int>(soundTime / (((double)SPECTRUM_BUFFER_SIZE / (double)sampleRate) * 1000)) + 1); soundAnalyzer->SetFrequencyStep(musicSpectrumSize / niquistRate); int index = 0; //double val; do{ FMOD_DSP_PARAMETER_FFT *dataSpectrum; dspSpectrum->getParameterData(FMOD_DSP_FFT_SPECTRUMDATA, (void **)&dataSpectrum, 0, 0, 0); SpectrumSegment segment(musicSpectrumSize / 2, musicSpectrumSize / niquistRate); threadpool.create_thread(boost::bind(&AnalyzerToolUtils::ExtractSpectrum, soundAnalyzer, boost::ref(dataSpectrum), musicSpectrumSize/2, musicSpectrumSize / niquistRate, index)); /*for (int bin = 0; bin < dataSpectrum->length/2; bin++) { val = 0; for (int channel = 0; channel < MAX_CHANNELS; channel++) { val += dataSpectrum->spectrum[channel][bin]; } segment.AddSegment(val); } soundAnalyzer->data.AddData(segment);*/ soundAnalyzer->sys->update(); index++; i += ((double)SPECTRUM_BUFFER_SIZE / (double)sampleRate) * 1000; } while (i < (soundTime)); threadpool.join_all(); }
// Taken mostly from ActiveSound.cpp void UFMODAudioComponent::UpdateInteriorVolumes() { // Result of the ambient calculations to apply to the instance float AmbientVolumeMultiplier = 1.0f; float AmbientHighFrequencyGain = 1.0f; FInteriorSettings Ambient; const FVector& Location = GetOwner()->GetTransform().GetTranslation(); AAudioVolume* AudioVolume = GetWorld()->GetAudioSettings(Location, NULL, &Ambient); const FFMODListener& Listener = IFMODStudioModule::Get().GetNearestListener(Location); if( InteriorLastUpdateTime < Listener.InteriorStartTime ) { SourceInteriorVolume = CurrentInteriorVolume; SourceInteriorLPF = CurrentInteriorLPF; InteriorLastUpdateTime = FApp::GetCurrentTime(); } bool bAllowSpatialization = true; if( Listener.Volume == AudioVolume || !bAllowSpatialization ) { // Ambient and listener in same ambient zone CurrentInteriorVolume = ( SourceInteriorVolume * ( 1.0f - Listener.InteriorVolumeInterp ) ) + Listener.InteriorVolumeInterp; AmbientVolumeMultiplier *= CurrentInteriorVolume; CurrentInteriorLPF = ( SourceInteriorLPF * ( 1.0f - Listener.InteriorLPFInterp ) ) + Listener.InteriorLPFInterp; AmbientHighFrequencyGain *= CurrentInteriorLPF; //UE_LOG(LogFMOD, Verbose, TEXT( "Ambient in same volume. Volume *= %g LPF *= %g" ), CurrentInteriorVolume, CurrentInteriorLPF); } else { // Ambient and listener in different ambient zone if( Ambient.bIsWorldSettings ) { // The ambient sound is 'outside' - use the listener's exterior volume CurrentInteriorVolume = ( SourceInteriorVolume * ( 1.0f - Listener.ExteriorVolumeInterp ) ) + ( Listener.InteriorSettings.ExteriorVolume * Listener.ExteriorVolumeInterp ); AmbientVolumeMultiplier *= CurrentInteriorVolume; CurrentInteriorLPF = ( SourceInteriorLPF * ( 1.0f - Listener.ExteriorLPFInterp ) ) + ( Listener.InteriorSettings.ExteriorLPF * Listener.ExteriorLPFInterp ); AmbientHighFrequencyGain *= CurrentInteriorLPF; //UE_LOG(LogFMOD, Verbose, TEXT( "Ambient in diff volume, ambient outside. Volume *= %g LPF *= %g" ), CurrentInteriorVolume, CurrentInteriorLPF); } else { // The ambient sound is 'inside' - use the ambient sound's interior volume multiplied with the listeners exterior volume CurrentInteriorVolume = (( SourceInteriorVolume * ( 1.0f - Listener.InteriorVolumeInterp ) ) + ( Ambient.InteriorVolume * Listener.InteriorVolumeInterp )) * (( SourceInteriorVolume * ( 1.0f - Listener.ExteriorVolumeInterp ) ) + ( Listener.InteriorSettings.ExteriorVolume * Listener.ExteriorVolumeInterp )); AmbientVolumeMultiplier *= CurrentInteriorVolume; CurrentInteriorLPF = (( SourceInteriorLPF * ( 1.0f - Listener.InteriorLPFInterp ) ) + ( Ambient.InteriorLPF * Listener.InteriorLPFInterp )) * (( SourceInteriorLPF * ( 1.0f - Listener.ExteriorLPFInterp ) ) + ( Listener.InteriorSettings.ExteriorLPF * Listener.ExteriorLPFInterp )); AmbientHighFrequencyGain *= CurrentInteriorLPF; //UE_LOG(LogFMOD, Verbose, TEXT( "Ambient in diff volume, ambient inside. Volume *= %g LPF *= %g" ), CurrentInteriorVolume, CurrentInteriorLPF); } } StudioInstance->setVolume(AmbientVolumeMultiplier); FMOD::ChannelGroup* ChanGroup = nullptr; StudioInstance->getChannelGroup(&ChanGroup); if (ChanGroup) { int NumDSP = 0; ChanGroup->getNumDSPs(&NumDSP); for (int Index=0; Index<NumDSP; ++Index) { FMOD::DSP* ChanDSP = nullptr; ChanGroup->getDSP(Index, &ChanDSP); if (ChanDSP) { FMOD_DSP_TYPE DSPType = FMOD_DSP_TYPE_UNKNOWN; ChanDSP->getType(&DSPType); if (DSPType == FMOD_DSP_TYPE_LOWPASS || DSPType == FMOD_DSP_TYPE_LOWPASS_SIMPLE) { static float MAX_FREQUENCY = 8000.0f; float Frequency = MAX_FREQUENCY * AmbientHighFrequencyGain; ChanDSP->setParameterFloat(FMOD_DSP_LOWPASS_CUTOFF, MAX_FREQUENCY * AmbientHighFrequencyGain); break; } } } } }
int main(int argc, char *argv[]) { FMOD::System *system; FMOD::Sound *sound; FMOD::Channel *channel; FMOD::DSP *mydsp; FMOD_RESULT result; int key; unsigned int version; float pan = 0; /* Create a System object and initialize. */ result = FMOD::System_Create(&system); ERRCHECK(result); result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { printf("Error! You are using an old version of FMOD %08x. This program requires %08x\n", version, FMOD_VERSION); return 0; } result = system->init(32, FMOD_INIT_NORMAL, 0); ERRCHECK(result); result = system->createSound("../media/drumloop.wav", FMOD_SOFTWARE | FMOD_LOOP_NORMAL, 0, &sound); ERRCHECK(result); printf("===============================================================================\n"); printf("Custom DSP example. Copyright (c) Firelight Technologies 2004-2011.\n"); printf("===============================================================================\n"); printf("Press 'f' to activate, deactivate user filter\n"); printf("Press 'Esc' to quit\n"); printf("\n"); result = system->playSound(FMOD_CHANNEL_FREE, sound, false, &channel); ERRCHECK(result); /* Create the DSP effects. */ { FMOD_DSP_DESCRIPTION dspdesc; memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); strcpy(dspdesc.name, "My first DSP unit"); dspdesc.channels = 0; // 0 = whatever comes in, else specify. dspdesc.read = myDSPCallback; dspdesc.userdata = (void *)0x12345678; result = system->createDSP(&dspdesc, &mydsp); ERRCHECK(result); } /* Inactive by default. */ mydsp->setBypass(true); /* Main loop. */ result = system->addDSP(mydsp, 0); /* Main loop. */ do { if (kbhit()) { key = getch(); switch (key) { case 'f' : case 'F' : { static bool active = false; mydsp->setBypass(active); active = !active; break; } } } system->update(); Sleep(10); } while (key != 27); printf("\n"); /* Shut down */ result = sound->release(); ERRCHECK(result); result = mydsp->release(); ERRCHECK(result); result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); return 0; }
int FMOD_Main() { void *extradriverdata = 0; Common_Init(&extradriverdata); /* Create a System object and initialize */ FMOD_RESULT result; FMOD::System* system; result = FMOD::System_Create(&system); ERRCHECK(result); unsigned int version; result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION); } result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); ERRCHECK(result); /* Create a new channel group to hold the convolution DSP unit */ FMOD::ChannelGroup* reverbGroup; result = system->createChannelGroup("reverb", &reverbGroup); ERRCHECK(result); /* Create a new channel group to hold all the channels and process the dry path */ FMOD::ChannelGroup* mainGroup; result = system->createChannelGroup("main", &mainGroup); ERRCHECK(result); /* Create the convultion DSP unit and set it as the tail of the channel group */ FMOD::DSP* reverbUnit; result = system->createDSPByType(FMOD_DSP_TYPE_CONVOLUTIONREVERB, &reverbUnit); ERRCHECK(result); result = reverbGroup->addDSP(FMOD_CHANNELCONTROL_DSP_TAIL, reverbUnit); ERRCHECK(result); /* Open the impulse response wav file, but use FMOD_OPENONLY as we want to read the data into a seperate buffer */ FMOD::Sound* irSound; result = system->createSound(Common_MediaPath("standrews.wav"), FMOD_DEFAULT | FMOD_OPENONLY, NULL, &irSound); ERRCHECK(result); /* Retrieve the sound information for the Impulse Response input file */ FMOD_SOUND_FORMAT irSoundFormat; FMOD_SOUND_TYPE irSoundType; int irSoundBits, irSoundChannels; result = irSound->getFormat(&irSoundType, &irSoundFormat, &irSoundChannels, &irSoundBits); ERRCHECK(result); unsigned int irSoundLength; result = irSound->getLength(&irSoundLength, FMOD_TIMEUNIT_PCM); ERRCHECK(result); if (irSoundFormat != FMOD_SOUND_FORMAT_PCM16) { /* For simplicity of the example, if the impulse response is the wrong format just display an error */ Common_Fatal("Impulse Response file is the wrong audio format"); } /* The reverb unit expects a block of data containing a single 16 bit int containing the number of channels in the impulse response, followed by PCM 16 data */ unsigned int irDataLength = sizeof(short) * (irSoundLength * irSoundChannels + 1); short* irData = (short*)malloc(irDataLength); irData[0] = irSoundChannels; unsigned int irDataRead; result = irSound->readData(&irData[1], irDataLength - sizeof(short), &irDataRead); ERRCHECK(result); result = reverbUnit->setParameterData(FMOD_DSP_CONVOLUTION_REVERB_PARAM_IR, irData, irDataLength); ERRCHECK(result); /* Don't pass any dry signal from the reverb unit, instead take the dry part of the mix from the main signal path */ result = reverbUnit->setParameterFloat(FMOD_DSP_CONVOLUTION_REVERB_PARAM_DRY, -80.0f); ERRCHECK(result); /* We can now free our copy of the IR data and release the sound object, the reverb unit has created it's internal data */ free(irData); result = irSound->release(); ERRCHECK(result); /* Load up and play a sample clip recorded in an anechoic chamber */ FMOD::Sound* sound; system->createSound(Common_MediaPath("singing.wav"), FMOD_3D | FMOD_LOOP_NORMAL, NULL, &sound); ERRCHECK(result); FMOD::Channel* channel; system->playSound(sound, mainGroup, true, &channel); ERRCHECK(result); /* Create a send connection between the channel head and the reverb unit */ FMOD::DSP* channelHead; channel->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &channelHead); ERRCHECK(result); FMOD::DSPConnection* reverbConnection; result = reverbUnit->addInput(channelHead, &reverbConnection, FMOD_DSPCONNECTION_TYPE_SEND); ERRCHECK(result); result = channel->setPaused(false); ERRCHECK(result); float wetVolume = 1.0; float dryVolume = 1.0; /* Main loop */ do { Common_Update(); if (Common_BtnPress(BTN_LEFT)) { wetVolume = (wetVolume <= 0.0f) ? wetVolume : wetVolume - 0.05; } if (Common_BtnPress(BTN_RIGHT)) { wetVolume = (wetVolume >= 1.0f) ? wetVolume : wetVolume + 0.05f; } if (Common_BtnPress(BTN_DOWN)) { dryVolume = (dryVolume <= 0.0f) ? dryVolume : dryVolume - 0.05f; } if (Common_BtnPress(BTN_UP)) { dryVolume = (dryVolume >= 1.0f) ? dryVolume : dryVolume + 0.05f; } result = system->update(); ERRCHECK(result); result = reverbConnection->setMix(wetVolume); ERRCHECK(result); result = mainGroup->setVolume(dryVolume); ERRCHECK(result); Common_Draw("=================================================="); Common_Draw("Convolution Example."); Common_Draw("Copyright (c) Firelight Technologies 2004-2015."); Common_Draw("=================================================="); Common_Draw("Press %s and %s to change dry mix", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN)); Common_Draw("Press %s and %s to change wet mix", Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT)); Common_Draw("wet mix [%.2f] dry mix [%.2f]", wetVolume, dryVolume); Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); Common_Draw(""); Common_Sleep(50); } while (!Common_BtnPress(BTN_QUIT)); /* Shut down */ result = sound->release(); ERRCHECK(result); result = mainGroup->release(); ERRCHECK(result); result = reverbGroup->removeDSP(reverbUnit); ERRCHECK(result); result = reverbUnit->disconnectAll(true, true); ERRCHECK(result); result = reverbUnit->release(); ERRCHECK(result); result = reverbGroup->release(); ERRCHECK(result); result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); Common_Close(); return 0; }
int FMOD_Main() { FMOD::System *system; FMOD::Channel *channel = 0; FMOD::DSP *dsp; FMOD_RESULT result; unsigned int version; void *extradriverdata = 0; Common_Init(&extradriverdata); /* Create a System object and initialize. */ result = FMOD::System_Create(&system); ERRCHECK(result); result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION); } result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); ERRCHECK(result); /* Create an oscillator DSP units for the tone. */ result = system->createDSPByType(FMOD_DSP_TYPE_OSCILLATOR, &dsp); ERRCHECK(result); result = dsp->setParameterFloat(FMOD_DSP_OSCILLATOR_RATE, 440.0f); /* Musical note 'A' */ ERRCHECK(result); /* Main loop */ do { Common_Update(); if (Common_BtnPress(BTN_ACTION1)) { if (channel) { result = channel->stop(); ERRCHECK(result); } result = system->playDSP(dsp, 0, true, &channel); ERRCHECK(result); result = channel->setVolume(0.5f); ERRCHECK(result); result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 0); ERRCHECK(result); result = channel->setPaused(false); ERRCHECK(result); } if (Common_BtnPress(BTN_ACTION2)) { if (channel) { result = channel->stop(); ERRCHECK(result); } result = system->playDSP(dsp, 0, true, &channel); ERRCHECK(result); result = channel->setVolume(0.125f); ERRCHECK(result); result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 1); ERRCHECK(result); result = channel->setPaused(false); ERRCHECK(result); } if (Common_BtnPress(BTN_ACTION3)) { if (channel) { result = channel->stop(); ERRCHECK(result); } result = system->playDSP(dsp, 0, true, &channel); ERRCHECK(result); result = channel->setVolume(0.125f); ERRCHECK(result); result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 2); ERRCHECK(result); result = channel->setPaused(false); ERRCHECK(result); } if (Common_BtnPress(BTN_ACTION4)) { if (channel) { result = channel->stop(); ERRCHECK(result); } result = system->playDSP(dsp, 0, true, &channel); ERRCHECK(result); result = channel->setVolume(0.5f); ERRCHECK(result); result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 4); ERRCHECK(result); result = channel->setPaused(false); ERRCHECK(result); } if (Common_BtnPress(BTN_MORE)) { if (channel) { result = channel->stop(); ERRCHECK(result); channel = 0; } } if (channel) { if (Common_BtnDown(BTN_UP) || Common_BtnDown(BTN_DOWN)) { float volume; result = channel->getVolume(&volume); ERRCHECK(result); volume += (Common_BtnDown(BTN_UP) ? +0.1f : -0.1f); volume = (volume > 1.0f) ? 1.0f : volume; volume = (volume < 0.0f) ? 0.0f : volume; result = channel->setVolume(volume); ERRCHECK(result); } if (Common_BtnDown(BTN_LEFT) || Common_BtnDown(BTN_RIGHT)) { float frequency; result = channel->getFrequency(&frequency); ERRCHECK(result); frequency += (Common_BtnDown(BTN_RIGHT) ? +500.0f : -500.0f); result = channel->setFrequency(frequency); ERRCHECK(result); } } result = system->update(); ERRCHECK(result); { float frequency = 0.0f, volume = 0.0f; bool playing = false; if (channel) { result = channel->getFrequency(&frequency); ERRCHECK(result); result = channel->getVolume(&volume); ERRCHECK(result); result = channel->isPlaying(&playing); ERRCHECK(result); } Common_Draw("=================================================="); Common_Draw("Generate Tone Example."); Common_Draw("Copyright (c) Firelight Technologies 2004-2015."); Common_Draw("=================================================="); Common_Draw(""); Common_Draw("Press %s to play a sine wave", Common_BtnStr(BTN_ACTION1)); Common_Draw("Press %s to play a square wave", Common_BtnStr(BTN_ACTION2)); Common_Draw("Press %s to play a saw wave", Common_BtnStr(BTN_ACTION3)); Common_Draw("Press %s to play a triangle wave", Common_BtnStr(BTN_ACTION4)); Common_Draw("Press %s to stop the channel", Common_BtnStr(BTN_MORE)); Common_Draw("Press %s and %s to change volume", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN)); Common_Draw("Press %s and %s to change frequency", Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT)); Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT)); Common_Draw(""); Common_Draw("Channel is %s", playing ? "playing" : "stopped"); Common_Draw("Volume %0.2f", volume); Common_Draw("Frequency %0.2f", frequency); } Common_Sleep(50); } while (!Common_BtnPress(BTN_QUIT)); /* Shut down */ result = dsp->release(); ERRCHECK(result); result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); Common_Close(); return 0; }
int main(int argc, char *argv[]) { FMOD::System *system; FMOD::Channel *channel = 0; FMOD::DSP *dsp = 0; FMOD_RESULT result; int key; unsigned int version; /* Create a System object and initialize. */ result = FMOD::System_Create(&system); ERRCHECK(result); result = system->getVersion(&version); ERRCHECK(result); if (version < FMOD_VERSION) { printf("Error! You are using an old version of FMOD %08x. This program requires %08x\n", version, FMOD_VERSION); getch(); return 0; } result = system->init(32, FMOD_INIT_NORMAL, 0); ERRCHECK(result); /* Create an oscillator DSP unit for the tone. */ result = system->createDSPByType(FMOD_DSP_TYPE_OSCILLATOR, &dsp); ERRCHECK(result); result = dsp->setParameter(FMOD_DSP_OSCILLATOR_RATE, 440.0f); ERRCHECK(result); printf("======================================================================\n"); printf("GenerateTone Example. Copyright (c) Firelight Technologies 2004-2011.\n"); printf("======================================================================\n\n"); printf("\n"); printf("Press '1' to play a sine wave\n"); printf("Press '2' to play a square wave\n"); printf("Press '3' to play a triangle wave\n"); printf("Press '4' to play a saw wave\n"); printf("Press '5' to play a white noise\n"); printf("Press 's' to stop channel\n"); printf("\n"); printf("Press 'v'/'V' to change channel volume\n"); printf("Press 'f'/'F' to change channel frequency\n"); printf("Press '['/']' to change channel pan\n"); printf("Press 'Esc' to quit\n"); printf("\n"); /* Main loop */ do { if (kbhit()) { key = getch(); switch (key) { case '1' : { result = system->playDSP(FMOD_CHANNEL_REUSE, dsp, true, &channel); channel->setVolume(0.5f); result = dsp->setParameter(FMOD_DSP_OSCILLATOR_TYPE, 0); ERRCHECK(result); channel->setPaused(false); break; } case '2' : { result = system->playDSP(FMOD_CHANNEL_REUSE, dsp, true, &channel); channel->setVolume(0.125f); result = dsp->setParameter(FMOD_DSP_OSCILLATOR_TYPE, 1); ERRCHECK(result); channel->setPaused(false); break; } case '3' : { result = system->playDSP(FMOD_CHANNEL_REUSE, dsp, true, &channel); channel->setVolume(0.5f); result = dsp->setParameter(FMOD_DSP_OSCILLATOR_TYPE, 2); ERRCHECK(result); channel->setPaused(false); break; } case '4' : { result = system->playDSP(FMOD_CHANNEL_REUSE, dsp, true, &channel); channel->setVolume(0.125f); result = dsp->setParameter(FMOD_DSP_OSCILLATOR_TYPE, 4); ERRCHECK(result); channel->setPaused(false); break; } case '5' : { result = system->playDSP(FMOD_CHANNEL_REUSE, dsp, true, &channel); channel->setVolume(0.25f); result = dsp->setParameter(FMOD_DSP_OSCILLATOR_TYPE, 5); ERRCHECK(result); channel->setPaused(false); break; } case 's' : { channel->stop(); break; } case 'v' : { float volume; channel->getVolume(&volume); volume -= 0.1f; channel->setVolume(volume); break; } case 'V' : { float volume; channel->getVolume(&volume); volume += 0.1f; channel->setVolume(volume); break; } case 'f' : { float frequency; channel->getFrequency(&frequency); frequency -= 500.0f; channel->setFrequency(frequency); break; } case 'F' : { float frequency; channel->getFrequency(&frequency); frequency += 500.0f; channel->setFrequency(frequency); break; } case '[' : { float pan; channel->getPan(&pan); pan -= 0.1f; channel->setPan(pan); break; } case ']' : { float pan; channel->getPan(&pan); pan += 0.1f; channel->setPan(pan); break; } } } system->update(); { float frequency = 0, volume = 0, pan = 0; bool playing = false; if (channel) { channel->getFrequency(&frequency); channel->getVolume(&volume); channel->getPan(&pan); channel->isPlaying(&playing); } printf("Channel %s : Frequency %.1f Volume %.1f Pan %.1f \r", playing ? "playing" : "stopped", frequency, volume, pan); fflush(stdout); } Sleep(10); } while (key != 27); printf("\n"); /* Shut down */ result = dsp->release(); ERRCHECK(result); result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); return 0; }