0
0

I’m having trouble getting a clean input from FMOD. I’ve tried a number of approaches to solve this over the last few days, but I can’t seem to get rid of this overlap in the buffer.

http://fileanchor.com/15949.jpg

Currently my code locks the sample data starting at position:-

[code:3l6t86j5]Rpos = FSOUND_Record_GetPosition() – length[/code:3l6t86j5]

length is the amount of data I want to lock. Shouldn’t starting at this point in the buffer, and locking ‘length’ bytes, not overlap the new data with the old data?

[code:3l6t86j5]FSOUND_Sample_Lock (Rec_Buffer, Rpos, length, @s_ptr1, @s_ptr2, @s_len1, @s_len2)[/code:3l6t86j5]

But the locked data still contains the newest recorded data AND a section of the oldest recorded data…

Is there any way to eliminate this completely??

Any help on this issue would be much appreciated. Thanks

  • You must to post comments
0
0

Also, can someone tell me why this crashes after a second or two?

[code:ju6qsvxe]’ Matthew Hart
‘ DNET4
‘ 02090201
‘ 10-01-06
OPTION EXPLICIT

INCLUDE ONCE "fmod.bi"

‘ FOR RECORD BUFFERS
CONST TOTALBUFFERS = 5 ‘ 6 buffers
CONST BUFFERSIZE = 2^11 ‘ 2048 samples
CONST BUFFERBYTES = BUFFERSIZE * 2 ‘ 4096 bytes
CONST FALSE = 0

‘ FOR FMOD
CONST SAMPLINGRATE = 44100

‘ FOR SAMPLE LOCK
DIM AS INTEGER PTR s_ptr1, s_ptr2
DIM AS INTEGER start, length
DIM AS UNSIGNED INTEGER s_len1, s_len2

‘ FOR BUFFERS
DIM AS INTEGER RecordBuf, WorkBuf, Buffer(TOTALBUFFERS)

‘ MISC
DIM AS INTEGER i, x, y, j

‘ INIT FMOD
IF( FSOUND_Init(44100, 32, 0) = FALSE ) THEN
PRINT "Can’t initialize FMOD"
END 1
END IF

‘ INIT ALL BUFFERS
FOR i = 0 TO TOTALBUFFERS
Buffer(i) = FSOUND_SAMPLE_Alloc (FSOUND_FREE, BUFFERSIZE, FSOUND_NORMAL, SAMPLINGRATE, 128, 0, 1)
NEXT i

SCREENRES 640,480,8,1

RecordBuf = 0
WorkBuf = 0

‘ Start recording into first buffer
FSOUND_Record_StartSample ( Buffer(RecordBuf), 0)

DO

' Wait for the buffer to fill
WHILE FSOUND_Record_GetPosition() < BUFFERSIZE: SLEEP 1: WEND

' Stop the recording
FSOUND_Record_Stop

' Start recording in the next buffer
RecordBuf = (RecordBuf + 1) MOD (TOTALBUFFERS + 1)
FSOUND_Record_StartSample ( Buffer(RecordBuf), 0)

' Lock WorkBuffer and grab all data
FSOUND_Sample_Lock (Buffer(WorkBuf), 0, BUFFERSIZE, @s_ptr1, @s_ptr2, @s_len1, @s_len2)

' Display data
SCREENLOCK
LINE (0,0)-(639,479),0,bf
PSET (-1,y),255
x = 0
y = 100
FOR i = 0 TO s_len1
    j = ((s_ptr1[i])*.00000002)+y
    LINE -(x,j),2
    x+=1
    IF x > 640 THEN x = 0:y += 100:PSET (-1,y),255
NEXT i
LOCATE 1,1:PRINT "Real-Time Audio Data Capture with N Buffers - Matthew Hart - DNET4 - 02090201"
SCREENUNLOCK

' Unlock WorkBuffer
FSOUND_Sample_UnLock (Buffer(WorkBuf), @s_ptr1, @s_ptr2, s_len1, s_len2)

' Set next WorkBuffer
WorkBuf = (WorkBuf + 1) MOD (TOTALBUFFERS + 1)

LOOP UNTIL MULTIKEY(1)

FSOUND_Close
END[/code:ju6qsvxe]

  • You must to post comments
0
0

Here is something that has come to my attention.

In the manual, it states that FSOUND_Record_GetPosition returns the amount of SAMPLES that have been recorded and placed into the buffer.

If my buffer is 2048 samples long. Then this function should never return a value larger than 2048.

BUT, this code keeps beeping.

[code:z3h92b60] WHILE FSOUND_Record_GetPosition() < BUFFERSIZE: WEND
length = FSOUND_Record_GetPosition()

IF length &gt; BUFFERSIZE THEN BEEP[/code:z3h92b60]
  • You must to post comments
0
0

I asked at the FreeBASIC forums incase it is due to the compiler.

[b:3qpfvc5c]
v1ctor (at freebasic.net) says:[/b:3qpfvc5c]
[quote:3qpfvc5c]FSOUND_Record_StartSample() or FSOUND_Record_Stop() are not releasing the handles used, Windows will run out of them in seconds (it’s much faster in Win9x).

