0
0

hi every body,

so here is my problem. I would to create a soft that will permit to speak over IP. so I used a RTP library (oRTP) and I would like to use FMOD to manage the sound.

I don’t know how can I do ? I have to record sound, encode it (with a codec like G711) then send it with RTP, recieve it, decode and then play it with fmod.

So how can I use fmod to play a sound with a streaming audio. Is it possible to manage a buffer ? If someone has an idea it will be my hero ๐Ÿ˜€

Thanks a lot, i like fmod

+Daff

  • You must to post comments
0
0

KarLKoX i want to encode it in G711 (ULAW). I want to do something to speak between 2 computers.

Thanks nci, I have done what you say and it works ๐Ÿ˜› my file is big very quickly but I think it’s normal, that’s why I should encode it after.

Now the maybe last question. If i suppose that i have encode/send/recieve and decode it correctly (we suppose :P)…. i should put that data like that ?

[code:3fijj7kj]
static FILE* file;
char * str = new char [10] ;
int i=0;
fpos_t pos; // to record position

signed char F_CALLBACKAPI streamcallback(FSOUND_STREAM *stream, void *buff, int len, void *param)
{
int count;
signed short *stereo16bitbuffer = (signed short *)buff;
file = fopen("record2.txt", "r");
fsetpos(file,&pos);

for (count=0; count<len>>2; count++){
    fgets(str,5,file);
    *stereo16bitbuffer++ = char_to_short(str,1,0);    // left channel

    fgets(str,5,file);
    *stereo16bitbuffer++ = char_to_short(str,1,0);    // right channel
}
fgetpos(file,&pos);
fclose(file);
return 1;

}[/code:3fijj7kj]

the function char_to_short is a function that convert a string to signed short.

I have done it but I have nothing on my speaker… :(

Here is my entire MAIN code:

[code:3fijj7kj]int main(int argc, char *argv[])
{
FSOUND_STREAM *stream;

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

if (!FSOUND_Init(44100, 16, 0))
{
    printf("FSOUND_Init Error !\n");
    printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
    return 0;
}

     stream = FSOUND_Stream_Create(streamcallback, 6*2048, FSOUND_NORMAL | FSOUND_16BITS | FSOUND_STEREO, 44100, (void *)12345);
if (!stream)
{
    printf("Error!\n");
    printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
    return 1;
}


printf("Press a key to start playing \n");
getch();

if (FSOUND_Stream_Play(FSOUND_FREE, stream) == -1)
{
printf("Error!\n");
printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
return 1;

}

getch();
FSOUND_Stream_Close(stream);
FSOUND_Close();
return 0;

}[/code:3fijj7kj]

I deleted some comments :)

Thanks again…

  • You must to post comments
0
0

[quote="Daffys":9vdpck7w]KarLKoX i want to encode it in G711 (ULAW). I want to do something to speak between 2 computers.
[/quote:9vdpck7w]

Ok but where is the problem : you can use this code and modify it to your needs (only the compression routine) :)

  • You must to post comments
0
0

yes KarLKoX, I will see it now. It’s in VB…. :( me it’s in C++ ๐Ÿ˜› but I try to look at it also.

I have never done VB…

  • You must to post comments
0
0

You can record using FMOD (see the ‘record’ example) and use a DSP unit to get access to the data so you can encode and send it using whatever method you like. On the receiving end, you receive and decode using your own method and then pass the data to FMOD using a custom stream (see the ‘stream2’ example). You’ll probably have to do some buffering in there as well to avoid skipping.

Cheers,

  • You must to post comments
0
0

Is anybody can tell me how can I do to play my raw pcm data please ?

See my reply just before…

Thanks.

  • You must to post comments
0
0

Thanks andrew for your quick answer,
it looks like so simple when you say that.

so i have done something like that

  • to record :

[code:8ltx9q91]FSOUND_SAMPLE *samp1 = FSOUND_Sample_Alloc(FSOUND_UNMANAGED, RECORDLEN, FSOUND_STEREO | FSOUND_16BITS , RECORDRATE, 255, 128, 255);
FSOUND_Record_StartSample(samp1, TRUE);
[/code:8ltx9q91]

then use a DSP unit to get access to the data ?
[code:8ltx9q91]
FSOUND_DSPUNIT *myDSP = FSOUND_DSP_Create(&DSP_GetData,0,0);
FSOUND_DSP_SetActive(myDSP, TRUE);[/code:8ltx9q91]

and

[code:8ltx9q91]
void * F_CALLBACKAPI DSP_GetData(void *originalbuffer, void *newbuffer, int length, void *param){
cout<<"i am here"<<endl;
}
[/code:8ltx9q91]

so i would like to know ? Where are my data ? Are they void *originalbuffer ?

now i would like to know what i have to encode and to send ? after that when i will recieve and decode it ! what can i do with that data ? You said that i have to use a custom stream ! and i put it with a sdp too ? and i get my data and i do something like :

newbuffer = mydata ?

Thanks a lot again :)

