FMOD_RESULT F_CALLBACK pcmreadcallback(FMOD_SOUND *sound, void *data, unsigned int datalen) { UScopeMutex scopeMutex(&g_mutex); //ROS_INFO("datalen=%d, g_readPtr=%d", datalen, g_readPtr); unsigned int count; char * buffer = (char *)data; bool okToCpy = false; if(g_readPtr < g_writePtr) { okToCpy = true; } else if(g_readingLooped < g_writingLooped) { okToCpy = true; } if(okToCpy) { g_warn = true; unsigned int start = g_readPtr; for(count=0; count<datalen; ++count) { *(buffer++) = g_ringBuffer[g_readPtr++]; g_readPtr %= g_ringBuffer.size(); } if(g_readPtr < start) { ++g_readingLooped; } if(g_plot && g_plot->isVisible() && g_curvePlaying) { int channels, bitsPerSample; FMOD_Sound_GetFormat(sound, 0, 0, &channels, &bitsPerSample); updateCurve(g_curvePlaying, &g_ringBuffer[start], datalen, channels, bitsPerSample/8); } //ROS_INFO("datalen=%d, writePtr=%d, readPtr=%d", datalen, g_writePtr, g_readPtr); } else { if(g_warn) { g_warn = false; ROS_WARN("Empty buffer : stream down? (this warning is shown only one time)"); } //fill data with zeros memset(buffer, 0, datalen); } return FMOD_OK; }
void UAudioCaptureMic::close() { if(_sound) { if(_fp) { // Write back the wav header now that we know its length. int channels, bits; float rate; FMOD_Sound_GetFormat(_sound, 0, 0, &channels, &bits); FMOD_Sound_GetDefaults(_sound, &rate, 0, 0, 0); UWav::writeWavHeader(_fp, _dataLength, rate, channels, bits); fclose(_fp); _fp = 0; if(_encodeToMp3) { #ifdef BUILT_WITH_LAME // Encode to mp3 UMp3Encoder mp3Encoder; // Rename the wav file std::string tempFileName = _fileName; tempFileName.append("TMP"); UFile::rename(_fileName, tempFileName); if(mp3Encoder.encode(tempFileName, _fileName) == 0) { //Erase the wav file UFile::erase(tempFileName); } #endif } } FMOD_RESULT result; result = FMOD_Sound_Release(_sound); UASSERT_MSG(result==FMOD_OK, FMOD_ErrorString(result)); _sound = 0; } if(_fp) { fclose(_fp); _fp = 0; } }
/* [ [DESCRIPTION] Writes out the contents of a record buffer to a file. [PARAMETERS] [RETURN_VALUE] void [REMARKS] ] */ void WriteWavHeader(FILE *fp, FMOD_SOUND *sound, int length) { int channels, bits; float rate; if (!sound) { return; } fseek(fp, 0, SEEK_SET); FMOD_Sound_GetFormat (sound, 0, 0, &channels, &bits); FMOD_Sound_GetDefaults(sound, &rate, 0, 0, 0); { #if defined(WIN32) || defined(_WIN64) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__) #pragma pack(1) #endif /* WAV Structures */ typedef struct { signed char id[4]; int size; } RiffChunk; struct { RiffChunk chunk __PACKED; unsigned short wFormatTag __PACKED; /* format type */ unsigned short nChannels __PACKED; /* number of channels (i.e. mono, stereo...) */ unsigned int nSamplesPerSec __PACKED; /* sample rate */ unsigned int nAvgBytesPerSec __PACKED; /* for buffer estimation */ unsigned short nBlockAlign __PACKED; /* block size of data */ unsigned short wBitsPerSample __PACKED; /* number of bits per sample of mono data */ } FmtChunk = { {{'f','m','t',' '}, sizeof(FmtChunk) - sizeof(RiffChunk) }, 1, channels, (int)rate, (int)rate * channels * bits / 8, 1 * channels * bits / 8, bits } __PACKED; struct { RiffChunk chunk; } DataChunk = { {{'d','a','t','a'}, length } }; struct { RiffChunk chunk; signed char rifftype[4]; } WavHeader = { {{'R','I','F','F'}, sizeof(FmtChunk) + sizeof(RiffChunk) + length }, {'W','A','V','E'} }; #if defined(WIN32) || defined(_WIN64) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__) #pragma pack() #endif /* Write out the WAV header. */ fwrite(&WavHeader, sizeof(WavHeader), 1, fp); fwrite(&FmtChunk, sizeof(FmtChunk), 1, fp); fwrite(&DataChunk, sizeof(DataChunk), 1, fp); } }
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-2011.\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 = FMOD_System_GetVersion(system, &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 = FMOD_System_Init(system, 100, FMOD_INIT_NORMAL, NULL); ERRCHECK(result); result = FMOD_System_SetStreamBufferSize(system, gFileBufferSize, FMOD_TIMEUNIT_RAWBYTES); ERRCHECK(result); result = FMOD_System_AttachFileSystem(system, myopen, myclose, myread, 0); ERRCHECK(result); printf("Buffering...\n\n"); result = FMOD_System_CreateSound(system, argv[1], FMOD_HARDWARE | FMOD_2D | FMOD_CREATESTREAM | FMOD_NONBLOCKING, 0, &sound); ERRCHECK(result); /* Main loop */ do { if (sound && !channel) { result = FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, sound, FALSE, &channel); } if (kbhit()) { key = getch(); switch (key) { case ' ' : { if (channel) { int paused; FMOD_Channel_GetPaused(channel, &paused); FMOD_Channel_SetPaused(channel, !paused); } break; } case 'm' : case 'M' : { if (channel) { int mute; FMOD_Channel_GetMute(channel, &mute); FMOD_Channel_SetMute(channel, !mute); } break; } } } FMOD_System_Update(system); if (channel) { unsigned int ms = 0; int playing = FALSE; int paused = FALSE; int tagsupdated = 0; FMOD_Sound_GetNumTags(sound, 0, &tagsupdated); if (tagsupdated) { printf("\n"); printf("\n"); for (;;) { FMOD_TAG tag; if (FMOD_Sound_GetTag(sound, 0, -1, &tag) != FMOD_OK) { break; } if (tag.datatype == FMOD_TAGDATATYPE_STRING) { printf("[%-11s] %s (%d bytes)\n", tag.name, (char *)tag.data, tag.datalen); FMOD_Sound_GetFormat(sound, &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 = FMOD_Channel_IsPlaying(channel, &playing); if (result != FMOD_OK || !playing) { FMOD_Sound_Release(sound); sound = 0; channel = 0; } else { result = FMOD_Channel_GetPaused(channel, &paused); result = FMOD_Channel_GetPosition(channel, &ms, FMOD_TIMEUNIT_MS); printf("\rTime %02d:%02d:%02d : %s : Press SPACE to pause. 'm' to mute. ESC to quit.", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, paused ? "Paused " : playing ? "Playing" : "Stopped"); fflush(stdout); } } if (sound) { FMOD_OPENSTATE openstate = FMOD_OPENSTATE_READY; FMOD_Sound_GetOpenState(sound, &openstate, 0, 0, 0); if (openstate == FMOD_OPENSTATE_ERROR) { FMOD_Sound_Release(sound); sound = 0; channel = 0; } } if (!sound) { printf("\n"); printf("Error occurred or stream ended. Restarting stream..\n"); result = FMOD_System_CreateSound(system, 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 = FMOD_Sound_Release(sound); ERRCHECK(result); result = FMOD_System_Close(system); ERRCHECK(result); result = FMOD_System_Release(system); ERRCHECK(result); return 0; }
/* [ [DESCRIPTION] Writes out the contents of a record buffer to a file. [PARAMETERS] [RETURN_VALUE] void [REMARKS] ] */ void SaveToWav(FMOD_SOUND *sound) { FILE *fp; int channels, bits; float rate; void *ptr1, *ptr2; unsigned int lenbytes, len1, len2; if (!sound) { return; } FMOD_Sound_GetFormat (sound, 0, 0, &channels, &bits); FMOD_Sound_GetDefaults(sound, &rate, 0, 0, 0); FMOD_Sound_GetLength (sound, &lenbytes, FMOD_TIMEUNIT_PCMBYTES); { #if defined(WIN32) || defined(_WIN64) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__) #pragma pack(1) #endif /* WAV Structures */ typedef struct { signed char id[4]; int size; } RiffChunk; struct { RiffChunk chunk __PACKED; unsigned short wFormatTag __PACKED; /* format type */ unsigned short nChannels __PACKED; /* number of channels (i.e. mono, stereo...) */ unsigned int nSamplesPerSec __PACKED; /* sample rate */ unsigned int nAvgBytesPerSec __PACKED; /* for buffer estimation */ unsigned short nBlockAlign __PACKED; /* block size of data */ unsigned short wBitsPerSample __PACKED; /* number of bits per sample of mono data */ } __PACKED FmtChunk = { {{'f','m','t',' '}, sizeof(FmtChunk) - sizeof(RiffChunk) }, 1, channels, (int)rate, (int)rate * channels * bits / 8, 1 * channels * bits / 8, bits }; struct { RiffChunk chunk; } DataChunk = { {{'d','a','t','a'}, lenbytes } }; struct { RiffChunk chunk; signed char rifftype[4]; } WavHeader = { {{'R','I','F','F'}, sizeof(FmtChunk) + sizeof(RiffChunk) + lenbytes }, {'W','A','V','E'} }; #if defined(WIN32) || defined(_WIN64) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__) #pragma pack() #endif fp = fopen("record.wav", "wb"); /* Write out the WAV header. */ fwrite(&WavHeader, sizeof(WavHeader), 1, fp); fwrite(&FmtChunk, sizeof(FmtChunk), 1, fp); fwrite(&DataChunk, sizeof(DataChunk), 1, fp); /* Lock the sound to get access to the raw data. */ FMOD_Sound_Lock(sound, 0, lenbytes, &ptr1, &ptr2, &len1, &len2); /* Write it to disk. */ fwrite(ptr1, len1, 1, fp); /* Unlock the sound to allow FMOD to use it again. */ FMOD_Sound_Unlock(sound, ptr1, ptr2, len1, len2); fclose(fp); } }
/* --------------------------------------- FMODEx 类型信息 --------------------------------------- */ static bool_t fmodex_info ( __CR_IO__ iXMM_FMOD* port ) { sint_t bits; sint_t chns; ansi_t* allx; const ansi_t* type; const ansi_t* fmts; FMOD_RESULT result; FMOD_SOUND_TYPE snd_type; FMOD_SOUND_FORMAT snd_fmts; /* 获取所有信息 */ result = FMOD_Sound_GetFormat(port->m_snd, &snd_type, &snd_fmts, &chns, &bits); if (result != FMOD_OK) return (FALSE); /* 音频格式类型 */ switch (snd_type) { default: type = "3rd party / unknown plugin format"; break; case FMOD_SOUND_TYPE_AIFF: type = "AIFF"; break; case FMOD_SOUND_TYPE_ASF: type = "Microsoft Advanced Systems Format (ie WMA/ASF/WMV)"; break; case FMOD_SOUND_TYPE_AT3: type = "Sony ATRAC 3 format"; break; case FMOD_SOUND_TYPE_CDDA: type = "Digital CD audio"; break; case FMOD_SOUND_TYPE_DLS: type = "Sound font / downloadable sound bank"; break; case FMOD_SOUND_TYPE_FLAC: type = "FLAC lossless codec"; break; case FMOD_SOUND_TYPE_FSB: type = "FMOD Sample Bank"; break; case FMOD_SOUND_TYPE_GCADPCM: type = "Nintendo GameCube/Wii ADPCM"; break; case FMOD_SOUND_TYPE_IT: type = "Impulse Tracker"; break; case FMOD_SOUND_TYPE_MIDI: type = "MIDI"; break; case FMOD_SOUND_TYPE_MOD: type = "Protracker / Fasttracker MOD"; break; case FMOD_SOUND_TYPE_MPEG: type = "MP2/MP3 MPEG"; break; case FMOD_SOUND_TYPE_OGGVORBIS: type = "Ogg vorbis"; break; case FMOD_SOUND_TYPE_PLAYLIST: type = "Information only from ASX/PLS/M3U/WAX playlists"; break; case FMOD_SOUND_TYPE_RAW: type = "Raw PCM data"; break; case FMOD_SOUND_TYPE_S3M: type = "ScreamTracker 3"; break; case FMOD_SOUND_TYPE_SF2: type = "Sound font 2 format"; break; case FMOD_SOUND_TYPE_USER: type = "User created sound"; break; case FMOD_SOUND_TYPE_WAV: type = "Microsoft WAV"; break; case FMOD_SOUND_TYPE_XM: type = "FastTracker 2 XM"; break; case FMOD_SOUND_TYPE_XMA: type = "Xbox360 XMA"; break; case FMOD_SOUND_TYPE_VAG: type = "PlayStation Portable ADPCM VAG format"; break; case FMOD_SOUND_TYPE_AUDIOQUEUE: type = "iPhone hardware decoder, supports AAC, ALAC and MP3"; break; case FMOD_SOUND_TYPE_XWMA: type = "Xbox360 XWMA"; break; case FMOD_SOUND_TYPE_BCWAV: type = "3DS BCWAV container format for DSP ADPCM and PCM"; break; case FMOD_SOUND_TYPE_AT9: type = "NGP ATRAC 9 format"; break; case FMOD_SOUND_TYPE_VORBIS: type = "Raw vorbis"; break; case FMOD_SOUND_TYPE_MEDIA_FOUNDATION: type = "Microsoft Media Foundation wrappers, supports ASF/WMA"; break; } /* 音频数据类型 */ switch (snd_fmts) { default: fmts = "Unitialized / unknown"; break; case FMOD_SOUND_FORMAT_PCM8: fmts = "8bit integer PCM data"; break; case FMOD_SOUND_FORMAT_PCM16: fmts = "16bit integer PCM data"; break; case FMOD_SOUND_FORMAT_PCM24: fmts = "24bit integer PCM data"; break; case FMOD_SOUND_FORMAT_PCM32: fmts = "32bit integer PCM data"; break; case FMOD_SOUND_FORMAT_PCMFLOAT: fmts = "32bit floating point PCM data"; break; case FMOD_SOUND_FORMAT_GCADPCM: fmts = "Compressed Nintendo 3DS/Wii DSP data"; break; case FMOD_SOUND_FORMAT_IMAADPCM: fmts = "Compressed IMA ADPCM data"; break; case FMOD_SOUND_FORMAT_VAG: fmts = "Compressed PlayStation Portable ADPCM data"; break; case FMOD_SOUND_FORMAT_HEVAG: fmts = "Compressed PSVita ADPCM data"; break; case FMOD_SOUND_FORMAT_XMA: fmts = "Compressed Xbox360 XMA data"; break; case FMOD_SOUND_FORMAT_MPEG: fmts = "Compressed MPEG layer 2 or 3 data"; break; case FMOD_SOUND_FORMAT_CELT: fmts = "Compressed CELT data"; break; case FMOD_SOUND_FORMAT_AT9: fmts = "Compressed PSVita ATRAC9 data"; break; case FMOD_SOUND_FORMAT_XWMA: fmts = "Compressed Xbox360 xWMA data"; break; case FMOD_SOUND_FORMAT_VORBIS: fmts = "Compressed Vorbis data"; break; } /* 合成说明字符串 */ allx = str_fmtA("%s (%s) - %uch / %ubits", type, fmts, chns, bits); if (allx == NULL) return (FALSE); str_cpyA(port->m_inf, allx); mem_free(allx); return (TRUE); }
bool UAudioCaptureMic::init() { this->close(); bool ok = UAudioCapture::init(); if(ok) { std::string::size_type loc; if(_fileName.size()) { loc = _fileName.find( ".mp3", 0 ); if( loc != std::string::npos ) { #ifdef BUILT_WITH_LAME _encodeToMp3 = true; #else _fileName.append(".wav"); UERROR("Cannot write to a mp3, saving to a wav instead (%s)", _fileName.c_str()); #endif } _fp = fopen(_fileName.c_str(), "wb"); } FMOD_RESULT result; FMOD_BOOL isRecording = false; result = UAudioSystem::isRecording(_driver, &isRecording); UASSERT_MSG(result==FMOD_OK, FMOD_ErrorString(result)); if(isRecording) { result = UAudioSystem::recordStop(_driver); UASSERT_MSG(result==FMOD_OK, FMOD_ErrorString(result)); } _dataLength = 0; _soundLength = 0; _lastRecordPos = 0; FMOD_CREATESOUNDEXINFO exinfo; memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); exinfo.numchannels = channels(); if(bytesPerSample() == 1) { exinfo.format = FMOD_SOUND_FORMAT_PCM8; } else if(bytesPerSample() == 2) { exinfo.format = FMOD_SOUND_FORMAT_PCM16; } else if(bytesPerSample() == 3) { exinfo.format = FMOD_SOUND_FORMAT_PCM24; } else if(bytesPerSample() == 4) { exinfo.format = FMOD_SOUND_FORMAT_PCM32; } exinfo.defaultfrequency = (int)fs(); exinfo.length = exinfo.defaultfrequency * bytesPerSample() * exinfo.numchannels * 2; // 2 -> pour deux secondes result = UAudioSystem::createSound(0, FMOD_2D | FMOD_SOFTWARE | FMOD_OPENUSER, &exinfo, &_sound); UASSERT_MSG(result==FMOD_OK, FMOD_ErrorString(result)); if(_fp) { int channels, bits; float rate; FMOD_Sound_GetFormat(_sound, 0, 0, &channels, &bits); FMOD_Sound_GetDefaults(_sound, &rate, 0, 0, 0); UWav::writeWavHeader(_fp, _dataLength, rate, channels, bits); // Write out the wav header. La longueur sera de 0 puisqu'elle est incunnue pour l'instant. } result = FMOD_Sound_GetLength(_sound, &_soundLength, FMOD_TIMEUNIT_PCM); UASSERT_MSG(result==FMOD_OK, FMOD_ErrorString(result)); } return ok; }
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; FMOD_BOOL isplaylist = 0; 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 = FMOD_System_GetVersion(system, &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 = FMOD_System_Init(system, 32, FMOD_INIT_NORMAL, 0); ERRCHECK(result); result = FMOD_System_CreateSound(system, "../media/playlist.m3u", FMOD_DEFAULT, 0, &playlist); ERRCHECK(result); result = FMOD_Sound_GetFormat(playlist, &soundtype, 0, 0, 0); ERRCHECK(result); isplaylist = (soundtype == FMOD_SOUND_TYPE_PLAYLIST); printf("===================================================================\n"); printf("PlayList Example. Copyright (c) Firelight Technologies 2004-2015.\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 = FMOD_Sound_GetTag(playlist, "FILE", count, &tag); ERRCHECK(result); sprintf(file, "../media/%s", (char *)tag.data); result = FMOD_System_CreateSound(system, file, FMOD_DEFAULT, 0, &sound); ERRCHECK(result); result = FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, sound, 0, &channel); ERRCHECK(result); FMOD_Sound_GetTag(playlist, "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 = FMOD_Sound_SetMode(sound, FMOD_LOOP_NORMAL); ERRCHECK(result); result = FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, sound, 0, &channel); ERRCHECK(result); } printf("\n"); /* Main loop. */ do { FMOD_BOOL isplaying = 0; if (channel && isplaylist) { /* When sound has finished playing, play the next sound in the playlist */ FMOD_Channel_IsPlaying(channel, &isplaying); if (!isplaying) { if (sound) { FMOD_Sound_Release(sound); sound = NULL; } result = FMOD_Sound_GetTag(playlist, "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 = FMOD_System_CreateSound(system, file, FMOD_DEFAULT, 0, &sound); ERRCHECK(result); result = FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, sound, 0, &channel); ERRCHECK(result); FMOD_Sound_GetTag(playlist, "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) { FMOD_Channel_Stop(channel); } break; } case ' ' : { if (channel) { FMOD_BOOL paused; FMOD_Channel_GetPaused(channel, &paused); FMOD_Channel_SetPaused(channel, !paused); } } } } FMOD_System_Update(system); { unsigned int ms = 0; unsigned int lenms = 0; FMOD_BOOL paused = 0; if (channel) { if (sound) { result = FMOD_Sound_GetLength(sound, &lenms, FMOD_TIMEUNIT_MS); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } } result = FMOD_Channel_GetPaused(channel, &paused); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } result = FMOD_Channel_GetPosition(channel, &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); } Sleep(10); } while (key != 27); printf("\n"); /* Shut down */ if (sound) { result = FMOD_Sound_Release(sound); ERRCHECK(result); } if (isplaylist) { result = FMOD_Sound_Release(playlist); ERRCHECK(result); } result = FMOD_System_Close(system); ERRCHECK(result); result = FMOD_System_Release(system); ERRCHECK(result); return 0; }
/* [ [DESCRIPTION] Writes out the contents of a record buffer to a file. [PARAMETERS] [RETURN_VALUE] void [REMARKS] ] */ void SaveToWav(FMOD_SOUND *sound) { FILE *fp; int channels, bits; float rate; void *ptr1, *ptr2; unsigned int lenbytes, len1, len2; FMOD_SOUND_FORMAT format; int count = 0; if (!sound) { return; } FMOD_Sound_GetFormat (sound, 0, &format, &channels, &bits); FMOD_Sound_GetDefaults(sound, &rate, 0, 0, 0); FMOD_Sound_GetLength (sound, &lenbytes, FMOD_TIMEUNIT_PCMBYTES); { /* WAV Structures */ typedef struct { signed char id[4]; int size; } RiffChunk; struct { RiffChunk chunk __PACKED; unsigned short wFormatTag __PACKED; /* format type */ unsigned short nChannels __PACKED; /* number of channels (i.e. mono, stereo...) */ unsigned int nSamplesPerSec __PACKED; /* sample rate */ unsigned int nAvgBytesPerSec __PACKED; /* for buffer estimation */ unsigned short nBlockAlign __PACKED; /* block size of data */ unsigned short wBitsPerSample __PACKED; /* number of bits per sample of mono data */ } __PACKED FmtChunk = { {{'f','m','t',' '}, sizeof(FmtChunk) - sizeof(RiffChunk) }, 1, channels, (int)rate, (int)rate * channels * bits / 8, 1 * channels * bits / 8, bits }; if (format == FMOD_SOUND_FORMAT_PCMFLOAT) { FmtChunk.wFormatTag = 3; } struct { RiffChunk chunk; } DataChunk = { {{'d','a','t','a'}, lenbytes } }; struct { RiffChunk chunk; signed char rifftype[4]; } WavHeader = { {{'R','I','F','F'}, sizeof(FmtChunk) + sizeof(RiffChunk) + lenbytes }, {'W','A','V','E'} }; #ifdef __BIG_ENDIAN__ /* Do some endian swapping */ FmtChunk.chunk.size = SWAPENDIAN_DWORD(FmtChunk.chunk.size); FmtChunk.wFormatTag = SWAPENDIAN_WORD(FmtChunk.wFormatTag); FmtChunk.nChannels = SWAPENDIAN_WORD(FmtChunk.nChannels); FmtChunk.nSamplesPerSec = SWAPENDIAN_DWORD(FmtChunk.nSamplesPerSec); FmtChunk.nAvgBytesPerSec = SWAPENDIAN_DWORD(FmtChunk.nAvgBytesPerSec); FmtChunk.nBlockAlign = SWAPENDIAN_WORD(FmtChunk.nBlockAlign); FmtChunk.wBitsPerSample = SWAPENDIAN_WORD(FmtChunk.wBitsPerSample); DataChunk.chunk.size = SWAPENDIAN_DWORD(DataChunk.chunk.size); WavHeader.chunk.size = SWAPENDIAN_DWORD(WavHeader.chunk.size); #endif fp = fopen("record.wav", "wb"); /* Write out the WAV header. */ fwrite(&WavHeader, sizeof(WavHeader), 1, fp); fwrite(&FmtChunk, sizeof(FmtChunk), 1, fp); fwrite(&DataChunk, sizeof(DataChunk), 1, fp); /* Lock the sound to get access to the raw data. */ FMOD_Sound_Lock(sound, 0, lenbytes, &ptr1, &ptr2, &len1, &len2); #ifdef __BIG_ENDIAN__ /* Write it to disk. */ if (format == FMOD_SOUND_FORMAT_PCM16) { signed short *wptr = (signed short *)ptr1; for (count = 0; count < len1 >> 1; count++) { wptr[count] = SWAPENDIAN_WORD(wptr[count]); } } else if (format == FMOD_SOUND_FORMAT_PCMFLOAT) { float *fptr = (float *)ptr1; for (count = 0; count < len1 >> 2; count++) { SWAPENDIAN_FLOAT(fptr[count]); } } #endif fwrite(ptr1, len1, 1, fp); /* Unlock the sound to allow FMOD to use it again. */ FMOD_Sound_Unlock(sound, ptr1, ptr2, len1, len2); fclose(fp); } }
int main(int argc, char *argv[]) { FMOD_SYSTEM *system; FMOD_SOUND *sound; FMOD_CHANNEL *channel = 0; FMOD_RESULT result; int key; FMOD_CREATESOUNDEXINFO createsoundexinfo; unsigned int version, decodesound_lengthbytes = 0; int decodesound_channels; float decodesound_rate; /* Create a System object and initialize. */ result = FMOD_System_Create(&system); ERRCHECK(result); result = FMOD_System_GetVersion(system, &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 = FMOD_System_Init(system, 32, FMOD_INIT_NORMAL, 0); ERRCHECK(result); InitializeCriticalSection(&decodecrit); /* First create the 'decoder sound'. Note it is a stream that does not initially read any data, because FMOD_OPENONLY has been specified. We could use createSound instead of createStream but that would allocate memory for the whole sound which is a waste. */ result = FMOD_System_CreateStream(system, "../media/wave.mp3", FMOD_OPENONLY | FMOD_LOOP_NORMAL | FMOD_LOWMEM | FMOD_CREATESTREAM, 0, &decodesound); ERRCHECK(result); result = FMOD_Sound_GetLength(decodesound, &decodesound_lengthbytes, FMOD_TIMEUNIT_PCMBYTES); ERRCHECK(result); result = FMOD_Sound_GetFormat(decodesound, 0, 0, &decodesound_channels, 0); ERRCHECK(result); result = FMOD_Sound_GetDefaults(decodesound, &decodesound_rate, 0, 0, 0); ERRCHECK(result); /* Now create a user created PCM stream that we will feed data into, and play. */ memset(&createsoundexinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); createsoundexinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); /* required. */ createsoundexinfo.decodebuffersize = 44100; /* Chunk size of stream update in samples. This will be the amount of data passed to the user callback. */ createsoundexinfo.numchannels = decodesound_channels; /* Number of channels in the sound. */ createsoundexinfo.length = decodesound_lengthbytes; /* Length of PCM data in bytes of whole song. -1 = infinite. */ createsoundexinfo.defaultfrequency = (int)decodesound_rate; /* Default playback rate of sound. */ createsoundexinfo.format = FMOD_SOUND_FORMAT_PCM16; /* Data format of sound. */ createsoundexinfo.pcmreadcallback = pcmreadcallback; /* User callback for reading. */ createsoundexinfo.pcmsetposcallback = pcmsetposcallback; /* User callback for seeking. */ result = FMOD_System_CreateStream(system, 0, FMOD_2D | FMOD_OPENUSER | FMOD_LOOP_NORMAL, &createsoundexinfo, &sound); ERRCHECK(result); printf("============================================================================\n"); printf("Manual Decode example. Copyright (c) Firelight Technologies 2004-2011.\n"); printf("============================================================================\n"); printf("Sound played here decoded in realtime by the user with a 'decoder sound' \n"); printf("The mp3 is created as a stream opened with FMOD_OPENONLY. This is the \n"); printf("'decoder sound'. The playback sound is a 16bit PCM FMOD_OPENUSER created \n"); printf("sound with a pcm read callback. When the callback happens, we call readData\n"); printf("on the decoder sound and use the pcmreadcallback data pointer as the parameter.\n"); printf("============================================================================\n"); printf("\n"); printf("Press space to pause, Esc to quit\n"); printf("Press '<' to rewind 1 second.\n"); printf("Press '>' to fast forward 1 second.\n"); printf("\n"); /* Play the sound. */ result = FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, sound, 0, &channel); ERRCHECK(result); /* Main loop. */ do { if (_kbhit()) { key = _getch(); switch (key) { case ' ' : { int paused; FMOD_Channel_GetPaused(channel, &paused); FMOD_Channel_SetPaused(channel, !paused); break; } case '<' : { unsigned int position; FMOD_Channel_GetPosition(channel, &position, FMOD_TIMEUNIT_MS); if (position >= 1000) { position -= 1000; } FMOD_Channel_SetPosition(channel, position, FMOD_TIMEUNIT_MS); break; } case '>' : { unsigned int position; FMOD_Channel_GetPosition(channel, &position, FMOD_TIMEUNIT_MS); position += 1000; FMOD_Channel_SetPosition(channel, position, FMOD_TIMEUNIT_MS); break; } } } FMOD_System_Update(system); if (channel) { unsigned int ms; unsigned int lenms; int playing; int paused; FMOD_Channel_IsPlaying(channel, &playing); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } result = FMOD_Channel_GetPaused(channel, &paused); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } result = FMOD_Channel_GetPosition(channel, &ms, FMOD_TIMEUNIT_MS); if ((result != FMOD_OK) && (result != FMOD_ERR_INVALID_HANDLE) && (result != FMOD_ERR_CHANNEL_STOLEN)) { ERRCHECK(result); } result = FMOD_Sound_GetLength(sound, &lenms, 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\r", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, lenms / 1000 / 60, lenms / 1000 % 60, lenms / 10 % 100, paused ? "Paused " : playing ? "Playing" : "Stopped"); } Sleep(20); } while (key != 27); printf("\n"); EnterCriticalSection(&decodecrit); { /* Remove the sound - wait! it might be still in use! Instead of releasing the decode sound first we could release it last, but this protection is here to make the issue obvious. */ result = FMOD_Sound_Release(decodesound); ERRCHECK(result); decodesound = 0; /* This will make the read callback fail from now on. */ } LeaveCriticalSection(&decodecrit); /* Shut down */ result = FMOD_Sound_Release(sound); ERRCHECK(result); result = FMOD_System_Close(system); ERRCHECK(result); result = FMOD_System_Release(system); ERRCHECK(result); DeleteCriticalSection(&decodecrit); return 0; }
float JiwokFMODWrapper::GetBPM(const char *filename) { FMOD_SYSTEM *system; FMOD_SOUND *sound; FMOD_RESULT result; unsigned int version; result = FMOD_System_Create(&system); ERRCHECK(result); result = FMOD_System_GetVersion(system, &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 = FMOD_System_Init(system, 1, FMOD_INIT_NORMAL, 0); ERRCHECK(result); result = FMOD_System_CreateStream(system,filename, FMOD_OPENONLY | FMOD_ACCURATETIME, 0, &sound); // ERRCHECK(result); unsigned int length = 0; int channels = 0, bits = 0; float frequency = 0; float volume = 0, pan = 0; int priority = 0; FMOD_SOUND_TYPE stype; FMOD_SOUND_FORMAT format; result = FMOD_Sound_GetLength(sound, &length, FMOD_TIMEUNIT_PCMBYTES); ERRCHECK(result); result = FMOD_Sound_GetDefaults(sound, &frequency, &volume, &pan, &priority); ERRCHECK(result); result = FMOD_Sound_GetFormat(sound, &stype, &format, &channels, &bits); ERRCHECK(result); printf("result is %d",result); soundtouch::BPMDetect *bpm = new soundtouch::BPMDetect(channels,frequency); //void *data; //unsigned int read; unsigned int bytesread; #define CHUNKSIZE 32768 //4096 // #define CHUNKSIZE 4096 bytesread = 0; soundtouch::SAMPLETYPE* samples = new soundtouch::SAMPLETYPE[CHUNKSIZE]; int sbytes = bits / 8; const unsigned int NUMSAMPLES = CHUNKSIZE; unsigned int bytes = NUMSAMPLES * sbytes; unsigned int readbytes = 0; do { readbytes = 0; if(sbytes == 2) { long int data[32768]; result = FMOD_Sound_ReadData(sound, data, bytes, &readbytes ); if(!result == FMOD_OK) break; for ( unsigned int i = 0; i < readbytes/sbytes; ++i ) samples[i] = (float) data[i] / 32768; } else if(sbytes == 1) { long int data[32768]; result = FMOD_Sound_ReadData(sound, data, bytes, &readbytes ); if(!result == FMOD_OK) break; for ( unsigned int i = 0; i < (readbytes); ++i ) samples[i] = (float) data[i] / 128; } bpm->inputSamples(samples, (readbytes /sbytes)/ channels ); bytesread += readbytes; } while (result == FMOD_OK && readbytes == CHUNKSIZE*2); result = FMOD_Sound_Release(sound); ERRCHECK(result); result = FMOD_System_Close(system); ERRCHECK(result); result = FMOD_System_Release(system); ERRCHECK(result); float bpmg = bpm->getBpm(); float bpm1 = bpmg; if ( bpmg < 1 ) return 0.; while ( bpmg > 190 ) bpmg /= 2.; while ( bpmg < 50 ) bpmg *= 2.; printf("bpmg bpmg is %f bpm %f",bpmg,bpm1); return bpmg; }