Пример #1
0
        // stream creation
        //-------------------------------------------------
        //  stream_alloc - allocate a new stream
        //-------------------------------------------------
        public sound_stream stream_alloc(device_t device, int inputs, int outputs, int sample_rate, stream_update_delegate callback = null)
        {
            var stream = new sound_stream(device, inputs, outputs, sample_rate, callback);

            m_stream_list.push_back(stream);
            return(stream);
        }
Пример #2
0
        //float input_gain(int inputnum) const;
        //float output_gain(int outputnum) const;
        //void set_input_gain(int inputnum, float gain);


        //-------------------------------------------------
        //  set_output_gain - set the gain on the given
        //  output index of the device
        //-------------------------------------------------
        public void set_output_gain(int outputnum, float gain)
        {
            // handle ALL_OUTPUTS as a special case
            if (outputnum == ALL_OUTPUTS)
            {
                foreach (var stream in device().machine().sound().streams())
                {
                    if (stream.device() == device())
                    {
                        for (int num = 0; num < stream.output_count(); num++)
                        {
                            stream.output(num).set_gain(gain);
                        }
                    }
                }
            }

            // look up the stream and stream output index
            else
            {
                int          stream_outputnum;
                sound_stream stream = output_to_stream_output(outputnum, out stream_outputnum);
                if (stream != null)
                {
                    stream.output(stream_outputnum).set_gain(gain);
                }
            }
        }
