summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/va_ops.cpp
blob: c3652817320e54eb7fdf674bcf28e3158ebfe46a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// license:BSD-3-Clause
// copyright-holders:m1macrophage

#include "emu.h"
#include "va_ops.h"
#include "machine/rescap.h"


va_const_device::va_const_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
	: device_t(mconfig, VA_CONST, tag, owner, clock)
	, device_sound_interface(mconfig, *this)
	, m_stream(nullptr)
	, m_value(0)
{
}

va_const_device &va_const_device::set_value(float value)
{
	if (m_stream)
		m_stream->update();
	m_value = value;
	return *this;
}

void va_const_device::device_start()
{
	m_stream = stream_alloc(0, 1, SAMPLE_RATE_OUTPUT_ADAPTIVE);
	save_item(NAME(m_value));
}

void va_const_device::sound_stream_update(sound_stream &stream)
{
	stream.fill(0, m_value);
}


va_scale_offset_device::va_scale_offset_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
	: device_t(mconfig, VA_SCALE_OFFSET, tag, owner, clock)
	, device_sound_interface(mconfig, *this)
	, m_stream(nullptr)
	, m_scale(1)
	, m_offset(0)
{
}

va_scale_offset_device &va_scale_offset_device::set_scale(float scale)
{
	if (m_stream)
		m_stream->update();
	m_scale = scale;
	return *this;
}

va_scale_offset_device &va_scale_offset_device::set_offset(float offset)
{
	if (m_stream)
		m_stream->update();
	m_offset = offset;
	return *this;
}

void va_scale_offset_device::device_start()
{
	save_item(NAME(m_scale));
	save_item(NAME(m_offset));
	m_stream = stream_alloc(1, 1, SAMPLE_RATE_INPUT_ADAPTIVE);
}

void va_scale_offset_device::sound_stream_update(sound_stream &stream)
{
	const int n = stream.samples();
	for (int i = 0; i < n; ++i)
		stream.put(0, i, m_scale * stream.get(0, i) + m_offset);
}


va_comparator_device::va_comparator_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
	: device_t(mconfig, VA_COMPARATOR, tag, owner, clock)
	, device_sound_interface(mconfig, *this)
	, m_thresh_pos(0.5F)
	, m_thresh_neg(0.5F)
	, m_inverted(false)
	, m_stream(nullptr)
	, m_state(false)
{
}

va_comparator_device &va_comparator_device::configure(float thresh_pos, float thresh_neg, bool inverted)
{
	if (thresh_neg > thresh_pos)
		fatalerror("%s: negative-going threshold needs to be <= positive-going threshold\n", tag());
	m_thresh_pos = thresh_pos;
	m_thresh_neg = thresh_neg;
	m_inverted = inverted;
	return *this;
}

va_comparator_device &va_comparator_device::configure(const comp_oc_hyst_config &c)
{
	return configure(
		(c.v_thresh - c.v_pullup) * RES_VOLTAGE_DIVIDER(c.r_thresh, c.r_feedback + c.r_pullup) + c.v_pullup,
		(c.v_thresh - c.v_minus) * RES_VOLTAGE_DIVIDER(c.r_thresh, c.r_feedback) + c.v_minus, true);
}

int va_comparator_device::state()
{
	m_stream->update();
	if (m_inverted)
		return m_state ? 0 : 1;
	else
		return m_state ? 1 : 0;
}

void va_comparator_device::device_start()
{
	m_stream = stream_alloc(1, 0, SAMPLE_RATE_INPUT_ADAPTIVE);
	save_item(NAME(m_state));
}

void va_comparator_device::sound_stream_update(sound_stream &stream)
{
	const int n = stream.samples();
	for (int i = 0; i < n; ++i)
	{
		const float threshold = m_state ? m_thresh_neg : m_thresh_pos;
		m_state = stream.get(0, i) >= threshold;
	}
}


DEFINE_DEVICE_TYPE(VA_CONST, va_const_device, "va_const", "Constant value stream")
DEFINE_DEVICE_TYPE(VA_SCALE_OFFSET, va_scale_offset_device, "va_scale_offset", "Stream scale and offset")
DEFINE_DEVICE_TYPE(VA_COMPARATOR, va_comparator_device, "va_comparator", "Stream comparator")