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