* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#define WIN32_NO_STATUS
+
#include <assert.h>
#include <stdarg.h>
-#include <string.h>
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "mmsystem.h"
-#include "mmreg.h"
-#include "msacm.h"
-#include "msacmdrv.h"
-#include "wine/debug.h"
+//#include <string.h>
+#include <windef.h>
+#include <winbase.h>
+#include <wingdi.h>
+#include <winuser.h>
+#include <winnls.h>
+//#include "mmsystem.h"
+//#include "mmreg.h"
+//#include "msacm.h"
+#include <msacmdrv.h>
+#include <wine/debug.h>
/* see http://www.pcisys.net/~melanson/codecs/adpcm.txt for the details */
/***********************************************************************
* R16
*
- * Read a 16 bit sample (correctly handles endianess)
+ * Read a 16 bit sample (correctly handles endianness)
*/
static inline short R16(const unsigned char* src)
{
/***********************************************************************
* W16
*
- * Write a 16 bit sample (correctly handles endianess)
+ * Write a 16 bit sample (correctly handles endianness)
*/
static inline void W16(unsigned char* dst, short s)
{
if (*idelta < 16) *idelta = 16;
}
+static inline unsigned char C168(short s)
+{
+ return HIBYTE(s) ^ (unsigned char)0x80;
+}
+
static void cvtSSms16K(const ACMDRVSTREAMINSTANCE *adsi,
const unsigned char* src, LPDWORD nsrc,
unsigned char* dst, LPDWORD ndst)
int nsamp;
int nsamp_blk = ((ADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock;
DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign,
- *ndst / (nsamp_blk * 2 * 2));
+ *ndst / (nsamp_blk * adsi->pwfxDst->nBlockAlign));
*nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
- *ndst = nblock * nsamp_blk * 2 * 2;
+ *ndst = nblock * nsamp_blk * adsi->pwfxDst->nBlockAlign;
nsamp_blk -= 2; /* see below for samples from block head */
for (; nblock > 0; nblock--)
sample2L = R16(src); src += 2;
sample2R = R16(src); src += 2;
- /* store samples from block head */
- W16(dst, sample2L); dst += 2;
- W16(dst, sample2R); dst += 2;
- W16(dst, sample1L); dst += 2;
- W16(dst, sample1R); dst += 2;
-
- for (nsamp = nsamp_blk; nsamp > 0; nsamp--)
- {
- process_nibble(*src >> 4, &ideltaL, &sample1L, &sample2L, &coeffL);
- W16(dst, sample1L); dst += 2;
- process_nibble(*src++ & 0x0F, &ideltaR, &sample1R, &sample2R, &coeffR);
- W16(dst, sample1R); dst += 2;
+ if(adsi->pwfxDst->wBitsPerSample == 8){
+ /* store samples from block head */
+ *dst = C168(sample2L); ++dst;
+ *dst = C168(sample2R); ++dst;
+ *dst = C168(sample1L); ++dst;
+ *dst = C168(sample1R); ++dst;
+
+ for (nsamp = nsamp_blk; nsamp > 0; nsamp--)
+ {
+ process_nibble(*src >> 4, &ideltaL, &sample1L, &sample2L, &coeffL);
+ *dst = C168(sample1L); ++dst;
+ process_nibble(*src++ & 0x0F, &ideltaR, &sample1R, &sample2R, &coeffR);
+ *dst = C168(sample1R); ++dst;
+ }
+ }else if(adsi->pwfxDst->wBitsPerSample == 16){
+ /* store samples from block head */
+ W16(dst, sample2L); dst += 2;
+ W16(dst, sample2R); dst += 2;
+ W16(dst, sample1L); dst += 2;
+ W16(dst, sample1R); dst += 2;
+
+ for (nsamp = nsamp_blk; nsamp > 0; nsamp--)
+ {
+ process_nibble(*src >> 4, &ideltaL, &sample1L, &sample2L, &coeffL);
+ W16(dst, sample1L); dst += 2;
+ process_nibble(*src++ & 0x0F, &ideltaR, &sample1R, &sample2R, &coeffR);
+ W16(dst, sample1R); dst += 2;
+ }
}
src = in_src + adsi->pwfxSrc->nBlockAlign;
}
int nsamp;
int nsamp_blk = ((ADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock;
DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign,
- *ndst / (nsamp_blk * 2));
+ *ndst / (nsamp_blk * adsi->pwfxDst->nBlockAlign));
*nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
- *ndst = nblock * nsamp_blk * 2;
+ *ndst = nblock * nsamp_blk * adsi->pwfxDst->nBlockAlign;
nsamp_blk -= 2; /* see below for samples from block head */
for (; nblock > 0; nblock--)
sample2 = R16(src); src += 2;
/* store samples from block head */
- W16(dst, sample2); dst += 2;
- W16(dst, sample1); dst += 2;
-
- for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
- {
- process_nibble(*src >> 4, &idelta, &sample1, &sample2, &coeff);
- W16(dst, sample1); dst += 2;
- process_nibble(*src++ & 0x0F, &idelta, &sample1, &sample2, &coeff);
- W16(dst, sample1); dst += 2;
+ if(adsi->pwfxDst->wBitsPerSample == 8){
+ *dst = C168(sample2); ++dst;
+ *dst = C168(sample1); ++dst;
+
+ for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
+ {
+ process_nibble(*src >> 4, &idelta, &sample1, &sample2, &coeff);
+ *dst = C168(sample1); ++dst;
+ process_nibble(*src++ & 0x0F, &idelta, &sample1, &sample2, &coeff);
+ *dst = C168(sample1); ++dst;
+ }
+ }else if(adsi->pwfxDst->wBitsPerSample == 16){
+ W16(dst, sample2); dst += 2;
+ W16(dst, sample1); dst += 2;
+
+ for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
+ {
+ process_nibble(*src >> 4, &idelta, &sample1, &sample2, &coeff);
+ W16(dst, sample1); dst += 2;
+ process_nibble(*src++ & 0x0F, &idelta, &sample1, &sample2, &coeff);
+ W16(dst, sample1); dst += 2;
+ }
}
+
src = in_src + adsi->pwfxSrc->nBlockAlign;
}
}
aftd->dwFormatTagIndex = 1; /* WAVE_FORMAT_ADPCM is bigger than PCM */
break;
}
- /* fall thru */
+ /* fall through */
case ACM_FORMATTAGDETAILSF_FORMATTAG:
switch (aftd->dwFormatTag)
{
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ADPCM &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
{
- /* resampling or mono <=> stereo not available
- * ADPCM algo only define 16 bit per sample output
- */
+ /* resampling or mono <=> stereo not available */
if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
- adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
- adsi->pwfxDst->wBitsPerSample != 16)
+ adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels)
goto theEnd;
#if 0
#endif
/* adpcm decoding... */
- if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 2)
+ if (adsi->pwfxDst->nChannels == 2)
aad->convert = cvtSSms16K;
- if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 1)
+ else if (adsi->pwfxDst->nChannels == 1)
aad->convert = cvtMMms16K;
}
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&