/* * Copyright (C) 2002-2015 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef DOSBOX_MIXER_H #define DOSBOX_MIXER_H #include #ifndef DOSBOX_DOSBOX_H #include "dosbox.h" #endif typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len); typedef void (*MIXER_Handler)(Bitu len); #define MIXER_BUFSIZE (16*1024) #define MIXER_BUFMASK (MIXER_BUFSIZE-1) extern Bit8u MixTemp[MIXER_BUFSIZE]; #define MAX_AUDIO ((1<<(16-1))-1) #define MIN_AUDIO -(1<<(16-1)) #define LOWPASS_ORDER 8 class MixerChannel { public: void SetVolume(float _left,float _right); void SetScale( float f ); void UpdateVolume(void); void SetLowpassFreq(Bitu _freq,unsigned int order=2); // _freq / 1 Hz. call with _freq == 0 to disable void SetSlewFreq(Bitu _freq); // denominator provided by call to SetFreq. call with _freq == 0 to disable void SetFreq(Bitu _freq,Bitu _den=1U); void Mix(Bitu whole,Bitu frac); void AddSilence(void); //Fill up until needed void EndFrame(Bitu samples); void lowpassUpdate(); Bit32s lowpassStep(Bit32s in,const unsigned int iteration,const unsigned int channel); void lowpassProc(Bit32s ch[2]); template void loadCurrentSample(Bitu &len, const Type* &data); template void AddSamples(Bitu len, const Type* data); double timeSinceLastSample(void); bool runSampleInterpolation(const Bitu upto); void updateSlew(void); void padFillSampleInterpolation(const Bitu upto); void finishSampleInterpolation(const Bitu upto); void AddSamples_m8(Bitu len, const Bit8u * data); void AddSamples_s8(Bitu len, const Bit8u * data); void AddSamples_m8s(Bitu len, const Bit8s * data); void AddSamples_s8s(Bitu len, const Bit8s * data); void AddSamples_m16(Bitu len, const Bit16s * data); void AddSamples_s16(Bitu len, const Bit16s * data); void AddSamples_m16u(Bitu len, const Bit16u * data); void AddSamples_s16u(Bitu len, const Bit16u * data); void AddSamples_m32(Bitu len, const Bit32s * data); void AddSamples_s32(Bitu len, const Bit32s * data); void AddSamples_m16_nonnative(Bitu len, const Bit16s * data); void AddSamples_s16_nonnative(Bitu len, const Bit16s * data); void AddSamples_m16u_nonnative(Bitu len, const Bit16u * data); void AddSamples_s16u_nonnative(Bitu len, const Bit16u * data); void AddSamples_m32_nonnative(Bitu len, const Bit32s * data); void AddSamples_s32_nonnative(Bitu len, const Bit32s * data); void FillUp(void); void Enable(bool _yesno); void SaveState( std::ostream& stream ); void LoadState( std::istream& stream ); MIXER_Handler handler; float volmain[2]; float scale; Bit32s volmul[2]; Bit32s lowpass[LOWPASS_ORDER][2]; // lowpass filter Bit32s lowpass_alpha; // "alpha" multiplier for lowpass (16.16 fixed point) Bitu lowpass_freq; unsigned int lowpass_order; bool lowpass_on_load; // apply lowpass on sample load (if source rate > mixer rate) bool lowpass_on_out; // apply lowpass on rendered output (if source rate <= mixer rate) unsigned int freq_f,freq_fslew; unsigned int freq_nslew,freq_nslew_want; unsigned int rendering_to_n,rendering_to_d; unsigned int rend_n,rend_d; unsigned int freq_n,freq_d,freq_d_orig; bool current_loaded; Bit32s current[2],last[2],delta[2],max_change; Bit32s msbuffer[2048][2]; // more than enough for 1ms of audio, at mixer sample rate Bits last_sample_write; Bitu msbuffer_o; Bitu msbuffer_i; const char * name; bool enabled; MixerChannel * next; }; MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,const char * name); MixerChannel * MIXER_FindChannel(const char * name); /* Find the device you want to delete with findchannel "delchan gets deleted" */ void MIXER_DelChannel(MixerChannel* delchan); /* Object to maintain a mixerchannel; As all objects it registers itself with create * and removes itself when destroyed. */ class MixerObject{ private: bool installed; char m_name[32]; public: MixerObject():installed(false){}; MixerChannel* Install(MIXER_Handler handler,Bitu freq,const char * name); ~MixerObject(); }; /* PC Speakers functions, tightly related to the timer functions */ void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode); void PCSPEAKER_SetType(bool pit_clock_gate_enabled, bool pit_output_enabled); void PCSPEAKER_SetPITControl(Bitu mode); #endif