File:  [RetroPC.NET] / np2 / sound / Attic / wavemix.c
Revision 1.2: download - view: text, annotated - select for diffs
Fri Jan 9 13:36:02 2004 JST (21 years, 9 months ago) by yui
Branches: MAIN
CVS tags: VER_0_74, VER_0_73, HEAD
add hostdrv (readonly...) (T.Yui)

#include	"compiler.h"

#if defined(SUPPORT_WAVEMIX)

#include	"pccore.h"
#include	"sound.h"
#include	"getsnd.h"
#include	"wavemix.res"

typedef struct {
const SINT16	*pcm;
	UINT		remain;
	SINT16		*sample;
	UINT		samples;
	UINT		flag;
	SINT32		volume;
} _WMTRK, *WMTRK;

typedef struct {
	UINT32	playing;
	_WMTRK	trk[WAVEMIX_MAXTRACK];
} _WAVEMIX, *WAVEMIX;

static	_WAVEMIX	wavemix;


static SINT16 *getpcmdata(void *datptr, UINT datsize,
										UINT rate, UINT *samples) {

	GETSND	gs;
	BYTE	tmp[256];
	UINT	size;
	UINT	r;
	SINT16	*ret;

	gs = getsnd_create(datptr, datsize);
	if (gs == NULL) {
		goto gpd_err1;
	}
	if (getsnd_setmixproc(gs, rate, 1) != SUCCESS) {
		goto gpd_err2;
	}
	size = 0;
	do {
		r = getsnd_getpcmbyleng(gs, tmp, sizeof(tmp));
		size += r;
	} while(r);
	getsnd_destroy(gs);
	if (size == 0) {
		goto gpd_err1;
	}

	ret = (SINT16 *)_MALLOC(size, "SEEKSND");
	if (ret == NULL) {
		goto gpd_err1;
	}
	gs = getsnd_create(datptr, datsize);
	if (gs == NULL) {
		goto gpd_err1;
	}
	if (getsnd_setmixproc(gs, rate, 1) != SUCCESS) {
		goto gpd_err2;
	}
	r = getsnd_getpcmbyleng(gs, ret, size);
	getsnd_destroy(gs);
	if (samples) {
		*samples = (r / 2);
	}
	return(ret);

gpd_err2:
	getsnd_destroy(gs);

gpd_err1:
	return(NULL);
}

static void SOUNDCALL wavemix_getpcm(WAVEMIX hdl, SINT32 *pcm, UINT count) {

	UINT32		bitmap;
	WMTRK		t;
const SINT16	*s;
	UINT		srem;
	SINT32		*d;
	UINT		drem;
	UINT		r;
	UINT		j;
	UINT		flag;
	SINT32		vol;
	SINT32		samp;

	if ((hdl->playing == 0) || (count == 0))  {
		return;
	}
	t = hdl->trk;
	bitmap = 1;
	do {
		if (hdl->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 & (WMFLAG_L | WMFLAG_R)) {
					case WMFLAG_L:
						for (j=0; j<r; j++) {
							d[j*2+0] += (s[j] * vol) >> 12;
						}
						break;

					case WMFLAG_R:
						for (j=0; j<r; j++) {
							d[j*2+1] += (s[j] * vol) >> 12;
						}
						break;

					case WMFLAG_L | WMFLAG_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 & WMFLAG_LOOP) {
						s = t->sample;
						srem = t->samples;
					}
					else {
						hdl->playing &= ~bitmap;
						break;
					}
				}
				drem -= r;
			} while(drem);
			t->pcm = s;
			t->remain = srem;
		}
		t++;
		bitmap <<= 1;
	} while(bitmap < (1 << WAVEMIX_MAXTRACK));
}


// ----

void wavemix_initialize(UINT rate) {

	SINT16	*sample;
	UINT	samples;

	ZeroMemory(&wavemix, sizeof(wavemix));

	sample = getpcmdata((void *)fddseek, sizeof(fddseek), rate, &samples);
	if (sample) {
		wavemix.trk[0].sample = sample;
		wavemix.trk[0].samples = samples;
		wavemix.trk[0].flag = WMFLAG_L | WMFLAG_R;
		wavemix.trk[0].volume = (np2cfg.MOTORVOL << 12) / 100;
	}
	sample = getpcmdata((void *)fddseek1, sizeof(fddseek1), rate, &samples);
	if (sample) {
		wavemix.trk[1].sample = sample;
		wavemix.trk[1].samples = samples;
		wavemix.trk[1].flag = WMFLAG_L | WMFLAG_R;
		wavemix.trk[1].volume = (np2cfg.MOTORVOL << 12) / 100;
	}
}

void wavemix_deinitialize(void) {

	WMTRK	t;
	WMTRK	tterm;

	t = wavemix.trk;
	tterm = t + WAVEMIX_MAXTRACK;
	while(t < tterm) {
		if (t->sample) {
			_MFREE(t->sample);
		}
		t++;
	}
	ZeroMemory(&wavemix, sizeof(wavemix));
}

void wavemix_play(UINT num, BOOL loop) {

	WMTRK	t;

	if (num < WAVEMIX_MAXTRACK) {
		t = wavemix.trk + num;
		if ((t->sample) && (t->samples)) {
			sound_sync();
			t->pcm = t->sample;
			t->remain = t->samples;
			if (loop) {
				t->flag |= WMFLAG_LOOP;
			}
			else {
				t->flag &= ~WMFLAG_LOOP;
			}
			wavemix.playing |= (1 << num);
		}
	}
}

void wavemix_stop(UINT num) {

	if (num < WAVEMIX_MAXTRACK) {
		sound_sync();
		wavemix.playing &= ~(1 << num);
	}
}

void wavemix_bind(void) {

	sound_streamregist(&wavemix, (SOUNDCB)wavemix_getpcm);
}

#endif


RetroPC.NET-CVS <cvs@retropc.net>