0
0

Okay after a while of playing around I get it managed to record realtime to harddisk using fmod. But there are still a few Issues in my test code. The first problem is, that Wavelab tell me that the Waveheader isn’t correct when opening one of my recorded files. Anyway it still opens the file, but that’s no good start 😉

The second problem is that there are cracks in the recorded file. I thought maybe Setting down the Main Thread Priority or Saving the buffer more frequently would fix the problem, but it didn’t helped.

I was really happy, if someone of you take a look at my sample source.

[code:3176qwxq]#include <stdio.h>

include <stdlib.h>

include <conio.h>

include <windows.h>

define __PACKED /dummy/

include "../../api/inc/fmod.h"

include "../../api/inc/fmod_errors.h" /* optional */

define RECORDRATE 44100

define RECORDLEN (RECORDRATE * 5) /* 5 seconds at RECORDRATE khz */

struct STR_WAVEHEADER
{
BYTE bChunkName[4];
DWORD dwChunkLength;
BYTE bRIFFType[4];
};

struct STR_WAVEFORMATHEADER
{
BYTE bChunkName[4];
DWORD dwChunkLength;
USHORT iFormatType;
USHORT iChannelCount;
DWORD dwSampleRate;
DWORD dwBytesPerSecond;
USHORT iBytesPerSample;
USHORT iBitsPerSample;
};

struct STR_WAVEDATAHEADER
{
BYTE bChunkName[4];
DWORD dwChunkLength;
};

void WriteWaveHeader(FILE* pFile, DWORD dwSampleRate, USHORT dwResolution, USHORT iChannelCount, DWORD dwDataSize)
{
STR_WAVEHEADER wavheader;
STR_WAVEFORMATHEADER wavfmtheader;
STR_WAVEDATAHEADER wavdataheader;

// Wave Header
memcpy(wavheader.bChunkName, &quot;RIFF&quot;, 4);
wavheader.dwChunkLength = dwDataSize + sizeof(STR_WAVEFORMATHEADER) + 
    sizeof(STR_WAVEDATAHEADER);
memcpy(wavheader.bRIFFType, &quot;WAVE&quot;, 4);

// Wave Format header
memcpy(wavfmtheader.bChunkName, &quot;fmt &quot;, 4);
wavfmtheader.dwChunkLength = sizeof(STR_WAVEFORMATHEADER) - sizeof(wavfmtheader.bChunkName)
    - sizeof(wavfmtheader.dwChunkLength);
wavfmtheader.iFormatType = iChannelCount==1 ? 0 : 1; // 0=Mono, 1=Stereo
wavfmtheader.iChannelCount = iChannelCount;
wavfmtheader.dwSampleRate = dwSampleRate;
wavfmtheader.dwBytesPerSecond = dwResolution/8 * iChannelCount * dwSampleRate;
wavfmtheader.iBytesPerSample = dwResolution/8 * iChannelCount;
wavfmtheader.iBitsPerSample = dwResolution;

// Wave Data Header
memcpy(wavdataheader.bChunkName, &quot;data&quot;, 4);
wavdataheader.dwChunkLength = dwDataSize;

fwrite(&amp;wavheader, sizeof(STR_WAVEHEADER), 1, pFile);
fwrite(&amp;wavfmtheader, sizeof(STR_WAVEFORMATHEADER), 1, pFile);
fwrite(&amp;wavdataheader, sizeof(STR_WAVEDATAHEADER), 1, pFile);

}

