summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/sound/dac.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/sound/dac.c')
-rw-r--r--src/emu/sound/dac.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/src/emu/sound/dac.c b/src/emu/sound/dac.c
new file mode 100644
index 00000000000..173f7d02e27
--- /dev/null
+++ b/src/emu/sound/dac.c
@@ -0,0 +1,187 @@
+#include "sndintrf.h"
+#include "streams.h"
+#include "dac.h"
+#include <math.h>
+
+
+/* default to 4x oversampling */
+#define DEFAULT_SAMPLE_RATE (48000 * 4)
+
+
+struct dac_info
+{
+ sound_stream *channel;
+ INT16 output;
+ INT16 UnsignedVolTable[256];
+ INT16 SignedVolTable[256];
+};
+
+
+
+static void DAC_update(void *param,stream_sample_t **inputs, stream_sample_t **_buffer,int length)
+{
+ struct dac_info *info = param;
+ stream_sample_t *buffer = _buffer[0];
+ INT16 out = info->output;
+
+ while (length--) *(buffer++) = out;
+}
+
+
+void DAC_data_w(int num,UINT8 data)
+{
+ struct dac_info *info = sndti_token(SOUND_DAC, num);
+ INT16 out = info->UnsignedVolTable[data];
+
+ if (info->output != out)
+ {
+ /* update the output buffer before changing the registers */
+ stream_update(info->channel);
+ info->output = out;
+ }
+}
+
+
+void DAC_signed_data_w(int num,UINT8 data)
+{
+ struct dac_info *info = sndti_token(SOUND_DAC, num);
+ INT16 out = info->SignedVolTable[data];
+
+ if (info->output != out)
+ {
+ /* update the output buffer before changing the registers */
+ stream_update(info->channel);
+ info->output = out;
+ }
+}
+
+
+void DAC_data_16_w(int num,UINT16 data)
+{
+ struct dac_info *info = sndti_token(SOUND_DAC, num);
+ INT16 out = data >> 1; /* range 0..32767 */
+
+ if (info->output != out)
+ {
+ /* update the output buffer before changing the registers */
+ stream_update(info->channel);
+ info->output = out;
+ }
+}
+
+
+void DAC_signed_data_16_w(int num,UINT16 data)
+{
+ struct dac_info *info = sndti_token(SOUND_DAC, num);
+ INT16 out = (INT32)data - (INT32)0x08000; /* range -32768..32767 */
+ /* casts avoid potential overflow on some ABIs */
+
+ if (info->output != out)
+ {
+ /* update the output buffer before changing the registers */
+ stream_update(info->channel);
+ info->output = out;
+ }
+}
+
+
+static void DAC_build_voltable(struct dac_info *info)
+{
+ int i;
+
+
+ /* build volume table (linear) */
+ for (i = 0;i < 256;i++)
+ {
+ info->UnsignedVolTable[i] = i * 0x101 / 2; /* range 0..32767 */
+ info->SignedVolTable[i] = i * 0x101 - 0x8000; /* range -32768..32767 */
+ }
+}
+
+
+static void *dac_start(int sndindex, int clock, const void *config)
+{
+ struct dac_info *info;
+
+ info = auto_malloc(sizeof(*info));
+ memset(info, 0, sizeof(*info));
+
+ DAC_build_voltable(info);
+
+ info->channel = stream_create(0,1,clock ? clock : DEFAULT_SAMPLE_RATE,info,DAC_update);
+ info->output = 0;
+
+ state_save_register_item("dac", sndindex, info->output);
+
+ return info;
+}
+
+
+
+WRITE8_HANDLER( DAC_0_data_w )
+{
+ DAC_data_w(0,data);
+}
+
+WRITE8_HANDLER( DAC_1_data_w )
+{
+ DAC_data_w(1,data);
+}
+
+WRITE8_HANDLER( DAC_2_data_w )
+{
+ DAC_data_w(2,data);
+}
+
+WRITE8_HANDLER( DAC_0_signed_data_w )
+{
+ DAC_signed_data_w(0,data);
+}
+
+WRITE8_HANDLER( DAC_1_signed_data_w )
+{
+ DAC_signed_data_w(1,data);
+}
+
+WRITE8_HANDLER( DAC_2_signed_data_w )
+{
+ DAC_signed_data_w(2,data);
+}
+
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+static void dac_set_info(void *token, UINT32 state, sndinfo *info)
+{
+ switch (state)
+ {
+ /* no parameters to set */
+ }
+}
+
+
+void dac_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 = dac_set_info; break;
+ case SNDINFO_PTR_START: info->start = dac_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 = "DAC"; break;
+ case SNDINFO_STR_CORE_FAMILY: info->s = "TI Speech"; 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) 2004, The MAME Team"; break;
+ }
+}
+