diff options
Diffstat (limited to 'src/emu/sound/tms3615.c')
-rw-r--r-- | src/emu/sound/tms3615.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/emu/sound/tms3615.c b/src/emu/sound/tms3615.c new file mode 100644 index 00000000000..46225348ccd --- /dev/null +++ b/src/emu/sound/tms3615.c @@ -0,0 +1,125 @@ +#include "sndintrf.h" +#include "streams.h" +#include "tms3615.h" + +#define VMIN 0x0000 +#define VMAX 0x7fff + +#define TONES 13 + +static int divisor[TONES] = { 478, 451, 426, 402, 379, 358, 338, 319, 301, 284, 268, 253, 239 }; + +struct TMS3615 { + sound_stream *channel; /* returned by stream_create() */ + int samplerate; /* output sample rate */ + int basefreq; /* chip's base frequency */ + int counter8[TONES]; /* tone frequency counter for 8' */ + int counter16[TONES]; /* tone frequency counter for 16'*/ + int output8; /* output signal bits for 8' */ + int output16; /* output signal bits for 16' */ + int enable; /* mask which tones to play */ +}; + +static void tms3615_sound_update(void *param, stream_sample_t **inputs, stream_sample_t **_buffer, int length) +{ + struct TMS3615 *tms = param; + int samplerate = tms->samplerate; + stream_sample_t *buffer8 = _buffer[TMS3615_FOOTAGE_8]; + stream_sample_t *buffer16 = _buffer[TMS3615_FOOTAGE_16]; + + while( length-- > 0 ) + { + int sum8 = 0, sum16 = 0, tone = 0; + + for (tone = 0; tone < TONES; tone++) + { + // 8' + + tms->counter8[tone] -= (tms->basefreq / divisor[tone]); + + while( tms->counter8[tone] <= 0 ) + { + tms->counter8[tone] += samplerate; + tms->output8 ^= 1 << tone; + } + + if (tms->output8 & tms->enable & (1 << tone)) + { + sum8 += VMAX; + } + + // 16' + + tms->counter16[tone] -= (tms->basefreq / divisor[tone] / 2); + + while( tms->counter16[tone] <= 0 ) + { + tms->counter16[tone] += samplerate; + tms->output16 ^= 1 << tone; + } + + if (tms->output16 & tms->enable & (1 << tone)) + { + sum16 += VMAX; + } + } + + *buffer8++ = sum8 / TONES; + *buffer16++ = sum16 / TONES; + } + + tms->enable = 0; +} + +void tms3615_enable_w(int chip, int enable) +{ + struct TMS3615 *tms = sndti_token(SOUND_TMS3615, chip); + tms->enable = enable; +} + +static void *tms3615_start(int sndindex, int clock, const void *config) +{ + struct TMS3615 *tms; + + tms = auto_malloc(sizeof(*tms)); + memset(tms, 0, sizeof(*tms)); + + tms->channel = stream_create(0, 2, clock/8, tms, tms3615_sound_update); + tms->samplerate = clock/8; + tms->basefreq = clock; + + return tms; +} + +/************************************************************************** + * Generic get_info + **************************************************************************/ + +static void tms3615_set_info(void *token, UINT32 state, sndinfo *info) +{ + switch (state) + { + /* no parameters to set */ + } +} + +void tms3615_get_info(void *token, UINT32 state, sndinfo *info) +{ + switch (state) + { + /* --- the following bits of info are returned as 64-bit signed integers --- */ + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case SNDINFO_PTR_SET_INFO: info->set_info = tms3615_set_info; break; + case SNDINFO_PTR_START: info->start = tms3615_start; break; + case SNDINFO_PTR_STOP: /* Nothing */ break; + case SNDINFO_PTR_RESET: /* Nothing */ break; + + /* --- the following bits of info are returned as NULL-terminated strings --- */ + case SNDINFO_STR_NAME: info->s = "TMS3615"; break; + case SNDINFO_STR_CORE_FAMILY: info->s = "TI PSG"; break; + case SNDINFO_STR_CORE_VERSION: info->s = "1.0"; break; + case SNDINFO_STR_CORE_FILE: info->s = __FILE__; break; + case SNDINFO_STR_CORE_CREDITS: info->s = "Copyright (c) 2006, The MAME Team"; break; + } +} |