summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/sound/disc_inp.inc
blob: 1116d07454621a0c8ce414b9930d508e2f381daf (plain) (tree)
1
2
3
4
5
6
7
                       
                              



                                                                         
                                             











                                                                           
 


                                             
 












                                                                          





                                                 
 
                             
 
                                           
 
                                                                
                                                 
         

                                                                            
 
                                        
                                             
                                                  
                    
                                                           


         
                              
 

                        
                                                                                                                           
                              
                                                                                             
 


                                                                                 



                                     

                                                                    







                                                                          

                                                  

         
                     









                                                                          
                                             
 
                            
 
                                          












                                                                          
 



                                     
 
                                 
                                                   

 
                                                                                
 


                              
 


                                                
                                                   

                                  
 
                                                                                     
                                                           
         



                               



                                                
                                                   




                                                                                 
 
                                 
 


                                                
                                                   



                                                                                     
                                                           
         



                             



                                                
                                                   




                                                                               
 
                                
 


                                                
                                                   



                                                                                     
                                                           
         

 
                              
 
                                
                               

                                                           
                                 

 


                                                
                               










                                                                                 
                                                   


                                  









                                                                          


                                                     
 
                                                                                                                                            




                                          
                                  
 
                               
 
                                                                                                            
                            
         
                                                             
                        

            
                                  
 
 
                                
 
                        













                                                                                  
                                                  





                                                        
                                                           

                                          
 
                                                                                             
                                                                     

                 

 
                                
 

                                    
                                                   


                                                      
                        
 
                                      
                                  



                                                              
                          
         



                                                                                                
                                                                                                                                                                                                       
 
                                                                                         
         
 
// license:BSD-3-Clause
// copyright-holders:K.Wilkins
/************************************************************************
 *
 *  MAME - Discrete sound system emulation library
 *
 *  Written by K.Wilkins (mame@esplexo.co.uk)
 *
 *  (c) K.Wilkins 2000
 *
 ***********************************************************************
 *
 * DSS_ADJUSTMENT        - UI Mapped adjustable input
 * DSS_CONSTANT          - Node based constant - Do we need this ???
 * DSS_INPUT_x           - Input devices
 * DSS_INPUT_STREAM      - Connects external streams to the discrete system
 *
 ************************************************************************/


#define DSS_INPUT__GAIN     DISCRETE_INPUT(0)
#define DSS_INPUT__OFFSET   DISCRETE_INPUT(1)
#define DSS_INPUT__INIT     DISCRETE_INPUT(2)

/************************************************************************
 *
 * DSS_ADJUSTMENT - UI Adjustable constant node to emulate trimmers
 *
 * input[0]    - Enable
 * input[1]    - Minimum value
 * input[2]    - Maximum value
 * input[3]    - Log/Linear 0=Linear !0=Log
 * input[4]    - Input Port number
 * input[5]    -
 * input[6]    -
 *
 ************************************************************************/
#define DSS_ADJUSTMENT__MIN     DISCRETE_INPUT(0)
#define DSS_ADJUSTMENT__MAX     DISCRETE_INPUT(1)
#define DSS_ADJUSTMENT__LOG     DISCRETE_INPUT(2)
#define DSS_ADJUSTMENT__PORT    DISCRETE_INPUT(3)
#define DSS_ADJUSTMENT__PMIN    DISCRETE_INPUT(4)
#define DSS_ADJUSTMENT__PMAX    DISCRETE_INPUT(5)

DISCRETE_STEP(dss_adjustment)
{
	INT32  rawportval = m_port->read();

	/* only recompute if the value changed from last time */
	if (UNEXPECTED(rawportval != m_lastpval))
	{
		double portval   = (double)(rawportval - m_pmin) * m_pscale;
		double scaledval = portval * m_scale + m_min;

		m_lastpval = rawportval;
		if (DSS_ADJUSTMENT__LOG == 0)
			set_output(0,  scaledval);
		else
			set_output(0,  pow(10, scaledval));
	}
}

