FMOD::Sound *SoundManager::CreatePlayList(std::string &fileName) { FMOD_RESULT result; FMOD::Sound *playlist; std::string fullPathName; bool isPlayList = false; FMOD_SOUND_TYPE soundType; fullPathName = SOUND_DIRECTORY + fileName; result = system->createSound(fullPathName.c_str(), FMOD_DEFAULT, 0, &playlist); if(result != FMOD_OK) { Ogre::LogManager::getSingleton().logMessage( "SoundManager::CreateSound could not load sound '" + fileName + "' (invalid soundType)"); return NULL; } result = playlist->getFormat(&soundType,0,0,0); isPlayList = (soundType == FMOD_SOUND_TYPE_PLAYLIST); if(isPlayList) { return playlist; } else { playlist->release(); return NULL; } }
// Sets the row position of a channel playing a MOD GMexport double FMODGMS_Chan_Set_ModRow(double channel, double row) { int c = (int)round(channel); int chanListSize = channelList.size(); if (chanListSize > c && c >= 0) { // get handle of sound currently playing in channel FMOD::Sound *snd; channelList[c]->getCurrentSound(&snd); // check to see if the sound is a module FMOD_SOUND_TYPE type; snd->getFormat(&type, 0, 0, 0); if (type == FMOD_SOUND_TYPE_MOD || type == FMOD_SOUND_TYPE_S3M || type == FMOD_SOUND_TYPE_XM || type == FMOD_SOUND_TYPE_IT) { unsigned int r; if (row < 0) r = 0; else r = (unsigned int)row; channelList[c]->setPosition(r, FMOD_TIMEUNIT_MODROW); errorMessage = "No errors."; return GMS_true; } // not a module else { errorMessage = "Not a MOD, S3M, XM, or IT."; return GMS_error; } } // index out of bounds else { errorMessage = "Index out of bounds."; return GMS_error; } }
void SoundManager::loadPlaylist(std::string filename) { FMOD::Sound* playlist; mSystem->createSound(filename.c_str(), FMOD_DEFAULT, 0, &playlist); FMOD_SOUND_TYPE type; playlist->getFormat(&type, 0, 0, 0); if(type != FMOD_SOUND_TYPE_PLAYLIST) { printf("%s, wasn't a playlist! Make sure it exists and it's in .m3u format.\n", filename.c_str()); return; } printf("loading playlist %s\n", filename.c_str()); int count = 0; FMOD_TAG tag; result = FMOD_OK; //go through the m3u file and extract the playlist info result = playlist->getTag("FILE", count, &tag); while(result == FMOD_OK) { unsigned int trackTime = 0; FMOD::Sound* music; //attempt to load the song result = mSystem->createSound((char*)tag.data, FMOD_CREATESTREAM | FMOD_SOFTWARE | FMOD_2D, 0, &music); //if we successfully found the file, get its length and close it if(result == FMOD_OK) { music->getLength(&trackTime, FMOD_TIMEUNIT_MS); music->release(); PlayListEntry p(std::string((char*)tag.data), 0.001 * trackTime + 2.f); mPlayList.push_back(p); // printf("our file is...%s at %f seconds\n", p.filename.c_str(), p.trackTime); } else printf("%s not found, but is listed in the playlist\n", (char*)tag.data); count++; //check to see if we have another file in the playlist result = playlist->getTag("FILE", count, &tag); } mUsePlayList = true; }
SPtr<Resource> FMODImporter::import(const Path& filePath, SPtr<const ImportOptions> importOptions) { WString extension = filePath.getWExtension(); StringUtil::toLowerCase(extension); AudioFileInfo info; FMOD::Sound* sound; String pathStr = filePath.toString(); if(gFMODAudio()._getFMOD()->createSound(pathStr.c_str(), FMOD_CREATESAMPLE, nullptr, &sound) != FMOD_OK) { LOGERR("Failed importing audio file: " + pathStr); return nullptr; } FMOD_SOUND_FORMAT format; INT32 numChannels = 0; INT32 numBits = 0; sound->getFormat(nullptr, &format, &numChannels, &numBits); if(format != FMOD_SOUND_FORMAT_PCM8 && format != FMOD_SOUND_FORMAT_PCM16 && format != FMOD_SOUND_FORMAT_PCM24 && format != FMOD_SOUND_FORMAT_PCM32 && format != FMOD_SOUND_FORMAT_PCMFLOAT) { LOGERR("Failed importing audio file, invalid imported format: " + pathStr); return nullptr; } float frequency = 0.0f; sound->getDefaults(&frequency, nullptr); UINT32 size; sound->getLength(&size, FMOD_TIMEUNIT_PCMBYTES); info.bitDepth = numBits; info.numChannels = numChannels; info.sampleRate = (UINT32)frequency; info.numSamples = size / (info.bitDepth / 8); UINT32 bytesPerSample = info.bitDepth / 8; UINT32 bufferSize = info.numSamples * bytesPerSample; UINT8* sampleBuffer = (UINT8*)bs_alloc(bufferSize); assert(bufferSize == size); UINT8* startData = nullptr; UINT8* endData = nullptr; UINT32 startSize = 0; UINT32 endSize = 0; sound->lock(0, size, (void**)&startData, (void**)&endData, &startSize, &endSize); if(format == FMOD_SOUND_FORMAT_PCMFLOAT) { assert(info.bitDepth == 32); UINT32* output = (UINT32*)sampleBuffer; for(UINT32 i = 0; i < info.numSamples; i++) { float value = *(((float*)startData) + i); *output = (UINT32)(value * 2147483647.0f); output++; } } else { memcpy(sampleBuffer, startData, bufferSize); } sound->unlock((void**)&startData, (void**)&endData, startSize, endSize); sound->release(); SPtr<const AudioClipImportOptions> clipIO = std::static_pointer_cast<const AudioClipImportOptions>(importOptions); // If 3D, convert to mono if (clipIO->getIs3D() && info.numChannels > 1) { UINT32 numSamplesPerChannel = info.numSamples / info.numChannels; UINT32 monoBufferSize = numSamplesPerChannel * bytesPerSample; UINT8* monoBuffer = (UINT8*)bs_alloc(monoBufferSize); AudioUtility::convertToMono(sampleBuffer, monoBuffer, info.bitDepth, numSamplesPerChannel, info.numChannels); info.numSamples = numSamplesPerChannel; info.numChannels = 1; bs_free(sampleBuffer); sampleBuffer = monoBuffer; bufferSize = monoBufferSize; } // Convert bit depth if needed if (clipIO->getBitDepth() != info.bitDepth) { UINT32 outBufferSize = info.numSamples * (clipIO->getBitDepth() / 8); UINT8* outBuffer = (UINT8*)bs_alloc(outBufferSize); AudioUtility::convertBitDepth(sampleBuffer, info.bitDepth, outBuffer, clipIO->getBitDepth(), info.numSamples); info.bitDepth = clipIO->getBitDepth(); bs_free(sampleBuffer); sampleBuffer = outBuffer; bufferSize = outBufferSize; } // Encode to Ogg Vorbis if needed if (clipIO->getFormat() == AudioFormat::VORBIS) { // TODO - Encode to Ogg Vorbis! } SPtr<MemoryDataStream> sampleStream = bs_shared_ptr_new<MemoryDataStream>(sampleBuffer, bufferSize); AUDIO_CLIP_DESC clipDesc; clipDesc.bitDepth = info.bitDepth; clipDesc.format = clipIO->getFormat(); clipDesc.frequency = info.sampleRate; clipDesc.numChannels = info.numChannels; clipDesc.readMode = clipIO->getReadMode(); clipDesc.is3D = clipIO->getIs3D(); SPtr<AudioClip> clip = AudioClip::_createPtr(sampleStream, bufferSize, info.numSamples, clipDesc); WString fileName = filePath.getWFilename(false); clip->setName(fileName); return clip; }
int main(int argc, char *argv[]) { FMOD::System *system; FMOD::Sound *sound; FMOD::Channel *channel = 0; FMOD_RESULT result; int key; unsigned int version; memset(gCurrentTrackArtist, 0, 256); memset(gCurrentTrackTitle, 0, 256); strcpy(gOutputFileName, "output.mp3"); /* Start off like this then rename if a title tag comes along */ printf("======================================================================\n"); printf("RipNetStream Example. Copyright (c) Firelight Technologies 2004-2014.\n"); printf("======================================================================\n\n"); if (argc < 2) { printf("Usage: ripnetstream <url>\n"); return -1; } /* 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(100, FMOD_INIT_NORMAL, 0); ERRCHECK(result); result = system->setStreamBufferSize(gFileBufferSize, FMOD_TIMEUNIT_RAWBYTES); ERRCHECK(result); result = system->attachFileSystem(myopen, myclose, myread, 0); ERRCHECK(result); printf("Buffering...\n\n"); result = system->createSound(argv[1], FMOD_HARDWARE | FMOD_2D | FMOD_CREATESTREAM | FMOD_NONBLOCKING, 0, &sound); ERRCHECK(result); /* Main loop */ do { static bool mute = false; if (sound && !channel) { result = system->playSound(FMOD_CHANNEL_FREE, sound, false, &channel); } if (_kbhit()) { key = _getch(); switch (key) { case ' ' : { if (channel) { bool paused; channel->getPaused(&paused); channel->setPaused(!paused); } break; } case 'm' : case 'M' : { if (channel) { channel->getMute(&mute); channel->setMute(!mute); } break; } } } system->update(); if (channel) { bool playing = false; int tagsupdated = 0; sound->getNumTags(0, &tagsupdated); if (tagsupdated) { printf("\n"); printf("\n"); for (;;) { FMOD_TAG tag; if (sound->getTag(0, -1, &tag) != FMOD_OK) { break; } if (tag.datatype == FMOD_TAGDATATYPE_STRING) { printf("[%-11s] %s (%d bytes)\n", tag.name, tag.data, tag.datalen); sound->getFormat(&gSoundType, 0, 0, 0); if (!strcmp(tag.name, "ARTIST")) { if (strncmp(gCurrentTrackArtist, (const char *)tag.data, 256)) { strncpy(gCurrentTrackArtist, (const char *)tag.data, 256); gUpdateFileName = true; } } if (!strcmp(tag.name, "TITLE")) { if (strncmp(gCurrentTrackTitle, (const char *)tag.data, 256)) { strncpy(gCurrentTrackTitle, (const char *)tag.data, 256); gUpdateFileName = true; } } } } printf("\n"); } result = channel->isPlaying(&playing); if (result != FMOD_OK || !playing) { sound->release(); sound = 0; channel = 0; } else { unsigned int ms = 0, percent = 0; bool paused = false; bool starving = false; FMOD_OPENSTATE openstate; result = sound->getOpenState(&openstate, &percent, &starving, 0); ERRCHECK(result); channel->setVolume(starving ? 0.0f : 1.0f); /* Don't use mute because the user is setting that. */ ERRCHECK(result); result = channel->getPaused(&paused); result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS); printf("Time %02d:%02d:%02d : (%3d%%%) %s SPACE = pause. 'm' = mute. ESC = quit.\r", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, percent, (openstate == FMOD_OPENSTATE_BUFFERING || starving) ? "Buffering..." : openstate == FMOD_OPENSTATE_CONNECTING ? "Connecting..." : paused ? "Paused " : playing ? "Playing " : "Stopped ", percent, starving ? "STARVING" : " "); } } if (sound) { FMOD_OPENSTATE openstate = FMOD_OPENSTATE_READY; sound->getOpenState(&openstate, 0, 0, 0); if (openstate == FMOD_OPENSTATE_ERROR) { sound->release(); sound = 0; channel = 0; } } if (!sound) { printf("\n"); printf("Error occurred or stream ended. Restarting stream..\n"); result = system->createSound(argv[1], FMOD_HARDWARE | FMOD_2D | FMOD_CREATESTREAM | FMOD_NONBLOCKING, 0, &sound); ERRCHECK(result); Sleep(1000); } 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() { 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 main(int argc, char *argv[]) { FMOD::System *system = 0; FMOD::Sound *playlist = 0; FMOD::Sound *sound = 0; FMOD::Channel *channel = 0; FMOD_TAG tag; FMOD_RESULT result; FMOD_SOUND_TYPE soundtype; bool isplaylist = false; char *title = NULL; int count = 0; int key; unsigned int version; char file[128]; /* 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/playlist.m3u", FMOD_DEFAULT, 0, &playlist); ERRCHECK(result); result = playlist->getFormat(&soundtype, 0, 0, 0); ERRCHECK(result); isplaylist = (soundtype == FMOD_SOUND_TYPE_PLAYLIST); printf("===================================================================\n"); printf("PlayList Example. Copyright (c) Firelight Technologies 2004-2011.\n"); printf("===================================================================\n"); printf("\n"); printf("Press 'n' to play next sound in playlist\n"); printf("Press 'space' to pause/unpause current sound\n"); printf("Press 'Esc' to quit\n"); printf("\n"); if (isplaylist) { printf("PLAYLIST loaded.\n"); /* Get the first song in the playlist, create the sound and then play it. */ result = playlist->getTag("FILE", count, &tag); ERRCHECK(result); sprintf(file, "../media/%s", (char *)tag.data); result = system->createSound(file, FMOD_DEFAULT, 0, &sound); ERRCHECK(result); result = system->playSound(FMOD_CHANNEL_FREE, sound, false, &channel); ERRCHECK(result); playlist->getTag("TITLE", count, &tag); title = (char *)tag.data; count++; } else { printf("SOUND loaded.\n"); /* This is just a normal sound, so just play it. */ sound = playlist; result = sound->setMode(FMOD_LOOP_NORMAL); ERRCHECK(result); result = system->playSound(FMOD_CHANNEL_FREE, sound, false, &channel); ERRCHECK(result); } printf("\n"); /* Main loop. */ do { bool isplaying = false; if (channel && isplaylist) { /* When sound has finished playing, play the next sound in the playlist */ channel->isPlaying(&isplaying); if (!isplaying) { if (sound) { sound->release(); sound = NULL; } result = playlist->getTag("FILE", count, &tag); if (result != FMOD_OK) { count = 0; } else { printf("playing next song in playlist...\n"); sprintf(file, "../media/%s", (char *)tag.data); result = system->createSound(file, FMOD_DEFAULT, 0, &sound); ERRCHECK(result); result = system->playSound(FMOD_CHANNEL_FREE, sound, false, &channel); ERRCHECK(result); playlist->getTag("TITLE", count, &tag); title = (char *)tag.data; count++; } } } if (kbhit()) { key = getch(); switch (key) { case 'n' : { /* Play the next song in the playlist */ if (channel && isplaylist) { channel->stop(); } break; } case ' ' : { if (channel) { bool paused; channel->getPaused(&paused); channel->setPaused(!paused); } } } } system->update(); { unsigned int ms = 0; unsigned int lenms = 0; bool paused = 0; if (channel) { if (sound) { result = sound->getLength(&lenms, FMOD_TIMEUNIT_MS); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } } result = channel->getPaused(&paused); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } } printf("Time %02d:%02d:%02d/%02d:%02d:%02d : %s : %s\r", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " : "Playing ", title); fflush(stdout); } Sleep(10); } while (key != 27); printf("\n"); /* Shut down */ if (sound) { result = sound->release(); ERRCHECK(result); } if (isplaylist) { result = playlist->release(); ERRCHECK(result); } result = system->close(); ERRCHECK(result); result = system->release(); ERRCHECK(result); return 0; }