Mercurial > hg > dmlib
comparison jssmod.c @ 49:033c660c25f5
Restructure module playing, removing 8bit sample mixing (output can still be
8bit, but samples are internally upconverted to 16bit after module loading.)
Also prepare for floating point mixing support.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 01 Oct 2012 02:51:41 +0300 |
parents | 064d1d1d5b0f |
children | 36e2f910219c |
comparison
equal
deleted
inserted
replaced
48:ee87513fff15 | 49:033c660c25f5 |
---|---|
116 } | 116 } |
117 } | 117 } |
118 return TRUE; | 118 return TRUE; |
119 } | 119 } |
120 | 120 |
121 | |
122 int jssConvertSampleFromFP(void **dst, void * src, const size_t len, const int flags) | |
123 { | |
124 // Convert from floating point to 8/16bit | |
125 size_t count = len; | |
126 float *in = (float *) src; | |
127 | |
128 if (flags & jsf16bit) | |
129 { | |
130 Sint16 *out; | |
131 *dst = out = dmMalloc(sizeof(sizeof(Sint16)) * len); | |
132 if (out == NULL) | |
133 return DMERR_MALLOC; | |
134 | |
135 while (count--) | |
136 *(out++) = (*(in++) * 32767.0f); | |
137 } | |
138 else | |
139 { | |
140 Uint8 *out; | |
141 *dst = out = dmMalloc(sizeof(sizeof(Uint8)) * len); | |
142 if (out == NULL) | |
143 return DMERR_MALLOC; | |
144 | |
145 while (count--) | |
146 *(out++) = 128 + (int) (*(in++) * 127.0f); | |
147 } | |
148 | |
149 return DMERR_OK; | |
150 } | |
151 | |
152 #endif | 121 #endif |
153 | 122 |
154 | 123 |
155 /* Decodes a given 8-bit sample | 124 /* Decodes a given 8-bit sample |
156 */ | 125 */ |
226 } | 195 } |
227 } | 196 } |
228 return TRUE; | 197 return TRUE; |
229 } | 198 } |
230 | 199 |
231 | 200 #ifdef JSS_MIX_FP |
201 /* Convert sample data from S16 or U8 to floating point | |
202 */ | |
232 int jssConvertSampleToFP(void **dst, void * src, const size_t len, const int flags) | 203 int jssConvertSampleToFP(void **dst, void * src, const size_t len, const int flags) |
233 { | 204 { |
234 // Convert from 8/16bit to floating point | |
235 size_t count = len; | 205 size_t count = len; |
236 float *out; | 206 float *out; |
237 | 207 |
238 *dst = out = dmMalloc(sizeof(float) * len); | 208 *dst = out = dmMalloc(sizeof(float) * len); |
239 if (out == NULL) | 209 if (out == NULL) |
241 | 211 |
242 if (flags & jsf16bit) | 212 if (flags & jsf16bit) |
243 { | 213 { |
244 Sint16 *in = (Sint16 *) src; | 214 Sint16 *in = (Sint16 *) src; |
245 while (count--) | 215 while (count--) |
216 { | |
246 *(out++) = (float) (*(in++)) / 32768.0f; | 217 *(out++) = (float) (*(in++)) / 32768.0f; |
218 } | |
247 } | 219 } |
248 else | 220 else |
249 { | 221 { |
250 Uint8 *in = (Uint8 *) src; | 222 Uint8 *in = (Uint8 *) src; |
251 while (count--) | 223 while (count--) |
224 { | |
252 *(out++) = (float) (*(in++) - 128) / 128.0f; | 225 *(out++) = (float) (*(in++) - 128) / 128.0f; |
226 } | |
227 } | |
228 | |
229 return DMERR_OK; | |
230 } | |
231 | |
232 #endif | |
233 | |
234 /* Convert sample data from U8 to S16 | |
235 */ | |
236 int jssConvertSampleTo16(void **dst, void * src, const size_t len) | |
237 { | |
238 size_t count = len; | |
239 Uint8 *in = (Uint8 *) src; | |
240 Sint16 *out; | |
241 | |
242 *dst = out = dmMalloc(sizeof(Sint16) * len); | |
243 if (out == NULL) | |
244 return DMERR_MALLOC; | |
245 | |
246 while (count--) | |
247 { | |
248 *(out++) = (*(in++) * 256) - 32768; | |
249 } | |
250 | |
251 return DMERR_OK; | |
252 } | |
253 | |
254 /* Converts the given module in preparation for playing it. | |
255 * This involves sample format conversion (8 to 16 bit, or | |
256 * if floating point mixing is enabled, 8/16 bit to FP.) | |
257 * | |
258 * NOTICE! The converted module can only be saved in JSSMOD | |
259 * format, but this is not recommended. | |
260 */ | |
261 int jssConvertModuleForPlaying(JSSModule *module) | |
262 { | |
263 int i; | |
264 if (module == NULL) | |
265 return DMERR_NULLPTR; | |
266 | |
267 // Convert instruments | |
268 for (i = 0; i < module->ninstruments; i++) | |
269 { | |
270 JSSInstrument *inst = module->instruments[i]; | |
271 if (inst != NULL && inst->data != NULL) | |
272 { | |
273 int res; | |
274 void *data = NULL; | |
275 #ifdef JSS_MIX_FP | |
276 if (inst->flags & jsfFP) | |
277 continue; | |
278 | |
279 if ((res = jssConvertSampleToFP(&data, inst->data, inst->size, inst->flags)) != DMERR_OK) | |
280 return res; | |
281 | |
282 inst->flags &= !(jsf16bit); | |
283 inst->flags |= jfsFP; | |
284 #else | |
285 if (inst->flags & jsf16bit) | |
286 continue; | |
287 | |
288 if ((res = jssConvertSampleTo16(&data, inst->data, inst->size)) != DMERR_OK) | |
289 return res; | |
290 | |
291 inst->flags |= jsf16bit; | |
292 #endif | |
293 dmFree(inst->data); | |
294 inst->data = data; | |
295 } | |
253 } | 296 } |
254 | 297 |
255 return DMERR_OK; | 298 return DMERR_OK; |
256 } | 299 } |
257 | 300 |