0
0

Hi again guys,
Thanks to brett and MocoN I managed to code a voice chat program which at least runs. It still has a couple of bugs to be fixed, and this is one of them. when I talk to the mic, there are continuous clicks in the received sound(on the remote computer). It’s fine when I’m not talking. I read about stuttering in FAQ section and played around with FSOUND_SetBufferSize but I get the same result. I’ll post part of my code below. What do you think might be causing that crack…?

Sending part
[code:2kglhv25]
LRESULT RecordSound::OnStartRecording(WPARAM wp,LPARAM lp)
{
char fmodBuf[RECBUFFER]; //RECBUFFER = 2000
char msg4dbg[100];
int recordpos;
int oldrecordpos = 0; //added 040629

void *ptr1, *ptr2;
unsigned int len1, len2;

if (!FSOUND_Record_StartSample(recSample, TRUE))    /* start recording and make it loop also */
{
    log.WriteString("Error in Record_StartSample!\n");

    FSOUND_Close();
    return FALSE;
}

recording = TRUE;
                    //what I'm trying to do is
                    //wait for the recSample to be filled with 2000 data
                    //, lock it, and send it
do{
    recordpos = FSOUND_Record_GetPosition();    //recordpos is # of samples. it can have values from 0 to RECLENGTH

    if(recordpos > oldrecordpos)         //the sample hasn't wrapped
    {                      //so store the recorded data into my fmodBuf
        FSOUND_Sample_Lock(recSample, oldrecordpos, recordpos-oldrecordpos, &ptr1, &ptr2, &len1, &len2);        //lenXX's are #s of BYTES
        memcpy(&fmodBuf[oldrecordpos], ptr1, len1);
        FSOUND_Sample_Unlock(recSample, ptr1, ptr2, len1, len2);

    }
    else if(recordpos < oldrecordpos)        //the sample has wrapped somewhere during the recording
    {                      //and started from the beginning again
        sprintf(msg4dbg, "\n recordpos / oldrecordpos : %d   %d", recordpos, oldrecordpos);
        log.WriteString(msg4dbg);
        log.WriteString("\nSample Wrapped. Locking and sending..");
        FSOUND_Sample_Lock(recSample, oldrecordpos, RECLENGTH-oldrecordpos, &ptr1, &ptr2, &len1, &len2);        //so store the RECLENGTH-oldrecordpos samples first
        memcpy(&fmodBuf[oldrecordpos], ptr1, len1);
                            //fmodBuf is filled with RECLENGTH data, so send it
        ((Display*)dlg)->sendMessage(&fmodBuf[0],sizeof(fmodBuf));
        FSOUND_Sample_Unlock(recSample, ptr1, ptr2, len1, len2);                    

        FSOUND_Sample_Lock(recSample, 0, recordpos, &ptr1, &ptr2, &len1, &len2);    
                            //now store the (0~recordpos) data from the beginning of fmodBuf 
        memcpy(&fmodBuf[0], ptr1, len1);
        FSOUND_Sample_Unlock(recSample, ptr1, ptr2, len1, len2);


    }

    oldrecordpos = recordpos;           //update the oldrecordpos
    Sleep(5);
} while(!terminateRec);

return TRUE;

[/code:2kglhv25]

And the receiving part:

[code:2kglhv25]
#define RECBUFFER 2000 //buffer size

sample = FSOUND_Sample_Alloc(FSOUND_UNMANAGED, RECBUFFER, FSOUND_MONO | FSOUND_SIGNED | FSOUND_8BITS , 8000, 255, 128, 255);
(...)
FSOUND_Sample_SetMode(sample, FSOUND_LOOP_NORMAL);  /* make it a looping sample */
(...)

LRESULT PlaySound2::OnWriteSoundData(WPARAM wParam, LPARAM lParam)
{
void *ptr1, *ptr2;
unsigned int len1, len2;

char logmsg[PLAYBUFFER+60];
char *wavBuf = (char *)lParam;      //lParam is pointing to the received data array(size : 2000)
if(wavBuf==NULL)
    return ERROR_SUCCESS;
int len = (int)wParam;

if(Playing)
{

    sprintf(logmsg,"\n2.Sample Uploading: wavHdr address = %p ",wavBuf);
    log.WriteString(logmsg);
    sprintf(logmsg,"\n3.Sample Uploading: wav-lpData address = %p ",wavBuf);
    log.WriteString(logmsg);        

    FSOUND_Sample_Lock(sample, 0, len, &ptr1, &ptr2, &len1, &len2);     //lock the sample-ptr1 has the pointer to locked sample
    memcpy(ptr1, wavBuf, len1);
    FSOUND_Sample_Unlock(sample, ptr1, ptr2, len1, len2);


    if(!alreadyStarted)
    {
        channel = FSOUND_PlaySound(FSOUND_FREE, sample); 
        log.WriteString("\n4.Playing sample");
        if(channel == -1)
        {
            log.WriteString("\n Error occurred in OnWriteSoundData-PlaySound");
            return FALSE;
        }
        alreadyStarted = TRUE;
    }



}
return ERROR_SUCCESS;

}
[/code:2kglhv25]

  • You must to post comments
0
0

Thanks, I guess I understand the problem.
There are possibilities that my OnWriteData(sample lock/memcpy/unlock) is called before fmod finishes playing the full length of data. And I suppose the opposite could happen, depending on the network traffic, where the playing sample hits the end and loops back to the beginning even before another buffer is received.
I tried to find out what to do with this but can’t think of anything special…has anyone coped with this kind of situation? What would be a suitable solution?

  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.