| 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); | 
 |  | } | 
 |  |  |