|
|
| version 1.2, 2003/10/19 14:56:15 | version 1.10, 2003/12/08 00:55:33 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include "soundmng.h" | #include "soundmng.h" |
| #include "i286.h" | #include "cpucore.h" |
| #include "pccore.h" | #include "pccore.h" |
| #include "iocore.h" | #include "iocore.h" |
| #include "sound.h" | #include "sound.h" |
| Line 8 | Line 8 |
| #include "beep.h" | #include "beep.h" |
| UINT32 opna_rate = 22050; | SOUNDCFG soundcfg; |
| static int writebytes = 0; | |
| UINT32 ratebase200 = 110; | |
| UINT32 dsound_lastclock = 0; | |
| #define STREAM_CBMAX 16 | #define STREAM_CBMAX 16 |
| Line 28 typedef struct { | Line 22 typedef struct { |
| SINT32 *buffer; | SINT32 *buffer; |
| SINT32 *ptr; | SINT32 *ptr; |
| UINT samples; | UINT samples; |
| UINT reserve; | |
| UINT remain; | UINT remain; |
| CBTBL *cbreg; | CBTBL *cbreg; |
| CBTBL cb[STREAM_CBMAX]; | CBTBL cb[STREAM_CBMAX]; |
| Line 38 static SNDSTREAM sndstream; | Line 33 static SNDSTREAM sndstream; |
| static void streamreset(void) { | static void streamreset(void) { |
| SNDCSEC_ENTER; | |
| sndstream.ptr = sndstream.buffer; | sndstream.ptr = sndstream.buffer; |
| sndstream.remain = sndstream.samples; | sndstream.remain = sndstream.samples + sndstream.reserve; |
| sndstream.cbreg = sndstream.cb; | sndstream.cbreg = sndstream.cb; |
| SNDCSEC_LEAVE; | |
| } | } |
| static void streamprepare(UINT samples) { | static void streamprepare(UINT samples) { |
| Line 67 static void streamprepare(UINT samples) | Line 64 static void streamprepare(UINT samples) |
| BOOL sound_create(UINT rate, UINT ms) { | BOOL sound_create(UINT rate, UINT ms) { |
| UINT samples; | UINT samples; |
| UINT reserve; | |
| ZeroMemory(&sndstream, sizeof(sndstream)); | ZeroMemory(&sndstream, sizeof(sndstream)); |
| if (rate == 0) { | |
| return(SUCCESS); | |
| } | |
| switch(rate) { | switch(rate) { |
| case 11025: | case 11025: |
| opna_rate = 11025; | |
| break; | |
| case 22050: | case 22050: |
| opna_rate = 22050; | |
| break; | |
| case 44100: | case 44100: |
| opna_rate = 44100; | |
| break; | break; |
| default: | default: |
| Line 94 BOOL sound_create(UINT rate, UINT ms) { | Line 82 BOOL sound_create(UINT rate, UINT ms) { |
| } | } |
| soundmng_reset(); | soundmng_reset(); |
| sndstream.buffer = (SINT32 *)_MALLOC(samples * 2 * sizeof(SINT32), | soundcfg.rate = rate; |
| "stream"); | 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) { | if (sndstream.buffer == NULL) { |
| goto scre_err2; | goto scre_err2; |
| } | } |
| sndstream.samples = samples; | sndstream.samples = samples; |
| streamreset(); | sndstream.reserve = reserve; |
| ratebase200 = (opna_rate + 199) / 200; | |
| SNDCSEC_INIT; | SNDCSEC_INIT; |
| streamreset(); | |
| return(SUCCESS); | return(SUCCESS); |
| scre_err2: | scre_err2: |
| Line 116 scre_err1: | Line 112 scre_err1: |
| void sound_destroy(void) { | void sound_destroy(void) { |
| if (sndstream.buffer) { | if (sndstream.buffer) { |
| SNDCSEC_TERM; | |
| soundmng_stop(); | soundmng_stop(); |
| streamreset(); | |
| soundmng_destroy(); | soundmng_destroy(); |
| SNDCSEC_TERM; | |
| _MFREE(sndstream.buffer); | _MFREE(sndstream.buffer); |
| sndstream.buffer = NULL; | sndstream.buffer = NULL; |
| } | } |
| Line 130 void sound_reset(void) { | Line 126 void sound_reset(void) { |
| if (sndstream.buffer) { | if (sndstream.buffer) { |
| soundmng_reset(); | soundmng_reset(); |
| streamreset(); | streamreset(); |
| dsound_lastclock = I286_CLOCK; | soundcfg.lastclock = CPU_CLOCK; |
| beep_eventreset(); | 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 = CPU_CLOCK; | |
| } | |
| void sound_streamregist(void *hdl, SOUNDCB cbfn) { | void sound_streamregist(void *hdl, SOUNDCB cbfn) { |
| if (sndstream.buffer) { | if (sndstream.buffer) { |
| Line 152 void sound_streamregist(void *hdl, SOUND | Line 174 void sound_streamregist(void *hdl, SOUND |
| void sound_sync(void) { | void sound_sync(void) { |
| UINT length; | UINT32 length; |
| if (sndstream.buffer == NULL) { | if (sndstream.buffer == NULL) { |
| return; | return; |
| } | } |
| length = (I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK | length = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK - soundcfg.lastclock; |
| - dsound_lastclock) * ratebase200; | if (length < soundcfg.minclock) { |
| if (length < pc.dsoundclock2) { | |
| return; | return; |
| } | } |
| length /= pc.dsoundclock; | length = (length * soundcfg.hzbase) / soundcfg.clockbase; |
| if (length) { | if (length == 0) { |
| SNDCSEC_ENTER; | return; |
| streamprepare(length); | |
| SNDCSEC_LEAVE; | |
| writebytes += length; | |
| dsound_lastclock += (length * pc.dsoundclock / ratebase200); | |
| beep_eventreset(); | |
| } | } |
| SNDCSEC_ENTER; | |
| if (writebytes >= 100) { | streamprepare(length); |
| writebytes = 0; | soundcfg.lastclock += length * soundcfg.clockbase / soundcfg.hzbase; |
| beep_eventreset(); | |
| SNDCSEC_LEAVE; | |
| soundcfg.writecount += length; | |
| if (soundcfg.writecount >= 100) { | |
| soundcfg.writecount = 0; | |
| soundmng_sync(); | soundmng_sync(); |
| } | } |
| } | } |
| static volatile int locks = 0; | |
| const SINT32 *sound_pcmlock(void) { | const SINT32 *sound_pcmlock(void) { |
| const SINT32 *ret; | const SINT32 *ret; |
| if (locks) { | |
| TRACEOUT(("sound pcm lock: already locked")); | |
| return(NULL); | |
| } | |
| locks++; | |
| ret = sndstream.buffer; | ret = sndstream.buffer; |
| if (ret) { | if (ret) { |
| SNDCSEC_ENTER; | SNDCSEC_ENTER; |
| if (sndstream.remain) { | if (sndstream.remain > sndstream.reserve) { |
| streamprepare(sndstream.remain); | streamprepare(sndstream.remain - sndstream.reserve); |
| dsound_lastclock = I286_CLOCK; | soundcfg.lastclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK; |
| beep_eventreset(); | beep_eventreset(); |
| } | } |
| } | } |
| else { | |
| locks--; | |
| } | |
| return(ret); | return(ret); |
| } | } |
| void sound_pcmunlock(const SINT32 *hdl) { | void sound_pcmunlock(const SINT32 *hdl) { |
| int leng; | |
| if (hdl) { | if (hdl) { |
| sndstream.ptr = sndstream.buffer; | leng = sndstream.reserve - sndstream.remain; |
| sndstream.remain = sndstream.samples; | 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 + sndstream.reserve - leng; | |
| // sndstream.remain += sndstream.samples; | |
| SNDCSEC_LEAVE; | SNDCSEC_LEAVE; |
| locks--; | |
| } | } |
| } | } |