I dunno if it’s some bug in FMOD or if something has to be realease by hand calling some FMOD function, i never used it for recording.[/quote:3qpfvc5c]

I noticed that the task manager shows the above code uses more and more memory every iteration. It crashes after about 20 loops.

Hope this helps.

  • You must to post comments
0
0

I understand you’re most likely very busy but, I’d really appreciate some help here…

  • You must to post comments
0
0

Thanks for the response 😀

I based my code on the C example. The olny difference is that my code uses multiple buffers to record into. When one is full, it stops recording that buffer, and then starts recording into the next, while it displays the contents of the full buffer.

[code:yznclume]OPTION EXPLICIT

INCLUDE ONCE "fmod.bi"

‘ FOR RECORD BUFFERS
CONST TOTALBUFFERS = 3 ‘ 6 buffers
CONST BUFFERSIZE = 2^11 ‘ 2048 samples
CONST BUFFERBYTES = BUFFERSIZE * 2 ‘ 4096 bytes
CONST FALSE = 0

‘ FOR FMOD
CONST SAMPLINGRATE = 44100

‘ FOR SAMPLE LOCK
DIM AS SHORT PTR s_ptr1, s_ptr2
DIM AS INTEGER start, length
DIM AS UNSIGNED INTEGER s_len1, s_len2

‘ FOR BUFFERS
DIM AS INTEGER RecordBuf, WorkBuf, Buffer(TOTALBUFFERS)

‘ MISC
DIM AS INTEGER i, x, y, j

‘ INIT FMOD
IF( FSOUND_Init(44100, 32, 0) = FALSE ) THEN
PRINT "Can’t initialize FMOD"
END 1
END IF

‘ INIT ALL BUFFERS
FOR i = 0 TO TOTALBUFFERS
Buffer(i) = FSOUND_SAMPLE_Alloc (FSOUND_FREE, BUFFERSIZE, FSOUND_NORMAL, SAMPLINGRATE, 255, 128, 255)
IF Buffer(i) = FALSE THEN
PRINT "Could not init buffer "; i
BEEP
SLEEP
END
END IF
NEXT i

‘ Set resolution
SCREENRES 640,480,8,1

” Display all available recording drivers
‘PRINT "Available Recording Drivers"
‘FOR i = 0 TO FSOUND_Record_GetNumDrivers() – 1
‘ PRINT i; ". Driver "; FSOUND_Record_GetDriverName(i)
‘NEXT i

‘INPUT "Choose Driver> ", i

” Set Recording Driver
‘FSOUND_Record_SetDriver(i)

RecordBuf = 0
WorkBuf = 0

‘ Start recording into first buffer
IF FSOUND_Record_StartSample ( Buffer(RecordBuf), 0) = FALSE THEN
PRINT "Could not start recording in buffer "; RecordBuf
BEEP
SLEEP
END
END IF

DO

' Wait for the buffer to fill
WHILE (FSOUND_Record_GetPosition()) &lt; BUFFERSIZE: WEND

' Stop the recording
FSOUND_Record_Stop()                                

' Start recording in the next buffer
RecordBuf = (RecordBuf + 1) MOD (TOTALBUFFERS + 1)
IF FSOUND_Record_StartSample ( Buffer(RecordBuf), 0) = FALSE THEN
    PRINT &quot;Could not start recording in buffer &quot;; RecordBuf
    BEEP
    SLEEP   
    END
END IF

' Lock WorkBuffer and grab all data
IF FSOUND_Sample_Lock (Buffer(WorkBuf), 0, BUFFERBYTES, @s_ptr1, @s_ptr2, @s_len1, @s_len2) &lt;&gt; FALSE THEN

    IF s_ptr1 THEN
        ' Display data
        SCREENLOCK
        LINE (0,0)-(639,479),0,bf
        PSET (-1,y),255
        x = 0
        y = 100
        FOR i = 0 TO (s_len1 SHR 1) - 1
            j = ((s_ptr1[i])*.002)+y
            LINE -(x,j),2
            x+=1
            IF x &gt; 640 THEN x = 0:y += 100: PSET (-1,y),255
        NEXT i
        LOCATE 1,1:PRINT &quot;Real-Time Audio Data Capture with N Buffers - Matthew Hart - DNET4 - 02090201&quot;
        PRINT &quot;Displaying buffer &quot;; WorkBuf
        SCREENUNLOCK
    ELSE
        PRINT &quot;s_ptr1 (&quot;; s_ptr1; &quot;) not valid!&quot;
        BEEP
        SLEEP
        END
    END IF

    ' Unlock WorkBuffer
    FSOUND_Sample_UnLock (Buffer(WorkBuf), @s_ptr1, @s_ptr2, s_len1, s_len2)
ELSE
    PRINT &quot;Could not lock buffer &quot;; WorkBuf
    BEEP
    SLEEP   
    END
END IF

