--- np2/sound/sound.c 2003/10/19 14:56:15 1.2 +++ np2/sound/sound.c 2003/10/21 16:27:54 1.5 @@ -8,13 +8,7 @@ #include "beep.h" - UINT32 opna_rate = 22050; - -static int writebytes = 0; - UINT32 ratebase200 = 110; - UINT32 dsound_lastclock = 0; - - + SOUNDCFG soundcfg; #define STREAM_CBMAX 16 @@ -28,6 +22,7 @@ typedef struct { SINT32 *buffer; SINT32 *ptr; UINT samples; + UINT reserve; UINT remain; CBTBL *cbreg; CBTBL cb[STREAM_CBMAX]; @@ -39,7 +34,7 @@ static SNDSTREAM sndstream; static void streamreset(void) { sndstream.ptr = sndstream.buffer; - sndstream.remain = sndstream.samples; + sndstream.remain = sndstream.samples + sndstream.reserve; sndstream.cbreg = sndstream.cb; } @@ -67,22 +62,13 @@ static void streamprepare(UINT samples) BOOL sound_create(UINT rate, UINT ms) { UINT samples; + UINT reserve; ZeroMemory(&sndstream, sizeof(sndstream)); - if (rate == 0) { - return(SUCCESS); - } switch(rate) { case 11025: - opna_rate = 11025; - break; - case 22050: - opna_rate = 22050; - break; - case 44100: - opna_rate = 44100; break; default: @@ -94,14 +80,22 @@ BOOL sound_create(UINT rate, UINT ms) { } soundmng_reset(); - sndstream.buffer = (SINT32 *)_MALLOC(samples * 2 * sizeof(SINT32), - "stream"); + soundcfg.rate = rate; + sound_changeclock(); + +#if defined(SOUNDRESERVE) + reserve = rate * SOUNDRESERVE / 1000; +#else + reserve = 0; +#endif + sndstream.buffer = (SINT32 *)_MALLOC((samples + reserve) * 2 + * sizeof(SINT32), "stream"); if (sndstream.buffer == NULL) { goto scre_err2; } sndstream.samples = samples; + sndstream.reserve = reserve; streamreset(); - ratebase200 = (opna_rate + 199) / 200; SNDCSEC_INIT; return(SUCCESS); @@ -130,11 +124,37 @@ void sound_reset(void) { if (sndstream.buffer) { soundmng_reset(); streamreset(); - dsound_lastclock = I286_CLOCK; + soundcfg.lastclock = I286_CLOCK; beep_eventreset(); } } +void sound_changeclock(void) { + + UINT32 clock; + UINT hz; + UINT hzmax; + + if (sndstream.buffer == NULL) { + return; + } + + // とりあえず 25で割り切れる。 + clock = pc.realclock / 25; + hz = soundcfg.rate / 25; + + // で、クロック数に合せて調整。(64bit演算しろよな的) + hzmax = (1 << (32 - 8)) / (clock >> 8); + while(hzmax < hz) { + clock = (clock + 1) >> 1; + hz = (hz + 1) >> 1; + } + soundcfg.hzbase = hz; + soundcfg.clockbase = clock; + soundcfg.minclock = 2 * clock / hz; + soundcfg.lastclock = I286_CLOCK; +} + void sound_streamregist(void *hdl, SOUNDCB cbfn) { if (sndstream.buffer) { @@ -152,29 +172,29 @@ void sound_streamregist(void *hdl, SOUND void sound_sync(void) { - UINT length; + UINT32 length; if (sndstream.buffer == NULL) { return; } - length = (I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK - - dsound_lastclock) * ratebase200; - if (length < pc.dsoundclock2) { + length = I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK - soundcfg.lastclock; + if (length < soundcfg.minclock) { return; } - length /= pc.dsoundclock; - if (length) { - SNDCSEC_ENTER; - streamprepare(length); - SNDCSEC_LEAVE; - writebytes += length; - dsound_lastclock += (length * pc.dsoundclock / ratebase200); - beep_eventreset(); + length = (length * soundcfg.hzbase) / soundcfg.clockbase; + if (length == 0) { + return; } + SNDCSEC_ENTER; + streamprepare(length); + SNDCSEC_LEAVE; + soundcfg.writecount += length; + soundcfg.lastclock += length * soundcfg.clockbase / soundcfg.hzbase; + beep_eventreset(); - if (writebytes >= 100) { - writebytes = 0; + if (soundcfg.writecount >= 100) { + soundcfg.writecount = 0; soundmng_sync(); } } @@ -186,9 +206,9 @@ const SINT32 *ret; ret = sndstream.buffer; if (ret) { SNDCSEC_ENTER; - if (sndstream.remain) { - streamprepare(sndstream.remain); - dsound_lastclock = I286_CLOCK; + if (sndstream.remain > sndstream.reserve) { + streamprepare(sndstream.remain - sndstream.reserve); + soundcfg.lastclock = I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK; beep_eventreset(); } } @@ -197,9 +217,17 @@ const SINT32 *ret; void sound_pcmunlock(const SINT32 *hdl) { + int leng; + if (hdl) { - sndstream.ptr = sndstream.buffer; - sndstream.remain = sndstream.samples; + leng = sndstream.reserve - sndstream.remain; + if (leng > 0) { + CopyMemory(sndstream.buffer, + sndstream.buffer + sndstream.samples * 2, + leng * 2 * sizeof(SINT32)); + } + sndstream.ptr = sndstream.buffer + (leng * 2); + sndstream.remain += sndstream.samples; SNDCSEC_LEAVE; } }