DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
include/mixer.h
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