int main(int argc, char *argv[]) { FMOD_SYSTEM *system = 0; FMOD_SOUND *sound = 0; FMOD_RESULT result; FMOD_CREATESOUNDEXINFO exinfo; int key, recorddriver, numdrivers, count; unsigned int version; FILE *fp; unsigned int datalength = 0, soundlength; /* 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; } /* System initialization */ printf("---------------------------------------------------------\n"); printf("Select OUTPUT type\n"); printf("---------------------------------------------------------\n"); printf("1 : DirectSound\n"); printf("2 : Windows Multimedia WaveOut\n"); printf("3 : ASIO\n"); printf("---------------------------------------------------------\n"); printf("Press a corresponding number or ESC to quit\n"); do { key = _getch(); } while (key != 27 && key < '1' && key > '5'); switch (key) { case '1' : result = FMOD_System_SetOutput(system, FMOD_OUTPUTTYPE_DSOUND); break; case '2' : result = FMOD_System_SetOutput(system, FMOD_OUTPUTTYPE_WINMM); break; case '3' : result = FMOD_System_SetOutput(system, FMOD_OUTPUTTYPE_ASIO); break; default : return 1; } ERRCHECK(result); /* Enumerate record devices */ result = FMOD_System_GetRecordNumDrivers(system, &numdrivers); ERRCHECK(result); printf("---------------------------------------------------------\n"); printf("Choose a RECORD driver\n"); printf("---------------------------------------------------------\n"); for (count=0; count < numdrivers; count++) { char name[256]; result = FMOD_System_GetRecordDriverInfo(system, count, name, 256, 0); ERRCHECK(result); printf("%d : %s\n", count + 1, name); } printf("---------------------------------------------------------\n"); printf("Press a corresponding number or ESC to quit\n"); recorddriver = 0; do { key = _getch(); if (key == 27) { return 0; } recorddriver = key - '1'; } while (recorddriver < 0 || recorddriver >= numdrivers); printf("\n"); result = FMOD_System_Init(system, 32, FMOD_INIT_NORMAL, 0); ERRCHECK(result); memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); exinfo.numchannels = 2; exinfo.format = FMOD_SOUND_FORMAT_PCM16; exinfo.defaultfrequency = 44100; exinfo.length = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels * 2; result = FMOD_System_CreateSound(system, 0, FMOD_2D | FMOD_SOFTWARE | FMOD_OPENUSER, &exinfo, &sound); ERRCHECK(result); printf("========================================================================\n"); printf("Record to disk example. Copyright (c) Firelight Technologies 2004-2014.\n"); printf("========================================================================\n"); printf("\n"); printf("Press a key to start recording to record.wav\n"); printf("\n"); _getch(); result = FMOD_System_RecordStart(system, recorddriver, sound, TRUE); ERRCHECK(result); printf("Press 'Esc' to quit\n"); printf("\n"); fp = fopen("record.wav", "wb"); if (!fp) { printf("ERROR : could not open record.wav for writing.\n"); return 1; } /* Write out the wav header. As we don't know the length yet it will be 0. */ WriteWavHeader(fp, sound, datalength); result = FMOD_Sound_GetLength(sound, &soundlength, FMOD_TIMEUNIT_PCM); ERRCHECK(result); /* Main loop. */ do { static unsigned int lastrecordpos = 0; unsigned int recordpos = 0; if (_kbhit()) { key = _getch(); } FMOD_System_GetRecordPosition(system, recorddriver, &recordpos); ERRCHECK(result); if (recordpos != lastrecordpos) { void *ptr1, *ptr2; int blocklength; unsigned int len1, len2; blocklength = (int)recordpos - (int)lastrecordpos; if (blocklength < 0) { blocklength += soundlength; } /* Lock the sound to get access to the raw data. */ FMOD_Sound_Lock(sound, lastrecordpos * exinfo.numchannels * 2, blocklength * exinfo.numchannels * 2, &ptr1, &ptr2, &len1, &len2); /* * exinfo.numchannels * 2 = stereo 16bit. 1 sample = 4 bytes. */ /* Write it to disk. */ if (ptr1 && len1) { datalength += fwrite(ptr1, 1, len1, fp); } if (ptr2 && len2) { datalength += fwrite(ptr2, 1, len2, fp); } /* Unlock the sound to allow FMOD to use it again. */ FMOD_Sound_Unlock(sound, ptr1, ptr2, len1, len2); } lastrecordpos = recordpos; printf("%-23s. Record buffer pos = %6d : Record time = %02d:%02d\r", (timeGetTime() / 500) & 1 ? "Recording to record.wav" : "", recordpos, datalength / exinfo.defaultfrequency / exinfo.numchannels / 2 / 60, (datalength / exinfo.defaultfrequency / exinfo.numchannels / 2) % 60); FMOD_System_Update(system); Sleep(10); } while (key != 27); printf("\n"); /* Write back the wav header now that we know its length. */ WriteWavHeader(fp, sound, datalength); fclose(fp); /* Shut down */ result = FMOD_Sound_Release(sound); ERRCHECK(result); result = FMOD_System_Release(system); ERRCHECK(result); return 0; }
/********************************* Fonction RecordFichier Permet d'enregistrer un fichier WAV *********************************/ void UAudioCaptureMic::mainLoop() { if(!_sound) { UERROR("Recorder is not initialized."); this->kill(); return; } FMOD_RESULT result; void *ptr1 = 0, *ptr2 = 0; int blockLength; unsigned int len1 = 0, len2 = 0; unsigned int recordPos = 0; result = UAudioSystem::getRecordPosition(_driver, &recordPos); UASSERT_MSG(result==FMOD_OK, FMOD_ErrorString(result)); if (recordPos != _lastRecordPos) { blockLength = (int)recordPos - (int)_lastRecordPos; if (blockLength < 0) { blockLength += _soundLength; } // * exinfo.numchannels * 2 = stereo 16bit. 1 sample = 4 bytes. // Lock the sound to get access to the raw data. FMOD_Sound_Lock(_sound, _lastRecordPos * channels() * bytesPerSample(), blockLength * channels() * bytesPerSample(), &ptr1, &ptr2, &len1, &len2); { if (ptr1 && len1) // Write it to disk. { if(_fp) { //write to file _dataLength += fwrite(ptr1, 1, len1, _fp); } // push back in the frames buffer pushBackSamples(ptr1, len1); } if (ptr2 && len2) // Write it to disk. { if(_fp) { //write to file _dataLength += fwrite(ptr2, 1, len2, _fp); } // push back in the frames buffer pushBackSamples(ptr2, len2); } } //Unlock the sound to allow FMOD to use it again. FMOD_Sound_Unlock(_sound, ptr1, ptr2, len1, len2); _lastRecordPos = recordPos; } UAudioSystem::update(); uSleep(10); // If we are recording to a file, make sure to stop // when the maximum file size is reached if (_fp && _maxFileSize != 0 && int(_dataLength) + frameLength()*bytesPerSample() > _maxFileSize) { UWARN("Recording max memory reached (%d Mb)... stopped", _maxFileSize/1000000); this->kill(); } }
/* [ [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); } }
/* [ [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); } }