Пример #3
0
        // device_sound_interface overrides
        //-------------------------------------------------
        //  sound_stream_update - update a sound stream
        //-------------------------------------------------
        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;
        {
            // find the channel with this stream
            stream_buffer_sample_t sample_scale = (stream_buffer_sample_t)(1.0 / 32768.0);

            for (int channel = 0; channel < m_channels; channel++)
            {
                if (stream == m_channel[channel].stream)
                {
                    channel_t chan   = m_channel[channel];
                    var       buffer = outputs[0];

                    // process if we still have a source and we're not paused
                    if (chan.source != null && !chan.paused)
                    {
                        // load some info locally
                        double            step   = (double)chan.curfreq / (double)buffer.sample_rate();
                        double            endpos = chan.source_len;
                        Pointer <int16_t> sample = new Pointer <int16_t>(chan.source);  //const int16_t *sample = chan.source;

                        for (int sampindex = 0; sampindex < buffer.samples(); sampindex++)
                        {
                            // do a linear interp on the sample
                            double  pos_floor = std.floor(chan.pos);
                            double  frac      = chan.pos - pos_floor;
                            int32_t ipos      = (int32_t)pos_floor;

                            stream_buffer_sample_t sample1 = (stream_buffer_sample_t)sample[ipos++];
                            stream_buffer_sample_t sample2 = (stream_buffer_sample_t)sample[(ipos + 1) % (int)chan.source_len];
                            buffer.put(sampindex, (stream_buffer_sample_t)(sample_scale * ((1.0 - frac) * sample1 + frac * sample2)));

                            // advance
                            chan.pos += step;

                            // handle looping/ending
                            if (chan.pos >= endpos)
                            {
                                if (chan.loop)
                                {
                                    chan.pos -= endpos;
                                }
                                else
                                {
                                    chan.source     = null;
                                    chan.source_num = -1;
                                    buffer.fill(0, sampindex);
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        buffer.fill(0);
                    }
                    break;
                }
            }
        }
Пример #4
0
        void stream_generate(sound_stream stream, ListPointer <stream_sample_t> [] inputs, ListPointer <stream_sample_t> [] outputs, int samples)
        {
            ListPointer <stream_sample_t> ptr = new ListPointer <stream_sample_t>(outputs[0]);  //stream_sample_t *ptr = outputs[0];
            int samplenum = samples;

            while (samplenum-- > 0)
            {
                ptr[0] = m_data;
                ptr++;
            }
        }
Пример #5
0
        std.vector <uint8_t> m_save_blob; // state saving buffer


        // constructor
        protected ymfm_device_base(machine_config mconfig, string tag, device_t owner, uint32_t clock, device_type type, Func <ymfm_interface, ChipClass> chip_class_creator)
            : base(mconfig, tag, owner, clock, type)
        {
            m_class_interfaces.Add(new device_sound_interface_ymfm_device_base(mconfig, this));  //device_sound_interface(mconfig, *this);
            m_disound = GetClassInterface <device_sound_interface_ymfm_device_base>();


            m_stream = null;
            m_chip   = chip_class_creator(m_ymfm_interface); //eg, m_chip = new ym2151(this);

            OUTPUTS = (int)m_chip.OUTPUTS;                   //static constexpr int OUTPUTS = ChipClass.OUTPUTS;
        }
Пример #6
0
        // handle device start
        protected override void device_start()
        {
            // let our parent do its startup
            base.device_start();

            // allocate our stream
            m_stream = m_disound.stream_alloc(0, OUTPUTS, m_chip.sample_rate(clock()));

            // compute the size of the save buffer by doing an initial save
            ymfm.ymfm_saved_state state = new ymfm.ymfm_saved_state(m_save_blob, true);
            m_chip.save_restore(state);

            // now register the blob for save, on the assumption the size won't change
            save_item(NAME(new { m_save_blob }));
        }
Пример #7
0
        // constructor
        public dac_device_base(machine_config mconfig, device_type type, string tag, device_t owner, uint32_t clock, u8 bits, dac_mapper_callback mapper, stream_buffer_sample_t gain)
            : base(mconfig, type, tag, owner, clock)
        {
            m_class_interfaces.Add(new device_sound_interface_dac_device_base(mconfig, this));  //device_sound_interface(mconfig, *this);
            m_disound = GetClassInterface <device_sound_interface_dac_device_base>();


            m_stream    = null;
            m_curval    = 0;
            m_value_map = new std.vector <stream_buffer_sample_t>(1 << bits);
            m_bits      = bits;
            m_mapper    = mapper;
            m_gain      = gain;
            m_range_min = (bits == 1) ? (stream_buffer_sample_t)0.0 : (stream_buffer_sample_t)(-1.0);
            m_range_max = (stream_buffer_sample_t)1.0;
        }
Пример #8
0
        // 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;
        {
            var output = outputs[0];

            /* if this voice is active */
            if (m_signal != 0)
            {
                stream_buffer_sample_t sample_scale = (stream_buffer_sample_t)(1.0 / (double)(1 << 12));
                int dac_mask = (m_dac_bits >= 12) ? 0 : (1 << (12 - m_dac_bits)) - 1;
                stream_buffer_sample_t val = (stream_buffer_sample_t)(m_signal & ~dac_mask) * sample_scale;
                output.fill(val);
            }
            else
            {
                output.fill(0);
            }
        }
Пример #9
0
        // sound interface overrides
        //-------------------------------------------------
        //  sound_stream_update - mix all inputs to one
        //  output
        //-------------------------------------------------
        public override void 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;
        {
            // special case: single input, single output, same rate
            if (inputs.size() == 1 && outputs.size() == 1 && inputs[0].sample_rate() == outputs[0].sample_rate())
            {
                outputs[0] = new write_stream_view(inputs[0]);  //outputs[0] = inputs[0];
                return;
            }

            // reset the clear flags
            std.fill(m_output_clear, false);  //std::fill(std::begin(m_output_clear), std::end(m_output_clear), false);

            // loop over inputs
            for (int inputnum = 0; inputnum < m_auto_allocated_inputs; inputnum++)
            {
                // skip if the gain is 0
                var input = inputs[inputnum];
                if (input.gain() == 0)
                {
                    continue;
                }

                // either store or accumulate
                int outputnum = m_outputmap[inputnum];
                var output    = outputs[outputnum];
                if (!m_output_clear[outputnum])
                {
                    output.copy(input);
                }
                else
                {
                    output.add(input);
                }

                m_output_clear[outputnum] = true;
            }

            // clear anything unused
            for (int outputnum = 0; outputnum < m_outputs; outputnum++)
            {
                if (!m_output_clear[outputnum])
                {
                    outputs[outputnum].fill(0);
                }
            }
        }
Пример #10
0
        protected ay8910_device(machine_config mconfig, device_type type, string tag, device_t owner, u32 clock,
                                psg_type_t psg_type, int streams, int ioports)
            : base(mconfig, type, tag, owner, clock)
        {
            m_class_interfaces.Add(new device_sound_interface_ay8910(mconfig, this));  // device_sound_interface(mconfig, *this);

            m_type            = psg_type;
            m_streams         = streams;
            m_ioports         = ioports;
            m_ready           = 0;
            m_channel         = null;
            m_active          = false;
            m_register_latch  = 0;
            m_last_enable     = 0;
            m_prescale_noise  = 0;
            m_count_noise     = 0;
            m_count_env       = 0;
            m_env_step        = 0;
            m_env_volume      = 0;
            m_hold            = 0;
            m_alternate       = 0;
            m_attack          = 0;
            m_holding         = 0;
            m_rng             = 0;
            m_env_step_mask   = psg_type == psg_type_t.PSG_TYPE_AY ? (byte)0x0f : (byte)0x1f;
            m_step            = psg_type == psg_type_t.PSG_TYPE_AY ? 2 : 1;
            m_zero_is_off     = psg_type == psg_type_t.PSG_TYPE_AY ? 1 : 0;
            m_par             = psg_type == psg_type_t.PSG_TYPE_AY ? ay8910_param : ym2149_param;
            m_par_env         = psg_type == psg_type_t.PSG_TYPE_AY ? ay8910_param : ym2149_param_env;
            m_flags           = AY8910_LEGACY_OUTPUT;
            m_port_a_read_cb  = new devcb_read8(this);
            m_port_b_read_cb  = new devcb_read8(this);
            m_port_a_write_cb = new devcb_write8(this);
            m_port_b_write_cb = new devcb_write8(this);


            memset(m_regs, (byte)0);
            memset(m_count, 0);
            memset(m_output, (byte)0);
            memset(m_vol_enabled, (byte)0);
            memset(m_vol_table, 0);
            memset(m_env_table, 0);
            m_res_load[0] = m_res_load[1] = m_res_load[2] = 1000; //Default values for resistor loads

            set_type(psg_type);
        }
Пример #11
0
        // device startup
        //-------------------------------------------------
        //  device_start - device startup
        //-------------------------------------------------
        protected override void device_start()
        {
            // precompute all gain-applied values
            for (s32 code = 0; code < (int)m_value_map.size(); code++)
            {
                m_value_map[code] = m_mapper((u32)code, m_bits) * m_gain;
            }

            // determine the number of inputs
            int inputs = (m_specified_inputs_mask == 0) ? 0 : 2;

            // create the stream
            m_stream = stream_alloc(inputs, 1, 48000 * 4);

            // save data
            save_item(NAME(new { m_curval }));
        }
Пример #12
0
        //-------------------------------------------------
        //  interface_post_start - verify that state was
        //  properly set up
        //-------------------------------------------------
        public override void interface_post_start()
        {
            // iterate over all the sound devices
            foreach (device_sound_interface sound in new sound_interface_enumerator(device().machine().root_device()))
            {
                // scan each route on the device
                foreach (sound_route route in sound.routes())
                {
                    // if we are the target of this route, hook it up
                    device_t target_device = route.m_base.subdevice(route.m_target);
                    if (target_device == device())
                    {
                        // iterate over all outputs, matching any that apply
                        int inputnum   = (int)route.m_input;
                        int numoutputs = sound.outputs();
                        for (int outputnum = 0; outputnum < numoutputs; outputnum++)
                        {
                            if (route.m_output == outputnum || route.m_output == ALL_OUTPUTS)
                            {
                                // find the output stream to connect from
                                int          streamoutputnum;
                                sound_stream outputstream = sound.output_to_stream_output(outputnum, out streamoutputnum);
                                if (outputstream == null)
                                {
                                    fatalerror("Sound device '{0}' specifies route for nonexistent output #{1}\n", sound.device().tag(), outputnum);
                                }

                                // find the input stream to connect to
                                int          streaminputnum;
                                sound_stream inputstream = input_to_stream_input(inputnum++, out streaminputnum);
                                if (inputstream == null)
                                {
                                    fatalerror("Sound device '{0}' targeted output #{1} to nonexistant device '{2}' input {3}\n", sound.device().tag(), outputnum, device().tag(), inputnum - 1);
                                }

                                // set the input
                                inputstream.set_input(streaminputnum, outputstream, streamoutputnum, route.m_gain);
                            }
                        }
                    }
                }
            }
        }
Пример #13
0
        // sound interface overrides
        //-------------------------------------------------
        //  mixer_update - mix all inputs to one output
        //-------------------------------------------------
        public override void sound_stream_update(sound_stream stream, ListPointer <stream_sample_t> [] inputs, ListPointer <stream_sample_t> [] outputs, int samples)
        {
            // clear output buffers
            for (int output = 0; output < m_outputs; output++)
            {
                memset(outputs[output], 0, (UInt32)samples);  //memset(outputs[output], 0, samples * sizeof(outputs[0][0]));
            }

            // loop over samples
            ListBytesPointer outmap = new ListBytesPointer(m_outputmap);  //const u8 *outmap = &m_outputmap[0];

            for (int pos = 0; pos < samples; pos++)
            {
                // for each input, add it to the appropriate output
                for (int inp = 0; inp < m_auto_allocated_inputs; inp++)
                {
                    outputs[outmap[inp]][pos] += inputs[inp][pos];
                }
            }
        }
Пример #14
0
        // stream generation
        //-------------------------------------------------
        //  sound_stream_update - stream updates
        //-------------------------------------------------
        protected virtual 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;
        {
            var out_ = outputs[0];

            // rails are constant
            if (inputs.size() == 0)
            {
                out_.fill(m_range_min + m_curval * (m_range_max - m_range_min));
                return;
            }

            var hi = inputs[DAC_INPUT_RANGE_HI];
            var lo = inputs[DAC_INPUT_RANGE_LO];

            // constant lo, streaming hi
            if (BIT(m_specified_inputs_mask, DAC_INPUT_RANGE_LO) == 0)
            {
                for (int sampindex = 0; sampindex < out_.samples(); sampindex++)
                {
                    out_.put(sampindex, m_range_min + m_curval * (hi.get(sampindex) - m_range_min));
                }
            }

            // constant hi, streaming lo
            else if (BIT(m_specified_inputs_mask, DAC_INPUT_RANGE_HI) == 0)
            {
                for (int sampindex = 0; sampindex < out_.samples(); sampindex++)
                {
                    out_.put(sampindex, lo.get(sampindex) + m_curval * (m_range_max - lo.get(sampindex)));
                }
            }

            // both streams provided
            else
            {
                for (int sampindex = 0; sampindex < out_.samples(); sampindex++)
                {
                    out_.put(sampindex, lo.get(sampindex) + m_curval * (hi.get(sampindex) - lo.get(sampindex)));
                }
            }
        }
Пример #15
0
        // device_sound_interface overrides
        //-------------------------------------------------
        //  sound_stream_update - handle a stream update
        //-------------------------------------------------
        public override void sound_stream_update(sound_stream stream, ListPointer <stream_sample_t> [] inputs, ListPointer <stream_sample_t> [] outputs, int samples)
        {
            msm5205_device pokey = (msm5205_device)device();

            ListPointer <stream_sample_t> buffer = outputs[0];

            /* if this voice is active */
            if (pokey.signal != 0)
            {
                short val = (short)(pokey.signal * 16);
                while (samples != 0)
                {
                    buffer[0] = val;  //*buffer++ = val;
                    buffer++;
                    samples--;
                }
            }
            else
            {
                memset(buffer, 0, (UInt32)samples);  //memset(buffer, 0, samples * sizeof(*buffer));
            }
        }
Пример #16
0
        // device-level overrides

        //-------------------------------------------------
        //  device_start - device-specific startup
        //-------------------------------------------------
        protected override void device_start()
        {
            m_disound = GetClassInterface <device_sound_interface_ay8910>();


            int master_clock = (int)clock();

            if (m_ioports < 1 && !(m_port_a_read_cb.isnull() && m_port_a_write_cb.isnull()))
            {
                fatalerror("Device '{0}' is a {1} and has no port A!", tag(), name());
            }

            if (m_ioports < 2 && !(m_port_b_read_cb.isnull() && m_port_b_write_cb.isnull()))
            {
                fatalerror("Device '{0}' is a {1} and has no port B!", tag(), name());
            }

            m_port_a_read_cb.resolve();
            m_port_b_read_cb.resolve();
            m_port_a_write_cb.resolve();
            m_port_b_write_cb.resolve();

            if ((m_flags & AY8910_SINGLE_OUTPUT) != 0)
            {
                logerror("{0} device using single output!\n", name());
                m_streams = 1;
            }

            m_vol3d_table = new int[8 * 32 * 32 * 32];  // make_unique_clear<int32_t[]>(8*32*32*32);

            build_mixer_table();

            /* The envelope is pacing twice as fast for the YM2149 as for the AY-3-8910,    */
            /* This handled by the step parameter. Consequently we use a divider of 8 here. */
            m_channel = machine().sound().stream_alloc(this, 0, m_streams, master_clock / 8);

            ay_set_clock(master_clock);
            ay8910_statesave();
        }
Пример #17
0
        // optional operation overrides

        //-------------------------------------------------
        //  interface_pre_start - perform startup prior
        //  to the device startup
        //-------------------------------------------------
        public override void interface_pre_start()
        {
            // call our parent
            base.interface_pre_start();

            // no inputs? that's weird
            if (m_auto_allocated_inputs == 0)
            {
                device().logerror("Warning: mixer \"{0}\" has no inputs\n", device().tag());
                return;
            }

            // generate the output map
            m_outputmap.resize((size_t)m_auto_allocated_inputs);

            // iterate through all routes that point to us and note their mixer output
            foreach (device_sound_interface sound in new sound_interface_enumerator(device().machine().root_device()))
            {
                foreach (sound_route route in sound.routes())
                {
                    // see if we are the target of this route
                    device_t target_device = route.m_base.subdevice(route.m_target);
                    if (target_device == device() && route.m_input < m_auto_allocated_inputs)
                    {
                        int count = (route.m_output == ALL_OUTPUTS) ? sound.outputs() : 1;
                        for (int output = 0; output < count; output++)
                        {
                            m_outputmap[(int)(route.m_input + output)] = (u8)route.m_mixoutput;
                        }
                    }
                }
            }

            // keep a small buffer handy for tracking cleared buffers
            m_output_clear.resize(m_outputs);

            // allocate the mixer stream
            m_mixer_stream = stream_alloc(m_auto_allocated_inputs, m_outputs, (u32)device().machine().sample_rate(), sound_stream_flags.STREAM_DEFAULT_FLAGS);
        }
Пример #18
0
        //void s1_w(int state);
        //void s2_w(int state);


        // device-level overrides
        protected override void device_start()
        {
            m_vck_cb.resolve_safe();
            m_vck_legacy_cb.resolve();

            /* compute the difference tables */
            compute_tables();

            /* stream system initialize */
            m_stream        = stream_alloc(0, 1, clock());
            m_vck_timer     = timer_alloc(TIMER_VCK);
            m_capture_timer = timer_alloc(TIMER_ADPCM_CAPTURE);

            /* register for save states */
            save_item(NAME(new { m_data }));
            save_item(NAME(new { m_vck }));
            save_item(NAME(new { m_reset }));
            save_item(NAME(new { m_s1 }));
            save_item(NAME(new { m_s2 }));
            save_item(NAME(new { m_bitwidth }));
            save_item(NAME(new { m_signal }));
            save_item(NAME(new { m_step }));
        }
Пример #19
0
        //DECLARE_WRITE_LINE_MEMBER(s1_w);
        //DECLARE_WRITE_LINE_MEMBER(s2_w);


        // device-level overrides
        protected override void device_start()
        {
            m_vck_cb.resolve_safe();
            m_vck_legacy_cb.resolve();

            /* compute the difference tables */
            compute_tables();

            /* stream system initialize */
            m_stream        = machine().sound().stream_alloc(this, 0, 1, (int)clock());
            m_vck_timer     = timer_alloc(TIMER_VCK);
            m_capture_timer = timer_alloc(TIMER_ADPCM_CAPTURE);

            /* register for save states */
            save_item(m_data, "m_data");
            save_item(m_vck, "m_vck");
            save_item(m_reset, "m_reset");
            save_item(m_s1, "m_s1");
            save_item(m_s2, "m_s2");
            save_item(m_bitwidth, "m_bitwidth");
            save_item(m_signal, "m_signal");
            save_item(m_step, "m_step");
        }
Пример #20
0
        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();
            }
        }
Пример #21
0
        // optional operation overrides

        //-------------------------------------------------
        //  interface_pre_start - perform startup prior
        //  to the device startup
        //-------------------------------------------------
        public override void interface_pre_start()
        {
            // call our parent
            base.interface_pre_start();

            // no inputs? that's weird
            if (m_auto_allocated_inputs == 0)
            {
                device().logerror("Warning: mixer \"{0}\" has no inputs\n", device().tag());
                return;
            }

            // generate the output map
            m_outputmap.resize(m_auto_allocated_inputs);

            // iterate through all routes that point to us and note their mixer output
            foreach (device_sound_interface sound in new sound_interface_iterator(device().machine().root_device()))
            {
                foreach (sound_route route in sound.routes())
                {
                    // see if we are the target of this route
                    device_t target_device = route.m_base.get().subdevice(route.m_target.c_str());
                    if ((target_device == device()) && (route.m_input < m_auto_allocated_inputs))
                    {
                        int count = (route.m_output == ALL_OUTPUTS) ? sound.outputs() : 1;
                        for (int output = 0; output < count; output++)
                        {
                            m_outputmap[(int)(route.m_input + output)] = (byte)route.m_mixoutput;
                        }
                    }
                }
            }

            // allocate the mixer stream
            m_mixer_stream = stream_alloc(m_auto_allocated_inputs, m_outputs, device().machine().sample_rate());
        }
Пример #22
0
        public sound_stream m_mixer_stream;                         // mixing stream


        // construction/destruction
        //-------------------------------------------------
        //  device_mixer_interface - constructor
        //-------------------------------------------------
        public device_mixer_interface(machine_config mconfig, device_t device, int outputs = 1)
            : base(mconfig, device)
        {
            m_outputs      = (u8)outputs;
            m_mixer_stream = null;
        }
Пример #23
0
            public s16 m_gain;                                                                 // gain to apply to the output


            // construction/destruction
            //-------------------------------------------------
            //  stream_output - constructor
            //-------------------------------------------------
            public stream_output()
            {
                m_stream     = null;
                m_dependents = 0;
                m_gain       = 0x100;
            }
Пример #24
0
 public override void sound_stream_update(sound_stream stream, std.vector <read_stream_view> inputs, std.vector <write_stream_view> outputs)
 {
     ((samples_device)device()).device_sound_interface_sound_stream_update(stream, inputs, outputs);
 }                                                                                                                                                                                                                                              //virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override
Пример #25
0
        // device_sound_interface overrides
        //-------------------------------------------------
        //  sound_stream_update - handle a stream update
        //-------------------------------------------------
        public override void sound_stream_update(sound_stream stream, ListPointer <stream_sample_t> [] inputs, ListPointer <stream_sample_t> [] outputs, int samples)
        {
            ay8910_device ay8910 = (ay8910_device)device();

            ListPointer <stream_sample_t> [] buf = new ListPointer <stream_sample_t> [ay8910_device.NUM_CHANNELS];  //stream_sample_t *buf[NUM_CHANNELS];
            int chan;

            buf[0] = new ListPointer <stream_sample_t>(outputs[0]);
            buf[1] = null;
            buf[2] = null;
            if (ay8910.m_streams == ay8910_device.NUM_CHANNELS)
            {
                buf[1] = outputs[1];
                buf[2] = outputs[2];
            }

            /* hack to prevent us from hanging when starting filtered outputs */
            if (ay8910.m_ready == 0)
            {
                for (chan = 0; chan < ay8910_device.NUM_CHANNELS; chan++)
                {
                    if (buf[chan] != null)
                    {
                        memset(buf[chan], 0, (UInt32)samples);  //memset(buf[chan], 0, samples * sizeof_(*buf[chan]));
                    }
                }
            }

            /* The 8910 has three outputs, each output is the mix of one of the three */
            /* tone generators and of the (single) noise generator. The two are mixed */
            /* BEFORE going into the DAC. The formula to mix each channel is: */
            /* (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable). */
            /* Note that this means that if both tone and noise are disabled, the output */
            /* is 1, not 0, and can be modulated changing the volume. */

            /* buffering loop */
            while (samples != 0)
            {
                for (chan = 0; chan < ay8910_device.NUM_CHANNELS; chan++)
                {
                    ay8910.m_count[chan]++;
                    if (ay8910.m_count[chan] >= ay8910.TONE_PERIOD(chan))
                    {
                        ay8910.m_output[chan] ^= 1;
                        ay8910.m_count[chan]   = 0;
                    }
                }

                ay8910.m_count_noise++;
                if (ay8910.m_count_noise >= ay8910.NOISE_PERIOD())
                {
                    /* toggle the prescaler output. Noise is no different to
                     * channels.
                     */
                    ay8910.m_count_noise     = 0;
                    ay8910.m_prescale_noise ^= 1;

                    if (ay8910.m_prescale_noise != 0)
                    {
                        /* The Random Number Generator of the 8910 is a 17-bit shift */
                        /* register. The input to the shift register is bit0 XOR bit3 */
                        /* (bit0 is the output). This was verified on AY-3-8910 and YM2149 chips. */

                        ay8910.m_rng  ^= (((ay8910.m_rng & 1) ^ ((ay8910.m_rng >> 3) & 1)) << 17);
                        ay8910.m_rng >>= 1;
                    }
                }

                for (chan = 0; chan < ay8910_device.NUM_CHANNELS; chan++)
                {
                    ay8910.m_vol_enabled[chan] = (byte)((ay8910.m_output[chan] | ay8910.TONE_ENABLEQ(chan)) & (ay8910.NOISE_OUTPUT() | ay8910.NOISE_ENABLEQ(chan)));
                }

                /* update envelope */
                if (ay8910.m_holding == 0)
                {
                    ay8910.m_count_env++;
                    if (ay8910.m_count_env >= ay8910.ENVELOPE_PERIOD() * ay8910.m_step)
                    {
                        ay8910.m_count_env = 0;
                        ay8910.m_env_step--;

                        /* check envelope current position */
                        if (ay8910.m_env_step < 0)
                        {
                            if (ay8910.m_hold != 0)
                            {
                                if (ay8910.m_alternate != 0)
                                {
                                    ay8910.m_attack ^= ay8910.m_env_step_mask;
                                }
                                ay8910.m_holding  = 1;
                                ay8910.m_env_step = 0;
                            }
                            else
                            {
                                /* if CountEnv has looped an odd number of times (usually 1), */
                                /* invert the output. */
                                if (ay8910.m_alternate != 0 && (ay8910.m_env_step & (ay8910.m_env_step_mask + 1)) != 0)
                                {
                                    ay8910.m_attack ^= ay8910.m_env_step_mask;
                                }

                                ay8910.m_env_step &= (sbyte)ay8910.m_env_step_mask;
                            }
                        }
                    }
                }
                ay8910.m_env_volume = (UInt32)(ay8910.m_env_step ^ ay8910.m_attack);

                if (ay8910.m_streams == 3)
                {
                    for (chan = 0; chan < ay8910_device.NUM_CHANNELS; chan++)
                    {
                        if (ay8910.TONE_ENVELOPE(chan) != 0)
                        {
                            if (ay8910.type() == ay8914_device.AY8914)                                                                                                  // AY8914 Has a two bit tone_envelope field
                            {
                                buf[chan][0] = ay8910.m_env_table[chan, ay8910.m_vol_enabled[chan] != 0 ? ay8910.m_env_volume >> (3 - ay8910.TONE_ENVELOPE(chan)) : 0]; // *(buf[chan]++)
                                buf[chan]++;
                            }
                            else
                            {
                                buf[chan][0] = ay8910.m_env_table[chan, ay8910.m_vol_enabled[chan] != 0 ? ay8910.m_env_volume : 0];  // *(buf[chan]++)
                                buf[chan]++;
                            }
                        }
                        else
                        {
                            buf[chan][0] = ay8910.m_vol_table[chan, ay8910.m_vol_enabled[chan] != 0 ? ay8910.TONE_VOLUME(chan) : 0];  // *(buf[chan]++)
                            buf[chan]++;
                        }
                    }
                }
                else
                {
                    buf[0][0] = ay8910.mix_3D();  // *(buf[0]++)
                    buf[0]++;
                }

                samples--;
            }
        }
Пример #26
0
        public static void sound_init()
        {
            iRecord = 0;

            leftmix  = new int[0x3c0];
            rightmix = new int[0x3c0];

            finalmixb = new byte[0xf00];

            sound_muted = 0;

            buf2.Play(0, BufferPlayFlags.Looping);

            last_update_second = 0;
            //WavWrite.CreateSoundFile(@"\VS2008\compare1\compare1\bin\Debug\2.wav");
            Atime update_frequency = new Atime(0, Attotime.ATTOSECONDS_PER_SECOND / 50);

            switch (Machine.sBoard)
            {
            case "CPS-1":
                latched_value      = new ushort[2];
                utempdata          = new ushort[2];
                sound_update       = sound_updateC;
                sound_update_timer = Timer.timer_alloc_common(sound_update, "sound_update", false);
                YM2151.ym2151_init(3579545);
                OKI6295.okim6295_start();
                ym2151stream = new sound_stream(55930, 0, 2, YM2151.ym2151_update_one);
                okistream    = new sound_stream(1000000 / 132, 0, 1, OKI6295.okim6295_update);
                mixerstream  = new sound_stream(48000, 3, 0, null);
                break;

            case "CPS-1(QSound)":
            case "CPS2":
                sound_update       = sound_updateQ;
                sound_update_timer = Timer.timer_alloc_common(sound_update, "sound_update", false);
                QSound.qsound_start();
                qsoundstream = new sound_stream(4000000 / 166, 0, 2, QSound.qsound_update);
                mixerstream  = new sound_stream(48000, 2, 0, null);
                break;

            case "Neo Geo":
                latched_value      = new ushort[2];
                utempdata          = new ushort[2];
                sound_update       = sound_updateN;
                sound_update_timer = Timer.timer_alloc_common(sound_update, "sound_update", false);
                YM2610.ym2610_start();
                ay8910stream = new sound_stream(250000, 0, 1, AY8910.ay8910_update);
                ym2610stream = new sound_stream(111111, 0, 2, FM.ym2610_update_one);
                mixerstream  = new sound_stream(48000, 3, 0, null);
                break;

            case "Namco System 1":
                sound_update       = sound_updateNa;
                sound_update_timer = Timer.timer_alloc_common(sound_update, "sound_update", false);
                YM2151.ym2151_init(3579580);
                Namco.namco_start();
                DAC.dac_start();
                ym2151stream = new sound_stream(55930, 0, 2, YM2151.ym2151_update_one);
                namcostream  = new sound_stream(192000, 0, 2, Namco.namco_update_stereo);
                dacstream    = new sound_stream(192000, 0, 1, DAC.DAC_update);
                mixerstream  = new sound_stream(48000, 5, 0, null);
                break;

            case "IGS011":
                sound_update       = sound_updateIGS011;
                sound_update_timer = Timer.timer_alloc_common(sound_update, "sound_update", false);
                OKI6295.okim6295_start();
                YM3812.ym3812_start(3579545);
                okistream    = new sound_stream(1047600 / 132, 0, 1, OKI6295.okim6295_update);
                ym3812stream = new sound_stream(49715, 0, 1, FMOpl.ym3812_update_one);
                mixerstream  = new sound_stream(48000, 2, 0, null);
                break;

            case "PGM":
                latched_value      = new ushort[3];
                utempdata          = new ushort[3];
                sound_update       = sound_updatePGM;
                sound_update_timer = Timer.timer_alloc_common(sound_update, "sound_update", false);
                ICS2115.ics2115_start();
                ics2115stream = new sound_stream(33075, 0, 2, ICS2115.ics2115_update);
                mixerstream   = new sound_stream(48000, 2, 0, null);
                break;

            case "M72":
                latched_value      = new ushort[1];
                utempdata          = new ushort[1];
                sound_update       = sound_updateM72;
                sound_update_timer = Timer.timer_alloc_common(sound_update, "sound_update", false);
                YM2151.ym2151_init(3579545);
                DAC.dac_start();
                ym2151stream = new sound_stream(55930, 0, 2, YM2151.ym2151_update_one);
                dacstream    = new sound_stream(192000, 0, 1, DAC.DAC_update);
                mixerstream  = new sound_stream(48000, 3, 0, null);
                break;

            case "M92":
                latched_value      = new ushort[1];
                utempdata          = new ushort[1];
                sound_update       = sound_updateM92;
                sound_update_timer = Timer.timer_alloc_common(sound_update, "sound_update", false);
                YM2151.ym2151_init(3579545);
                Iremga20.iremga20_start();
                ym2151stream   = new sound_stream(55930, 0, 2, YM2151.ym2151_update_one);
                iremga20stream = new sound_stream(894886, 0, 2, Iremga20.iremga20_update);
                mixerstream    = new sound_stream(48000, 4, 0, null);
                break;
            }
            Timer.timer_adjust_periodic(sound_update_timer, update_frequency, update_frequency);
        }
Пример #27
0
 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;
 {
     throw new emu_unimplemented();
 }
Пример #28
0
        // 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);
                        }
                    }
                }
            }
        }
Пример #29
0
        // 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
        }
Пример #30
0
        //device_sound_interface &reset_routes() { m_route_list.clear(); return *this; }


        // sound stream update overrides

        //-------------------------------------------------
        //  sound_stream_update - default implementation
        //  that should be overridden
        //-------------------------------------------------
        public virtual void sound_stream_update(sound_stream stream, std.vector <read_stream_view> inputs, std.vector <write_stream_view> outputs)  //void device_sound_interface::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
        {
            throw new emu_fatalerror("sound_stream_update called but not overridden by owning class");
        }