1 // license:BSD-3-Clause 2 // copyright-holders:Nicola Salmoria 3 /********************************************************************** 4 5 speaker.h 6 Sound driver to emulate a simple speaker, 7 driven by one or more output bits 8 9 **********************************************************************/ 10 #ifndef MAME_SOUND_SPKRDEV_H 11 #define MAME_SOUND_SPKRDEV_H 12 13 #pragma once 14 15 16 class speaker_sound_device : public device_t, 17 public device_sound_interface 18 { 19 public: 20 speaker_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); ~speaker_sound_device()21 ~speaker_sound_device() {} 22 23 // configuration set_levels(int num_levels,const double * levels)24 void set_levels(int num_levels, const double *levels) { m_num_levels = num_levels; m_levels = levels; } 25 26 void level_w(int new_level); // can use as writeline 27 28 protected: 29 // device-level overrides 30 virtual void device_start() override; 31 virtual void device_reset() override; 32 virtual void device_post_load() override; 33 34 // sound stream update overrides 35 virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override; 36 37 private: 38 // Length of anti-aliasing filter kernel, measured in number of intermediate samples 39 enum 40 { 41 FILTER_LENGTH = 64 42 }; 43 44 // internal state 45 46 // Updates the composed volume array according to time 47 void update_interm_samples(const attotime &time, int volume); 48 49 // Updates the composed volume array and returns final filtered volume of next stream sample 50 double update_interm_samples_get_filtered_volume(double volume); 51 52 void finalize_interm_sample(double volume); 53 void init_next_interm_sample(); 54 inline double make_fraction(const attotime &a, const attotime &b, double timediv); 55 double get_filtered_volume(); 56 57 // Kernel (pulse response) for filtering across samples (while we avoid fancy filtering within samples) 58 double m_ampl[FILTER_LENGTH]; 59 60 sound_stream *m_channel; 61 int m_level; 62 63 /* The volume of a composed sample grows incrementally each time the speaker is over-sampled. 64 * That is in effect a basic average filter. 65 * Another filter can and will be applied to the array of composed samples. 66 */ 67 double m_composed_volume[FILTER_LENGTH]; /* integrator(s) */ 68 int m_composed_sample_index; /* array index for composed_volume */ 69 attoseconds_t m_channel_sample_period; /* in as */ 70 double m_channel_sample_period_secfrac; /* in fraction of second */ 71 attotime m_channel_last_sample_time; 72 attotime m_channel_next_sample_time; 73 attoseconds_t m_interm_sample_period; 74 double m_interm_sample_period_secfrac; 75 attotime m_next_interm_sample_time; 76 int m_interm_sample_index; /* counts interm. samples between stream samples */ 77 attotime m_last_update_time; /* internal timestamp */ 78 79 // DC blocker state 80 double m_prevx, m_prevy; 81 82 int m_num_levels; /* optional: number of levels (if not two) */ 83 const double *m_levels; /* optional: pointer to level lookup table */ 84 }; 85 86 DECLARE_DEVICE_TYPE(SPEAKER_SOUND, speaker_sound_device) 87 88 #endif // MAME_SOUND_SPKRDEV_H 89