DISCRETE_RESET(dss_adjustment)
{
	double min, max;

	m_port = m_device->machine().root_device().ioport(m_device->siblingtag((const char *)this->custom_data()).c_str());
	if (m_port == nullptr)
		fatalerror("DISCRETE_ADJUSTMENT - NODE_%d has invalid tag\n", this->index());

	m_lastpval = 0x7fffffff;
	m_pmin     = DSS_ADJUSTMENT__PMIN;
	m_pscale   = 1.0 / (double)(DSS_ADJUSTMENT__PMAX - DSS_ADJUSTMENT__PMIN);

	/* linear scale */
	if (DSS_ADJUSTMENT__LOG == 0)
	{
		m_min   = DSS_ADJUSTMENT__MIN;
		m_scale = DSS_ADJUSTMENT__MAX - DSS_ADJUSTMENT__MIN;
	}

	/* logarithmic scale */
	else
	{
		/* force minimum and maximum to be > 0 */
		min = (DSS_ADJUSTMENT__MIN > 0) ? DSS_ADJUSTMENT__MIN : 1;
		max = (DSS_ADJUSTMENT__MAX > 0) ? DSS_ADJUSTMENT__MAX : 1;
		m_min   = log10(min);
		m_scale = log10(max) - log10(min);
	}

	this->step();
}


/************************************************************************
 *
 * DSS_CONSTANT - This is a constant.
 *
 * input[0]    - Constant value
 *
 ************************************************************************/
#define DSS_CONSTANT__INIT  DISCRETE_INPUT(0)

DISCRETE_RESET(dss_constant)
{
	set_output(0, DSS_CONSTANT__INIT);
}


/************************************************************************
 *
 * DSS_INPUT_x    - Receives input from discrete_sound_w
 *
 * input[0]    - Gain value
 * input[1]    - Offset value
 * input[2]    - Starting Position
 * input[3]    - Current data value
 *
 ************************************************************************/

DISCRETE_RESET(dss_input_data)
{
	m_gain = DSS_INPUT__GAIN;
	m_offset = DSS_INPUT__OFFSET;

	m_data = DSS_INPUT__INIT;
	set_output(0,  m_data * m_gain + m_offset);
}

void DISCRETE_CLASS_FUNC(dss_input_data, input_write)(int sub_node, UINT8 data )
{
	UINT8 new_data    = 0;

	new_data = data;

	if (m_data != new_data)
	{
		/* Bring the system up to now */
		m_device->update_to_current_time();

		m_data = new_data;

		/* Update the node output here so we don't have to do it each step */
		set_output(0,  m_data * m_gain + m_offset);
	}
}

DISCRETE_RESET(dss_input_logic)
{
	m_gain = DSS_INPUT__GAIN;
	m_offset = DSS_INPUT__OFFSET;

	m_data = (DSS_INPUT__INIT == 0) ? 0 : 1;
	set_output(0,  m_data * m_gain + m_offset);
}

void DISCRETE_CLASS_FUNC(dss_input_logic, input_write)(int sub_node, UINT8 data )
{
	UINT8 new_data    = 0;

	new_data =  data ? 1 : 0;

	if (m_data != new_data)
	{
		/* Bring the system up to now */
		m_device->update_to_current_time();

		m_data = new_data;

		/* Update the node output here so we don't have to do it each step */
		set_output(0,  m_data * m_gain + m_offset);
	}
}

DISCRETE_RESET(dss_input_not)
{
	m_gain = DSS_INPUT__GAIN;
	m_offset = DSS_INPUT__OFFSET;

	m_data = (DSS_INPUT__INIT == 0) ? 1 : 0;
	set_output(0,  m_data * m_gain + m_offset);
}

