1 // license:BSD-3-Clause
2 // copyright-holders:Krzysztof Strzecha
3 /***************************************************************************
4
5 audio/dai_snd.c
6
7 Functions to emulate sound hardware of DAI Personal Computer
8
9 Krzysztof Strzecha
10
11 ****************************************************************************/
12
13 #include "emu.h"
14 #include "dai_snd.h"
15
16 // device type definition
17 DEFINE_DEVICE_TYPE(DAI_SOUND, dai_sound_device, "dai_sound", "DAI Custom Sound")
18
19
20 //-------------------------------------------------
21 // dai_sound_device - constructor
22 //-------------------------------------------------
23
dai_sound_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)24 dai_sound_device::dai_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
25 : device_t(mconfig, DAI_SOUND, tag, owner, clock)
26 , device_sound_interface(mconfig, *this)
27 {
28 }
29
30 //-------------------------------------------------
31 // device_start - device-specific startup
32 //-------------------------------------------------
33
device_start()34 void dai_sound_device::device_start()
35 {
36 m_mixer_channel = stream_alloc(0, 2, machine().sample_rate());
37 }
38
39 //-------------------------------------------------
40 // device_reset - device-specific reset
41 //-------------------------------------------------
42
device_reset()43 void dai_sound_device::device_reset()
44 {
45 memset(m_dai_input, 0, sizeof(m_dai_input));
46 memset(m_osc_volume, 0, sizeof(m_osc_volume));
47 m_noise_volume = 0;
48 }
49
50
51 //-------------------------------------------------
52 // channels 0/1/2 volume table
53 //-------------------------------------------------
54
55 const uint16_t dai_sound_device::s_osc_volume_table[] = {
56 0, 500, 1000, 1500,
57 2000, 2500, 3000, 3500,
58 4000, 4500, 5000, 5500,
59 6000, 6500, 7000, 7500
60 };
61
62 //-------------------------------------------------
63 // noise volume table
64 //-------------------------------------------------
65
66 const uint16_t dai_sound_device::s_noise_volume_table[] = {
67 0, 0, 0, 0,
68 0, 0, 0, 0,
69 500, 1000, 1500, 2000,
70 2500, 3000, 3500, 4000
71 };
72
73
74 //-------------------------------------------------
75 // set_volume
76 //-------------------------------------------------
77
set_volume(offs_t offset,uint8_t data)78 void dai_sound_device::set_volume(offs_t offset, uint8_t data)
79 {
80 m_mixer_channel->update();
81
82 switch (offset & 1)
83 {
84 case 0x00:
85 m_osc_volume[0] = data&0x0f;
86 m_osc_volume[1] = (data&0xf0)>>4;
87 break;
88
89 case 0x01:
90 m_osc_volume[2] = data&0x0f;
91 m_noise_volume = (data&0xf0)>>4;
92 }
93 }
94
95 //-------------------------------------------------
96 // PIT callbacks
97 //-------------------------------------------------
98
WRITE_LINE_MEMBER(dai_sound_device::set_input_ch0)99 WRITE_LINE_MEMBER(dai_sound_device::set_input_ch0)
100 {
101 m_mixer_channel->update();
102 m_dai_input[0] = state;
103 }
104
WRITE_LINE_MEMBER(dai_sound_device::set_input_ch1)105 WRITE_LINE_MEMBER(dai_sound_device::set_input_ch1)
106 {
107 m_mixer_channel->update();
108 m_dai_input[1] = state;
109 }
110
WRITE_LINE_MEMBER(dai_sound_device::set_input_ch2)111 WRITE_LINE_MEMBER(dai_sound_device::set_input_ch2)
112 {
113 m_mixer_channel->update();
114 m_dai_input[2] = state;
115 }
116
117 //-------------------------------------------------
118 // sound_stream_update - handle update requests for
119 // our sound stream
120 //-------------------------------------------------
121
sound_stream_update(sound_stream & stream,std::vector<read_stream_view> const & inputs,std::vector<write_stream_view> & outputs)122 void dai_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
123 {
124 auto &sample_left = outputs[0];
125 auto &sample_right = outputs[1];
126
127 int16_t channel_0_signal = m_dai_input[0] ? s_osc_volume_table[m_osc_volume[0]] : -s_osc_volume_table[m_osc_volume[0]];
128 int16_t channel_1_signal = m_dai_input[1] ? s_osc_volume_table[m_osc_volume[1]] : -s_osc_volume_table[m_osc_volume[1]];
129 int16_t channel_2_signal = m_dai_input[2] ? s_osc_volume_table[m_osc_volume[2]] : -s_osc_volume_table[m_osc_volume[2]];
130
131 for (int sampindex = 0; sampindex < sample_left.samples(); sampindex++)
132 {
133 int16_t noise = machine().rand()&0x01 ? s_noise_volume_table[m_noise_volume] : -s_noise_volume_table[m_noise_volume];
134
135 /* channel 0 + channel 1 + noise */
136 sample_left.put_int(sampindex, channel_0_signal + channel_1_signal + noise, 32768);
137
138 /* channel 1 + channel 2 + noise */
139 sample_right.put_int(sampindex, channel_1_signal + channel_2_signal + noise, 32768);
140 }
141 }
142