summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/sound/speaker.h
diff options
context:
space:
mode:
author Fabio Priuli <etabeta78@users.noreply.github.com>2013-06-04 07:57:44 +0000
committer Fabio Priuli <etabeta78@users.noreply.github.com>2013-06-04 07:57:44 +0000
commit0a3efaf5411165de0f8eb3eddc84835c98ea55fc (patch)
tree45d11b5ec788d183f9a691cf555ad3f061eed4f4 /src/emu/sound/speaker.h
parent35704b5ad4241167afead2c66771e5f4f9e20981 (diff)
modernized speaker device. [Fabio Priuli]
Diffstat (limited to 'src/emu/sound/speaker.h')
-rw-r--r--src/emu/sound/speaker.h56
1 files changed, 48 insertions, 8 deletions
diff --git a/src/emu/sound/speaker.h b/src/emu/sound/speaker.h
index cee9949c591..fba5e13e33b 100644
--- a/src/emu/sound/speaker.h
+++ b/src/emu/sound/speaker.h
@@ -13,23 +13,30 @@
#include "devlegcy.h"
+// Length of anti-aliasing filter kernel, measured in number of intermediate samples
+enum
+{
+ FILTER_LENGTH = 64
+};
+
+
struct speaker_interface
{
- int num_level; /* optional: number of levels (if not two) */
- const INT16 *levels; /* optional: pointer to level lookup table */
+ int m_num_levels; /* optional: number of levels (if not two) */
+ const INT16 *m_levels; /* optional: pointer to level lookup table */
};
-void speaker_level_w (device_t *device, int new_level);
class speaker_sound_device : public device_t,
- public device_sound_interface
+ public device_sound_interface,
+ public speaker_interface
{
public:
speaker_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- ~speaker_sound_device() { global_free(m_token); }
+ ~speaker_sound_device() {}
+
+ void level_w(int new_level);
- // access to legacy token
- void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
@@ -37,9 +44,42 @@ protected:
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
+
private:
// internal state
- void *m_token;
+
+ // Updates the composed volume array according to time
+ void update_interm_samples(attotime time, int volume);
+
+ // Updates the composed volume array and returns final filtered volume of next stream sample
+ double update_interm_samples_get_filtered_volume(int volume);
+
+ void finalize_interm_sample(int volume);
+ void init_next_interm_sample();
+ inline double make_fraction(attotime a, attotime b, double timediv);
+ double get_filtered_volume();
+
+ // Kernel (pulse response) for filtering across samples (while we avoid fancy filtering within samples)
+ double m_ampl[FILTER_LENGTH];
+
+ sound_stream *m_channel;
+ int m_level;
+
+ /* The volume of a composed sample grows incrementally each time the speaker is over-sampled.
+ * That is in effect a basic average filter.
+ * Another filter can and will be applied to the array of composed samples.
+ */
+ double m_composed_volume[FILTER_LENGTH]; /* integrator(s) */
+ int m_composed_sample_index; /* array index for composed_volume */
+ attoseconds_t m_channel_sample_period; /* in as */
+ double m_channel_sample_period_secfrac; /* in fraction of second */
+ attotime m_channel_last_sample_time;
+ attotime m_channel_next_sample_time;
+ attoseconds_t m_interm_sample_period;
+ double m_interm_sample_period_secfrac;
+ attotime m_next_interm_sample_time;
+ int m_interm_sample_index; /* counts interm. samples between stream samples */
+ attotime m_last_update_time; /* internal timestamp */
};
extern const device_type SPEAKER_SOUND;