1 /***************************************************************************
2 * S3m/Mod player by Daniel Marks (dmarks@ais.net)
3 * GUS support by David Jeske (jeske@uiuc.edu)
4 *
5 * (C) 1994,1995 By Daniel Marks and David Jeske
6 *
7 * While we retain the copyright to this code, this source code is FREE.
8 * You may use it in any way you wish, in any product you wish. You may
9 * NOT steal the copyright for this code from us.
10 *
11 * We respectfully ask that you email one of us, if possible, if you
12 * produce something significant with this code, or if you have any bug
13 * fixes to contribute. We also request that you give credit where
14 * credit is due if you include part of this code in a program of your own.
15 *
16 * Email: s3mod@uiuc.edu
17 * jeske@uiuc.edu
18 *
19 * See the associated README file for Thanks
20 ***************************************************************************
21 *
22 * mix.c - The mod/s3m mixer
23 *
24 */
25
26 #include "config.h"
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include "mod.h"
31
32
mixtrack_8_mono(track_info_ptr track,sample8_near buffer,uint16 buflen)33 void mixtrack_8_mono(track_info_ptr track, sample8_near buffer, uint16 buflen)
34 {
35 register sample8_far sample;
36 sample8_far endtr;
37 uint16 volume;
38 uint8 lopitch;
39 uint8 hipitch;
40 uint16 error;
41
42 if (track->replen < 3)
43 {
44 sample = track->samples + track->position;
45 endtr = track->samples + track->length;
46 volume = ((uint16)track->volume) << 8;
47 error = track->error;
48 lopitch = track->pitch & 0xFF;
49 hipitch = track->pitch >> 8;
50 while ((sample < endtr) && (buflen > 0))
51 {
52 *buffer++ += vol.vol_table[*sample | volume];
53 sample += hipitch + ((error += lopitch) >> 8);
54 error &= 0xFF;
55 buflen--;
56 }
57 track->error = error;
58 track->position = (uint32)sample - (uint32)track->samples;
59 } else
60 {
61 sample = track->samples + track->position;
62 endtr = track->samples + track->replen + track->repeat;
63 error = track->error;
64 volume = ((uint16)track->volume) << 8;
65 lopitch = track->pitch & 0xFF;
66 hipitch = track->pitch >> 8;
67 while (buflen > 0)
68 {
69 if (sample > endtr) sample -= track->replen;
70 *buffer++ += vol.vol_table[*sample | volume];
71 sample += hipitch + ((error += lopitch) >> 8);
72 error &= 0xFF;
73 buflen--;
74 }
75 track->error = error;
76 track->position = (uint32)sample - (uint32)track->samples;
77 }
78 }
79
mixtrack_8_stereo(track_info_ptr track,sample8_near buffer,uint16 buflen,uint32 channel)80 void mixtrack_8_stereo(track_info_ptr track, sample8_near buffer,
81 uint16 buflen, uint32 channel)
82 {
83 register sample8_far sample;
84 sample8_far endtr;
85 uint16 volume;
86 uint8 lopitch;
87 uint8 hipitch;
88 uint16 error;
89
90 if (channel) buffer++;
91
92 if (track->replen < 3)
93 {
94 sample = track->samples + track->position;
95 endtr = track->samples + track->length;
96 volume = ((uint16)track->volume) << 8;
97 error = track->error;
98 lopitch = track->pitch & 0xFF;
99 hipitch = track->pitch >> 8;
100 while ((sample < endtr) && (buflen > 0))
101 {
102 *buffer++ += vol.vol_table[*sample | volume];
103 buffer++;
104 sample += hipitch + ((error += lopitch) >> 8);
105 error &= 0xFF;
106 buflen--;
107 }
108 track->error = error;
109 track->position = (uint32)sample - (uint32)track->samples;
110 } else
111 {
112 sample = track->samples + track->position;
113 endtr = track->samples + track->replen + track->repeat;
114 error = track->error;
115 volume = ((uint16)track->volume) << 8;
116 lopitch = track->pitch & 0xFF;
117 hipitch = track->pitch >> 8;
118 while (buflen > 0)
119 {
120 if (sample > endtr) sample -= track->replen;
121 *buffer++ += vol.vol_table[*sample | volume];
122 buffer++;
123 sample += hipitch + ((error += lopitch) >> 8);
124 error &= 0xFF;
125 buflen--;
126 }
127 track->error = error;
128 track->position = (uint32)sample - (uint32)track->samples;
129 }
130 }
131
mixtrack_16_mono(track_info_ptr track,sample16_near buffer,uint16 buflen)132 void mixtrack_16_mono(track_info_ptr track, sample16_near buffer,
133 uint16 buflen)
134 {
135 register sample8_far sample;
136 sample8_far endtr;
137 uint16 volume;
138 uint8 lopitch;
139 uint8 hipitch;
140 uint16 error;
141
142 if (track->replen < 3)
143 {
144 sample = track->samples + track->position;
145 endtr = track->samples + track->length;
146 volume = ((uint16)track->volume) << 8;
147 error = track->error;
148 lopitch = track->pitch & 0xFF;
149 hipitch = track->pitch >> 8;
150 while ((sample < endtr) && (buflen > 0))
151 {
152 *buffer++ += vol.vol_table16[*sample | volume];
153 sample += hipitch + ((error += lopitch) >> 8);
154 error &= 0xFF;
155 buflen--;
156 }
157 track->error = error;
158 track->position = (uint32)sample - (uint32)track->samples;
159 } else
160 {
161 sample = track->samples + track->position;
162 endtr = track->samples + track->replen + track->repeat;
163 error = track->error;
164 volume = ((uint16)track->volume) << 8;
165 lopitch = track->pitch & 0xFF;
166 hipitch = track->pitch >> 8;
167 while (buflen > 0)
168 {
169 if (sample > endtr) sample -= track->replen;
170 *buffer++ += vol.vol_table16[*sample | volume];
171 sample += hipitch + ((error += lopitch) >> 8);
172 error &= 0xFF;
173 buflen--;
174 }
175 track->error = error;
176 track->position = (uint32)sample - (uint32)track->samples;
177 }
178 }
179
mixtrack_16_stereo(track_info_ptr track,sample16_near buffer,uint16 buflen,uint32 channel)180 void mixtrack_16_stereo(track_info_ptr track, sample16_near buffer, uint16 buflen, uint32 channel)
181 {
182 register sample8_far sample;
183 sample8_far endtr;
184 uint16 volume;
185 uint8 lopitch;
186 uint8 hipitch;
187 uint16 error;
188
189 if (channel) buffer++;
190
191 if (track->replen < 3)
192 {
193 sample = track->samples + track->position;
194 endtr = track->samples + track->length;
195 volume = ((uint16)track->volume) << 8;
196 error = track->error;
197 lopitch = track->pitch & 0xFF;
198 hipitch = track->pitch >> 8;
199 while ((sample < endtr) && (buflen > 0))
200 {
201 *buffer++ += vol.vol_table16[*sample | volume];
202 buffer++;
203 sample += hipitch + ((error += lopitch) >> 8);
204 error &= 0xFF;
205 buflen--;
206 }
207 track->error = error;
208 track->position = (uint32)sample - (uint32)track->samples;
209 } else
210 {
211 sample = track->samples + track->position;
212 endtr = track->samples + track->replen + track->repeat;
213 error = track->error;
214 volume = ((uint16)track->volume) << 8;
215 lopitch = track->pitch & 0xFF;
216 hipitch = track->pitch >> 8;
217 while (buflen > 0)
218 {
219 if (sample > endtr) sample -= track->replen;
220 *buffer++ += vol.vol_table16[*sample | volume];
221 buffer++;
222 sample += hipitch + ((error += lopitch) >> 8);
223 error &= 0xFF;
224 buflen--;
225 }
226 track->error = error;
227 track->position = (uint32)sample - (uint32)track->samples;
228 }
229 }
230