MemoryContainer <int16_t> [] m_waveform = new MemoryContainer <int16_t> [MAX_VOLUME]; //std::unique_ptr<int16_t[]> m_waveform[MAX_VOLUME]; public namco_audio_device(machine_config mconfig, device_type type, string tag, device_t owner, u32 clock) : base(mconfig, type, tag, owner, clock) { m_class_interfaces.Add(new device_sound_interface_namco_audio(mconfig, this)); //device_sound_interface(mconfig, *this), m_disound = GetClassInterface <device_sound_interface_namco_audio>(); m_wave_ptr = new optional_region_ptr <uint8_t>(this, DEVICE_SELF); m_last_channel = null; m_wavedata = null; m_wave_size = 0; m_sound_enable = false; m_stream = null; m_namco_clock = 0; m_sample_rate = 0; m_f_fracbits = 0; m_voices = 0; m_stereo = false; for (int i = 0; i < m_channel_list.Length; i++) { m_channel_list[i] = new sound_channel(); } }
// device_sound_interface overrides //------------------------------------------------- // sound_stream_update - handle a stream update //------------------------------------------------- void device_sound_interface_sound_stream_update(sound_stream stream, std.vector <read_stream_view> inputs, std.vector <write_stream_view> outputs) //virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; { if (m_stereo) { /* zap the contents of the buffers */ outputs[0].fill(0); outputs[1].fill(0); /* if no sound, we're done */ if (!m_sound_enable) { return; } /* loop over each voice and add its contribution */ for (int voiceIdx = 0; m_channel_list[voiceIdx] != m_last_channel; voiceIdx++) //for (sound_channel *voice = m_channel_list; voice < m_last_channel; voice++) { sound_channel voice = m_channel_list[voiceIdx]; var lmix = outputs[0]; var rmix = outputs[1]; int lv = voice.volume[0]; int rv = voice.volume[1]; if (voice.noise_sw != 0) { int f = (int)(voice.frequency & 0xff); /* only update if we have non-zero volume */ if (lv != 0 || rv != 0) { int hold_time = 1 << (m_f_fracbits - 16); int hold = voice.noise_hold; uint32_t delta = (uint32_t)(f << 4); uint32_t c = voice.noise_counter; int16_t l_noise_data = OUTPUT_LEVEL(0x07 * (lv >> 1)); int16_t r_noise_data = OUTPUT_LEVEL(0x07 * (rv >> 1)); int i; /* add our contribution */ for (i = 0; i < lmix.samples(); i++) { int cnt; if (voice.noise_state != 0) { lmix.add_int(i, l_noise_data, 32768); rmix.add_int(i, r_noise_data, 32768); } else { lmix.add_int(i, -l_noise_data, 32768); rmix.add_int(i, -r_noise_data, 32768); } if (hold != 0) { hold--; continue; } hold = hold_time; c += delta; cnt = (int)(c >> 12); c &= (1 << 12) - 1; for ( ; cnt > 0; cnt--) { if (((voice.noise_seed + 1) & 2) != 0) { voice.noise_state ^= 1; } if ((voice.noise_seed & 1) != 0) { voice.noise_seed ^= 0x28000; } voice.noise_seed >>= 1; } } /* update the counter and hold time for this voice */ voice.noise_counter = c; voice.noise_hold = hold; } } else { /* save the counter for this voice */ uint32_t c = voice.counter; /* only update if we have non-zero left volume */ if (lv != 0) { Pointer <int16_t> lw = new Pointer <int16_t>(m_waveform[lv], voice.waveform_select * 32); //const int16_t *lw = &m_waveform[lv][voice->waveform_select * 32]; /* generate sound into the buffer */ c = namco_update_one(lmix, lw, voice.counter, voice.frequency); } /* only update if we have non-zero right volume */ if (rv != 0) { Pointer <int16_t> rw = new Pointer <int16_t>(m_waveform[rv], voice.waveform_select * 32); //const int16_t *rw = &m_waveform[rv][voice->waveform_select * 32]; /* generate sound into the buffer */ c = namco_update_one(rmix, rw, voice.counter, voice.frequency); } /* update the counter for this voice */ voice.counter = c; } } } else { int voiceIdx; // sound_channel *voice; var buffer = outputs[0]; /* zap the contents of the buffer */ buffer.fill(0); /* if no sound, we're done */ if (!m_sound_enable) { return; } /* loop over each voice and add its contribution */ for (voiceIdx = 0; m_channel_list[voiceIdx] != m_last_channel; voiceIdx++) //for (voice = m_channel_list; voice < m_last_channel; voice++) { sound_channel voice = m_channel_list[voiceIdx]; int v = voice.volume[0]; if (voice.noise_sw != 0) { int f = (int)(voice.frequency & 0xff); /* only update if we have non-zero volume */ if (v != 0) { int hold_time = 1 << (m_f_fracbits - 16); int hold = voice.noise_hold; uint32_t delta = (uint32_t)(f << 4); uint32_t c = voice.noise_counter; int16_t noise_data = OUTPUT_LEVEL(0x07 * (v >> 1)); int i; /* add our contribution */ for (i = 0; i < buffer.samples(); i++) { int cnt; if (voice.noise_state != 0) { buffer.add_int(i, noise_data, 32768); } else { buffer.add_int(i, -noise_data, 32768); } if (hold != 0) { hold--; continue; } hold = hold_time; c += delta; cnt = (int)(c >> 12); c &= (1 << 12) - 1; for ( ; cnt > 0; cnt--) { if (((voice.noise_seed + 1) & 2) != 0) { voice.noise_state ^= 1; } if ((voice.noise_seed & 1) != 0) { voice.noise_seed ^= 0x28000; } voice.noise_seed >>= 1; } } } } else { /* only update if we have non-zero volume */ if (v != 0) { Pointer <int16_t> w = new Pointer <int16_t>(m_waveform[v], voice.waveform_select * 32); //const int16_t *w = &m_waveform[v][voice->waveform_select * 32]; /* generate sound into buffer and update the counter for this voice */ voice.counter = namco_update_one(buffer, w, voice.counter, voice.frequency); } } } } }
// device-level overrides //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- protected override void device_start() { /* extract globals from the interface */ m_last_channel = m_channel_list[m_voices]; /* build the waveform table */ build_decoded_waveform(m_wave_ptr.op); /* get stream channels */ if (m_stereo) { m_stream = m_disound.stream_alloc(0, 2, 192000); } else { m_stream = m_disound.stream_alloc(0, 1, 192000); } /* start with sound enabled, many games don't have a sound enable register */ m_sound_enable = true; //throw new emu_unimplemented(); #if false if (m_wave_ptr == null) { save_pointer(m_wavedata, "m_wavedata", 0x400); } save_item(m_voices, "m_voices"); save_item(m_sound_enable, "m_sound_enable"); for (int v = 0; v < MAX_VOLUME; v++) { save_pointer(NAME(m_waveform[v]), 32 * 8 * (1 + m_wave_size), v); } #endif /* reset all the voices */ for (int voiceIdx = 0; m_channel_list[voiceIdx] != m_last_channel; voiceIdx++) //for (sound_channel *voice = m_channel_list; voice < m_last_channel; voice++) { sound_channel voice = m_channel_list[voiceIdx]; voice.frequency = 0; voice.volume[0] = voice.volume[1] = 0; voice.waveform_select = 0; voice.counter = 0; voice.noise_sw = 0; voice.noise_state = 0; voice.noise_seed = 1; voice.noise_counter = 0; voice.noise_hold = 0; } //throw new emu_unimplemented(); #if false /* register with the save state system */ save_pointer(STRUCT_MEMBER(m_channel_list, frequency), m_voices); save_pointer(STRUCT_MEMBER(m_channel_list, counter), m_voices); save_pointer(STRUCT_MEMBER(m_channel_list, volume), m_voices); save_pointer(STRUCT_MEMBER(m_channel_list, noise_sw), m_voices); save_pointer(STRUCT_MEMBER(m_channel_list, noise_state), m_voices); save_pointer(STRUCT_MEMBER(m_channel_list, noise_seed), m_voices); save_pointer(STRUCT_MEMBER(m_channel_list, noise_hold), m_voices); save_pointer(STRUCT_MEMBER(m_channel_list, noise_counter), m_voices); save_pointer(STRUCT_MEMBER(m_channel_list, waveform_select), m_voices); #endif }
public override int start(xnamame036.mame.Mame.MachineSound msound) { string mono_name = "NAMCO sound"; string[] stereo_names = { "NAMCO sound left", "NAMCO sound right" }; Namco_interface intf = (Namco_interface)msound.sound_interface; namco_clock = intf.samplerate; sample_rate = Mame.Machine.sample_rate; /* get stream channels */ if (intf.stereo) { int[] vol = new int[2]; vol[1] = Mame.MIXER(intf.volume, Mame.MIXER_PAN_RIGHT); vol[0] = Mame.MIXER(intf.volume, Mame.MIXER_PAN_LEFT); stream = Mame.stream_init_multi(2, stereo_names, vol, intf.samplerate, 0, namco_update_stereo); } else { stream = Mame.stream_init(mono_name, intf.volume, intf.samplerate, 0, namco_update_mono); } /* allocate a pair of buffers to mix into - 1 second's worth should be more than enough */ mixer_buffer = new _ShortPtr(2 * intf.samplerate * sizeof(short) ); mixer_buffer_2 = new _ShortPtr(mixer_buffer, intf.samplerate * sizeof(short)); /* build the mixer table */ make_mixer_table(intf.voices); /* extract globals from the interface */ num_voices = intf.voices; last_channel = num_voices; if (intf.region == -1) { sound_prom = namco_wavedata; samples_per_byte = 2; /* first 4 high bits, then low 4 bits */ } else { sound_prom = Mame.memory_region(intf.region); samples_per_byte = 1; /* use only low 4 bits */ } /* start with sound enabled, many games don't have a sound enable register */ sound_enable = true; /* reset all the voices */ for (int i = 0; i < last_channel; i++) //for (voice = channel_list; voice < last_channel; voice++) { channel_list[i] = new sound_channel(); channel_list[i].frequency = 0; channel_list[i].volume[0] = channel_list[i].volume[1] = 0; channel_list[i].wave = sound_prom; channel_list[i].counter = 0; channel_list[i].noise_sw = 0; channel_list[i].noise_state = 0; channel_list[i].noise_seed = 1; channel_list[i].noise_counter = 0; } return 0; }
// device-level overrides //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- protected override void device_start() { int voiceIdx; // sound_channel *voice; /* extract globals from the interface */ m_last_channel = m_channel_list[m_voices]; m_soundregs = new uint8_t[0x400]; //auto_alloc_array_clear(machine(), uint8_t, 0x400); /* build the waveform table */ build_decoded_waveform(m_wave_ptr.target); /* get stream channels */ if (m_stereo) { m_stream = machine().sound().stream_alloc(this, 0, 2, 192000); } else { m_stream = machine().sound().stream_alloc(this, 0, 1, 192000); } /* start with sound enabled, many games don't have a sound enable register */ m_sound_enable = true; //throw new emu_unimplemented(); #if false /* register with the save state system */ save_pointer(m_soundregs, "m_soundregs", 0x400); if (m_wave_ptr == null) { save_pointer(m_wavedata, "m_wavedata", 0x400); } save_item(m_voices, "m_voices"); save_item(m_sound_enable, "m_sound_enable"); save_pointer(NAME(m_waveform[0]), MAX_VOLUME * 32 * 8 * (1 + m_wave_size)); #endif /* reset all the voices */ for (voiceIdx = 0; m_channel_list[voiceIdx] != m_last_channel; voiceIdx++) //for (voice = m_channel_list; voice < m_last_channel; voice++) { sound_channel voice = m_channel_list[voiceIdx]; int voicenum = voiceIdx; // voice - m_channel_list; voice.frequency = 0; voice.volume[0] = voice.volume[1] = 0; voice.waveform_select = 0; voice.counter = 0; voice.noise_sw = 0; voice.noise_state = 0; voice.noise_seed = 1; voice.noise_counter = 0; voice.noise_hold = 0; /* register with the save state system */ save_item(voice.frequency, "voice.frequency", voicenum); save_item(voice.counter, "voice.counter", voicenum); save_item(voice.volume, "voice.volume", voicenum); save_item(voice.noise_sw, "voice.noise_sw", voicenum); save_item(voice.noise_state, "voice.noise_state", voicenum); save_item(voice.noise_seed, "voice.noise_seed", voicenum); save_item(voice.noise_hold, "voice.noise_hold", voicenum); save_item(voice.noise_counter, "voice.noise_counter", voicenum); save_item(voice.waveform_select, "voice.waveform_select", voicenum); } }