1 /*
2  * Schism Tracker - a cross-platform Impulse Tracker clone
3  * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
4  * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
5  * copyright (c) 2009 Storlek & Mrs. Brisby
6  * copyright (c) 2010-2012 Storlek
7  * URL: http://schismtracker.org/
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23 
24 #include <string.h>
25 
26 #include "sndfile.h"
27 
28 #include "cmixer.h"
29 
30 #define OFSDECAYSHIFT 8
31 #define OFSDECAYMASK  0xFF
32 
33 
init_mix_buffer(int * buffer,unsigned int samples)34 void init_mix_buffer(int *buffer, unsigned int samples)
35 {
36     memset(buffer, 0, samples * sizeof(int));
37 }
38 
39 
stereo_fill(int * buffer,unsigned int samples,int * profs,int * plofs)40 void stereo_fill(int *buffer, unsigned int samples, int* profs, int *plofs)
41 {
42     int rofs = *profs;
43     int lofs = *plofs;
44 
45     if (!rofs && !lofs) {
46 	init_mix_buffer(buffer, samples * 2);
47 	return;
48     }
49 
50     for (unsigned int i = 0; i < samples; i++) {
51 	int x_r = (rofs + (((-rofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
52 	int x_l = (lofs + (((-lofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
53 
54 	rofs -= x_r;
55 	lofs -= x_l;
56 	buffer[i * 2 ]    = x_r;
57 	buffer[i * 2 + 1] = x_l;
58     }
59 
60     *profs = rofs;
61     *plofs = lofs;
62 }
63 
64 
end_channel_ofs(song_voice_t * channel,int * buffer,unsigned int samples)65 void end_channel_ofs(song_voice_t *channel, int *buffer, unsigned int samples)
66 {
67     int rofs = channel->rofs;
68     int lofs = channel->lofs;
69 
70     if (!rofs && !lofs)
71 	return;
72 
73     for (unsigned int i = 0; i < samples; i++) {
74 	int x_r = (rofs + (((-rofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
75 	int x_l = (lofs + (((-lofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
76 
77 	rofs -= x_r;
78 	lofs -= x_l;
79 	buffer[i * 2]     += x_r;
80 	buffer[i * 2 + 1] += x_l;
81     }
82 
83     channel->rofs = rofs;
84     channel->lofs = lofs;
85 }
86 
87 
mono_from_stereo(int * mix_buf,unsigned int samples)88 void mono_from_stereo(int *mix_buf, unsigned int samples)
89 {
90     for (unsigned int j, i = 0; i < samples; i++) {
91 	j = i << 1;
92 	mix_buf[i] = (mix_buf[j] + mix_buf[j + 1]) >> 1;
93     }
94 }
95 
96 
97 static const float f2ic = (float) (1 << 28);
98 static const float i2fc = (float) (1.0 / (1 << 28));
99 
100 
stereo_mix_to_float(const int * src,float * out1,float * out2,unsigned int count)101 void stereo_mix_to_float(const int *src, float *out1, float *out2, unsigned int count)
102 {
103     for (unsigned int i = 0; i < count; i++) {
104 	*out1++ = *src * i2fc;
105 	src++;
106 
107 	*out2++ = *src * i2fc;
108 	src++;
109     }
110 }
111 
112 
float_to_stereo_mix(const float * in1,const float * in2,int * out,unsigned int count)113 void float_to_stereo_mix(const float *in1, const float *in2, int *out, unsigned int count)
114 {
115     for (unsigned int i = 0; i < count; i++) {
116 	*out++ = (int) (*in1 * f2ic);
117 	*out++ = (int) (*in2 * f2ic);
118 	in1++;
119 	in2++;
120     }
121 }
122 
123 
mono_mix_to_float(const int * src,float * out,unsigned int count)124 void mono_mix_to_float(const int *src, float *out, unsigned int count)
125 {
126     for (unsigned int i = 0; i < count; i++) {
127 	*out++ = *src * i2fc;
128 	src++;
129     }
130 }
131 
132 
float_to_mono_mix(const float * in,int * out,unsigned int count)133 void float_to_mono_mix(const float *in, int *out, unsigned int count)
134 {
135     for (unsigned int i = 0; i < count; i++) {
136 	*out++ = (int) (*in * f2ic);
137 	in++;
138     }
139 }
140 
141 
142 // ----------------------------------------------------------------------------
143 // Clip and convert functions
144 // ----------------------------------------------------------------------------
145 // XXX mins/max were int[2]
146 //
147 // The original C version was written by Rani Assaf <rani@magic.metawire.com>
148 
149 
150 // Clip and convert to 8 bit. mins and maxs returned in 27bits: [MIXING_CLIPMIN..MIXING_CLIPMAX]. mins[0] left, mins[1] right.
clip_32_to_8(void * ptr,int * buffer,unsigned int samples,int * mins,int * maxs)151 unsigned int clip_32_to_8(void *ptr, int *buffer, unsigned int samples, int *mins, int *maxs)
152 {
153     unsigned char *p = (unsigned char *) ptr;
154 
155     for (unsigned int i = 0; i < samples; i++) {
156 	int n = buffer[i];
157 
158 	if (n < MIXING_CLIPMIN)
159 	    n = MIXING_CLIPMIN;
160 	else if (n > MIXING_CLIPMAX)
161 	    n = MIXING_CLIPMAX;
162 
163 	if (n < mins[i & 1])
164 	    mins[i & 1] = n;
165 	else if (n > maxs[i & 1])
166 	    maxs[i & 1] = n;
167 
168 	// 8-bit unsigned
169 	p[i] = (n >> (24 - MIXING_ATTENUATION)) ^ 0x80;
170     }
171 
172     return samples;
173 }
174 
175 
176 // Clip and convert to 16 bit. mins and maxs returned in 27bits: [MIXING_CLIPMIN..MIXING_CLIPMAX]. mins[0] left, mins[1] right.
clip_32_to_16(void * ptr,int * buffer,unsigned int samples,int * mins,int * maxs)177 unsigned int clip_32_to_16(void *ptr, int *buffer, unsigned int samples, int *mins, int *maxs)
178 {
179     signed short *p = (signed short *) ptr;
180 
181     for (unsigned int i = 0; i < samples; i++) {
182 	int n = buffer[i];
183 
184 	if (n < MIXING_CLIPMIN)
185 	    n = MIXING_CLIPMIN;
186 	else if (n > MIXING_CLIPMAX)
187 	    n = MIXING_CLIPMAX;
188 
189 	if (n < mins[i & 1])
190 	    mins[i & 1] = n;
191 	else if (n > maxs[i & 1])
192 	    maxs[i & 1] = n;
193 
194 	// 16-bit signed
195 	p[i] = n >> (16 - MIXING_ATTENUATION);
196     }
197 
198     return samples * 2;
199 }
200 
201 
202 // Clip and convert to 24 bit. mins and maxs returned in 27bits: [MIXING_CLIPMIN..MIXING_CLIPMAX]. mins[0] left, mins[1] right.
203 // Note, this is 24bit, not 24-in-32bits. The former is used in .wav. The latter is used in audio IO
clip_32_to_24(void * ptr,int * buffer,unsigned int samples,int * mins,int * maxs)204 unsigned int clip_32_to_24(void *ptr, int *buffer, unsigned int samples, int *mins, int *maxs)
205 {
206     /* the inventor of 24bit anything should be shot */
207     unsigned char *p = (unsigned char *) ptr;
208 
209     for (unsigned int i = 0; i < samples; i++) {
210 	int n = buffer[i];
211 
212 	if (n < MIXING_CLIPMIN)
213 	    n = MIXING_CLIPMIN;
214 	else if (n > MIXING_CLIPMAX)
215 	    n = MIXING_CLIPMAX;
216 
217 	if (n < mins[i & 1])
218 	    mins[i & 1] = n;
219 	else if (n > maxs[i & 1])
220 	    maxs[i & 1] = n;
221 
222 	// 24-bit signed
223 	n = n >> (8 - MIXING_ATTENUATION);
224 
225 	/* err, assume same endian */
226 	memcpy(p, &n, 3);
227 	p += 3;
228     }
229 
230     return samples * 3;
231 }
232 
233 
234 // Clip and convert to 32 bit(int). mins and maxs returned in 27bits: [MIXING_CLIPMIN..MIXING_CLIPMAX]. mins[0] left, mins[1] right.
clip_32_to_32(void * ptr,int * buffer,unsigned int samples,int * mins,int * maxs)235 unsigned int clip_32_to_32(void *ptr, int *buffer, unsigned int samples, int *mins, int *maxs)
236 {
237     signed int *p = (signed int *) ptr;
238 
239     for (unsigned int i = 0; i < samples; i++) {
240 	int n = buffer[i];
241 
242 	if (n < MIXING_CLIPMIN)
243 	    n = MIXING_CLIPMIN;
244 	else if (n > MIXING_CLIPMAX)
245 	    n = MIXING_CLIPMAX;
246 
247 	if (n < mins[i & 1])
248 	    mins[i & 1] = n;
249 	else if (n > maxs[i & 1])
250 	    maxs[i & 1] = n;
251 
252 	// 32-bit signed
253 	p[i] = (n << MIXING_ATTENUATION);
254     }
255 
256     return samples * 4;
257 }
258 
259