Example #1
0
void ymz770_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
	stream_sample_t *outL, *outR;

	outL = outputs[0];
	outR = outputs[1];

	for (int i = 0; i < samples; i++)
	{
		// run sequencers (should probably be in separate timer callbacks)
		for (int ch = 0; ch < 8; ch++)
		{
			if (m_channels[ch].is_seq_playing)
			{
				if (m_channels[ch].seqdelay > 0)
				{
					m_channels[ch].seqdelay--;
				}
				else
				{
					int reg = *m_channels[ch].seqdata++;
					UINT8 data = *m_channels[ch].seqdata++;
					switch (reg)
					{
						case 0x0f:
							if (m_channels[ch].seqcontrol & 1)
							{
								// loop sequence
								UINT8 sqn = m_channels[ch].sequence;
								UINT32 pptr = m_rom_base[(4*sqn)+1+0x400]<<16 | m_rom_base[(4*sqn)+2+0x400]<<8 | m_rom_base[(4*sqn)+3+0x400];
								m_channels[ch].seqdata = &m_rom_base[pptr];
							}
							else
							{
								m_channels[ch].is_seq_playing = false;
							}
							break;
						case 0x0e:
							m_channels[ch].seqdelay = 32 - 1;
							break;
						default:
							internal_reg_write(reg, data);
							break;
					}
				}
			}
		}

		// process channels
		INT32 mix = 0;

		for (int ch = 0; ch < 8; ch++)
		{
			if (m_channels[ch].output_remaining > 0)
			{
				// force finish current block
				mix += (m_channels[ch].output_data[m_channels[ch].output_ptr++]*m_channels[ch].volume);
				m_channels[ch].output_remaining--;

				if (m_channels[ch].output_remaining == 0 && !m_channels[ch].is_playing)
					m_channels[ch].decoder->clear();
			}

			else if (m_channels[ch].is_playing)
			{
retry:
				if (m_channels[ch].last_block)
				{
					if (m_channels[ch].control & 1)
					{
						// loop sample
						UINT8 phrase = m_channels[ch].phrase;
						m_channels[ch].atbl = m_rom_base[(4*phrase)+0] >> 4 & 7;
						m_channels[ch].pptr = 8*(m_rom_base[(4*phrase)+1]<<16 | m_rom_base[(4*phrase)+2]<<8 | m_rom_base[(4*phrase)+3]);
					}
					else
					{
						m_channels[ch].is_playing = false;
						m_channels[ch].output_remaining = 0;
						m_channels[ch].decoder->clear();
					}
				}

				if (m_channels[ch].is_playing)
				{
					// next block
					int sample_rate, channel_count;
					if (!m_channels[ch].decoder->decode_buffer(m_channels[ch].pptr, m_rom_limit, m_channels[ch].output_data, m_channels[ch].output_remaining, sample_rate, channel_count) || m_channels[ch].output_remaining == 0)
					{
						m_channels[ch].is_playing = !m_channels[ch].last_block; // detect infinite retry loop
						m_channels[ch].last_block = true;
						m_channels[ch].output_remaining = 0;
						goto retry;
					}

					m_channels[ch].last_block = m_channels[ch].output_remaining < 1152;
					m_channels[ch].output_remaining--;
					m_channels[ch].output_ptr = 1;

					mix += (m_channels[ch].output_data[0]*m_channels[ch].volume);
				}
			}
Example #2
0
void ymz770_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
	stream_sample_t *outL, *outR;

	outL = outputs[0];
	outR = outputs[1];

	for (int i = 0; i < samples; i++)
	{
		// run sequencers (should probably be in separate timer callbacks)
		for (auto & elem : m_channels)
		{
			if (elem.is_seq_playing)
			{
				if (elem.seqdelay > 0)
				{
					elem.seqdelay--;
				}
				else
				{
					int reg = *elem.seqdata++;
					uint8_t data = *elem.seqdata++;
					switch (reg)
					{
						case 0x0f:
							if (elem.seqcontrol & 1)
							{
								// loop sequence
								uint8_t sqn = elem.sequence;
								uint32_t pptr = m_rom[(4*sqn)+1+0x400]<<16 | m_rom[(4*sqn)+2+0x400]<<8 | m_rom[(4*sqn)+3+0x400];
								elem.seqdata = &m_rom[pptr];
							}
							else
							{
								elem.is_seq_playing = false;
							}
							break;
						case 0x0e:
							elem.seqdelay = 32 - 1;
							break;
						default:
							internal_reg_write(reg, data);
							break;
					}
				}
			}
		}

		// process channels
		int32_t mix = 0;

		for (auto & elem : m_channels)
		{
			if (elem.output_remaining > 0)
			{
				// force finish current block
				mix += (elem.output_data[elem.output_ptr++]*elem.volume);
				elem.output_remaining--;

				if (elem.output_remaining == 0 && !elem.is_playing)
					elem.decoder->clear();
			}

			else if (elem.is_playing)
			{
retry:
				if (elem.last_block)
				{
					if (elem.control & 1)
					{
						// loop sample
						uint8_t phrase = elem.phrase;
						elem.atbl = m_rom[(4*phrase)+0] >> 4 & 7;
						elem.pptr = 8*(m_rom[(4*phrase)+1]<<16 | m_rom[(4*phrase)+2]<<8 | m_rom[(4*phrase)+3]);
					}
					else
					{
						elem.is_playing = false;
						elem.output_remaining = 0;
						elem.decoder->clear();
					}
				}

				if (elem.is_playing)
				{
					// next block
					int sample_rate, channel_count;
					if (!elem.decoder->decode_buffer(elem.pptr, m_rom.bytes()*8, elem.output_data, elem.output_remaining, sample_rate, channel_count) || elem.output_remaining == 0)
					{
						elem.is_playing = !elem.last_block; // detect infinite retry loop
						elem.last_block = true;
						elem.output_remaining = 0;
						goto retry;
					}

					elem.last_block = elem.output_remaining < 1152;
					elem.output_remaining--;
					elem.output_ptr = 1;

					mix += (elem.output_data[0]*elem.volume);
				}
			}
Example #3
0
void ymz770_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
	stream_sample_t *outL, *outR;
	int i, ch;

	outL = outputs[0];
	outR = outputs[1];

	for (i = 0; i < samples; i++)
	{
		INT32 mix;

		mix = 0;

		for (ch = 0; ch < 8; ch++)
		{
			if (channels[ch].is_seq_playing)
			{
				if (channels[ch].seqdelay != 0)
				{
					channels[ch].seqdelay--;
				}
				else
				{
					int reg = *channels[ch].seqdata++;
					UINT8 data = *channels[ch].seqdata++;
					switch (reg)
					{
						case 0x0f:
							if (channels[ch].seqcontrol & 1)
							{
								UINT8 sqn = channels[ch].sequence;
								UINT32 pptr = rom_base[(4*sqn)+1+0x400]<<16 | rom_base[(4*sqn)+2+0x400]<<8 | rom_base[(4*sqn)+3+0x400];
								channels[ch].seqdata = &rom_base[pptr];
							}
							else
							{
								channels[ch].is_seq_playing = false;
							}
							break;
						case 0x0e:
							channels[ch].seqdelay = 32 - 1;
							break;
						default:
							cur_reg = reg;
							internal_reg_write(1, data);
							break;
					}
				}
			}
			if (channels[ch].is_playing)
			{
				if (channels[ch].output_remaining > 0)
				{
					mix += (channels[ch].output_data[channels[ch].output_ptr++]*2*channels[ch].volume);
					channels[ch].output_remaining--;
				}
				else
				{
				retry:
					if (channels[ch].last_block)
					{
						if (channels[ch].control & 1)
						{
								UINT8 phrase = channels[ch].phrase;
								channels[ch].pptr = 8*(rom_base[(4*phrase)+1]<<16 | rom_base[(4*phrase)+2]<<8 | rom_base[(4*phrase)+3]);
						}
						else
						{
								channels[ch].is_playing = false;
						}
					}

					if (channels[ch].is_playing)
					{
						int sample_rate, channel_count;
						if(!channels[ch].decoder->decode_buffer(channels[ch].pptr,
																rom_size,
																channels[ch].output_data,
																channels[ch].output_remaining,
																sample_rate,
																channel_count))
						{
							channels[ch].last_block = true;
							goto retry;
						}

						channels[ch].last_block = channels[ch].output_remaining < 1152;
						channels[ch].output_remaining--;
						channels[ch].output_ptr = 1;

						mix += (channels[ch].output_data[0]*2*channels[ch].volume);
					}
				}
			}
		}

		outL[i] = outR[i] = mix>>8;
	}
}