示例#1
0
文件: s14001a.c 项目: bji/libmame
static STREAM_UPDATE( s14001a_pcm_update )
{
	INT32 mix[48000];
	//INT32 *mixp;
	S14001AChip *chip = (S14001AChip *)param;
	int i;

	memset(mix, 0, sizeof(mix));

	//mixp = &mix[0];
	for (i = 0; i < samples; i++)
	{
		s14001a_clock(chip);
#ifdef ACCURATE_SQUEAL
		if (chip->audioout == ALTFLAG) // input from test pins -> output
		{
			shiftIntoFilter(chip, audiofilter(chip)); // shift over the previous outputs and stick in audioout.
			outputs[0][i] = audiofilter(chip)*chip->VSU1000_amp;
		}
		else // normal, dac-driven output
		{
			shiftIntoFilter(chip, ((((INT16)chip->audioout)-8)<<9)); // shift over the previous outputs and stick in audioout 4 times. note <<9 instead of <<10, to prevent clipping, and to simulate that the filtered output normally has a somewhat lower amplitude than the driven one.
#endif
			outputs[0][i] = ((((INT16)chip->audioout)-8)<<10)*chip->VSU1000_amp;
#ifdef ACCURATE_SQUEAL
		}
#endif
	}
}
示例#2
0
void s14001a_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
	int i;

	for (i = 0; i < samples; i++)
		{
			s14001a_clock();
	#ifdef ACCURATE_SQUEAL
		if (m_audioout == ALTFLAG) // input from test pins -> output
			{
				shiftIntoFilter(chip, audiofilter(chip)); // shift over the previous outputs and stick in audioout.
				outputs[0][i] = audiofilter(chip)*m_VSU1000_amp;
			}
		else // normal, dac-driven output
			{
				shiftIntoFilter(chip, ((((INT16)m_audioout)-8)<<9)); // shift over the previous outputs and stick in audioout 4 times. note <<9 instead of <<10, to prevent clipping, and to simulate that the filtered output normally has a somewhat lower amplitude than the driven one.
	#endif
				outputs[0][i] = ((((INT16)m_audioout)-8)<<10)*m_VSU1000_amp;
	#ifdef ACCURATE_SQUEAL
			}
	#endif
		}
}
示例#3
0
void s14001a_clock(void) /* called once per clock */
{
	UINT8 CurDelta; // Current delta

	/* on even clocks, audio output is floating, /romen is low so rom data bus is driven, input is latched?
	 * on odd clocks, audio output is driven, /romen is high, state machine 2 is clocked */
	oddeven = !(oddeven); // invert the clock
	if (oddeven == 0) // even clock
        {
		audioout = audiofilter(); // function to handle output filtering by internal capacitance based on clock speed and such
#ifdef PINMAME
		if (!machineState) audioout = SILENCE;
#endif
		shiftIntoFilter(audioout); // shift over all the filter outputs and stick in audioout
	}
	else // odd clock
	{
		// fix dac output between samples. theoretically this might be unnecessary but it would require some messy logic in state 5 on the first sample load.
		if (GlobalSilenceState || LOCALSILENCESTATE)
		{
			DACOutput = SILENCE;
			OldDelta = 2;
		}
		audioout = (GlobalSilenceState || LOCALSILENCESTATE) ? SILENCE : DACOutput; // when either silence state is 1, output silence.
#ifdef PINMAME
		if (!machineState) audioout = SILENCE;
#endif
		shiftIntoFilter(audioout); // shift over all the filter outputs and stick in audioout
		switch(machineState)
		{
		case 0: // idle state
			nextstate = 0;
			break;
		case 1: // read starting syllable high byte from word table
			SyllableAddress = 0; // clear syllable address
			SyllableAddress |= s14001a_readmem(LatchedWord<<1)<<4;
			nextstate = resetState ? 1 : 2;
			break;
		case 2: // read starting syllable low byte from word table
			SyllableAddress |= s14001a_readmem((LatchedWord<<1)+1)>>4;
			nextstate = 3;
			break;
		case 3: // read starting phone address
			PhoneAddress = s14001a_readmem(SyllableAddress)<<4;
			nextstate = 4;
			break;
		case 4: // read playback parameters and prepare for play
			PlayParams = s14001a_readmem(SyllableAddress+1);
			GlobalSilenceState = SILENCEFLAG; // load phone silence flag
			LengthCounter = LENGTHCOUNT; // load length counter
			RepeatCounter = REPEATCOUNT; // load repeat counter
			OutputCounter = 0; // clear output counter and disable mirrored phoneme silence indirectly via LOCALSILENCESTATE
			PhoneOffset = 0; // set offset within phone to zero
			OldDelta = 0x2; // set old delta to 2 <- is this right?
			DACOutput = 0x88; // set DAC output to center/silence position (0x88)
			nextstate = 5;
			break;
		case 5: // Play phone forward, shift = 0 (also load)
			CurDelta = (s14001a_readmem((PhoneAddress)+PhoneOffset)&0xc0)>>6; // grab current delta from high 2 bits of high nybble
			DACOutput += DeltaTable[CurDelta][OldDelta]; // send data to forward delta table and add result to accumulator
			OldDelta = CurDelta; // Move current delta to old
			nextstate = 6;
			break;
		case 6: // Play phone forward, shift = 2
	   		CurDelta = (s14001a_readmem((PhoneAddress)+PhoneOffset)&0x30)>>4; // grab current delta from low 2 bits of high nybble
			DACOutput += DeltaTable[CurDelta][OldDelta]; // send data to forward delta table and add result to accumulator
			OldDelta = CurDelta; // Move current delta to old
			nextstate = 7;
			break;
		case 7: // Play phone forward, shift = 4
			CurDelta = (s14001a_readmem((PhoneAddress)+PhoneOffset)&0xc)>>2; // grab current delta from high 2 bits of low nybble
			DACOutput += DeltaTable[CurDelta][OldDelta]; // send data to forward delta table and add result to accumulator
			OldDelta = CurDelta; // Move current delta to old
			nextstate = 8;
			break;
		case 8: // Play phone forward, shift = 6 (increment address if needed)
			CurDelta = s14001a_readmem((PhoneAddress)+PhoneOffset)&0x3; // grab current delta from low 2 bits of low nybble
			DACOutput += DeltaTable[CurDelta][OldDelta]; // send data to forward delta table and add result to accumulator
			OldDelta = CurDelta; // Move current delta to old
			PhoneOffset++; // increment phone offset
			if (PhoneOffset == 0x8) // if we're now done this phone
			{
				/* call the PostPhoneme Function */
				PostPhoneme();
			}
			else
			{
				nextstate = 5;
			}
			break;
		case 9: // Play phone backward, shift = 6 (also load)
			CurDelta = (s14001a_readmem((PhoneAddress)+PhoneOffset)&0x3); // grab current delta from low 2 bits of low nybble
			if (laststate != 8) // ignore first (bogus) dac change in mirrored backwards mode. observations and the patent show this.
			{
				DACOutput -= DeltaTable[OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
			}
			OldDelta = CurDelta; // Move current delta to old
			nextstate = 10;
			break;
		case 10: // Play phone backward, shift = 4
			CurDelta = (s14001a_readmem((PhoneAddress)+PhoneOffset)&0xc)>>2; // grab current delta from high 2 bits of low nybble
			DACOutput -= DeltaTable[OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
			OldDelta = CurDelta; // Move current delta to old
			nextstate = 11;
			break;
		case 11: // Play phone backward, shift = 2
			CurDelta = (s14001a_readmem((PhoneAddress)+PhoneOffset)&0x30)>>4; // grab current delta from low 2 bits of high nybble
			DACOutput -= DeltaTable[OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
			OldDelta = CurDelta; // Move current delta to old
			nextstate = 12;
			break;
		case 12: // Play phone backward, shift = 0 (increment address if needed)
			CurDelta = (s14001a_readmem((PhoneAddress)+PhoneOffset)&0xc0)>>6; // grab current delta from high 2 bits of high nybble
			DACOutput -= DeltaTable[OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
			OldDelta = CurDelta; // Move current delta to old
			PhoneOffset--; // decrement phone offset
			if (PhoneOffset == 0xFF) // if we're now done this phone
			{
				/* call the PostPhoneme() function */
				PostPhoneme();
			}
			else
			{
				nextstate = 9;
			}
			break;
		case 13: // For those pedantic among us, consume an extra two clocks like the real chip does.
			nextstate = 0;
			break;
		}
#ifdef DEBUGSTATE
		fprintf(stderr, "Machine state is now %d, was %d, PhoneOffset is %d\n", nextstate, machineState, PhoneOffset);
#endif
		laststate = machineState;
		machineState = nextstate;
	}
}