|
|
| version 1.6, 2003/10/22 15:21:23 | version 1.14, 2004/02/18 20:11:37 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include "dosio.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" |
| #include "sndcsec.h" | #include "sndcsec.h" |
| #include "beep.h" | #include "beep.h" |
| #include "getsnd.h" | |
| SOUNDCFG soundcfg; | SOUNDCFG soundcfg; |
| Line 33 static SNDSTREAM sndstream; | Line 35 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.reserve; | 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 95 BOOL sound_create(UINT rate, UINT ms) { | Line 99 BOOL sound_create(UINT rate, UINT ms) { |
| } | } |
| sndstream.samples = samples; | sndstream.samples = samples; |
| sndstream.reserve = reserve; | sndstream.reserve = reserve; |
| streamreset(); | |
| SNDCSEC_INIT; | SNDCSEC_INIT; |
| streamreset(); | |
| return(SUCCESS); | return(SUCCESS); |
| scre_err2: | scre_err2: |
| Line 111 void sound_destroy(void) { | Line 115 void sound_destroy(void) { |
| if (sndstream.buffer) { | if (sndstream.buffer) { |
| soundmng_stop(); | soundmng_stop(); |
| streamreset(); | |
| soundmng_destroy(); | soundmng_destroy(); |
| SNDCSEC_TERM; | SNDCSEC_TERM; |
| _MFREE(sndstream.buffer); | _MFREE(sndstream.buffer); |
| Line 123 void sound_reset(void) { | Line 128 void sound_reset(void) { |
| if (sndstream.buffer) { | if (sndstream.buffer) { |
| soundmng_reset(); | soundmng_reset(); |
| streamreset(); | streamreset(); |
| soundcfg.lastclock = I286_CLOCK; | soundcfg.lastclock = CPU_CLOCK; |
| beep_eventreset(); | beep_eventreset(); |
| } | } |
| } | } |
| Line 139 void sound_changeclock(void) { | Line 144 void sound_changeclock(void) { |
| } | } |
| // とりあえず 25で割り切れる。 | // とりあえず 25で割り切れる。 |
| clock = pc.realclock / 25; | clock = pccore.realclock / 25; |
| hz = soundcfg.rate / 25; | hz = soundcfg.rate / 25; |
| // で、クロック数に合せて調整。(64bit演算しろよな的) | // で、クロック数に合せて調整。(64bit演算しろよな的) |
| Line 151 void sound_changeclock(void) { | Line 156 void sound_changeclock(void) { |
| soundcfg.hzbase = hz; | soundcfg.hzbase = hz; |
| soundcfg.clockbase = clock; | soundcfg.clockbase = clock; |
| soundcfg.minclock = 2 * clock / hz; | soundcfg.minclock = 2 * clock / hz; |
| soundcfg.lastclock = I286_CLOCK; | soundcfg.lastclock = CPU_CLOCK; |
| } | } |
| void sound_streamregist(void *hdl, SOUNDCB cbfn) { | void sound_streamregist(void *hdl, SOUNDCB cbfn) { |
| Line 177 void sound_sync(void) { | Line 182 void sound_sync(void) { |
| return; | return; |
| } | } |
| length = I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK - soundcfg.lastclock; | length = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK - soundcfg.lastclock; |
| if (length < soundcfg.minclock) { | if (length < soundcfg.minclock) { |
| return; | return; |
| } | } |
| Line 205 const SINT32 *sound_pcmlock(void) { | Line 210 const SINT32 *sound_pcmlock(void) { |
| const SINT32 *ret; | const SINT32 *ret; |
| if (locks) { | if (locks) { |
| TRACEOUT(("sound pcm lock: already locked")); | |
| return(NULL); | return(NULL); |
| } | } |
| locks++; | locks++; |
| Line 213 const SINT32 *ret; | Line 219 const SINT32 *ret; |
| SNDCSEC_ENTER; | SNDCSEC_ENTER; |
| if (sndstream.remain > sndstream.reserve) { | if (sndstream.remain > sndstream.reserve) { |
| streamprepare(sndstream.remain - sndstream.reserve); | streamprepare(sndstream.remain - sndstream.reserve); |
| soundcfg.lastclock = I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK; | soundcfg.lastclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK; |
| beep_eventreset(); | beep_eventreset(); |
| } | } |
| } | } |
| else { | |
| locks--; | |
| } | |
| return(ret); | return(ret); |
| } | } |
| Line 239 void sound_pcmunlock(const SINT32 *hdl) | Line 248 void sound_pcmunlock(const SINT32 *hdl) |
| } | } |
| } | } |
| // ---- | |
| BOOL pcmmix_regist(PMIXDAT *dat, void *datptr, UINT datsize, UINT rate) { | |
| GETSND gs; | |
| BYTE tmp[256]; | |
| UINT size; | |
| UINT r; | |
| SINT16 *buf; | |
| gs = getsnd_create(datptr, datsize); | |
| if (gs == NULL) { | |
| goto pmr_err1; | |
| } | |
| if (getsnd_setmixproc(gs, rate, 1) != SUCCESS) { | |
| goto pmr_err2; | |
| } | |
| size = 0; | |
| do { | |
| r = getsnd_getpcmbyleng(gs, tmp, sizeof(tmp)); | |
| size += r; | |
| } while(r); | |
| getsnd_destroy(gs); | |
| if (size == 0) { | |
| goto pmr_err1; | |
| } | |
| buf = (SINT16 *)_MALLOC(size, "PCM DATA"); | |
| if (buf == NULL) { | |
| goto pmr_err1; | |
| } | |
| gs = getsnd_create(datptr, datsize); | |
| if (gs == NULL) { | |
| goto pmr_err1; | |
| } | |
| if (getsnd_setmixproc(gs, rate, 1) != SUCCESS) { | |
| goto pmr_err2; | |
| } | |
| r = getsnd_getpcmbyleng(gs, buf, size); | |
| getsnd_destroy(gs); | |
| dat->sample = buf; | |
| dat->samples = r / 2; | |
| return(SUCCESS); | |
| pmr_err2: | |
| getsnd_destroy(gs); | |
| pmr_err1: | |
| return(FAILURE); | |
| } | |
| BOOL pcmmix_regfile(PMIXDAT *dat, const char *fname, UINT rate) { | |
| FILEH fh; | |
| UINT size; | |
| BYTE *ptr; | |
| BOOL r; | |
| r = FAILURE; | |
| fh = file_open_rb(fname); | |
| if (fh == FILEH_INVALID) { | |
| goto pmrf_err1; | |
| } | |
| size = file_getsize(fh); | |
| if (size == 0) { | |
| goto pmrf_err2; | |
| } | |
| ptr = (BYTE *)_MALLOC(size, fname); | |
| if (ptr == NULL) { | |
| goto pmrf_err2; | |
| } | |
| file_read(fh, ptr, size); | |
| file_close(fh); | |
| r = pcmmix_regist(dat, ptr, size, rate); | |
| _MFREE(ptr); | |
| return(r); | |
| pmrf_err2: | |
| file_close(fh); | |
| pmrf_err1: | |
| return(FAILURE); | |
| } | |
| void SOUNDCALL pcmmix_getpcm(PCMMIX hdl, SINT32 *pcm, UINT count) { | |
| UINT32 bitmap; | |
| PMIXTRK *t; | |
| const SINT16 *s; | |
| UINT srem; | |
| SINT32 *d; | |
| UINT drem; | |
| UINT r; | |
| UINT j; | |
| UINT flag; | |
| SINT32 vol; | |
| SINT32 samp; | |
| if ((hdl->hdr.playing == 0) || (count == 0)) { | |
| return; | |
| } | |
| t = hdl->trk; | |
| bitmap = 1; | |
| do { | |
| if (hdl->hdr.playing & bitmap) { | |
| s = t->pcm; | |
| srem = t->remain; | |
| d = pcm; | |
| drem = count; | |
| flag = t->flag; | |
| vol = t->volume; | |
| do { | |
| r = min(srem, drem); | |
| switch(flag & (PMIXFLAG_L | PMIXFLAG_R)) { | |
| case PMIXFLAG_L: | |
| for (j=0; j<r; j++) { | |
| d[j*2+0] += (s[j] * vol) >> 12; | |
| } | |
| break; | |
| case PMIXFLAG_R: | |
| for (j=0; j<r; j++) { | |
| d[j*2+1] += (s[j] * vol) >> 12; | |
| } | |
| break; | |
| case PMIXFLAG_L | PMIXFLAG_R: | |
| for (j=0; j<r; j++) { | |
| samp = (s[j] * vol) >> 12; | |
| d[j*2+0] += samp; | |
| d[j*2+1] += samp; | |
| } | |
| break; | |
| } | |
| s += r; | |
| d += r*2; | |
| srem -= r; | |
| if (srem == 0) { | |
| if (flag & PMIXFLAG_LOOP) { | |
| s = t->data.sample; | |
| srem = t->data.samples; | |
| } | |
| else { | |
| hdl->hdr.playing &= ~bitmap; | |
| break; | |
| } | |
| } | |
| drem -= r; | |
| } while(drem); | |
| t->pcm = s; | |
| t->remain = srem; | |
| } | |
| t++; | |
| bitmap <<= 1; | |
| } while(bitmap < hdl->hdr.enable); | |
| } | |