void DISCRETE_CLASS_FUNC(dss_input_not, input_write)(int sub_node, UINT8 data )
{
	UINT8 new_data    = 0;

	new_data = data ? 0 : 1;

	if (m_data != new_data)
	{
		/* Bring the system up to now */
		m_device->update_to_current_time();

		m_data = new_data;

		/* Update the node output here so we don't have to do it each step */
		set_output(0,  m_data * m_gain + m_offset);
	}
}

DISCRETE_STEP(dss_input_pulse)
{
	/* Set a valid output */
	set_output(0,  m_data);
	/* Reset the input to default for the next cycle */
	/* node order is now important */
	m_data = DSS_INPUT__INIT;
}

DISCRETE_RESET(dss_input_pulse)
{
	m_data = (DSS_INPUT__INIT == 0) ? 0 : 1;
	set_output(0,  m_data);
}

void DISCRETE_CLASS_FUNC(dss_input_pulse, input_write)(int sub_node, UINT8 data )
{
	UINT8 new_data    = 0;

	new_data =  data ? 1 : 0;

	if (m_data != new_data)
	{
		/* Bring the system up to now */
		m_device->update_to_current_time();
		m_data = new_data;
	}
}

/************************************************************************
 *
 * DSS_INPUT_STREAM    - Receives input from a routed stream
 *
 * input[0]    - Input stream number
 * input[1]    - Gain value
 * input[2]    - Offset value
 *
 ************************************************************************/
#define DSS_INPUT_STREAM__STREAM    DISCRETE_INPUT(0)
#define DSS_INPUT_STREAM__GAIN      DISCRETE_INPUT(1)
#define DSS_INPUT_STREAM__OFFSET    DISCRETE_INPUT(2)

void discrete_dss_input_stream_node::stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
	stream_sample_t *ptr = outputs[0];
	int samplenum = samples;

	while (samplenum-- > 0)
		*(ptr++) = m_data;
}
DISCRETE_STEP(dss_input_stream)
{
	/* the context pointer is set to point to the current input stream data in discrete_stream_update */
	if (EXPECTED(m_ptr))
	{
		set_output(0,  (*m_ptr) * m_gain + m_offset);
		m_ptr++;
	}
	else
		set_output(0,  0);
}

DISCRETE_RESET(dss_input_stream)
{
	m_ptr = nullptr;
	m_data = 0;
}

void DISCRETE_CLASS_FUNC(dss_input_stream, input_write)(int sub_node, UINT8 data )
{
	UINT8 new_data    = 0;

	new_data =  data;

	if (m_data != new_data)
	{
		if (m_is_buffered)
		{
			/* Bring the system up to now */
			m_buffer_stream->update();

			m_data = new_data;
		}
		else
		{
			/* Bring the system up to now */
			m_device->update_to_current_time();

			m_data = new_data;

			/* Update the node output here so we don't have to do it each step */
			set_output(0,  new_data * m_gain + m_offset);
		}
	}
}

DISCRETE_START(dss_input_stream)
{
	discrete_base_node::start();

	/* Stream out number is set during start */
	m_stream_in_number = DSS_INPUT_STREAM__STREAM;
	m_gain = DSS_INPUT_STREAM__GAIN;
	m_offset = DSS_INPUT_STREAM__OFFSET;
	m_ptr = nullptr;

	m_is_buffered = is_buffered();
	m_buffer_stream = nullptr;
}

void DISCRETE_CLASS_NAME(dss_input_stream)::stream_start(void)
{
	if (m_is_buffered)
	{
		/* stream_buffered input only supported for sound devices */
		discrete_sound_device *snd_device = downcast<discrete_sound_device *>(m_device);
		//assert(DSS_INPUT_STREAM__STREAM < snd_device->m_input_stream_list.count());

		m_buffer_stream = m_device->machine().sound().stream_alloc(*snd_device, 0, 1, this->sample_rate(), stream_update_delegate(FUNC(discrete_dss_input_stream_node::stream_generate),this));

		snd_device->get_stream()->set_input(m_stream_in_number, m_buffer_stream);
	}
}