' Set next WorkBuffer
WorkBuf = (WorkBuf + 1) MOD (TOTALBUFFERS + 1)

LOOP UNTIL MULTIKEY(1)

‘ Stop the recording
FSOUND_Record_Stop()

‘ Close FMOD
PRINT "Closing FMOD..."
FSOUND_Close
END[/code:yznclume]

I’m pretty certain if I did this in C, the same error would occur after a few cycles.

http://fileanchor.com/16037.jpg

I made the C example in FreeBASIC and it runs no problem. I have a feeling it has something to do with the memory regarding continuously calling FSOUND_Record_StartSample(…….)

  • You must to post comments
0
0

Regarding FSOUND_Record_GetPosition()

My buffer is 2048 samples

But FSOUND_Record_GetPosition() returns values such as:-

2646
2646
2646
3087
2205
2205

I read somewhere that the Record position is incremented in ‘blocks’, does this mean that it is supposed to exceed the actual sample size?

  • You must to post comments
0
0

If it helps at all. This is what the FMOD record example translates to in FreeBASIC.

This works perfectly!

[code:3qhfw8o7]OPTION EXPLICIT

INCLUDE ONCE "fmod.bi"

‘ FOR FMOD
CONST SAMPLINGRATE = 44100

‘ FOR RECORD BUFFERS
CONST BUFFERSIZE = SAMPLINGRATE * 20 ‘ 20 seconds
CONST FALSE = 0

‘ FOR BUFFER
DIM AS INTEGER Buffer

‘ FOR PLAYBACK
DIM AS INTEGER channel

‘ INIT FMOD
IF( FSOUND_Init(44100, 32, 0) = FALSE ) THEN
PRINT "Can’t initialize FMOD"
END 1
END IF

‘ INIT BUFFER
Buffer = FSOUND_SAMPLE_Alloc (FSOUND_FREE, BUFFERSIZE, FSOUND_NORMAL, SAMPLINGRATE, 255, 128, 255)
IF Buffer = FALSE THEN
PRINT "Could not init buffer!"
BEEP
SLEEP
END
END IF

‘ Set resolution
SCREENRES 640,480,8,1

PRINT "Press any key to start Recording!"
SLEEP

‘ Start recording into first buffer
IF FSOUND_Record_StartSample ( Buffer, 0) = FALSE THEN
PRINT "Could not start recording in buffer!"
BEEP
SLEEP
END
END IF

WHILE FSOUND_Record_GetPosition() < BUFFERSIZE
PRINT "Record Position = "; FSOUND_Record_GetPosition()
SLEEP 100
WEND

‘ Stop the recording
FSOUND_Record_Stop()

PRINT "Press any key to Play it back!"
SLEEP

‘ Play back the buffer
channel = FSOUND_PlaySound(FSOUND_FREE, buffer)

WHILE FSOUND_IsPlaying(channel)
PRINT "Playback Position = "; FSOUND_GetCurrentPosition(channel)
SLEEP 100
WEND

PRINT "Press a key to exit."
SLEEP

‘ Close FMOD
PRINT "Closing FMOD..."
FSOUND_Sample_Free(buffer)
FSOUND_Close
END[/code:3qhfw8o7]

Please note that in the code that crashes due to excessive memory usage, I’m not trying to play any sound. Only record and display it.

  • You must to post comments
0
0

I’ve recreated the problem in C. Hope this helps.

[code:2ml5amp4]
/*
RECORD.EXE
Copyright (c), Firelight Technologies Pty, Ltd, 2000-2004.

This example shows how to record data to a static sample, or record dynamically, and have
a dsp unit processing the result.
The reverb below is taken from /samples/fmod/fmod.c
*/

include <stdio.h>

include <stdlib.h>

if defined(WIN32) || defined(WATCOMC) || defined(_WIN32) || defined(WIN32)

#include &lt;conio.h&gt;
#include &lt;windows.h&gt;
#define __PACKED /*dummy*/

else

#include &quot;../../api/inc/wincompat.h&quot;
#include &lt;string.h&gt;
#define __PACKED __attribute__((packed)) /* gcc packed */

endif

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

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

define ENABLEREVERB TRUE

define RECORDRATE 44100

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

define OUTPUTRATE 44100

define REVERB_NUMTAPS 7

typedef struct
{
FSOUND_DSPUNIT Unit;
char *historybuff; /
storage space for tap history /
char *workarea; /
a place to hold 1 buffer worth of data (for reverb) /
int delayms; /
delay of reverb tab in milliseconds /
int volume; /
volume of reverb tab /
int pan; /
pan of reverb tab /
int historyoffset; /
running offset into history buffer /
int historylen; /
size of history buffer in SAMPLES */
} REVERBTAP;

/*
Reverb stuff
*/
REVERBTAP DSP_ReverbTap[REVERB_NUMTAPS];