DWORD WriteToWave(FSOUND_SAMPLE* pSample, FILE* pFile, DWORD dwBufferSampleCount, int &iLastPos, DWORD dwSampleRate, int iChannels, USHORT iResolution)
{
// Safe Buffer to file
BYTE* pData1 = NULL;
BYTE* pData2 = NULL;
UINT dwLen1 = 0;
UINT dwLen2 = 0;
DWORD dwDataSize = 0;

BYTE bSampleSize = iChannels * (iResolution/8);

int iPos = FSOUND_Record_GetPosition() * bSampleSize;
int iRange = 0;
if (iPos&lt;iLastPos)
{
    // Puffer hat sich überschlagen
    iRange = (dwBufferSampleCount*bSampleSize)-iLastPos;
    printf(&quot;\n%i&quot;, iRange);

    FSOUND_Sample_Lock(pSample, iLastPos, iRange, (void**)&amp;pData1, (void**)&amp;pData2, &amp;dwLen1, &amp;dwLen2);
    fwrite(pData1, 1, dwLen1, pFile);
    dwDataSize+=dwLen1;
    FSOUND_Sample_Unlock(pSample, (void*)pData1, (void*)pData2, dwLen1, dwLen2);

    iLastPos = 0;
}
iRange = iPos-iLastPos;
printf(&quot;\n%i&quot;, iRange);

FSOUND_Sample_Lock(pSample, iLastPos, iRange, (void**)&amp;pData1, (void**)&amp;pData2, &amp;dwLen1, &amp;dwLen2);
fwrite(pData1, 1, dwLen1, pFile);
dwDataSize+=dwLen1;
FSOUND_Sample_Unlock(pSample, (void*)pData1, (void*)pData2, dwLen1, dwLen2);

iLastPos = iPos;

return dwDataSize;

}

int main(int argc, char *argv[])
{
FSOUND_SAMPLE *samp1;
signed char key;
int driver, i, channel, originalfreq;

if (FSOUND_GetVersion() &lt; FMOD_VERSION)
{
    printf(&quot;Error : You are using the wrong DLL version!  You should be using FMOD %.02f\n&quot;, FMOD_VERSION);
    return 0;
}

FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND);
FSOUND_SetDriver(0);
FSOUND_SetMixer(FSOUND_MIXER_QUALITY_AUTODETECT);
if (!FSOUND_Init(44100, 64, FSOUND_INIT_ACCURATEVULEVELS))
{
    printf(&quot;Error!\n&quot;);
    printf(&quot;%s\n&quot;, FMOD_ErrorString(FSOUND_GetError()));
    return 0;
}
FSOUND_Record_SetDriver(0);

samp1 = FSOUND_Sample_Alloc(FSOUND_UNMANAGED, RECORDLEN, FSOUND_STEREO | FSOUND_16BITS , RECORDRATE, 255, 128, 255);

printf(&quot;\n&quot;);
printf(&quot;=========================================================================\n&quot;);
printf(&quot;Press a key to start recording 5 seconds worth of data\n&quot;);
printf(&quot;=========================================================================\n&quot;);

getch();

if (!FSOUND_Record_StartSample(samp1, true))    /* it will record into this sample for 5 seconds then stop */
{
    printf(&quot;Error!\n&quot;);
    printf(&quot;%s\n&quot;, FMOD_ErrorString(FSOUND_GetError()));

    FSOUND_Close();
    return 0;
}

FILE* pFile = fopen(&quot;C:\\output.wav&quot;, &quot;wb&quot;);

// Write Dummy Header with Data Size 0
WriteWaveHeader(pFile, 44100, 16, 2, 0);

DWORD dwOldTime = GetTickCount();
DWORD dwDataSize = 0;
int iLastPos = 0;
do
{
    Sleep(50);

    DWORD dwCurrentTime = GetTickCount();
    if (dwCurrentTime-1000&gt;dwOldTime)
    {
        dwDataSize += WriteToWave(samp1, pFile, RECORDLEN, iLastPos, 44100, 2, 16);
        dwOldTime = dwCurrentTime;
    }
} while (!kbhit());

dwDataSize += WriteToWave(samp1, pFile, RECORDLEN, iLastPos, 44100, 2, 16);

// Seek to start and Write Final header
fseek(pFile, 0, 0);
WriteWaveHeader(pFile, 44100, 16, 2, dwDataSize);

fclose(pFile);

FSOUND_Record_Stop();   /* it already stopped anyway */

FSOUND_Sample_Free(samp1);
FSOUND_Close();
return 0;

}[/code:3176qwxq]

Thanks in advance

  • You must to post comments
0
0

I’ve continued playing around with some Values and Settings and after a few Changes, the cracks seemed to gone. Not sure, that it’s perfect now, but it’s surley better than before. That are the changes:

  • Used FSOUND_OUTPUT_WINMM as Output Driver
  • Used FSOUND_MIXER_QUALITY_MMXP6 for the Mixer
  • Removed FSOUND_INIT_ACCURATEVULEVELS from the Init Flags
  • Set Sample Buffer Size to 60 Seconds.
  • Changed Saving Delay from 1 Second to 30 Seconds.
  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.