having been desperately working on my code and getting no luck for 2 weeks, I finally decided to ask for a little more favor…
I’m trying to make a network chatting program with GUI where you can toss raw wave data headers between the clients through a server.
I’ve searched for similar topics around the forum and figured out there are 2 ways to play the received raw data:
- using a custom stream
-(1) before receiving, create a stream and the callback function for it
-(2) if a buffer filled with data is received, throw the pointer to the stream callback(as a user parameter), and use it to copy the data to the stream buffer(the second argument in callback function)
-(3) play the stream
I checked out everything I could, and the pointers seemed to be referred correctly. But the sound stuttered. All those above were done in a client thread. I think once you finish (1)-(2)-(3), then you just keep doing (2) repeatedly when a new buffer is received, and the stream is automatically updated. Is this theoretically correct? I also played with the buffer size(when receiving the socket, or when creating the stream), but the stuttering didn’t go away. Can this be because the streamcallback function is called more frequently than the buffer-updating function?
- using a custom sample
-(1) create a sample using FSOUND_Sample_Alloc(…)
-(2) when a data block is received, use FSOUND_Sample_Upload to feed the data buffer to the sample
-(3) play the sample
My buffer size is 2000 bytes – 8 bit mono, 8kHz rate. I’m not sure when the three should be done. First I tried calling sample playback function only once and just updating the sample like (2). And then I tried doing (2) and (3) whenever the data buffer was received. Here in both cases I had no sound…In what sequence and how often should these three be done…?
Can there be any problems in my using threads for all these…?
Please let me know If I’m making mistakes somewhere(theoretically..). And has anyone reading this finished this kind of project using VC++? I’d be so grateful if somebody showed me the code, at least just parts I mentioned above. Thanks for reading…
- geewoo asked 12 years ago
Thanks (always…). Please check if I’m getting it correctly:
you arent feeding the data to the soundcard fast enough
I guess this means the stream callback function is called more frequently than buffer transmission. The header I defined inside my receiving client thread is supposed to be updated when a buffer is filled, but the callback refers to the header even before it is updated. Am I understanding the story correctly? Is this why I’m getting stuttering sound?
I tried increasing the size of stream buffer, from the recording buffer size(2000) to 4 times of it(8000) just to see what happens. There were fewer(or maybe slower..?) stutterings and I could hear a larger portion of the voice I recorded. I’ll try setting a bigger buffer size for all.
And about the sample…is it possible to use things as FSOUND_Sample_Lock and FSOUND_Sample_Unlock with my own data? Asking because those two have FSOUND_SAPLE as the parameter(in the html document), and what I have is raw pcm data.
Once again, please correct me if I got something wrong.
You know what…IT WORKED!
Ok. I used FSOUND_Sample_Lock and _Unlock just as what you said, and ‘memcpy’ed the received data to the returned pointer. So I didn’t have to FSOUND_Sample_SetMode(sample, FSOUND_LOOP_NORMAL); to make the sample loop and call channel = FSOUND_PlaySound(FSOUND_FREE, sample); only once.
- receive a buffer of raw pcm data
- lock my sample and upload(using memcpy)
- unlock and play the uploaded block only
Now even my coffee tastes different…phew… 8)
But can I ask a few more which I haven’t figured out yet…?
I had tried to calculate how it goes, but could you explain briefly what the ‘XORing the data with 128’ did?
sample = FSOUND_Sample_Alloc(FSOUND_UNMANAGED, (int)wParam, FSOUND_MONO | FSOUND_UNSIGNED | FSOUND_8BITS , 8000, 255, 128, 255);
FSOUND_UNSIGNED or FSOUND_SIGNED flag didn’t work in my case, and I wonder why…
And another thing is about the streaming stuff I kept failing…
The streamcallback ,I guess, is called whenever the data in stream buffer are passed to the soundcard.
But if the network receiving routine didn’t keep up with the speed which the streamcallback is called with, then there would come the stuttering problem.
Larger stream buffer would make the callback called less frequently, but the network receiving would be slower too(This is what I tried. Stuttering still happened…). So I wonder if it could be the solution to make the network socket size smaller while keeping the stream buffer big. But I have no idea of how to implement it, or what would be a suitable combination (of buffer sizes). Can you brett, or anybody, give me a hint on this…? I really appreciate your help. What a wonderful library you’ve got here…. 😛
Please login first to submit.