/*
[
[DESCRIPTION]
Callback to mix in one reverb tap. It copies the buffer into its own history buffer also.

[PARAMETERS]
'originalbuffer'    Pointer to the original mixbuffer, not any buffers passed down 
                    through the dsp chain.  They are in newbuffer.
'newbuffer'         Pointer to buffer passed from previous DSP unit.
'length'            Length in SAMPLES of buffer being passed.
'param'             User parameter.  In this case it is a pointer to DSP_LowPassBuffer.

[RETURN_VALUE]
a pointer to the buffer that was passed in, with a tap mixed into it.

[REMARKS]

]
*/
void * F_CALLBACKAPI DSP_ReverbCallback(void *originalbuffer, void *newbuffer, int length, void *param)
{
int mixertype = FSOUND_GetMixer();
int count;
int bytesperoutputsample;
REVERBTAP *tap = (REVERBTAP *)param;
union sample
{
void *vptr;
signed int *dptr;
signed short *wptr;
float *fptr;
};

if (mixertype == FSOUND_MIXER_MMXP5 || mixertype == FSOUND_MIXER_MMXP6 || mixertype == FSOUND_MIXER_QUALITY_MMXP5 || mixertype == FSOUND_MIXER_QUALITY_MMXP6)
{
    bytesperoutputsample = 4;   // 16bit stereo
}
else
{
    bytesperoutputsample = 8;   // 32bit stereo
}

// reverb history buffer is a ringbuffer.  If the length makes the copy wrap, then split the copy 
// into end part, and start part.. 
if (tap-&gt;historyoffset + length &gt; tap-&gt;historylen)
{
    int taillen = tap-&gt;historylen - tap-&gt;historyoffset;
    int startlen = length - taillen;

    // mix a scaled version of history buffer into output
    FSOUND_DSP_MixBuffers(newbuffer, tap-&gt;historybuff + (tap-&gt;historyoffset &lt;&lt; 2), taillen, OUTPUTRATE, tap-&gt;volume, tap-&gt;pan, FSOUND_STEREO | FSOUND_16BITS);
    FSOUND_DSP_MixBuffers((char *)newbuffer+(taillen * bytesperoutputsample), tap-&gt;historybuff, startlen, OUTPUTRATE, tap-&gt;volume, tap-&gt;pan, FSOUND_STEREO | FSOUND_16BITS);

    // now copy input into reverb/history buffer 
    {
        signed short *dest;
        union sample src;

        dest = (signed short *)(tap-&gt;historybuff + (tap-&gt;historyoffset &lt;&lt; 2));
        src.vptr = newbuffer;

        for (count=0; count &lt; taillen * 2; count++)
        {
            int val;

            if (mixertype == FSOUND_MIXER_QUALITY_FPU)
            {
                val = (int)src.fptr[count];
            }
            else if (mixertype == FSOUND_MIXER_MMXP5 || mixertype == FSOUND_MIXER_MMXP6 || mixertype == FSOUND_MIXER_QUALITY_MMXP5 || mixertype == FSOUND_MIXER_QUALITY_MMXP6)
            {
                val = (int)src.wptr[count];
            }
            else
            {
                val = (int)src.dptr[count];
            }               

            val = (val &gt; 32767 ? 32767 : val &lt; -32768 ? -32768 : val);
            dest[count] = val;
        }  
    }
    {
        signed short *dest;
        union sample src;

        dest = (signed short *)tap-&gt;historybuff;    // always 16bit
        src.vptr = (char *)newbuffer + (taillen * bytesperoutputsample);

        for (count=0; count &lt; startlen * 2; count++)
        {
            int val;

            if (mixertype == FSOUND_MIXER_QUALITY_FPU)
            {
                val = (int)src.fptr[count];
            }
            else if (mixertype == FSOUND_MIXER_MMXP5 || mixertype == FSOUND_MIXER_MMXP6 || mixertype == FSOUND_MIXER_QUALITY_MMXP5 || mixertype == FSOUND_MIXER_QUALITY_MMXP6)
            {
                val = (int)src.wptr[count];
            }
            else
            {
                val = (int)src.dptr[count];
            }               

            val = (val &gt; 32767 ? 32767 : val &lt; -32768 ? -32768 : val);
            dest[count] = val;
        }  
    }

}
// no wrapping reverb buffer, just write dest
else
{
    // mix a scaled version of history buffer into output
    FSOUND_DSP_MixBuffers(newbuffer, tap-&gt;historybuff + (tap-&gt;historyoffset &lt;&lt; 2), length, OUTPUTRATE, tap-&gt;volume, tap-&gt;pan, FSOUND_STEREO | FSOUND_16BITS);

    // now copy input into reverb/history buffer 
    {
        signed short *dest;
        union sample src = { newbuffer };

        dest = (signed short *)(tap-&gt;historybuff + (tap-&gt;historyoffset &lt;&lt; 2));

        for (count=0; count &lt; length * 2; count++)
        {
            int val;

            if (mixertype == FSOUND_MIXER_QUALITY_FPU)
            {
                val = (int)src.fptr[count];
            }
            else if (mixertype == FSOUND_MIXER_MMXP5 || mixertype == FSOUND_MIXER_MMXP6 || mixertype == FSOUND_MIXER_QUALITY_MMXP5 || mixertype == FSOUND_MIXER_QUALITY_MMXP6)
            {
                val = (int)src.wptr[count];
            }
            else
            {
                val = (int)src.dptr[count];
            }               
            val = (val &gt; 32767 ? 32767 : val &lt; -32768 ? -32768 : val);
            dest[count] = val;
        }  
    }
}


tap-&gt;historyoffset += length;
if (tap-&gt;historyoffset &gt;= tap-&gt;historylen) 
{
    tap-&gt;historyoffset -= tap-&gt;historylen;
}

// reverb history has been mixed into new buffer, so return it.
return newbuffer;

}

