libElysianVMU 1.6.0
Full-featured, accurate, cross-platform library emulating the Dreamcast's Visual Memory Unit
Loading...
Searching...
No Matches
evmu_buzzer.h
Go to the documentation of this file.
1/*! \file
2 * \brief EvmuBuzzer: Piezoelectric buzzer, PWM tone generation
3 * \ingroup peripherals
4 *
5 * The EvmuBuzzer API encompasses everything pertaining to signal
6 * generation and driving the piezoelectric buzzer. It provides
7 * a front-end API for generating and playing tones, as well as a
8 * polymorphic event-driven back-end for buffering and playing the
9 * generated tones with an audio back-end.
10 *
11 * \todo
12 * - Stop playback when emulation halts
13 * - Have to emulate Timer1 mode 3 buzzer output
14 * - Have to emulate base timer PWM output mode
15 * - Document emulated modes
16 * - Document how to implement a new back-end
17 * - Represent PCM buffer as GblByteArray, resizable samples
18 *
19 * \test
20 * - PCMs generated from setting tones under different timer1 configs
21 * - signals for tone generation
22 *
23 * \bug
24 * - Mini PacMan has no sound
25 * - Still not quite handling T1ELDC perfectly
26 *
27 * \author 2023 Falco Girgis
28 * \copyright MIT License
29 */
30#ifndef EVMU_BUZZER_H
31#define EVMU_BUZZER_H
32
33#include "../types/evmu_peripheral.h"
34#include <gimbal/meta/signals/gimbal_signal.h>
35
36/*! \name Type System
37 * \brief Type UUID and cast operators
38 * @{
39 */
40#define EVMU_BUZZER_TYPE (GBL_TYPEID(EvmuBuzzer)) //!< GblType UUID for GblBuzzer
41#define EVMU_BUZZER(self) (GBL_CAST(EvmuBuzzer, self)) //!< Cast GblInstance to EvmuBuzzer
42#define EVMU_BUZZER_CLASS(klass) (GBL_CLASS_CAST(EvmuBuzzer, klass)) //!< Cast GblClass to EvmuBuzzerClass
43#define EVMU_BUZZER_GET_CLASS(self) (GBL_CLASSOF(EvmuBuzzer, self)) //!< Get EvmuBuzzerClass from GblInstance
44//! @}
45
46#define EVMU_BUZZER_NAME "buzzer" //!< EvmuBuzzer GblObject name
47#define EVMU_BUZZER_PCM_BUFFER_SIZE 256 //!< Size of internal PCM buffer (bytes)
48
49#define GBL_SELF_TYPE EvmuBuzzer
50
51GBL_DECLS_BEGIN
52
53GBL_FORWARD_DECLARE_STRUCT(EvmuBuzzer);
54
55/*! \struct EvmuBuzzerClass
56 * \extends EvmuPeripheralClass
57 * \brief GblClass structure for EvmuBuzzer
58 *
59 * EvmuBuzzerClass provides a virtual table of overridable function
60 * pointers for implementing PCM audio playback functionality.
61 *
62 * \note
63 * The default implementations simply emit the corresponding signals
64 * for each event.
65 *
66 * \sa EvmuBuzzer
67 */
68GBL_CLASS_DERIVE(EvmuBuzzer, EvmuPeripheral)
69 EVMU_RESULT (*pFnPlayPcm) (GBL_SELF); //!< Called when a sample is ready to be played
70 EVMU_RESULT (*pFnStopPcm) (GBL_SELF); //!< Called when the playing sample should be stopped
71 EVMU_RESULT (*pFnBufferPcm)(GBL_SELF); //!< Called when a sample should be changed or reloaded
72GBL_CLASS_END
73
74/*! \struct EvmuBuzzer
75 * \extends EvmuPeripheral
76 * \ingroup peripherals
77 * \brief Instance structure for Buzzer Peripheral
78 *
79 * EvmuBuzzer is the GblInstance structure representing the
80 * piezoelectric buzzer peripheral and associated logic.
81 *
82 * \sa EvmuBuzzerClass
83 */
84GBL_INSTANCE_DERIVE(EvmuBuzzer, EvmuPeripheral)
85 GblBool pcmChanged; //!< User-toggle for polling updates
86 GblBool enableFreqResp; //!< Enables per-tone gain/volume emulation
87GBL_INSTANCE_END
88
89//! \cond
90GBL_PROPERTIES(EvmuBuzzer,
91 (enabled, GBL_GENERIC, (READ, WRITE), GBL_BOOL_TYPE),
92 (configured, GBL_GENERIC, (READ), GBL_BOOL_TYPE),
93 (active, GBL_GENERIC, (READ), GBL_BOOL_TYPE),
94 (period, GBL_GENERIC, (READ), GBL_UINT16_TYPE),
95 (invPulseLength, GBL_GENERIC, (READ), GBL_UINT8_TYPE),
96 (frequency, GBL_GENERIC, (READ), GBL_UINT32_TYPE),
97 (gain, GBL_GENERIC, (READ), GBL_FLOAT_TYPE)
98)
99
100GBL_SIGNALS(EvmuBuzzer,
101 (toneStart, (GBL_INSTANCE_TYPE, pReceiver)),
102 (toneStop, (GBL_INSTANCE_TYPE, pReceiver)),
103 (toneUpdate, (GBL_INSTANCE_TYPE, pReceiver),
104 (GBL_UINT16_TYPE, period),
105 (GBL_UINT8_TYPE, invPulseLength))
106)
107//! \endcond
108
109//! EvmuBuzzer's type ID
111
112/*! \name Configuration
113 * \brief Methods for managing buzzer configuration
114 * \relatesalso EvmuBuzzer
115 * @{
116 */
117//! Returns whether playback is active or not
118EVMU_EXPORT GblBool EvmuBuzzer_isActive (GBL_CSELF) GBL_NOEXCEPT;
119//! Returns whether the buzzer has been configured for playback
121//! Returns whether software has enabled or disabled the buzzer
122EVMU_EXPORT GblBool EvmuBuzzer_isEnabled (GBL_CSELF) GBL_NOEXCEPT;
123//! Allows software to enable or disable buzzer emulation
125 GblBool en) GBL_NOEXCEPT;
126//! @}
127
128/*! \name Tone Playback
129 * \brief Methods for managing tone generation and playback
130 * \relatesalso EvmuBuzzer
131 * @{
132 */
133//! Returns the current tone's square wave
135 uint16_t* pPeriod,
136 uint8_t* pInvPulseLen) GBL_NOEXCEPT;
137//! Sets the square wave of the current tone without impacting playback
138EVMU_EXPORT EVMU_RESULT EvmuBuzzer_setTone (GBL_SELF,
139 uint16_t period,
140 uint8_t invPulseLen) GBL_NOEXCEPT;
141//! Plays the current tone's square wave
142EVMU_EXPORT EVMU_RESULT EvmuBuzzer_playTone (GBL_SELF) GBL_NOEXCEPT;
143//! Stops playback of the current tone
144EVMU_EXPORT EVMU_RESULT EvmuBuzzer_stopTone (GBL_SELF) GBL_NOEXCEPT;
145//! @}
146
147/*! \name PCM Back-End
148 * \brief Methods used to implement an audio driver back-end
149 * \relatesalso EvmuBuzzer
150 * @{
151 */
152//! Returns the current PCM buffer to the audio driver
153EVMU_EXPORT const void* EvmuBuzzer_pcmBuffer (GBL_CSELF) GBL_NOEXCEPT;
154//! Returns the PCM buffer's sample size to the audio driver
155EVMU_EXPORT size_t EvmuBuzzer_pcmSamples (GBL_CSELF) GBL_NOEXCEPT;
156//! Returns the PCM buffer's sample frequency to the audio driver
157EVMU_EXPORT size_t EvmuBuzzer_pcmFrequency (GBL_CSELF) GBL_NOEXCEPT;
158//! Returns the PCM buffer's gain to the audio driver
159EVMU_EXPORT float EvmuBuzzer_pcmGain (GBL_CSELF) GBL_NOEXCEPT;
160//! @}
161
162GBL_DECLS_END
163
164#undef GBL_SELF_TYPE
165
166#endif // EVMU_BUZZER_H
#define EVMU_EXPORT
Define used for adding attributes to export public symbols.
Definition evmu_api.h:18
GblType EvmuBuzzer_type(void)
EvmuBuzzer's type ID.
#define GBL_UINT16_TYPE
#define GBL_FLOAT_TYPE
#define GBL_BOOL_TYPE
#define GBL_UINT8_TYPE
#define GBL_UINT32_TYPE
#define GBL_PROPERTIES(object,...)
uint8_t GblBool
uintptr_t GblType
Instance structure for Buzzer Peripheral.
Definition evmu_buzzer.h:84
float EvmuBuzzer_pcmGain(const EvmuBuzzer *pSelf)
Returns the PCM buffer's gain to the audio driver.
EVMU_RESULT EvmuBuzzer_stopTone(EvmuBuzzer *pSelf)
Stops playback of the current tone.
EVMU_RESULT EvmuBuzzer_playTone(EvmuBuzzer *pSelf)
Plays the current tone's square wave.
GblBool EvmuBuzzer_isEnabled(const EvmuBuzzer *pSelf)
Returns whether software has enabled or disabled the buzzer.
GblBool EvmuBuzzer_isConfigured(const EvmuBuzzer *pSelf)
Returns whether the buzzer has been configured for playback.
GblBool pcmChanged
User-toggle for polling updates.
Definition evmu_buzzer.h:85
EVMU_RESULT EvmuBuzzer_setTone(EvmuBuzzer *pSelf, uint16_t period, uint8_t invPulseLen)
Sets the square wave of the current tone without impacting playback.
GblBool EvmuBuzzer_isActive(const EvmuBuzzer *pSelf)
Returns whether playback is active or not.
void EvmuBuzzer_setEnabled(EvmuBuzzer *pSelf, GblBool en)
Allows software to enable or disable buzzer emulation.
size_t EvmuBuzzer_pcmFrequency(const EvmuBuzzer *pSelf)
Returns the PCM buffer's sample frequency to the audio driver.
void EvmuBuzzer_tone(const EvmuBuzzer *pSelf, uint16_t *pPeriod, uint8_t *pInvPulseLen)
Returns the current tone's square wave.
GblBool enableFreqResp
Enables per-tone gain/volume emulation.
Definition evmu_buzzer.h:86
const void * EvmuBuzzer_pcmBuffer(const EvmuBuzzer *pSelf)
Returns the current PCM buffer to the audio driver.
size_t EvmuBuzzer_pcmSamples(const EvmuBuzzer *pSelf)
Returns the PCM buffer's sample size to the audio driver.
#define GBL_CLASS_CAST(cType, klass)
#define GBL_CLASSOF(cType, self)
#define GBL_CAST(cType, self)