|
|
| version 1.7, 2004/02/18 18:29:29 | version 1.9, 2004/02/21 16:35:31 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include <math.h> | #include <math.h> |
| #include "wavefile.h" | |
| #include "dosio.h" | |
| #include "pccore.h" | #include "pccore.h" |
| #include "sound.h" | #include "sound.h" |
| #include "rhythm.h" | #include "rhythm.h" |
| Line 14 static const char file_2608hh[] = "2608_ | Line 12 static const char file_2608hh[] = "2608_ |
| static const char file_2608tom[] = "2608_tom.wav"; | static const char file_2608tom[] = "2608_tom.wav"; |
| static const char file_2608rim[] = "2608_rim.wav"; | static const char file_2608rim[] = "2608_rim.wav"; |
| static const char *rhythmfile[RHYTHM_MAX] = { | static const char *rhythmfile[6] = { |
| file_2608bd, file_2608sd, file_2608top, | file_2608bd, file_2608sd, file_2608top, |
| file_2608hh, file_2608tom, file_2608rim}; | file_2608hh, file_2608tom, file_2608rim}; |
| RHYTHMCFG rhythmcfg; | typedef struct { |
| UINT rate; | |
| UINT pcmexist; | |
| PMIXDAT pcm[6]; | |
| UINT vol; | |
| UINT voltbl[96]; | |
| } RHYTHMCFG; | |
| static RHYTHMCFG rhythmcfg; | |
| static BOOL pcmload(RHYTHMPCM *pcm, const char *fname, UINT rate) { | |
| char path[MAX_PATH]; | |
| FILEH fh; | |
| RIFF_HEADER riff; | |
| BOOL head; | |
| WAVE_HEADER whead; | |
| UINT size; | |
| WAVE_INFOS info; | |
| UINT step; | |
| UINT samples; | |
| SINT16 *ptr; | |
| UINT rsize; | |
| UINT pos; | |
| BYTE work[256]; | |
| getbiospath(path, fname, sizeof(path)); | |
| fh = file_open_rb(path); | |
| if (fh == FILEH_INVALID) { | |
| goto pld_err1; | |
| } | |
| if ((file_read(fh, &riff, sizeof(riff)) != sizeof(riff)) || | |
| (riff.sig != WAVE_SIG('R','I','F','F')) || | |
| (riff.fmt != WAVE_SIG('W','A','V','E'))) { | |
| goto pld_err2; | |
| } | |
| head = FALSE; | |
| while(1) { | |
| if (file_read(fh, &whead, sizeof(whead)) != sizeof(whead)) { | |
| goto pld_err2; | |
| } | |
| size = LOADINTELDWORD(whead.size); | |
| if (whead.sig == WAVE_SIG('f','m','t',' ')) { | |
| if (size >= sizeof(info)) { | |
| if (file_read(fh, &info, sizeof(info)) != sizeof(info)) { | |
| goto pld_err2; | |
| } | |
| size -= sizeof(info); | |
| head = TRUE; | |
| } | |
| } | |
| else if (whead.sig == WAVE_SIG('d','a','t','a')) { | |
| break; | |
| } | |
| if (size) { | |
| file_seek(fh, size, FSEEK_CUR); | |
| } | |
| } | |
| if (!head) { | |
| goto pld_err2; | |
| } | |
| if ((LOADINTELWORD(info.channel) != 1) || | |
| (LOADINTELDWORD(info.rate) != 44100) || | |
| (LOADINTELWORD(info.bit) != 16)) { | |
| goto pld_err2; | |
| } | |
| if (rate == 0) { | |
| goto pld_err2; | |
| } | |
| step = 44100 / rate; | |
| if (step == 0) { | |
| goto pld_err2; | |
| } | |
| samples = size / 2 / step; | |
| if (samples == 0) { | |
| goto pld_err2; | |
| } | |
| ptr = (SINT16 *)_MALLOC(samples * sizeof(SINT16), fname); | |
| if (ptr == NULL) { | |
| goto pld_err2; | |
| } | |
| ZeroMemory(ptr, samples * sizeof(SINT16)); | |
| pcm->data = ptr; | |
| pcm->samples = samples; | |
| pos = 0; | |
| rsize = 0; | |
| do { | |
| while(pos >= rsize) { | |
| pos -= rsize; | |
| rsize = file_read(fh, work, sizeof(work)); | |
| rsize &= (~1); | |
| if (rsize == 0) { | |
| break; | |
| } | |
| } | |
| *ptr++ = (SINT16)LOADINTELWORD(work + pos); | |
| pos += step * sizeof(SINT16); | |
| } while(--samples); | |
| file_close(fh); | |
| return(SUCCESS); | |
| pld_err2: | |
| file_close(fh); | |
| pld_err1: | |
| return(FAILURE); | |
| } | |
| void rhythm_initialize(UINT rate) { | void rhythm_initialize(UINT rate) { |
| UINT i; | UINT i; |
| ZeroMemory(&rhythmcfg, sizeof(rhythmcfg)); | ZeroMemory(&rhythmcfg, sizeof(rhythmcfg)); |
| for (i=0; i<6; i++) { | rhythmcfg.rate = rate; |
| pcmload(rhythmcfg.pcm + i, rhythmfile[i], rate); | |
| } | |
| for (i=0; i<96; i++) { | for (i=0; i<96; i++) { |
| rhythmcfg.voltbl[i] = (UINT)(32768.0 * | rhythmcfg.voltbl[i] = (UINT)(32768.0 * |
| pow(2.0, (double)i * (-3.0) / 40.0)); | pow(2.0, (double)i * (-3.0) / 40.0)); |
| Line 139 void rhythm_deinitialize(void) { | Line 45 void rhythm_deinitialize(void) { |
| UINT i; | UINT i; |
| SINT16 *ptr; | SINT16 *ptr; |
| for (i=0; i<RHYTHM_MAX; i++) { | for (i=0; i<6; i++) { |
| ptr = rhythmcfg.pcm[i].data; | ptr = rhythmcfg.pcm[i].sample; |
| rhythmcfg.pcm[i].data = NULL; | rhythmcfg.pcm[i].sample = NULL; |
| if (ptr) { | if (ptr) { |
| _MFREE(ptr); | _MFREE(ptr); |
| } | } |
| } | } |
| } | } |
| static void rhythm_load(void) { | |
| int i; | |
| char path[MAX_PATH]; | |
| for (i=0; i<6; i++) { | |
| if (rhythmcfg.pcm[i].sample == NULL) { | |
| getbiospath(path, rhythmfile[i], sizeof(path)); | |
| pcmmix_regfile(rhythmcfg.pcm + i, path, rhythmcfg.rate); | |
| } | |
| } | |
| } | |
| UINT rhythm_getcaps(void) { | |
| UINT ret; | |
| UINT i; | |
| ret = 0; | |
| for (i=0; i<6; i++) { | |
| if (rhythmcfg.pcm[i].sample) { | |
| ret |= 1 << i; | |
| } | |
| } | |
| return(ret); | |
| } | |
| void rhythm_setvol(UINT vol) { | void rhythm_setvol(UINT vol) { |
| rhythmcfg.vol = vol; | rhythmcfg.vol = vol; |
| Line 156 void rhythm_setvol(UINT vol) { | Line 89 void rhythm_setvol(UINT vol) { |
| void rhythm_reset(RHYTHM rhy) { | void rhythm_reset(RHYTHM rhy) { |
| ZeroMemory(rhy, sizeof(_RHYTHM)); | ZeroMemory(rhy, sizeof(_RHYTHM)); |
| } | |
| void rhythm_bind(RHYTHM rhy) { | |
| UINT i; | |
| rhythm_load(); | |
| rhy->hdr.enable = 0x3f; | |
| for (i=0; i<6; i++) { | |
| rhy->trk[i].data = rhythmcfg.pcm[i]; | |
| } | |
| rhythm_update(rhy); | rhythm_update(rhy); |
| sound_streamregist(rhy, (SOUNDCB)pcmmix_getpcm); | |
| } | } |
| void rhythm_update(RHYTHM rhy) { | void rhythm_update(RHYTHM rhy) { |
| RHYTHMCH *r; | UINT i; |
| RHYTHMCH *rterm; | |
| r = rhy->r; | for (i=0; i<6; i++) { |
| rterm = r + RHYTHM_MAX; | rhy->trk[i].volume = (rhythmcfg.voltbl[rhy->vol + rhy->trkvol[i]] * |
| do { | |
| r->volume = (rhythmcfg.voltbl[rhy->vol + r->volreg] * | |
| rhythmcfg.vol) >> 10; | rhythmcfg.vol) >> 10; |
| } while(++r < rterm); | } |
| } | } |
| void rhythm_setreg(RHYTHM rhy, REG8 reg, REG8 value) { | void rhythm_setreg(RHYTHM rhy, REG8 reg, REG8 value) { |
| RHYTHMCH *r; | PMIXTRK *trk; |
| REG8 bit; | REG8 bit; |
| int i; | |
| if (reg == 0x10) { | if (reg == 0x10) { |
| sound_sync(); | sound_sync(); |
| r = rhy->r; | trk = rhy->trk; |
| for (i=0, bit=1; i<6; i++, bit<<=1) { | bit = 0x01; |
| do { | |
| if (value & bit) { | if (value & bit) { |
| if (value & 0x80) { | if (value & 0x80) { |
| rhy->bitmap &= ~((UINT)bit); | rhy->hdr.playing &= ~((UINT)bit); |
| } | } |
| else { | else if (trk->data.sample) { |
| if (rhythmcfg.pcm[i].data) { | trk->pcm = trk->data.sample; |
| r->ptr = rhythmcfg.pcm[i].data; | trk->remain = trk->data.samples; |
| r->remain = rhythmcfg.pcm[i].samples; | rhy->hdr.playing |= bit; |
| rhy->bitmap |= bit; | |
| } | |
| } | } |
| } | } |
| r++; | trk++; |
| } | bit <<= 1; |
| } while(bit < 0x40); | |
| } | } |
| else if (reg == 0x11) { | else if (reg == 0x11) { |
| sound_sync(); | sound_sync(); |
| Line 204 void rhythm_setreg(RHYTHM rhy, REG8 reg, | Line 145 void rhythm_setreg(RHYTHM rhy, REG8 reg, |
| } | } |
| else if ((reg >= 0x18) && (reg < 0x1e)) { | else if ((reg >= 0x18) && (reg < 0x1e)) { |
| sound_sync(); | sound_sync(); |
| r = rhy->r + (reg - 0x18); | trk = rhy->trk + (reg - 0x18); |
| r->volreg = (~value) & 0x1f; | trk->flag = ((value & 0x80) >> 7) + ((value & 0x40) >> 5); |
| r->volume = (rhythmcfg.voltbl[rhy->vol + r->volreg] * | value = (~value) & 0x1f; |
| rhy->trkvol[reg - 0x18] = (UINT8)value; | |
| trk->volume = (rhythmcfg.voltbl[rhy->vol + value] * | |
| rhythmcfg.vol) >> 10; | rhythmcfg.vol) >> 10; |
| r->lr = value & 0xc0; | |
| } | } |
| } | } |