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