/*
[
[DESCRIPTION]
Initializes reverb, creates DSP units and history buffers for all reverb tabs

[PARAMETERS]

[RETURN_VALUE]
void

[REMARKS]

]
/
void SetupReverb()
{
/

REVERB SETUP
/
/
something to fiddle with. /
int delay[REVERB_NUMTAPS] = { 131, 149, 173, 211, 281, 401, 457}; /
prime numbers make it sound good! */
int volume[REVERB_NUMTAPS] = { 120, 100, 95, 90, 80, 60, 50};
int pan[REVERB_NUMTAPS] = { 100, 128, 128, 152, 128, 100, 152};
int count;

for (count=0; count&lt; REVERB_NUMTAPS; count++)
{
    DSP_ReverbTap[count].delayms        = delay[count]; 
    DSP_ReverbTap[count].volume         = volume[count];
    DSP_ReverbTap[count].pan            = pan[count];
    DSP_ReverbTap[count].historyoffset  = 0;
    DSP_ReverbTap[count].historylen     = (DSP_ReverbTap[count].delayms * 44100 / 1000);
    if (DSP_ReverbTap[count].historylen &lt; FSOUND_DSP_GetBufferLength())
        DSP_ReverbTap[count].historylen = FSOUND_DSP_GetBufferLength(); /* just in case our calc is not the same. */

    DSP_ReverbTap[count].historybuff    = (char *)calloc(DSP_ReverbTap[count].historylen, 4);   /* * 4 is for 16bit stereo (mmx only) */
    DSP_ReverbTap[count].workarea       = NULL;
    DSP_ReverbTap[count].Unit           = FSOUND_DSP_Create(&amp;DSP_ReverbCallback, FSOUND_DSP_DEFAULTPRIORITY_USER+20+(count*2), (void *)&amp;DSP_ReverbTap[count]);

    FSOUND_DSP_SetActive(DSP_ReverbTap[count].Unit, TRUE);
}

}

/*
[
[DESCRIPTION]
Shuts down and frees anything to do with the software reverb

[PARAMETERS]

[RETURN_VALUE]
void

[REMARKS]

]
*/
void CloseReverb()
{
int count;

for (count=0; count&lt;REVERB_NUMTAPS; count++)
{
    FSOUND_DSP_Free(DSP_ReverbTap[count].Unit); 
    DSP_ReverbTap[count].Unit = NULL;

    free(DSP_ReverbTap[count].historybuff);     
    DSP_ReverbTap[count].historybuff = NULL;

    free(DSP_ReverbTap[count].workarea);        
    DSP_ReverbTap[count].workarea = NULL;
}

}

/*
[
[DESCRIPTION]
Writes out the contents of a record buffer to a file.

[PARAMETERS]

[RETURN_VALUE]
void

[REMARKS]

]
*/
void SaveToWav(FSOUND_SAMPLE *samp)
{
FILE *fp;
int lenbytes, channels, bits, rate;
void *ptr1, *ptr2;
unsigned int len1, len2;
unsigned int mode;

if (!samp)
{
    return;
}

mode     = FSOUND_Sample_GetMode(samp);
bits     = (mode &amp; FSOUND_16BITS) ? 16 : 8;
channels = (mode &amp; FSOUND_STEREO) ? 2  : 1;
lenbytes = FSOUND_Sample_GetLength(samp) * channels * bits / 8;
FSOUND_Sample_GetDefaults(samp, &amp;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, rate, rate * channels * bits / 8, 1 * channels * bits / 8, bits } __PACKED;

    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(&quot;record.wav&quot;, &quot;wb&quot;);

    /*
        Write out the WAV header.
    */
    fwrite(&amp;WavHeader, sizeof(WavHeader), 1, fp);
    fwrite(&amp;FmtChunk, sizeof(FmtChunk), 1, fp);
    fwrite(&amp;DataChunk, sizeof(DataChunk), 1, fp);

    /*
        Lock the sample to get acces to the data
    */
    FSOUND_Sample_Lock(samp, 0, lenbytes, &amp;ptr1, &amp;ptr2, &amp;len1, &amp;len2);

    fwrite(ptr1, len1, 1, fp);

    FSOUND_Sample_Unlock(samp, ptr1, ptr2, len1, len2);

    fclose(fp);
}

}

/*
[
[DESCRIPTION]
Main example function

[PARAMETERS]
'argc'      Number of arguments passed on the command line
'argv'      Pointer to an array of arguments.

[RETURN_VALUE]
void

[REMARKS]

]
*/
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;
}

