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