Daffys

  • You must to post comments
0
0

[url=http://www.fmod.org/docs/HTML/FSOUND_PlaySound.html:24x6aswd]FSOUND_PlaySound[/url:24x6aswd]

  • You must to post comments
0
0

[quote:2e6eqpdq]so i would like to know ? Where are my data ? Are they void *originalbuffer ?[/quote:2e6eqpdq]

Yes. Have a look at the DSP tutorial and the record example to see this in action.

[quote:2e6eqpdq]after that when i will recieve and decode it ! what can i do with that data ? You said that i have to use a custom stream ! and i put it with a sdp too ?[/quote:2e6eqpdq]

Have a look at the stream2 example – it makes a custom stream and feeds its own data to it in a stream callback – this is how you would give your decoded data to FMOD for playing.

Cheers,

  • You must to post comments
0
0

hehe merci KarLKoX, enfin thanks ๐Ÿ˜‰

but I will recieve my pcm raw data one by one…. so when I will have enough data I will start to play but I should put my new data on my sample too…

So have I to use a dsp callback a bit like that :

[code:2wxds74r]static FILE* file;
char * str = new char [10] ;
int i=0;
fpos_t pos; // to record position

signed char F_CALLBACKAPI streamcallback(FSOUND_STREAM *stream, void *buff, int len, void *param)
{
int count;
signed short *stereo16bitbuffer = (signed short *)buff;
file = fopen("record2.txt", "r");
fsetpos(file,&pos);

for (count=0; count&lt;len&gt;&gt;2; count++){
    fgets(str,5,file);
    *stereo16bitbuffer++ = char_to_short(str,1,0);    // left channel

    fgets(str,5,file);
    *stereo16bitbuffer++ = char_to_short(str,1,0);    // right channel
    //char_to_short convert a string to signed short
}
fgetpos(file,&amp;pos);
fclose(file);
return 1;

}[/code:2wxds74r]

Thanks for you help :p

  • You must to post comments
0
0

I looked example and tuto but , certainly, I have not understrand everything….

I have done it :

[code:j61abnz3]FSOUND_Sample_SetMode(samp1, FSOUND_LOOP_NORMAL);
FSOUND_Record_StartSample(samp1, TRUE);

FSOUND_DSPUNIT *myDSP = FSOUND_DSP_Create(&DSP_GetData,FSOUND_DSP_DEFAULTPRIORITY_USER+100,0);
FSOUND_DSP_SetActive(myDSP, TRUE);[/code:j61abnz3]
ps : FSOUND_DSP_DEFAULTPRIORITY_USER+100 is ok ?

and In my Callback I want to save my data in a file to test (I want to see what I have to encode). So i tried :

[code:j61abnz3]void * F_CALLBACKAPI DSP_GetData(void *originalbuffer, void *newbuffer, int length, void *param)
{
FILE *fp;
fp = fopen("record", "a");
fwrite(originalbuffer, length, 1, fp);
return originalbuffer;
}[/code:j61abnz3]

And i have nothing. Juste 0000000 in my file . What is my problem ? I am doing something wrong but I don’t know what :(

Please Help !

Regards,

  • You must to post comments
0
0

first off, that is a horrible way to do it, but if it works, hey, more power to
you :)

second, you should not open and close the file each time you are in that
callback because the callback fills a buffer, not the entire song.

1st, open you file in another procedure
2nd, you fill the buffer with your data from the file. a good size is required,
say 2*4096. you fill the buffer with the data, then when fmod requires
more, you fill the buffer again with the next batch of data
3rd, you close the file when the stream is done.

you could also use a sample, and upload the entire data to that sample
then you just play the sample instead of streaming it. (haven’t done much
with that yet.)

  • You must to post comments
0
0

[code:14g6wsrh]
void * F_CALLBACKAPI DSP_GetData(void *originalbuffer, void *newbuffer, int length, void *param)
{
FILE *fp;
fp = fopen("record", "a");
fwrite(originalbuffer, length, 1, fp);
return originalbuffer;
}
[/code:14g6wsrh]

originalbuffer is a pointer the the buffer that has not been touched by any
other DSP unit. newbuffer is the pointer that was changed in the last dsp
unit. What you are doing is writing the pointer to the file.

use

[code:14g6wsrh]
{

int Count;
short* Buffer;
static FILE* hFile;
Buffer=newbuffer;

  hFile=fopen(&quot;temp.txt&quot;,&quot;a&quot;)

for(Count=0; Count<=length; Count++)
{
TempBufferL=(Buffer++); //get the left channel
TempBufferR=
(Buffer++); //get the right channel

  // Write left and right channels 

  fprintf(hFile,&quot;% d\n&quot;,(int)TempBufferL);
  fprintf(hFile,&quot;% d\n&quot;,(int)TempBufferR);


}

  fflush(hFile);
  fclose(hFile);

return newbuffer;
[/code:14g6wsrh]

Forgive the bad coding…. you loop thru length, incramenting the pointer
and getting the data as you incrament thru it. data is interleaved as LRLRLR

This causes some major sound skippage becuase the DSP callback is too
slow. So, only use it to test. and by the way, the data you need to encode
is raw PCM

kinda looks like this

-337
-589
-296
-525
-254
-453
-209
-377
-154
-288
-90
-177
-8
-43
88
107
174
255
225
372
232
427
193
405
113
313
16
182
-61
53
-95
-38
-76
-61
-3
-3
98
117
192
249
263
357
306
425
307
450
268
431
213

this is what that function wrote to the file

  • You must to post comments
0
0

I got it to work, Use a buffer size of 6*2048, it is smooth and doesnt
skip, tho fmods cpu usagae runs about 30 to 40% ๐Ÿ˜ฎ

This is what i used to write the file:

[code:3g4j2u96]
{
int Count;
short* Buffer;
static FILE* hFile;
Buffer=newbuffer;
// Write left and right channels
int hFilelen = 1;

hFile=fopen("temp.txt","rb+") // you must have the file already in existance. I didn’t get too fancy on this :)

for(Count=0; Count<=length; Count+=1)
{
TempBufferL=(Buffer++);
TempBufferR=
(Buffer++);

  fseek(hFile,intWrite,0);
  PUT(hFile,&amp;TempBufferL,sizeof(short));
   //incrament the next position
  intWrite+=sizeof(short);

   //Set the next position
  fseek(hFile,intWrite,0);
  PUT(hFile,&amp;TempBufferR,sizeof(short));
  intWrite+=sizeof(short);
}

if(hFile)
{
fflush(hFile);
fclose(hFile);
}
return newbuffer;
[/code:3g4j2u96]

all this does is write a binary file of raw pcm data, then, you incrament the
byte position. and write the next one, alternating LRLRLR

The code to stream:

[code:3g4j2u96]

static short lpData[2];

{
// This routine MUST be as FAST as possible
shortstereo16bitbuffer=(short)buff;
hFile=fopen("temp.txt","rb+")
// FMOD custom stream. Len is the buffer in BYTES. >>2 Is the buffer in samples (1000 bytes, 250 Samples)
for(Count=0; Count<=length>>2; Count+=1)
{
// read the file at the byte position
fseek(hFile,intFile,0);
GET(hFile,&lpData[0],sizeof(short));
//incrament byte pos
intFile+=sizeof(short);

 //read
 fseek(hFile,intFile,0);
  GET(hFile,&amp;lpData[1],sizeof(short));
   //incrament
  intFile+=sizeof(short);


  if(EoF(hFile))
    {
      return 0;
    }
  *stereo16bitbuffer++=lpData[0];
  *stereo16bitbuffer++=lpData[1];
}

if(hFile)
{
fflush(hFile);
fclose(hFile);
}
return 1;
[/code:3g4j2u96]

This isn’t the way you plan on sending data right? even just a few seconds
of sound is 1000 + kb, and that is in binary. Can you send a small packet
of data say 1 Left and one Right sample when it needs it? This way, you
are only sending a couple of bytes every time FMOD needs data, tho
i have no networking expirence so, correct me if i am wrong, but
have fun with this.

EDIT:

by the way, i was wrong:
[quote:3g4j2u96]
1st, open you file in another procedure ‘WRONG! Crashes
[/quote:3g4j2u96]

if you use a smaller buffer size, fmod wont lag.

  • You must to post comments
0
0

hehe thanks a lot nci,
an another quesion :

[quote:3climvfy] So, only use it to test. and by the way, the data you need to encode
is raw PCM[/quote:3climvfy]

hum ? what does it means ? i have to encode the raw PCM ? where can i find it ?

Thanks again… And have a nice end of week end :p

++

  • You must to post comments
0
0

Oh, the reason why it is slow, is beacuse i was doing it wrong, i was
opening and closing the file each loop. ๐Ÿ˜ฎ Duh, hurrr. Any way, i edited the
post and corrected the code and forgot to delete that part. Now about the
raw pcm? What do you mean where can you find it? It is right there….

[code:1ze4r25y]
TempBufferL=(Buffer++); //get the left channel
TempBufferR=
(Buffer++); //get the right channel
[/code:1ze4r25y]

each loop, you get one left and right sample of RAW PCM. Don’t ask me
how to encode it cuz i have no clue :)

  • You must to post comments
0
0

For MP3/OGG Vorbis encoding, check [url=http://www.fmod.org/forum/viewtopic.php?t=2240&highlight=ripper:1d390wu3]this[/url:1d390wu3] topic :)

  • You must to post comments
Showing 16 results
Your Answer

Please first to submit.