Example #1
0
        int mixer_sh_start()
        {
            /* reset all channels to their defaults */
            for (int i = 0; i < mixer_channel.Length; i++)
            {
                mixer_channel[i] = new mixer_channel_data();
                mixer_channel[i].mixing_level = 0xff;
                mixer_channel[i].default_mixing_level = 0xff;
                mixer_channel[i].config_mixing_level = config_mixing_level[i];
                mixer_channel[i].config_default_mixing_level = config_default_mixing_level[i];
            }

            /* determine if we're playing in stereo or not */
            first_free_channel = 0;
            is_stereo = ((Machine.drv.sound_attributes & SOUND_SUPPORTS_STEREO) != 0);

            /* clear the accumulators */
            accum_base = 0;
            for (int i = 0; i < ACCUMULATOR_SAMPLES; i++)
            {
                left_accum[i] = 0;
                right_accum[i] = 0;
            }

            samples_this_frame = (uint)osd_start_audio_stream(is_stereo);

            mixer_sound_enabled = true;

            return 0;
        }
Example #2
0
        static void mix_sample_16(mixer_channel_data channel, int samples_to_generate)
        {
            uint step_size, input_frac, output_pos;
            _ShortPtr source;
            int source_end;
            int mixing_volume;

            /* compute the overall mixing volume */
            if (mixer_sound_enabled)
                mixing_volume = ((channel.volume * channel.mixing_level * 256) << channel.gain) / (100 * 100);
            else
                mixing_volume = 0;

            /* get the initial state */
            step_size = channel.step_size;
            source = new _ShortPtr(channel.data_current);
            source_end = channel.data_end;
            input_frac = channel.input_frac;
            output_pos = (accum_base + channel.samples_available) & ACCUMULATOR_MASK;

            /* an outer loop to handle looping samples */
            while (samples_to_generate > 0)
            {
                /* if we're mono or left panning, just mix to the left channel */
                if (!is_stereo || channel.pan == MIXER_PAN_LEFT)
                {
                    while (source.offset < source_end && samples_to_generate > 0)
                    {
                        left_accum[output_pos] += (source.read16(0) * mixing_volume) >> 8;

                        input_frac += step_size;
                        source.offset += (int)(input_frac >> FRACTION_BITS) * 2;
                        input_frac &= FRACTION_MASK;

                        output_pos = (output_pos + 1) & ACCUMULATOR_MASK;
                        samples_to_generate--;
                    }
                }

                /* if we're right panning, just mix to the right channel */
                else if (channel.pan == MIXER_PAN_RIGHT)
                {
                    while (source.offset < source_end && samples_to_generate > 0)
                    {
                        right_accum[output_pos] += (source.read16(0) * mixing_volume) >> 8;

                        input_frac += step_size;
                        source.offset += (int)(input_frac >> FRACTION_BITS) * 2;
                        input_frac &= FRACTION_MASK;

                        output_pos = (output_pos + 1) & ACCUMULATOR_MASK;
                        samples_to_generate--;
                    }
                }

                /* if we're stereo center, mix to both channels */
                else
                {
                    while (source.offset < source_end && samples_to_generate > 0)
                    {
                        int mixing_value = (source.read16(0) * mixing_volume) >> 8;
                        left_accum[output_pos] += mixing_value;
                        right_accum[output_pos] += mixing_value;

                        input_frac += step_size;
                        source.offset += (int)(input_frac >> FRACTION_BITS) * 2;
                        input_frac &= FRACTION_MASK;

                        output_pos = (output_pos + 1) & ACCUMULATOR_MASK;
                        samples_to_generate--;
                    }
                }

                /* handle the end case */
                if (source.offset >= source_end)
                {
                    /* if we're done, stop playing */
                    if (!channel.is_looping)
                    {
                        channel.is_playing = false;
                        break;
                    }

                    /* if we're looping, wrap to the beginning */
                    else
                        source.offset-=source_end;// source.offset -= (INT16*)source_end - (INT16*)channel.data_start;
                }
            }

            /* update the final positions */
            channel.input_frac = input_frac;
            channel.data_current = source.offset;
        }
Example #3
0
        static void mixer_update_channel(mixer_channel_data channel, int total_sample_count)
        {
            int samples_to_generate = (int)(total_sample_count - channel.samples_available);

            /* don't do anything for streaming channels */
            if (channel.is_stream)
                return;

            /* if we're all caught up, just return */
            if (samples_to_generate <= 0)
                return;

            /* if we're playing, mix in the data */
            if (channel.is_playing)
            {
                if (channel.is_16bit)
                    mix_sample_16(channel, samples_to_generate);
                else
                    mix_sample_8(channel, samples_to_generate);
            }

            /* just eat the rest */
            channel.samples_available += (uint)samples_to_generate;
        }