forked from joncampbell123/dosbox-x
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmixer.h
141 lines (120 loc) · 5.14 KB
/
mixer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
* Copyright (C) 2002-2021 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef DOSBOX_MIXER_H
#define DOSBOX_MIXER_H
typedef void (*MIXER_MixHandler)(uint8_t * sampdate,uint32_t len);
typedef void (*MIXER_Handler)(Bitu len);
template <class T> T clamp(const T& n, const T& lower, const T& upper) {
return std::max<T>(lower, std::min<T>(n, upper));
}
#define MIXER_BUFSIZE (16*1024)
#define MIXER_BUFMASK (MIXER_BUFSIZE-1)
extern uint8_t 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 SetScale(float _left, float _right);
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();
int32_t lowpassStep(int32_t in,const unsigned int iteration,const unsigned int channel);
void lowpassProc(int32_t ch[2]);
template<class Type,bool stereo,bool signeddata,bool nativeorder,bool lowpass>
void loadCurrentSample(Bitu &len, const Type* &data);
template<class Type,bool stereo,bool signeddata,bool nativeorder>
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 uint8_t * data);
void AddSamples_s8(Bitu len, const uint8_t * data);
void AddSamples_m8s(Bitu len, const int8_t * data);
void AddSamples_s8s(Bitu len, const int8_t * data);
void AddSamples_m16(Bitu len, const int16_t * data);
void AddSamples_s16(Bitu len, const int16_t * data);
void AddSamples_m16u(Bitu len, const uint16_t * data);
void AddSamples_s16u(Bitu len, const uint16_t * data);
void AddSamples_m32(Bitu len, const int32_t * data);
void AddSamples_s32(Bitu len, const int32_t * data);
void AddSamples_m16_nonnative(Bitu len, const int16_t * data);
void AddSamples_s16_nonnative(Bitu len, const int16_t * data);
void AddSamples_m16u_nonnative(Bitu len, const uint16_t * data);
void AddSamples_s16u_nonnative(Bitu len, const uint16_t * data);
void AddSamples_m32_nonnative(Bitu len, const int32_t * data);
void AddSamples_s32_nonnative(Bitu len, const int32_t * 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[2];
int32_t volmul[2];
int32_t lowpass[LOWPASS_ORDER][2]; // lowpass filter
int32_t 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;
int32_t current[2],last[2],delta[2],max_change;
int32_t 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;
};
void MIXER_SetMaster(float vol0,float vol1);
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 = false;
char m_name[32] = {};
public:
MixerObject() {};
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