DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 00020 #ifndef DOSBOX_MIXER_H 00021 #define DOSBOX_MIXER_H 00022 00023 #include <sstream> 00024 00025 #ifndef DOSBOX_DOSBOX_H 00026 #include "dosbox.h" 00027 #endif 00028 00029 typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len); 00030 typedef void (*MIXER_Handler)(Bitu len); 00031 00032 template <class T> T clamp(const T& n, const T& lower, const T& upper) { 00033 return std::max<T>(lower, std::min<T>(n, upper)); 00034 } 00035 00036 #define MIXER_BUFSIZE (16*1024) 00037 #define MIXER_BUFMASK (MIXER_BUFSIZE-1) 00038 extern Bit8u MixTemp[MIXER_BUFSIZE]; 00039 00040 #define MAX_AUDIO ((1<<(16-1))-1) 00041 #define MIN_AUDIO -(1<<(16-1)) 00042 00043 #define LOWPASS_ORDER 8 00044 00045 class MixerChannel { 00046 public: 00047 void SetVolume(float _left,float _right); 00048 void SetScale( float f ); 00049 void SetScale(float _left, float _right); 00050 void UpdateVolume(void); 00051 void SetLowpassFreq(Bitu _freq,unsigned int order=2); // _freq / 1 Hz. call with _freq == 0 to disable 00052 void SetSlewFreq(Bitu _freq); // denominator provided by call to SetFreq. call with _freq == 0 to disable 00053 void SetFreq(Bitu _freq,Bitu _den=1U); 00054 void Mix(Bitu whole,Bitu frac); 00055 void AddSilence(void); //Fill up until needed 00056 void EndFrame(Bitu samples); 00057 00058 void lowpassUpdate(); 00059 Bit32s lowpassStep(Bit32s in,const unsigned int iteration,const unsigned int channel); 00060 void lowpassProc(Bit32s ch[2]); 00061 00062 template<class Type,bool stereo,bool signeddata,bool nativeorder,bool lowpass> 00063 void loadCurrentSample(Bitu &len, const Type* &data); 00064 00065 template<class Type,bool stereo,bool signeddata,bool nativeorder> 00066 void AddSamples(Bitu len, const Type* data); 00067 double timeSinceLastSample(void); 00068 00069 bool runSampleInterpolation(const Bitu upto); 00070 00071 void updateSlew(void); 00072 void padFillSampleInterpolation(const Bitu upto); 00073 void finishSampleInterpolation(const Bitu upto); 00074 void AddSamples_m8(Bitu len, const Bit8u * data); 00075 void AddSamples_s8(Bitu len, const Bit8u * data); 00076 void AddSamples_m8s(Bitu len, const Bit8s * data); 00077 void AddSamples_s8s(Bitu len, const Bit8s * data); 00078 void AddSamples_m16(Bitu len, const Bit16s * data); 00079 void AddSamples_s16(Bitu len, const Bit16s * data); 00080 void AddSamples_m16u(Bitu len, const Bit16u * data); 00081 void AddSamples_s16u(Bitu len, const Bit16u * data); 00082 void AddSamples_m32(Bitu len, const Bit32s * data); 00083 void AddSamples_s32(Bitu len, const Bit32s * data); 00084 void AddSamples_m16_nonnative(Bitu len, const Bit16s * data); 00085 void AddSamples_s16_nonnative(Bitu len, const Bit16s * data); 00086 void AddSamples_m16u_nonnative(Bitu len, const Bit16u * data); 00087 void AddSamples_s16u_nonnative(Bitu len, const Bit16u * data); 00088 void AddSamples_m32_nonnative(Bitu len, const Bit32s * data); 00089 void AddSamples_s32_nonnative(Bitu len, const Bit32s * data); 00090 00091 void FillUp(void); 00092 void Enable(bool _yesno); 00093 void SaveState( std::ostream& stream ); 00094 void LoadState( std::istream& stream ); 00095 00096 MIXER_Handler handler; 00097 float volmain[2]; 00098 float scale[2]; 00099 Bit32s volmul[2]; 00100 Bit32s lowpass[LOWPASS_ORDER][2]; // lowpass filter 00101 Bit32s lowpass_alpha; // "alpha" multiplier for lowpass (16.16 fixed point) 00102 Bitu lowpass_freq; 00103 unsigned int lowpass_order; 00104 bool lowpass_on_load; // apply lowpass on sample load (if source rate > mixer rate) 00105 bool lowpass_on_out; // apply lowpass on rendered output (if source rate <= mixer rate) 00106 unsigned int freq_f,freq_fslew; 00107 unsigned int freq_nslew,freq_nslew_want; 00108 unsigned int rendering_to_n,rendering_to_d; 00109 unsigned int rend_n,rend_d; 00110 unsigned int freq_n,freq_d,freq_d_orig; 00111 bool current_loaded; 00112 Bit32s current[2],last[2],delta[2],max_change; 00113 Bit32s msbuffer[2048][2]; // more than enough for 1ms of audio, at mixer sample rate 00114 Bits last_sample_write; 00115 Bitu msbuffer_o; 00116 Bitu msbuffer_i; 00117 const char * name; 00118 bool enabled; 00119 MixerChannel * next; 00120 }; 00121 00122 MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,const char * name); 00123 MixerChannel * MIXER_FindChannel(const char * name); 00124 /* Find the device you want to delete with findchannel "delchan gets deleted" */ 00125 void MIXER_DelChannel(MixerChannel* delchan); 00126 00127 /* Object to maintain a mixerchannel; As all objects it registers itself with create 00128 * and removes itself when destroyed. */ 00129 class MixerObject{ 00130 private: 00131 bool installed; 00132 char m_name[32] = {}; 00133 public: 00134 MixerObject():installed(false){}; 00135 MixerChannel* Install(MIXER_Handler handler,Bitu freq,const char * name); 00136 ~MixerObject(); 00137 }; 00138 00139 00140 /* PC Speakers functions, tightly related to the timer functions */ 00141 void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode); 00142 void PCSPEAKER_SetType(bool pit_clock_gate_enabled, bool pit_output_enabled); 00143 void PCSPEAKER_SetPITControl(Bitu mode); 00144 00145 #endif