/*
    SELECT OUTPUT METHOD
*/

printf(&quot;---------------------------------------------------------\n&quot;);    
printf(&quot;Output Type\n&quot;);  
printf(&quot;---------------------------------------------------------\n&quot;);    

if defined(WIN32) || defined(_WIN64) || defined(CYGWIN32) || defined(WATCOMC)

printf(&quot;1 - Direct Sound\n&quot;);
printf(&quot;2 - Windows Multimedia Waveout\n&quot;);
printf(&quot;3 - NoSound\n&quot;);

elif defined(linux)

printf(&quot;1 - OSS - Open Sound System\n&quot;);
printf(&quot;2 - ESD - Elightment Sound Daemon\n&quot;);
printf(&quot;3 - ALSA 0.9 - Advanced Linux Sound Architecture\n&quot;);   

endif

printf(&quot;---------------------------------------------------------\n&quot;);    /* print driver names */
printf(&quot;Press a corresponding number or ESC to quit\n&quot;);

do
{
    key = getch();
} while (key != 27 &amp;&amp; key &lt; '1' &amp;&amp; key &gt; '4');

switch (key)
{

if defined(WIN32) || defined(_WIN64) || defined(CYGWIN32) || defined(WATCOMC)

    case '1' :  FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND);
                break;
    case '2' :  FSOUND_SetOutput(FSOUND_OUTPUT_WINMM);
                break;
    case '3' :  FSOUND_SetOutput(FSOUND_OUTPUT_NOSOUND);
                break;

elif defined(linux)

    case '1' :  FSOUND_SetOutput(FSOUND_OUTPUT_OSS);
                break;
    case '2' :  FSOUND_SetOutput(FSOUND_OUTPUT_ESD);
                break;
    case '3' :  FSOUND_SetOutput(FSOUND_OUTPUT_ALSA);
                break;

endif

    default :   return 0;
}

/*
    SELECT OUTPUT DRIVER
*/

/* The following list are the drivers for the output method selected above. */
printf(&quot;---------------------------------------------------------\n&quot;);    
switch (FSOUND_GetOutput())
{
    case FSOUND_OUTPUT_NOSOUND:    printf(&quot;NoSound&quot;); break;
    case FSOUND_OUTPUT_WINMM:      printf(&quot;Windows Multimedia Waveout&quot;); break;
    case FSOUND_OUTPUT_DSOUND:     printf(&quot;Direct Sound&quot;); break;
    case FSOUND_OUTPUT_OSS:        printf(&quot;Open Sound System&quot;); break;
    case FSOUND_OUTPUT_ESD:        printf(&quot;Enlightment Sound Daemon&quot;); break;
    case FSOUND_OUTPUT_ALSA:       printf(&quot;ALSA&quot;); break;       
};
printf(&quot; Driver list\n&quot;); 
printf(&quot;---------------------------------------------------------\n&quot;);    

for (i=0; i &lt; FSOUND_GetNumDrivers(); i++) 
{
    printf(&quot;%d - %s\n&quot;, i+1, FSOUND_GetDriverName(i));    /* print driver names */
}
printf(&quot;---------------------------------------------------------\n&quot;);    /* print driver names */
printf(&quot;Press a corresponding number or ESC to quit\n&quot;);

do
{
    key = getch();
    if (key == 27) 
    {
        FSOUND_Close();
        return 0;
    }
    driver = key - '1';
} while (driver &lt; 0 || driver &gt;= FSOUND_GetNumDrivers());

FSOUND_SetDriver(driver);                   /* Select sound card (0 = default) */

/*
    SELECT MIXER
*/

FSOUND_SetMixer(FSOUND_MIXER_QUALITY_AUTODETECT);

/*
    INITIALIZE
*/
if (!FSOUND_Init(OUTPUTRATE, 64, FSOUND_INIT_ACCURATEVULEVELS))
{
    printf(&quot;Error!\n&quot;);
    printf(&quot;%s\n&quot;, FMOD_ErrorString(FSOUND_GetError()));
    return 0;
}


/*
    SELECT INPUT DRIVER (can be done before or after init)
*/

/* The following list are the drivers for the output method selected above. */
printf(&quot;---------------------------------------------------------\n&quot;);    
switch (FSOUND_GetOutput())
{
    case FSOUND_OUTPUT_NOSOUND:    printf(&quot;NoSound&quot;); break;
    case FSOUND_OUTPUT_WINMM:      printf(&quot;Windows Multimedia Waveout&quot;); break;
    case FSOUND_OUTPUT_DSOUND:     printf(&quot;Direct Sound&quot;); break;
    case FSOUND_OUTPUT_OSS:        printf(&quot;Open Sound System&quot;); break;
    case FSOUND_OUTPUT_ESD:        printf(&quot;Enlightment Sound Daemon&quot;); break;
    case FSOUND_OUTPUT_ALSA:       printf(&quot;ALSA&quot;); break;       
};
printf(&quot; Recording device driver list\n&quot;);    
printf(&quot;---------------------------------------------------------\n&quot;);    

