It is currently Thu Oct 19, 2017 9:35 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Thu Oct 06, 2005 5:08 pm 
Offline
User avatar

Joined: Tue Dec 21, 2004 8:35 pm
Posts: 600
Location: Argentina
I just write cos i want to implement faster dsound routines. What im currently doing is to have my own write cursor and a function "CanWrite()" that tell me if there is enoughf space to stream the data. But there is a cons to this when i fill my own buffer with NES sound data (2048 bytes) and then i send you to the function that will play the buffer, the only way to get more or less good sound (no distorded, etc) is to have inside de playbuffer func. a line of code like:

Code:
While (CanWrite() < buffer_size);


CanWrite return the number of bytes that can be written.
that is done in the playbuffer function and the problem is that the while nevers exits if the amount of memory in the dsound buffer is, as the code line says < buffer_size.
It actually works (dont get stuck), but it keeps waiting to have a razonable amount of mem to write to the buffer which make my emulation slower.

I thought that making it MultiThreaded could solve the problem, but i dont want to do it that way.

Any idea/suggestion?

_________________
ANes


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 5:13 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Regulating a framerate on the rate of soundoutput is actually a very solid way to keep a proper framerate. If you're waiting on DSound to empty enough of the buffer and it's slowing emulation down... then your emulator may be producing too many samples.

Rather than having an empty loop like you pasted, maybe you could sleep inside the loop so that you ease CPU time which you're waiting for samples to play.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 6:13 pm 
Offline
User avatar

Joined: Sat Jan 22, 2005 8:51 am
Posts: 427
Location: Chicago, IL
Here's how I keep the sound in sync/un-distorted in my emulator (I'm using Blargg's sound library with DirectSound):

- Create a DirectSound buffer of an arbitrary size. I use 100ms, or 6 frames
- Define a low and high threshold -- essentially how many frames worth of sound (or how many bytes) I want to have buffered.
- Here's what I do at the end of a frame:
Code:
while (samples available)
{
   Get number of bytes available in DS buffer (DSB)
   if (DSB bytes == 0) //DS buffer full
      continue;
   read DSB bytes worth of samples into a buffer
   if (no more samples)
      break;
   else
      Copy sample buffer into DSB
}

Get number of bytes available in DSB

if (DSB bytes < loThreshold)  //play pointer approaching write pointer
   generate more samples next frame to catch up
else if (DSB bytes > hiThreshold) //write pointer approaching play pointer
   generate less samples next frame to slow down


Blargg's library handles the NES sample -> output sample rate adjustment, so when I say generate more/less samples, I'm modifying the adjustment rate here. Oh -- and the sample adjustment is very small; only a couple of samples difference per frame, so it's inaudible.

Look at the source code if you're interested (link in my sig). It's in dire need of a cleanup, but it seems to get the job done pretty well. With a +/- 3 sample/frame adjustment, I stay pretty well locked on to my buffer target.

James

_________________
get nemulator
http://nemulator.com


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 6:21 pm 
Offline
User avatar

Joined: Mon Jun 06, 2005 12:47 pm
Posts: 67
Yes, typically, you use Sleep(1) or so while waiting. If you actually want time slices that fine, you should use timeBeginPeriod(1) / timeEndPeriod(1) or so in your sound init/cleanup code.

1ms or so is still about as fine as you can get out of that. You can also do no better with WaveOut callback notifications.


In fact, the only real way you can get a guaranteed timely response when your blocks of samples have been played is to use Kernel Streaming, which is not future proof, offers no easy way to enumerate the output filter associated with the system default device, and is limited to sample depths and rates actually supported by the hardware. ( And no software mixing either, so you effectively hog the sound card if it doesn't feature hardware mixing. ) Bad drivers can lead to BSODs real easy this way.

Lots of limitations, but if you feed it one frame worth of samples per write operation, you can sync the sound output to the completion events for each block and get spot-on timing, unlike with DSound or WaveOut.


For safest results, though, stick with DSound, or perhaps even try WaveOut, and use vsync to smooth out the frame display. Depending on how fast or slow your emulation loop is, it may be easy to get away with that, as long as your sample generation is accurate relative to frames rendered and the output sample rate, I think....


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 06, 2005 7:29 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Quote:
Blargg's library handles the NES sample -> output sample rate adjustment, so when I say generate more/less samples, I'm modifying the adjustment rate here. Oh -- and the sample adjustment is very small; only a couple of samples difference per frame, so it's inaudible.


What's really being adjusted here is the basic pitch of the sound. But the APU is still running the same number of emulated clocks per frame, just that each clock takes a little more/less of a fraction of an output sample than usual. Put another way, you're telling the APU that your output sampling rate (i.e. 44100 Hz) is 44160 Hz (for example), so it'll generate an extra sample for that frame. If you keep these adjustments very small, the pitch change will be inaudible (assuming you can adjust the pitch in that fine an increment).


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group