summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/speaker.h
blob: c4fd19edca15e016a94a637b6453ff70d315a1f0 (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
134
135
136
137
138
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    speaker.h

    Speaker output sound device.
    Microphone input sound device.

    They have (x, y, z) coordinates in 3D space:
    * Observer is at position (0, 0, 0)
    * Positive x is to the right of the observer
    * Negative x is to the left of the observer
    * Positive y is above the observer
    * Negative y is below the observer
    * Positive z is in front of the observer
    * Negative z is behind the observer

***************************************************************************/

#ifndef MAME_EMU_SPEAKER_H
#define MAME_EMU_SPEAKER_H

#pragma once


//**************************************************************************
//  GLOBAL VARIABLES
//**************************************************************************

// device type definition
DECLARE_DEVICE_TYPE(SPEAKER, speaker_device)
DECLARE_DEVICE_TYPE(MICROPHONE, microphone_device)



//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

class sound_io_device : public device_t, public device_sound_interface
{
public:
	virtual ~sound_io_device();

	// configuration helpers
	sound_io_device &set_position(u32 channel, double x, double y, double z);
	sound_io_device &front_center(u32 channel = 0)      { return set_position(channel,  0.0,  0.0,  1.0); }
	sound_io_device &front_left(u32 channel = 0)        { return set_position(channel, -0.2,  0.0,  1.0); }
	sound_io_device &front_floor(u32 channel = 0)       { return set_position(channel,  0.0, -0.5,  1.0); }
	sound_io_device &front_right(u32 channel = 0)       { return set_position(channel,  0.2,  0.0,  1.0); }
	sound_io_device &rear_center(u32 channel = 0)       { return set_position(channel,  0.0,  0.0, -0.5); }
	sound_io_device &rear_left(u32 channel = 0)         { return set_position(channel, -0.2,  0.0, -0.5); }
	sound_io_device &rear_right(u32 channel = 0)        { return set_position(channel,  0.2,  0.0, -0.5); }
	sound_io_device &headrest_center(u32 channel = 0)   { return set_position(channel,  0.0,  0.0, -0.1); }
	sound_io_device &headrest_left(u32 channel = 0)     { return set_position(channel, -0.1,  0.0, -0.1); }
	sound_io_device &headrest_right(u32 channel = 0)    { return set_position(channel,  0.1,  0.0, -0.1); }
	sound_io_device &seat(u32 channel = 0)              { return set_position(channel,  0.0, -0.5,  0.0); }
	sound_io_device &backrest(u32 channel = 0)          { return set_position(channel,  0.0, -0.2,  0.1); }
	sound_io_device &front()                            { return front_left(0).front_right(1); }
	sound_io_device &rear()                             { return rear_left(0).rear_right(1); }
	sound_io_device &corners()                          { return front_left(0).front_right(1).rear_left(2).rear_right(3); }
	std::array<double, 3> get_position(u32 channel) const { return m_positions[channel]; }
	std::string get_position_name(u32 channel) const;

	virtual bool is_output() const = 0;
	void set_id(int id) { m_id = id; }

	sound_stream *stream() const { return m_stream; }

protected:
	struct position_name_mapping {
		double m_x, m_y, m_z;
		const char *m_name;
	};

	static const position_name_mapping position_name_mappings[];

	// configuration state
	std::vector<std::array<double, 3>> m_positions;
	sound_stream *m_stream;
	int m_id;

	sound_io_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, double x, double y, double z)
		: sound_io_device(mconfig, type, tag, owner, 1)
	{
		set_position(0, x, y, z);
	}
	sound_io_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 channels); // Collides with clock, but not important
};

class speaker_device : public sound_io_device
{
public:
	// construction/destruction
	speaker_device(const machine_config &mconfig, const char *tag, device_t *owner, double x, double y, double z)
		: sound_io_device(mconfig, SPEAKER, tag, owner, x, y, z) {}
	speaker_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 channels = 1)
		: sound_io_device(mconfig, SPEAKER, tag, owner, channels) {}

	virtual ~speaker_device();

	virtual bool is_output() const override { return true; }

protected:

	// device-level overrides
	virtual void device_start() override ATTR_COLD;

	virtual void sound_stream_update(sound_stream &stream) override;
};

class microphone_device : public sound_io_device
{
public:
	// construction/destruction
	microphone_device(const machine_config &mconfig, const char *tag, device_t *owner, double x, double y, double z)
		: sound_io_device(mconfig, MICROPHONE, tag, owner, x, y, z) {}
	microphone_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 channels = 1)
		: sound_io_device(mconfig, MICROPHONE, tag, owner, channels) {}

	virtual ~microphone_device();

	virtual bool is_output() const override { return false; }

protected:

	// device-level overrides
	virtual void device_start() override ATTR_COLD;

	virtual void sound_stream_update(sound_stream &stream) override;
};

using speaker_device_enumerator = device_type_enumerator<speaker_device>;
using microphone_device_enumerator = device_type_enumerator<microphone_device>;


#endif // MAME_EMU_SPEAKER_H