summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/audio/channelf.cpp
blob: 8823294c75e7777fc73bc0f162b7572f4288da42 (plain) (tree)
1
2
3
4
5
6
7
8
9

                                                                      

                           

 
                             
 
                                                                                              
 
                                                                                                                             
                                                               
                                                       
                                   





                                    
                               
 

 
                                                   

                                                   
 
                                          
 

                 

                                                                

          















                                                                            

                                                        
                                           


                                                           
                                                                                     


                                                                      
                                               

                                
                       


                                                   
                                                

                                                   
                                                                                                                                       
 
                                      

                                             
 




                                                                 
 












                                                         
 











                                                                                                                        
 
                                             
 


















                                                                                      
 
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller, Frank Palazzolo, Sean Riddle
#include "emu.h"
#include "audio/channelf.h"


#define MAX_AMPLITUDE  0x7fff

DEFINE_DEVICE_TYPE(CHANNELF_SOUND, channelf_sound_device, "channelf_sound", "Channel F Sound")

channelf_sound_device::channelf_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, CHANNELF_SOUND, tag, owner, clock),
		device_sound_interface(mconfig, *this),
		m_channel(nullptr),
		m_sound_mode(0),
		m_incr(0),
		m_decay_mult(0),
		m_envelope(0),
		m_sample_counter(0),
		m_forced_ontime(0),
		m_min_ontime(0)
{
}

//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------

void channelf_sound_device::device_start()
{
	int rate;

	m_channel = stream_alloc(0, 1, machine().sample_rate());
	rate = machine().sample_rate();

	/*
	 * 2V = 1000Hz ~= 3579535/224/16
	 * Note 2V on the schematic is not the 2V scanline counter -
	 *      it is the 2V vertical pixel counter
	 *      1 pixel = 4 scanlines high
	 *
	 *
	 * This is a convenient way to generate the relevant frequencies,
	 * using a DDS (Direct Digital Synthesizer)
	 *
	 * Essentially, you want a counter to overflow some bit position
	 * at a fixed rate.  So, you figure out a number which you can add
	 * to the counter at every sample, so that you will achieve this
	 *
	 * In this case, we want to overflow bit 16 and the 2V rate, 1000Hz.
	 * This means we also get bit 17 = 4V, bit 18 = 8V, etc.
	 */

	/* This is the proper value to add per sample */
	m_incr = 65536.0/(rate/1000.0/2.0);

	//  added for improved sound
	/* This is the minimum forced ontime, in samples */
	m_min_ontime = rate/1000*2;  /* approx 2ms - estimated, not verified on HW */

	/* This was measured, decay envelope with half life of ~9ms */
	/* (this is decay multiplier per sample) */
	m_decay_mult = exp((-0.693/9e-3)/rate);

	/* initial conditions */
	m_envelope = 0;
}

//-------------------------------------------------
//  sound_stream_update - handle a stream update
//-------------------------------------------------

void channelf_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
	uint32_t mask = 0, target = 0;
	stream_sample_t *buffer = outputs[0];
	stream_sample_t *sample = buffer;

	switch( m_sound_mode )
	{
		case 0: /* sound off */
			memset(buffer,0,sizeof(*buffer)*samples);
			return;

		case 1: /* high tone (2V) - 1000Hz */
			mask   = 0x00010000;
			target = 0x00010000;
			break;
		case 2: /* medium tone (4V) - 500Hz */
			mask   = 0x00020000;
			target = 0x00020000;
			break;
		case 3: /* low (weird) tone (32V & 8V) */
			mask   = 0x00140000;
			target = 0x00140000;
			break;
	}

	while (samples-- > 0)
	{
		if ((m_forced_ontime > 0) || ((m_sample_counter & mask) == target))   //  change made for improved sound
			*sample++ = m_envelope;
		else
			*sample++ = 0;
		m_sample_counter += m_incr;
		m_envelope *= m_decay_mult;
		if (m_forced_ontime > 0)          //  added for improved sound
			m_forced_ontime -= 1;      //  added for improved sound
	}
}

void channelf_sound_device::sound_w(int mode)
{
	if (mode == m_sound_mode)
		return;

	m_channel->update();
	m_sound_mode = mode;

	switch(mode)
	{
		case 0:
			m_envelope = 0;
			m_forced_ontime = 0;     //  added for improved sound
			break;
		case 1:
		case 2:
		case 3:
			m_envelope = MAX_AMPLITUDE;
			m_forced_ontime = m_min_ontime;   //  added for improved sound
			break;
	}
}