4 * This file is part of OpenTTD.
5 * OpenTTD 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, version 2.
6 * OpenTTD 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.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file mixer.cpp Mixing of sound samples. */
14 #include "core/math_func.hpp"
19 /* pointer to allocated buffer memory */
22 /* current position in memory */
35 static MixerChannel _channels
[8];
36 static uint32 _play_rate
= 11025;
37 static uint32 _max_size
= UINT_MAX
;
40 * The theoretical maximum volume for a single sound sample. Multiple sound
41 * samples should not exceed this limit as it will sound too loud. It also
42 * stops overflowing when too many sounds are played at the same time, which
43 * causes an even worse sound quality.
45 static const int MAX_VOLUME
= 128 * 128;
48 * Perform the rate conversion between the input and output.
49 * @param b the buffer to read the data from
50 * @param frac_pos the position from the begin of the buffer till the next element
51 * @tparam T the size of the buffer (8 or 16 bits)
52 * @return the converted value.
55 static int RateConversion(T
*b
, int frac_pos
)
57 return ((b
[0] * ((1 << 16) - frac_pos
)) + (b
[1] * frac_pos
)) >> 16;
60 static void mix_int16(MixerChannel
*sc
, int16
*buffer
, uint samples
)
62 if (samples
> sc
->samples_left
) samples
= sc
->samples_left
;
63 sc
->samples_left
-= samples
;
66 const int16
*b
= (const int16
*)sc
->memory
+ sc
->pos
;
67 uint32 frac_pos
= sc
->frac_pos
;
68 uint32 frac_speed
= sc
->frac_speed
;
69 int volume_left
= sc
->volume_left
;
70 int volume_right
= sc
->volume_right
;
72 if (frac_speed
== 0x10000) {
73 /* Special case when frac_speed is 0x10000 */
75 buffer
[0] = Clamp(buffer
[0] + (*b
* volume_left
>> 16), -MAX_VOLUME
, MAX_VOLUME
);
76 buffer
[1] = Clamp(buffer
[1] + (*b
* volume_right
>> 16), -MAX_VOLUME
, MAX_VOLUME
);
79 } while (--samples
> 0);
82 int data
= RateConversion(b
, frac_pos
);
83 buffer
[0] = Clamp(buffer
[0] + (data
* volume_left
>> 16), -MAX_VOLUME
, MAX_VOLUME
);
84 buffer
[1] = Clamp(buffer
[1] + (data
* volume_right
>> 16), -MAX_VOLUME
, MAX_VOLUME
);
86 frac_pos
+= frac_speed
;
89 } while (--samples
> 0);
92 sc
->frac_pos
= frac_pos
;
93 sc
->pos
= b
- (const int16
*)sc
->memory
;
96 static void mix_int8_to_int16(MixerChannel
*sc
, int16
*buffer
, uint samples
)
98 if (samples
> sc
->samples_left
) samples
= sc
->samples_left
;
99 sc
->samples_left
-= samples
;
102 const int8
*b
= sc
->memory
+ sc
->pos
;
103 uint32 frac_pos
= sc
->frac_pos
;
104 uint32 frac_speed
= sc
->frac_speed
;
105 int volume_left
= sc
->volume_left
;
106 int volume_right
= sc
->volume_right
;
108 if (frac_speed
== 0x10000) {
109 /* Special case when frac_speed is 0x10000 */
111 buffer
[0] = Clamp(buffer
[0] + (*b
* volume_left
>> 8), -MAX_VOLUME
, MAX_VOLUME
);
112 buffer
[1] = Clamp(buffer
[1] + (*b
* volume_right
>> 8), -MAX_VOLUME
, MAX_VOLUME
);
115 } while (--samples
> 0);
118 int data
= RateConversion(b
, frac_pos
);
119 buffer
[0] = Clamp(buffer
[0] + (data
* volume_left
>> 8), -MAX_VOLUME
, MAX_VOLUME
);
120 buffer
[1] = Clamp(buffer
[1] + (data
* volume_right
>> 8), -MAX_VOLUME
, MAX_VOLUME
);
122 frac_pos
+= frac_speed
;
125 } while (--samples
> 0);
128 sc
->frac_pos
= frac_pos
;
129 sc
->pos
= b
- sc
->memory
;
132 static void MxCloseChannel(MixerChannel
*mc
)
137 void MxMixSamples(void *buffer
, uint samples
)
141 /* Clear the buffer */
142 memset(buffer
, 0, sizeof(int16
) * 2 * samples
);
144 /* Mix each channel */
145 for (mc
= _channels
; mc
!= endof(_channels
); mc
++) {
148 mix_int16(mc
, (int16
*)buffer
, samples
);
150 mix_int8_to_int16(mc
, (int16
*)buffer
, samples
);
152 if (mc
->samples_left
== 0) MxCloseChannel(mc
);
157 MixerChannel
*MxAllocateChannel()
160 for (mc
= _channels
; mc
!= endof(_channels
); mc
++) {
170 void MxSetChannelRawSrc(MixerChannel
*mc
, int8
*mem
, size_t size
, uint rate
, bool is16bit
)
176 mc
->frac_speed
= (rate
<< 16) / _play_rate
;
178 if (is16bit
) size
/= 2;
180 /* adjust the magnitude to prevent overflow */
181 while (size
>= _max_size
) {
183 rate
= (rate
>> 1) + 1;
186 mc
->samples_left
= (uint
)size
* _play_rate
/ rate
;
187 mc
->is16bit
= is16bit
;
191 * Set volume and pan parameters for a sound.
192 * @param mc MixerChannel to set
193 * @param volume Volume level for sound, range is 0..16384
194 * @param pan Pan position for sound, range is 0..1
196 void MxSetChannelVolume(MixerChannel
*mc
, uint volume
, float pan
)
198 /* Use sinusoidal pan to maintain overall sound power level regardless
200 mc
->volume_left
= (uint
)(sin((1.0 - pan
) * M_PI
/ 2.0) * volume
);
201 mc
->volume_right
= (uint
)(sin(pan
* M_PI
/ 2.0) * volume
);
205 void MxActivateChannel(MixerChannel
*mc
)
211 bool MxInitialize(uint rate
)
214 _max_size
= UINT_MAX
/ _play_rate
;