Mercurial > hg > dmlib
diff 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 |
line wrap: on
line diff
--- a/jssmod.c Mon Oct 01 01:29:26 2012 +0300 +++ b/jssmod.c Mon Oct 01 02:51:41 2012 +0300 @@ -118,37 +118,6 @@ return TRUE; } - -int jssConvertSampleFromFP(void **dst, void * src, const size_t len, const int flags) -{ - // Convert from floating point to 8/16bit - size_t count = len; - float *in = (float *) src; - - if (flags & jsf16bit) - { - Sint16 *out; - *dst = out = dmMalloc(sizeof(sizeof(Sint16)) * len); - if (out == NULL) - return DMERR_MALLOC; - - while (count--) - *(out++) = (*(in++) * 32767.0f); - } - else - { - Uint8 *out; - *dst = out = dmMalloc(sizeof(sizeof(Uint8)) * len); - if (out == NULL) - return DMERR_MALLOC; - - while (count--) - *(out++) = 128 + (int) (*(in++) * 127.0f); - } - - return DMERR_OK; -} - #endif @@ -228,10 +197,11 @@ return TRUE; } - +#ifdef JSS_MIX_FP +/* Convert sample data from S16 or U8 to floating point + */ int jssConvertSampleToFP(void **dst, void * src, const size_t len, const int flags) { - // Convert from 8/16bit to floating point size_t count = len; float *out; @@ -243,13 +213,86 @@ { Sint16 *in = (Sint16 *) src; while (count--) + { *(out++) = (float) (*(in++)) / 32768.0f; + } } else { Uint8 *in = (Uint8 *) src; while (count--) + { *(out++) = (float) (*(in++) - 128) / 128.0f; + } + } + + return DMERR_OK; +} + +#endif + +/* Convert sample data from U8 to S16 + */ +int jssConvertSampleTo16(void **dst, void * src, const size_t len) +{ + size_t count = len; + Uint8 *in = (Uint8 *) src; + Sint16 *out; + + *dst = out = dmMalloc(sizeof(Sint16) * len); + if (out == NULL) + return DMERR_MALLOC; + + while (count--) + { + *(out++) = (*(in++) * 256) - 32768; + } + + return DMERR_OK; +} + +/* Converts the given module in preparation for playing it. + * This involves sample format conversion (8 to 16 bit, or + * if floating point mixing is enabled, 8/16 bit to FP.) + * + * NOTICE! The converted module can only be saved in JSSMOD + * format, but this is not recommended. + */ +int jssConvertModuleForPlaying(JSSModule *module) +{ + int i; + if (module == NULL) + return DMERR_NULLPTR; + + // Convert instruments + for (i = 0; i < module->ninstruments; i++) + { + JSSInstrument *inst = module->instruments[i]; + if (inst != NULL && inst->data != NULL) + { + int res; + void *data = NULL; +#ifdef JSS_MIX_FP + if (inst->flags & jsfFP) + continue; + + if ((res = jssConvertSampleToFP(&data, inst->data, inst->size, inst->flags)) != DMERR_OK) + return res; + + inst->flags &= !(jsf16bit); + inst->flags |= jfsFP; +#else + if (inst->flags & jsf16bit) + continue; + + if ((res = jssConvertSampleTo16(&data, inst->data, inst->size)) != DMERR_OK) + return res; + + inst->flags |= jsf16bit; +#endif + dmFree(inst->data); + inst->data = data; + } } return DMERR_OK;