for (i=0; i &lt; FSOUND_Record_GetNumDrivers(); i++) 
{
    printf(&quot;%d - %s\n&quot;, i+1, FSOUND_Record_GetDriverName(i)); /* print driver names */
}
printf(&quot;---------------------------------------------------------\n&quot;);    /* print driver names */
printf(&quot;Press a corresponding number or ESC to quit\n&quot;);

do
{
    key = getch();
    if (key == 27) 
        return 0;
    driver = key - '1';
} while (driver &lt; 0 || driver &gt;= FSOUND_Record_GetNumDrivers());

if (!FSOUND_Record_SetDriver(driver))   /* Select input sound card (0 = default) */
{
    printf(&quot;Error!\n&quot;);
    printf(&quot;%s\n&quot;, FMOD_ErrorString(FSOUND_GetError()));
    FSOUND_Close();
    return 0;
}

/*
    DISPLAY HELP
*/

printf(&quot;FSOUND Output Method : &quot;);
switch (FSOUND_GetOutput())
{
    case FSOUND_OUTPUT_NOSOUND:    printf(&quot;FSOUND_OUTPUT_NOSOUND\n&quot;); break;
    case FSOUND_OUTPUT_WINMM:      printf(&quot;FSOUND_OUTPUT_WINMM\n&quot;); break;
    case FSOUND_OUTPUT_DSOUND:     printf(&quot;FSOUND_OUTPUT_DSOUND\n&quot;); break;
    case FSOUND_OUTPUT_OSS:        printf(&quot;FSOUND_OUTPUT_OSS\n&quot;); break;
    case FSOUND_OUTPUT_ESD:        printf(&quot;FSOUND_OUTPUT_ESD\n&quot;); break;
    case FSOUND_OUTPUT_ALSA:       printf(&quot;FSOUND_OUTPUT_ALSA\n&quot;); break;       
};

printf(&quot;FSOUND Mixer         : &quot;);
switch (FSOUND_GetMixer())
{
    case FSOUND_MIXER_BLENDMODE:    printf(&quot;FSOUND_MIXER_BLENDMODE\n&quot;); break;
    case FSOUND_MIXER_MMXP5:        printf(&quot;FSOUND_MIXER_MMXP5\n&quot;); break;
    case FSOUND_MIXER_MMXP6:        printf(&quot;FSOUND_MIXER_MMXP6\n&quot;); break;
    case FSOUND_MIXER_QUALITY_FPU:  printf(&quot;FSOUND_MIXER_QUALITY_FPU\n&quot;); break;
    case FSOUND_MIXER_QUALITY_MMXP5:printf(&quot;FSOUND_MIXER_QUALITY_MMXP5\n&quot;); break;
    case FSOUND_MIXER_QUALITY_MMXP6:printf(&quot;FSOUND_MIXER_QUALITY_MMXP6\n&quot;); break;
};
printf(&quot;FSOUND Driver        : %s\n&quot;, FSOUND_GetDriverName(FSOUND_GetDriver()));
printf(&quot;FSOUND Record Driver : %s\n&quot;, FSOUND_Record_GetDriverName(FSOUND_Record_GetDriver()));

/*
    RECORD INTO A STATIC SAMPLE
*/

/*
    Create a sample to record into
*/
if (FSOUND_GetOutput() == FSOUND_OUTPUT_OSS)
{
    samp1 = FSOUND_Sample_Alloc(FSOUND_UNMANAGED, RECORDLEN, FSOUND_MONO | FSOUND_8BITS | FSOUND_UNSIGNED, RECORDRATE, 255, 128, 255);
}
else
{
    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();


/* LOOP ADDED BY MAMBAZO */
for (i=0; i &lt; 20; i++) {


    if (!FSOUND_Record_StartSample(samp1, FALSE))   /* 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;
    }

    do
    {
        printf(&quot;Recording position = %d\r&quot;, FSOUND_Record_GetPosition());
        Sleep(50);
    } while (FSOUND_Record_GetPosition() &lt; RECORDLEN &amp;&amp; !kbhit());

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

}

printf(&quot;\n=========================================================================\n&quot;);
printf(&quot;Press a key to play back recorded data\n&quot;);
printf(&quot;=========================================================================\n&quot;);

getch();

channel = FSOUND_PlaySound(FSOUND_FREE, samp1);

printf(&quot;Playing back sound...\n&quot;);

do
{
    printf(&quot;Playback position = %d\r&quot;, FSOUND_GetCurrentPosition(channel));
    Sleep(50);
} while (FSOUND_IsPlaying(channel) &amp;&amp; !kbhit());

if (FSOUND_GetOutput() == FSOUND_OUTPUT_OSS)
{
    FSOUND_Sample_Free(samp1);
    FSOUND_Close();
    return 0;
}


/*
    SAVED TO 
*/
SaveToWav(samp1);

printf(&quot;\nSaved to record.wav!\n&quot;);


/*
    REALTIME FULL DUPLEX RECORD / PLAYBACK!
*/

printf(&quot;\n=========================================================================\n&quot;);
printf(&quot;Press a key to do some full duplex realtime recording!\n&quot;);
printf(&quot;(with reverb for mmx users)\n&quot;);
printf(&quot;=========================================================================\n&quot;);

getch();

FSOUND_Sample_SetMode(samp1, FSOUND_LOOP_NORMAL);   /* make it a looping sample */

if (!FSOUND_Record_StartSample(samp1, TRUE))    /* start recording and make it loop also */
{
    printf(&quot;Error!\n&quot;);
    printf(&quot;%s\n&quot;, FMOD_ErrorString(FSOUND_GetError()));

    FSOUND_Close();
    return 0;
}

/*
    Increase this value if the sound sounds corrupted or the time between recording
    and hearing the result is longer than it should be..
*/
#define RECORD_DELAY_MS       25
#define RECORD_DELAY_SAMPLES  (RECORDRATE * RECORD_DELAY_MS / 1000)

/*
    Let the record cursor move forward a little bit first before we try to play it
    (the position jumps in blocks, so any non 0 value will mean 1 block has been recorded)
*/
while (!FSOUND_Record_GetPosition()) 
{
    Sleep(1);
}

ifdef ENABLEREVERB

SetupReverb();

endif

channel = FSOUND_PlaySound(FSOUND_FREE, samp1); /* play the sound */

originalfreq = FSOUND_GetFrequency(channel);

/* printf("initial delay = %d\n", FSOUND_GetCurrentPosition(channel) – FSOUND_Record_GetPosition()); */

do
{
    int playpos, recordpos, diff;
    static int oldrecordpos = 0, oldplaypos = 0;

    playpos = FSOUND_GetCurrentPosition(channel);
    recordpos = FSOUND_Record_GetPosition();

    /* 
        NOTE : As the recording and playback frequencies arent guarranteed to be exactly in 
        sync, we have to adjust the playback frequency to keep the 2 cursors just enough 
        apart not to overlap. (and sound corrupted)
        This code tries to keep it inside a reasonable size window just behind the record
        cursor. ie [........|play window|&lt;-delay-&gt;|&lt;-Record cursor.............] 
    */

    /*
        Dont do this code if either of the cursors just wrapped
    */
    if (playpos &gt; oldplaypos &amp;&amp; recordpos &gt; oldrecordpos) 
    {
        diff = playpos - recordpos;

        if (diff &gt; -RECORD_DELAY_SAMPLES)
        {
            FSOUND_SetFrequency(channel, originalfreq - 1000);  /* slow it down */
        }
        else if (diff &lt; -(RECORD_DELAY_SAMPLES * 2))
        {
            FSOUND_SetFrequency(channel, originalfreq + 1000);  /* speed it up */
        }
        else
        {
            FSOUND_SetFrequency(channel, originalfreq); 
        }
    }

    oldplaypos = playpos;
    oldrecordpos = recordpos;

    /*
        Print some info and a VU meter (vu is smoothed)
    */
    {
        char vu[19];
        float vuval, l, r;
        static float smoothedvu = 0;

        FSOUND_GetCurrentLevels(channel, &amp;l, &amp;r);
        vuval = (l+r) * 0.5f;
        vuval *= 18.0f;

        #define VUSPEED 0.2f

        if (vuval &gt; smoothedvu)
        {
            smoothedvu = vuval;
        }

        smoothedvu -= VUSPEED;
        if (smoothedvu &lt; 0)
        {
            smoothedvu = 0;
        }

        memset(vu, 0, 19);
        memset(vu, '=', (int)(smoothedvu));

        printf(&quot;Play=%6d Rec=%6d (gap=%6d, freqchange=%6d hz) VU:%-15s\r&quot;, playpos, recordpos,  diff, FSOUND_GetFrequency(channel) - originalfreq, vu);
    }

    Sleep(10);
} while (!kbhit());

getch();

FSOUND_StopSound(channel);
FSOUND_Record_Stop();

ifdef ENABLEREVERB

CloseReverb();

endif

/*
    CLEANUP AND SHUTDOWN
*/

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

}

[/code:2ml5amp4]

  • You must to post comments
0
0

Perfect!! Thanks! Now we have the possibility to record an infinite length wave/riff!

Just out of curiosity, what turned out the be the problem?

EDIT: Holy S@#T!!! My recording programs were running at about 65 cycles per second with the old dll. They now run at 400+ plus!! I don’t know what you did but blimey!!!

  • You must to post comments
0
0

We had a similar issue with 3.74 and actually found a bug in the FMOD source. I thought we had emailed support but I will get the programmer that fixed it to send you the patch.

Should we be downloading a patched version for our CE app?

Edited: The DLL you posted in this thread, is it 3.75 or do you have new fixes to release? If possible, can we get this ASAP, we have another recurring issue that customers run into with the recording after a few use cycles.

-Melvin

  • You must to post comments
Showing 10 results
Your Answer

Please first to submit.