ReactOS  0.4.14-dev-317-g96040ec
imaadp32.c File Reference
#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 dependency graph for imaadp32.c:

Go to the source code of this file.

Classes

struct  tagAcmAdpcmData
 
struct  Format
 

Typedefs

typedef struct tagAcmAdpcmData AcmAdpcmData
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (adpcm)
 
static LRESULT ADPCM_drvClose (DWORD_PTR dwDevID)
 
static DWORD ADPCM_GetFormatIndex (const WAVEFORMATEX *wfx)
 
static void init_wfx_ima_adpcm (IMAADPCMWAVEFORMAT *awfx)
 
static short R16 (const unsigned char *src)
 
static void W16 (unsigned char *dst, short s)
 
static void W8 (unsigned char *dst, short s)
 
static void W8_16 (unsigned char *dst, short s, int bytes)
 
static void clamp_step_index (int *stepIndex)
 
static void clamp_sample (int *sample)
 
static void process_nibble (unsigned char code, int *stepIndex, int *sample)
 
static unsigned char generate_nibble (int in, int *stepIndex, int *sample)
 
static void cvtSSima16K (PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
 
static void cvtMMimaK (PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
 
static void cvtSS16imaK (PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
 
static void cvtMM16imaK (PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
 
static LRESULT ADPCM_DriverDetails (PACMDRIVERDETAILSW add)
 
static LRESULT ADPCM_FormatTagDetails (PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
 
static LRESULT ADPCM_FormatDetails (PACMFORMATDETAILSW afd, DWORD dwQuery)
 
static LRESULT ADPCM_FormatSuggest (PACMDRVFORMATSUGGEST adfs)
 
static void ADPCM_Reset (PACMDRVSTREAMINSTANCE adsi, AcmAdpcmData *aad)
 
static LRESULT ADPCM_StreamOpen (PACMDRVSTREAMINSTANCE adsi)
 
static LRESULT ADPCM_StreamClose (PACMDRVSTREAMINSTANCE adsi)
 
static LRESULT ADPCM_StreamSize (const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMSIZE adss)
 
static LRESULT ADPCM_StreamConvert (PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
 
LRESULT CALLBACK ADPCM_DriverProc (DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
 

Variables

static const Format PCM_Formats []
 
static const Format ADPCM_Formats []
 
static const unsigned IMA_StepTable [89]
 
static const int IMA_IndexTable [16]
 

Typedef Documentation

◆ AcmAdpcmData

Function Documentation

◆ ADPCM_DriverDetails()

static LRESULT ADPCM_DriverDetails ( PACMDRIVERDETAILSW  add)
static

Definition at line 520 of file imaadp32.c.

521 {
524  add->wMid = MM_MICROSOFT;
525  add->wPid = MM_MSFT_ACM_IMAADPCM;
526  add->vdwACM = 0x3320000;
527  add->vdwDriver = 0x04000000;
528  add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
529  add->cFormatTags = 2; /* PCM, IMA ADPCM */
530  add->cFilterTags = 0;
531  add->hicon = NULL;
532  MultiByteToWideChar( CP_ACP, 0, "Microsoft IMA ADPCM", -1,
533  add->szShortName, ARRAY_SIZE(add->szShortName) );
534  MultiByteToWideChar( CP_ACP, 0, "Microsoft IMA ADPCM CODEC", -1,
535  add->szLongName, ARRAY_SIZE(add->szLongName) );
536  MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
537  add->szCopyright, ARRAY_SIZE(add->szCopyright) );
538  MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
539  add->szLicensing, ARRAY_SIZE(add->szLicensing) );
540  add->szFeatures[0] = 0;
541 
542  return MMSYSERR_NOERROR;
543 }
int add
Definition: i386-dis.c:3122
#define CP_ACP
Definition: compat.h:99
#define ACMDRIVERDETAILS_SUPPORTF_CODEC
Definition: msacm.h:61
#define ACMDRIVERDETAILS_FCCCOMP_UNDEFINED
Definition: msacm.h:59
smooth NULL
Definition: ftsmooth.c:416
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define MM_MSFT_ACM_IMAADPCM
Definition: mmreg.h:147
#define MM_MICROSOFT
Definition: mmreg.h:144
#define ARRAY_SIZE(a)
Definition: main.h:24
#define MultiByteToWideChar
Definition: compat.h:100
#define ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC
Definition: msacm.h:58

Referenced by ADPCM_DriverProc().

◆ ADPCM_DriverProc()

LRESULT CALLBACK ADPCM_DriverProc ( DWORD_PTR  dwDevID,
HDRVR  hDriv,
UINT  wMsg,
LPARAM  dwParam1,
LPARAM  dwParam2 
)

Definition at line 926 of file imaadp32.c.

928 {
929  TRACE("(%08lx %p %04x %08lx %08lx);\n",
930  dwDevID, hDriv, wMsg, dwParam1, dwParam2);
931 
932  switch (wMsg)
933  {
934  case DRV_LOAD: return 1;
935  case DRV_FREE: return 1;
936  case DRV_OPEN: return 1;
937  case DRV_CLOSE: return ADPCM_drvClose(dwDevID);
938  case DRV_ENABLE: return 1;
939  case DRV_DISABLE: return 1;
940  case DRV_QUERYCONFIGURE: return 1;
941  case DRV_CONFIGURE: MessageBoxA(0, "MSACM IMA ADPCM filter !", "Wine Driver", MB_OK); return 1;
942  case DRV_INSTALL: return DRVCNF_RESTART;
943  case DRV_REMOVE: return DRVCNF_RESTART;
944 
945  case ACMDM_DRIVER_NOTIFY:
946  /* no caching from other ACM drivers is done so far */
947  return MMSYSERR_NOERROR;
948 
950  return ADPCM_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
951 
953  return ADPCM_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
954 
956  return ADPCM_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
957 
959  return ADPCM_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
960 
961  case ACMDM_STREAM_OPEN:
962  return ADPCM_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
963 
964  case ACMDM_STREAM_CLOSE:
965  return ADPCM_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
966 
967  case ACMDM_STREAM_SIZE:
968  return ADPCM_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
969 
972 
975  /* this converter is not a hardware driver */
978  /* this converter is not a filter */
979  case ACMDM_STREAM_RESET:
980  /* only needed for asynchronous driver... we aren't, so just say it */
981  return MMSYSERR_NOTSUPPORTED;
984  /* nothing special to do here... so don't do anything */
985  return MMSYSERR_NOERROR;
986 
987  default:
988  return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
989  }
990 }
#define DRV_DISABLE
Definition: mmsystem.h:123
static LRESULT ADPCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
Definition: imaadp32.c:602
#define ACMDM_STREAM_RESET
Definition: msacmdrv.h:62
#define DRV_CLOSE
Definition: mmsystem.h:122
#define ACMDM_STREAM_OPEN
Definition: msacmdrv.h:58
#define ACMDM_FORMATTAG_DETAILS
Definition: msacmdrv.h:51
#define ACMDM_STREAM_PREPARE
Definition: msacmdrv.h:63
#define ACMDM_STREAM_CLOSE
Definition: msacmdrv.h:59
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define DRV_OPEN
Definition: mmsystem.h:121
int WINAPI MessageBoxA(_In_opt_ HWND, _In_opt_ LPCSTR, _In_opt_ LPCSTR, _In_ UINT)
#define ACMDM_DRIVER_NOTIFY
Definition: msacmdrv.h:45
#define ACMDM_FORMAT_SUGGEST
Definition: msacmdrv.h:53
static LRESULT ADPCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
Definition: imaadp32.c:652
#define ACMDM_DRIVER_DETAILS
Definition: msacmdrv.h:46
#define ACMDM_STREAM_CONVERT
Definition: msacmdrv.h:61
#define DRV_LOAD(x)
#define DRVCNF_RESTART
Definition: mmsystem.h:135
#define DRV_REMOVE
Definition: mmsystem.h:128
#define ACMDM_HARDWARE_WAVE_CAPS_OUTPUT
Definition: msacmdrv.h:49
#define ACMDM_HARDWARE_WAVE_CAPS_INPUT
Definition: msacmdrv.h:48
static LRESULT ADPCM_DriverDetails(PACMDRIVERDETAILSW add)
Definition: imaadp32.c:520
#define TRACE(s)
Definition: solgame.cpp:4
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define DRV_CONFIGURE
Definition: mmsystem.h:125
static LRESULT ADPCM_StreamClose(PACMDRVSTREAMINSTANCE adsi)
Definition: imaadp32.c:814
#define DRV_FREE
Definition: mmsystem.h:124
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define ACMDM_FILTERTAG_DETAILS
Definition: msacmdrv.h:55
static LRESULT ADPCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
Definition: imaadp32.c:549
#define ACMDM_STREAM_UNPREPARE
Definition: msacmdrv.h:64
#define DRV_ENABLE
Definition: mmsystem.h:120
static LRESULT ADPCM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
Definition: imaadp32.c:893
static LRESULT ADPCM_drvClose(DWORD_PTR dwDevID)
Definition: imaadp32.c:43
#define MB_OK
Definition: winuser.h:784
static LRESULT ADPCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
Definition: imaadp32.c:719
#define DRV_INSTALL
Definition: mmsystem.h:127
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
static LRESULT ADPCM_StreamSize(const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMSIZE adss)
Definition: imaadp32.c:824
#define ACMDM_FORMAT_DETAILS
Definition: msacmdrv.h:52
#define ACMDM_STREAM_SIZE
Definition: msacmdrv.h:60
#define ACMDM_FILTER_DETAILS
Definition: msacmdrv.h:56

◆ ADPCM_drvClose()

static LRESULT ADPCM_drvClose ( DWORD_PTR  dwDevID)
static

Definition at line 43 of file imaadp32.c.

44 {
45  return 1;
46 }

Referenced by ADPCM_DriverProc().

◆ ADPCM_FormatDetails()

static LRESULT ADPCM_FormatDetails ( PACMFORMATDETAILSW  afd,
DWORD  dwQuery 
)
static

Definition at line 602 of file imaadp32.c.

603 {
604  switch (dwQuery)
605  {
607  if (ADPCM_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
608  break;
610  afd->pwfx->wFormatTag = afd->dwFormatTag;
611  switch (afd->dwFormatTag)
612  {
613  case WAVE_FORMAT_PCM:
618  /* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible
619  * afd->pwfx->cbSize = 0;
620  */
621  afd->pwfx->nBlockAlign =
622  (afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8;
623  afd->pwfx->nAvgBytesPerSec =
624  afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
625  break;
632  break;
633  default:
634  WARN("Unsupported tag %08x\n", afd->dwFormatTag);
635  return MMSYSERR_INVALPARAM;
636  }
637  break;
638  default:
639  WARN("Unsupported query %08x\n", dwQuery);
640  return MMSYSERR_NOTSUPPORTED;
641  }
643  afd->szFormat[0] = 0; /* let MSACM format this for us... */
644 
645  return MMSYSERR_NOERROR;
646 }
PWAVEFORMATEX pwfx
Definition: msacm.h:507
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
WORD nChannels
Definition: mmreg.h:79
#define WARN(fmt,...)
Definition: debug.h:111
#define ACMDRIVERDETAILS_SUPPORTF_CODEC
Definition: msacm.h:61
int nChannels
Definition: imaadp32.c:63
int nBits
Definition: imaadp32.c:64
static void init_wfx_ima_adpcm(IMAADPCMWAVEFORMAT *awfx)
Definition: imaadp32.c:134
static const Format ADPCM_Formats[]
Definition: imaadp32.c:76
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define ACM_FORMATDETAILSF_FORMAT
Definition: msacm.h:161
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define WAVE_FORMAT_IMA_ADPCM
Definition: mmreg.h:103
WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]
Definition: msacm.h:509
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
WORD wFormatTag
Definition: mmreg.h:78
DWORD dwFormatIndex
Definition: msacm.h:504
#define ACMERR_NOTPOSSIBLE
Definition: msacm.h:36
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define ARRAY_SIZE(a)
Definition: main.h:24
DWORD fdwSupport
Definition: msacm.h:506
static const Format PCM_Formats[]
Definition: imaadp32.c:68
static DWORD ADPCM_GetFormatIndex(const WAVEFORMATEX *wfx)
Definition: imaadp32.c:85
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
#define ACM_FORMATDETAILSF_INDEX
Definition: msacm.h:160
int rate
Definition: imaadp32.c:65
WORD wBitsPerSample
Definition: mmreg.h:83
DWORD dwFormatTag
Definition: msacm.h:505

Referenced by ADPCM_DriverProc().

◆ ADPCM_FormatSuggest()

static LRESULT ADPCM_FormatSuggest ( PACMDRVFORMATSUGGEST  adfs)
static

Definition at line 652 of file imaadp32.c.

653 {
654  /* some tests ... */
655  if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
656  adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
657  adfs->pwfxSrc->wFormatTag == adfs->pwfxDst->wFormatTag ||
658  ADPCM_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
659 
660  /* If no suggestion for destination, then copy source value */
662  adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels;
665 
667  {
668  if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
669  adfs->pwfxDst->wBitsPerSample = 4;
670  else
671  adfs->pwfxDst->wBitsPerSample = 16;
672  }
674  {
675  if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
677  else
679  }
680 
681  /* recompute other values */
682  switch (adfs->pwfxDst->wFormatTag)
683  {
684  case WAVE_FORMAT_PCM:
685  if (adfs->cbwfxSrc < sizeof(IMAADPCMWAVEFORMAT)) return ACMERR_NOTPOSSIBLE;
686  adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8;
688  /* check if result is ok */
689  if (ADPCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
690  break;
692  if (adfs->cbwfxDst < sizeof(IMAADPCMWAVEFORMAT)) return ACMERR_NOTPOSSIBLE;
694  /* FIXME: not handling header overhead */
695  TRACE("setting spb=%u\n", ((IMAADPCMWAVEFORMAT*)adfs->pwfxDst)->wSamplesPerBlock);
696  /* check if result is ok */
697  if (ADPCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
698  break;
699  default:
700  return ACMERR_NOTPOSSIBLE;
701  }
702 
703  return MMSYSERR_NOERROR;
704 }
#define ACM_FORMATSUGGESTF_NSAMPLESPERSEC
Definition: msacm.h:176
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:153
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
WORD nChannels
Definition: mmreg.h:79
#define ACM_FORMATSUGGESTF_WFORMATTAG
Definition: msacm.h:174
static void init_wfx_ima_adpcm(IMAADPCMWAVEFORMAT *awfx)
Definition: imaadp32.c:134
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define ACM_FORMATSUGGESTF_NCHANNELS
Definition: msacm.h:175
#define TRACE(s)
Definition: solgame.cpp:4
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define WAVE_FORMAT_IMA_ADPCM
Definition: mmreg.h:103
WORD wFormatTag
Definition: mmreg.h:78
#define ACMERR_NOTPOSSIBLE
Definition: msacm.h:36
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:151
static DWORD ADPCM_GetFormatIndex(const WAVEFORMATEX *wfx)
Definition: imaadp32.c:85
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
WORD wBitsPerSample
Definition: mmreg.h:83
#define ACM_FORMATSUGGESTF_WBITSPERSAMPLE
Definition: msacm.h:177

Referenced by ADPCM_DriverProc().

◆ ADPCM_FormatTagDetails()

static LRESULT ADPCM_FormatTagDetails ( PACMFORMATTAGDETAILSW  aftd,
DWORD  dwQuery 
)
static

Definition at line 549 of file imaadp32.c.

550 {
551  static const WCHAR szPcm[]={'P','C','M',0};
552  static const WCHAR szImaAdPcm[]={'I','M','A',' ','A','D','P','C','M',0};
553 
554  switch (dwQuery)
555  {
557  if (aftd->dwFormatTagIndex >= 2) return ACMERR_NOTPOSSIBLE;
558  break;
560  if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN)
561  {
562  aftd->dwFormatTagIndex = 1; /* WAVE_FORMAT_IMA_ADPCM is bigger than PCM */
563  break;
564  }
565  /* fall through */
567  switch (aftd->dwFormatTag)
568  {
569  case WAVE_FORMAT_PCM: aftd->dwFormatTagIndex = 0; break;
570  case WAVE_FORMAT_IMA_ADPCM: aftd->dwFormatTagIndex = 1; break;
571  default: return ACMERR_NOTPOSSIBLE;
572  }
573  break;
574  default:
575  WARN("Unsupported query %08x\n", dwQuery);
576  return MMSYSERR_NOTSUPPORTED;
577  }
578 
580  switch (aftd->dwFormatTagIndex)
581  {
582  case 0:
584  aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
586  lstrcpyW(aftd->szFormatTag, szPcm);
587  break;
588  case 1:
590  aftd->cbFormatSize = sizeof(IMAADPCMWAVEFORMAT);
592  lstrcpyW(aftd->szFormatTag, szImaAdPcm);
593  break;
594  }
595  return MMSYSERR_NOERROR;
596 }
#define WAVE_FORMAT_UNKNOWN
Definition: mmreg.h:95
#define WARN(fmt,...)
Definition: debug.h:111
#define ACMDRIVERDETAILS_SUPPORTF_CODEC
Definition: msacm.h:61
static const Format ADPCM_Formats[]
Definition: imaadp32.c:76
struct pcmwaveformat_tag PCMWAVEFORMAT
#define WAVE_FORMAT_PCM
Definition: constants.h:425
DWORD cStandardFormats
Definition: msacm.h:534
#define ACM_FORMATTAGDETAILSF_FORMATTAG
Definition: msacm.h:183
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define WAVE_FORMAT_IMA_ADPCM
Definition: mmreg.h:103
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ACM_FORMATTAGDETAILSF_INDEX
Definition: msacm.h:182
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define ACM_FORMATTAGDETAILSF_LARGESTSIZE
Definition: msacm.h:184
DWORD dwFormatTagIndex
Definition: msacm.h:530
#define ACMERR_NOTPOSSIBLE
Definition: msacm.h:36
struct ima_adpcmwaveformat_tag IMAADPCMWAVEFORMAT
#define lstrcpyW
Definition: compat.h:406
#define ARRAY_SIZE(a)
Definition: main.h:24
static const Format PCM_Formats[]
Definition: imaadp32.c:68
WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]
Definition: msacm.h:535

Referenced by ADPCM_DriverProc().

◆ ADPCM_GetFormatIndex()

static DWORD ADPCM_GetFormatIndex ( const WAVEFORMATEX wfx)
static

Definition at line 85 of file imaadp32.c.

86 {
87  int i, hi;
88  const Format* fmts;
89 
90  switch (wfx->wFormatTag)
91  {
92  case WAVE_FORMAT_PCM:
93  hi = ARRAY_SIZE(PCM_Formats);
94  fmts = PCM_Formats;
95  break;
99  break;
100  default:
101  return 0xFFFFFFFF;
102  }
103 
104  for (i = 0; i < hi; i++)
105  {
106  if (wfx->nChannels == fmts[i].nChannels &&
107  wfx->nSamplesPerSec == fmts[i].rate &&
108  wfx->wBitsPerSample == fmts[i].nBits)
109  return i;
110  }
111 
112  switch (wfx->wFormatTag)
113  {
114  case WAVE_FORMAT_PCM:
115  if(3 > wfx->nChannels &&
116  wfx->nChannels > 0 &&
117  wfx->nAvgBytesPerSec == 2 * wfx->nSamplesPerSec * wfx->nChannels &&
118  wfx->nBlockAlign == 2 * wfx->nChannels &&
119  wfx->wBitsPerSample == 16)
120  return hi;
121  break;
123  if(3 > wfx->nChannels &&
124  wfx->nChannels > 0 &&
125  wfx->wBitsPerSample == 4 &&
126  wfx->cbSize == 2)
127  return hi;
128  break;
129  }
130 
131  return 0xFFFFFFFF;
132 }
static const Format ADPCM_Formats[]
Definition: imaadp32.c:76
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define WAVE_FORMAT_PCM
Definition: constants.h:425
WORD wBitsPerSample
Definition: audioclient.idl:45
static struct fmt fmts[]
DWORD nSamplesPerSec
Definition: audioclient.idl:42
#define WAVE_FORMAT_IMA_ADPCM
Definition: mmreg.h:103
#define ARRAY_SIZE(a)
Definition: main.h:24
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
static const Format PCM_Formats[]
Definition: imaadp32.c:68

Referenced by ADPCM_FormatDetails(), ADPCM_FormatSuggest(), ADPCM_StreamOpen(), and init_wfx_ima_adpcm().

◆ ADPCM_Reset()

static void ADPCM_Reset ( PACMDRVSTREAMINSTANCE  adsi,
AcmAdpcmData aad 
)
static

Definition at line 710 of file imaadp32.c.

711 {
712  aad->stepIndexL = aad->stepIndexR = 0;
713 }
BYTE stepIndexL
Definition: imaadp32.c:53
BYTE stepIndexR
Definition: imaadp32.c:54

Referenced by ADPCM_StreamConvert(), and ADPCM_StreamOpen().

◆ ADPCM_StreamClose()

static LRESULT ADPCM_StreamClose ( PACMDRVSTREAMINSTANCE  adsi)
static

Definition at line 814 of file imaadp32.c.

815 {
816  HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
817  return MMSYSERR_NOERROR;
818 }
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:395
DWORD_PTR dwDriver
Definition: msacmdrv.h:107
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by ADPCM_DriverProc().

◆ ADPCM_StreamConvert()

static LRESULT ADPCM_StreamConvert ( PACMDRVSTREAMINSTANCE  adsi,
PACMDRVSTREAMHEADER  adsh 
)
static

Definition at line 893 of file imaadp32.c.

894 {
895  AcmAdpcmData* aad = (AcmAdpcmData*)adsi->dwDriver;
896  DWORD nsrc = adsh->cbSrcLength;
897  DWORD ndst = adsh->cbDstLength;
898 
899  if (adsh->fdwConvert &
903  {
904  FIXME("Unsupported fdwConvert (%08x), ignoring it\n", adsh->fdwConvert);
905  }
906  /* ACM_STREAMCONVERTF_BLOCKALIGN
907  * currently all conversions are block aligned, so do nothing for this flag
908  * ACM_STREAMCONVERTF_END
909  * no pending data, so do nothing for this flag
910  */
911  if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START))
912  {
913  ADPCM_Reset(adsi, aad);
914  }
915 
916  aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst);
917  adsh->cbSrcLengthUsed = nsrc;
918  adsh->cbDstLengthUsed = ndst;
919 
920  return MMSYSERR_NOERROR;
921 }
static void ADPCM_Reset(PACMDRVSTREAMINSTANCE adsi, AcmAdpcmData *aad)
Definition: imaadp32.c:710
#define ACM_STREAMCONVERTF_BLOCKALIGN
Definition: msacm.h:205
#define ACM_STREAMCONVERTF_END
Definition: msacm.h:207
#define FIXME(fmt,...)
Definition: debug.h:110
void(* convert)(PACMDRVSTREAMINSTANCE adsi, const unsigned char *, LPDWORD, unsigned char *, LPDWORD)
Definition: imaadp32.c:50
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
if(!(yy_init))
Definition: macro.lex.yy.c:714
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ACM_STREAMCONVERTF_START
Definition: msacm.h:206
DWORD_PTR dwDriver
Definition: msacmdrv.h:107

Referenced by ADPCM_DriverProc().

◆ ADPCM_StreamOpen()

static LRESULT ADPCM_StreamOpen ( PACMDRVSTREAMINSTANCE  adsi)
static

Definition at line 719 of file imaadp32.c.

720 {
721  AcmAdpcmData* aad;
722  unsigned nspb;
723 
725 
726  if (ADPCM_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
727  ADPCM_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
728  return ACMERR_NOTPOSSIBLE;
729 
730  aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmAdpcmData));
731  if (aad == 0) return MMSYSERR_NOMEM;
732 
733  adsi->dwDriver = (DWORD_PTR)aad;
734 
735  if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
737  {
738  goto theEnd;
739  }
740  else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM &&
742  {
743  /* resampling or mono <=> stereo not available
744  * ADPCM algo only define 16 bit per sample output
745  * (The API seems to still allow 8 bit per sample output)
746  */
747  if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
748  adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
749  (adsi->pwfxDst->wBitsPerSample != 16 && adsi->pwfxDst->wBitsPerSample != 8))
750  goto theEnd;
751 
752  nspb = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
753  TRACE("spb=%u\n", nspb);
754 
755  /* we check that in a block, after the header, samples are present on
756  * 4-sample packet pattern
757  * we also check that the block alignment is bigger than the expected size
758  */
759  if (((nspb - 1) & 3) != 0) goto theEnd;
760  if ((((nspb - 1) / 2) + 4) * adsi->pwfxSrc->nChannels < adsi->pwfxSrc->nBlockAlign)
761  goto theEnd;
762 
763  /* adpcm decoding... */
764  if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 2)
765  aad->convert = cvtSSima16K;
766  if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 1)
767  aad->convert = cvtMMimaK;
768  if (adsi->pwfxDst->wBitsPerSample == 8 && adsi->pwfxDst->nChannels == 1)
769  aad->convert = cvtMMimaK;
770  /* FIXME: Stereo support for 8bit samples*/
771  if (adsi->pwfxDst->wBitsPerSample == 8 && adsi->pwfxDst->nChannels == 2)
772  goto theEnd;
773  }
774  else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
776  {
777  if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
778  adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
779  adsi->pwfxSrc->wBitsPerSample != 16)
780  goto theEnd;
781 
782  nspb = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock;
783  TRACE("spb=%u\n", nspb);
784 
785  /* we check that in a block, after the header, samples are present on
786  * 4-sample packet pattern
787  * we also check that the block alignment is bigger than the expected size
788  */
789  if (((nspb - 1) & 3) != 0) goto theEnd;
790  if ((((nspb - 1) / 2) + 4) * adsi->pwfxDst->nChannels < adsi->pwfxDst->nBlockAlign)
791  goto theEnd;
792 
793  /* adpcm coding... */
794  if (adsi->pwfxSrc->wBitsPerSample == 16 && adsi->pwfxSrc->nChannels == 2)
795  aad->convert = cvtSS16imaK;
796  if (adsi->pwfxSrc->wBitsPerSample == 16 && adsi->pwfxSrc->nChannels == 1)
797  aad->convert = cvtMM16imaK;
798  }
799  else goto theEnd;
800  ADPCM_Reset(adsi, aad);
801 
802  return MMSYSERR_NOERROR;
803 
804  theEnd:
805  HeapFree(GetProcessHeap(), 0, aad);
806  adsi->dwDriver = 0L;
807  return MMSYSERR_NOTSUPPORTED;
808 }
static void ADPCM_Reset(PACMDRVSTREAMINSTANCE adsi, AcmAdpcmData *aad)
Definition: imaadp32.c:710
#define DWORD_PTR
Definition: treelist.c:76
static void cvtMM16imaK(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:463
WORD nChannels
Definition: mmreg.h:79
static void cvtSSima16K(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:298
IMAADPCMWAVEFORMAT * LPIMAADPCMWAVEFORMAT
Definition: mmreg.h:190
#define assert(x)
Definition: debug.h:53
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
#define WAVE_FORMAT_PCM
Definition: constants.h:425
static void cvtMMimaK(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:358
void(* convert)(PACMDRVSTREAMINSTANCE adsi, const unsigned char *, LPDWORD, unsigned char *, LPDWORD)
Definition: imaadp32.c:50
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:101
#define TRACE(s)
Definition: solgame.cpp:4
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define WAVE_FORMAT_IMA_ADPCM
Definition: mmreg.h:103
#define ACM_STREAMOPENF_ASYNC
Definition: msacm.h:214
static void cvtSS16imaK(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:400
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
WORD wFormatTag
Definition: mmreg.h:78
static const WCHAR L[]
Definition: oid.c:1250
#define ACMERR_NOTPOSSIBLE
Definition: msacm.h:36
DWORD_PTR dwDriver
Definition: msacmdrv.h:107
static DWORD ADPCM_GetFormatIndex(const WAVEFORMATEX *wfx)
Definition: imaadp32.c:85
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
WORD wBitsPerSample
Definition: mmreg.h:83
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:100
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by ADPCM_DriverProc().

◆ ADPCM_StreamSize()

static LRESULT ADPCM_StreamSize ( const ACMDRVSTREAMINSTANCE adsi,
PACMDRVSTREAMSIZE  adss 
)
static

Definition at line 824 of file imaadp32.c.

825 {
826  DWORD nblocks;
827 
828  switch (adss->fdwSize)
829  {
831  /* cbDstLength => cbSrcLength */
832  if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
834  {
835  nblocks = adss->cbDstLength / adsi->pwfxDst->nBlockAlign;
836  if (nblocks == 0)
837  return ACMERR_NOTPOSSIBLE;
838  adss->cbSrcLength = nblocks * adsi->pwfxSrc->nBlockAlign * ((IMAADPCMWAVEFORMAT*)adsi->pwfxDst)->wSamplesPerBlock;
839  }
840  else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM &&
842  {
843  nblocks = adss->cbDstLength / (adsi->pwfxDst->nBlockAlign * ((IMAADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock);
844  if (nblocks == 0)
845  return ACMERR_NOTPOSSIBLE;
846  adss->cbSrcLength = nblocks * adsi->pwfxSrc->nBlockAlign;
847  }
848  else
849  {
850  return MMSYSERR_NOTSUPPORTED;
851  }
852  break;
854  /* cbSrcLength => cbDstLength */
855  if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
857  {
858  nblocks = adss->cbSrcLength / (adsi->pwfxSrc->nBlockAlign * ((IMAADPCMWAVEFORMAT*)adsi->pwfxDst)->wSamplesPerBlock);
859  if (nblocks == 0)
860  return ACMERR_NOTPOSSIBLE;
861  if (adss->cbSrcLength % (adsi->pwfxSrc->nBlockAlign * ((IMAADPCMWAVEFORMAT*)adsi->pwfxDst)->wSamplesPerBlock))
862  /* Round block count up. */
863  nblocks++;
864  adss->cbDstLength = nblocks * adsi->pwfxDst->nBlockAlign;
865  }
866  else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM &&
868  {
869  nblocks = adss->cbSrcLength / adsi->pwfxSrc->nBlockAlign;
870  if (nblocks == 0)
871  return ACMERR_NOTPOSSIBLE;
872  if (adss->cbSrcLength % adsi->pwfxSrc->nBlockAlign)
873  /* Round block count up. */
874  nblocks++;
875  adss->cbDstLength = nblocks * adsi->pwfxDst->nBlockAlign * ((IMAADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock;
876  }
877  else
878  {
879  return MMSYSERR_NOTSUPPORTED;
880  }
881  break;
882  default:
883  WARN("Unsupported query %08x\n", adss->fdwSize);
884  return MMSYSERR_NOTSUPPORTED;
885  }
886  return MMSYSERR_NOERROR;
887 }
#define ACM_STREAMSIZEF_DESTINATION
Definition: msacm.h:218
#define WARN(fmt,...)
Definition: debug.h:111
#define WAVE_FORMAT_PCM
Definition: constants.h:425
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:101
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define WAVE_FORMAT_IMA_ADPCM
Definition: mmreg.h:103
#define ACM_STREAMSIZEF_SOURCE
Definition: msacm.h:217
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
WORD wFormatTag
Definition: mmreg.h:78
#define ACMERR_NOTPOSSIBLE
Definition: msacm.h:36
WORD nBlockAlign
Definition: mmreg.h:82
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:100

Referenced by ADPCM_DriverProc().

◆ clamp_sample()

static void clamp_sample ( int sample)
inlinestatic

Definition at line 228 of file imaadp32.c.

229 {
230  if (*sample < -32768) *sample = -32768;
231  if (*sample > 32767) *sample = 32767;
232 }

Referenced by generate_nibble(), and process_nibble().

◆ clamp_step_index()

static void clamp_step_index ( int stepIndex)
inlinestatic

Definition at line 222 of file imaadp32.c.

223 {
224  if (*stepIndex < 0 ) *stepIndex = 0;
225  if (*stepIndex > 88) *stepIndex = 88;
226 }

Referenced by cvtMMimaK(), cvtSSima16K(), generate_nibble(), and process_nibble().

◆ cvtMM16imaK()

static void cvtMM16imaK ( PACMDRVSTREAMINSTANCE  adsi,
const unsigned char src,
LPDWORD  nsrc,
unsigned char dst,
LPDWORD  ndst 
)
static

Definition at line 463 of file imaadp32.c.

466 {
467  int stepIndex;
468  int sample;
469  BYTE code1, code2;
470  int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock;
471  int nsamp;
472  /* compute the number of entire blocks we can decode...
473  * it's the min of the number of entire blocks in source buffer and the number
474  * of entire blocks in destination buffer
475  */
476  DWORD nblock = min(*nsrc / (nsamp_blk * 2),
477  *ndst / adsi->pwfxDst->nBlockAlign);
478 
479  *nsrc = nblock * (nsamp_blk * 2);
480  *ndst = nblock * adsi->pwfxDst->nBlockAlign;
481 
482  stepIndex = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL;
483  nsamp_blk--; /* so that we won't count the sample in header while filling the block */
484 
485  for (; nblock > 0; nblock--)
486  {
487  unsigned char* in_dst = dst;
488 
489  /* generate header */
490  /* FIXME: what about the last effective sample from previous block ??? */
491  /* perhaps something like:
492  * sample += R16(src);
493  * clamp_sample(sample);
494  * and with :
495  * + saving the sample in adsi->dwDriver when all blocks are done
496  + + reset should set the field in adsi->dwDriver to 0 too
497  */
498  sample = R16(src); src += 2;
499  W16(dst, sample); dst += 2;
500  *dst = (unsigned char)(unsigned)stepIndex;
501  dst += 2;
502 
503  for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
504  {
505  code1 = generate_nibble(R16(src), &stepIndex, &sample);
506  src += 2;
507  code2 = generate_nibble(R16(src), &stepIndex, &sample);
508  src += 2;
509  *dst++ = (code2 << 4) | code1;
510  }
511  dst = in_dst + adsi->pwfxDst->nBlockAlign;
512  }
513  ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL = stepIndex;
514 }
IMAADPCMWAVEFORMAT * LPIMAADPCMWAVEFORMAT
Definition: mmreg.h:190
static unsigned char generate_nibble(int in, int *stepIndex, int *sample)
Definition: imaadp32.c:253
unsigned char
Definition: typeof.h:29
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:101
static void W16(unsigned char *dst, short s)
Definition: imaadp32.c:173
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned char BYTE
Definition: mem.h:68
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
DWORD_PTR dwDriver
Definition: msacmdrv.h:107
#define min(a, b)
Definition: monoChain.cc:55
WORD nBlockAlign
Definition: mmreg.h:82
static short R16(const unsigned char *src)
Definition: imaadp32.c:163

Referenced by ADPCM_StreamOpen().

◆ cvtMMimaK()

static void cvtMMimaK ( PACMDRVSTREAMINSTANCE  adsi,
const unsigned char src,
LPDWORD  nsrc,
unsigned char dst,
LPDWORD  ndst 
)
static

Definition at line 358 of file imaadp32.c.

361 {
362  int sample;
363  int stepIndex;
364  int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
365  int nsamp;
366  int bytesPerSample = adsi->pwfxDst->wBitsPerSample / 8;
367  /* compute the number of entire blocks we can decode...
368  * it's the min of the number of entire blocks in source buffer and the number
369  * of entire blocks in destination buffer
370  */
371  DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign, *ndst / (nsamp_blk * bytesPerSample));
372 
373  *nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
374  *ndst = nblock * nsamp_blk * bytesPerSample;
375 
376  nsamp_blk--; /* remove the sample in block header */
377  for (; nblock > 0; nblock--)
378  {
379  const unsigned char* in_src = src;
380 
381  /* handle header first */
382  sample = R16(src);
383  stepIndex = (unsigned)*(src + 2);
384  clamp_step_index(&stepIndex);
385  src += 4;
386  W8_16(dst, sample, bytesPerSample); dst += bytesPerSample;
387 
388  for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
389  {
390  process_nibble(*src, &stepIndex, &sample);
391  W8_16(dst, sample, bytesPerSample); dst += bytesPerSample;
392  process_nibble(*src++ >> 4, &stepIndex, &sample);
393  W8_16(dst, sample, bytesPerSample); dst += bytesPerSample;
394  }
395  /* we have now to realign the source pointer on block */
396  src = in_src + adsi->pwfxSrc->nBlockAlign;
397  }
398 }
static void process_nibble(unsigned char code, int *stepIndex, int *sample)
Definition: imaadp32.c:234
IMAADPCMWAVEFORMAT * LPIMAADPCMWAVEFORMAT
Definition: mmreg.h:190
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:101
unsigned long DWORD
Definition: ntddk_ex.h:95
static void clamp_step_index(int *stepIndex)
Definition: imaadp32.c:222
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
#define min(a, b)
Definition: monoChain.cc:55
WORD nBlockAlign
Definition: mmreg.h:82
WORD wBitsPerSample
Definition: mmreg.h:83
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:100
static short R16(const unsigned char *src)
Definition: imaadp32.c:163
static void W8_16(unsigned char *dst, short s, int bytes)
Definition: imaadp32.c:190

Referenced by ADPCM_StreamOpen().

◆ cvtSS16imaK()

static void cvtSS16imaK ( PACMDRVSTREAMINSTANCE  adsi,
const unsigned char src,
LPDWORD  nsrc,
unsigned char dst,
LPDWORD  ndst 
)
static

Definition at line 400 of file imaadp32.c.

403 {
404  int stepIndexL, stepIndexR;
405  int sampleL, sampleR;
406  BYTE code1, code2;
407  int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock;
408  int i, nsamp;
409  /* compute the number of entire blocks we can decode...
410  * it's the min of the number of entire blocks in source buffer and the number
411  * of entire blocks in destination buffer
412  */
413  DWORD nblock = min(*nsrc / (nsamp_blk * 2 * 2),
414  *ndst / adsi->pwfxDst->nBlockAlign);
415 
416  *nsrc = nblock * (nsamp_blk * 2 * 2);
417  *ndst = nblock * adsi->pwfxDst->nBlockAlign;
418 
419  stepIndexL = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL;
420  stepIndexR = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexR;
421 
422  nsamp_blk--; /* so that we won't count the sample in header while filling the block */
423 
424  for (; nblock > 0; nblock--)
425  {
426  unsigned char* in_dst = dst;
427 
428  /* generate header */
429  sampleL = R16(src); src += 2;
430  W16(dst, sampleL); dst += 2;
431  W16(dst, stepIndexL); dst += 2;
432 
433  sampleR = R16(src); src += 2;
434  W16(dst, sampleR); dst += 2;
435  W16(dst, stepIndexR); dst += 2;
436 
437  for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 8)
438  {
439  for (i = 0; i < 4; i++)
440  {
441  code1 = generate_nibble(R16(src + (4 * i + 0) * 2),
442  &stepIndexL, &sampleL);
443  code2 = generate_nibble(R16(src + (4 * i + 2) * 2),
444  &stepIndexL, &sampleL);
445  *dst++ = (code2 << 4) | code1;
446  }
447  for (i = 0; i < 4; i++)
448  {
449  code1 = generate_nibble(R16(src + (4 * i + 1) * 2),
450  &stepIndexR, &sampleR);
451  code2 = generate_nibble(R16(src + (4 * i + 3) * 2),
452  &stepIndexR, &sampleR);
453  *dst++ = (code2 << 4) | code1;
454  }
455  src += 32;
456  }
457  dst = in_dst + adsi->pwfxDst->nBlockAlign;
458  }
459  ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL = stepIndexL;
460  ((AcmAdpcmData*)adsi->dwDriver)->stepIndexR = stepIndexR;
461 }
IMAADPCMWAVEFORMAT * LPIMAADPCMWAVEFORMAT
Definition: mmreg.h:190
static unsigned char generate_nibble(int in, int *stepIndex, int *sample)
Definition: imaadp32.c:253
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:101
static void W16(unsigned char *dst, short s)
Definition: imaadp32.c:173
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned char BYTE
Definition: mem.h:68
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
DWORD_PTR dwDriver
Definition: msacmdrv.h:107
#define min(a, b)
Definition: monoChain.cc:55
WORD nBlockAlign
Definition: mmreg.h:82
static short R16(const unsigned char *src)
Definition: imaadp32.c:163

Referenced by ADPCM_StreamOpen().

◆ cvtSSima16K()

static void cvtSSima16K ( PACMDRVSTREAMINSTANCE  adsi,
const unsigned char src,
LPDWORD  nsrc,
unsigned char dst,
LPDWORD  ndst 
)
static

Definition at line 298 of file imaadp32.c.

301 {
302  int i;
303  int sampleL, sampleR;
304  int stepIndexL, stepIndexR;
305  int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
306  int nsamp;
307  /* compute the number of entire blocks we can decode...
308  * it's the min of the number of entire blocks in source buffer and the number
309  * of entire blocks in destination buffer
310  */
311  DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign,
312  *ndst / (nsamp_blk * 2 * 2));
313 
314  *nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
315  *ndst = nblock * (nsamp_blk * 2 * 2);
316 
317  nsamp_blk--; /* remove the sample in block header */
318  for (; nblock > 0; nblock--)
319  {
320  const unsigned char* in_src = src;
321 
322  /* handle headers first */
323  sampleL = R16(src);
324  stepIndexL = (unsigned)*(src + 2);
325  clamp_step_index(&stepIndexL);
326  src += 4;
327  W16(dst, sampleL); dst += 2;
328 
329  sampleR = R16(src);
330  stepIndexR = (unsigned)*(src + 2);
331  clamp_step_index(&stepIndexR);
332  src += 4;
333  W16(dst, sampleR); dst += 2;
334 
335  for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 8)
336  {
337  for (i = 0; i < 4; i++)
338  {
339  process_nibble(*src, &stepIndexL, &sampleL);
340  W16(dst + (2 * i + 0) * 4 + 0, sampleL);
341  process_nibble(*src++ >> 4, &stepIndexL, &sampleL);
342  W16(dst + (2 * i + 1) * 4 + 0, sampleL);
343  }
344  for (i = 0; i < 4; i++)
345  {
346  process_nibble(*src , &stepIndexR, &sampleR);
347  W16(dst + (2 * i + 0) * 4 + 2, sampleR);
348  process_nibble(*src++ >>4, &stepIndexR, &sampleR);
349  W16(dst + (2 * i + 1) * 4 + 2, sampleR);
350  }
351  dst += 32;
352  }
353  /* we have now to realign the source pointer on block */
354  src = in_src + adsi->pwfxSrc->nBlockAlign;
355  }
356 }
static void process_nibble(unsigned char code, int *stepIndex, int *sample)
Definition: imaadp32.c:234
IMAADPCMWAVEFORMAT * LPIMAADPCMWAVEFORMAT
Definition: mmreg.h:190
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static void W16(unsigned char *dst, short s)
Definition: imaadp32.c:173
unsigned long DWORD
Definition: ntddk_ex.h:95
static void clamp_step_index(int *stepIndex)
Definition: imaadp32.c:222
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
#define min(a, b)
Definition: monoChain.cc:55
WORD nBlockAlign
Definition: mmreg.h:82
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:100
static short R16(const unsigned char *src)
Definition: imaadp32.c:163

Referenced by ADPCM_StreamOpen().

◆ generate_nibble()

static unsigned char generate_nibble ( int  in,
int stepIndex,
int sample 
)
inlinestatic

Definition at line 253 of file imaadp32.c.

254 {
255  int effdiff, diff = in - *sample;
256  unsigned step;
257  unsigned char code;
258 
259  if (diff < 0)
260  {
261  diff = -diff;
262  code = 8;
263  }
264  else
265  {
266  code = 0;
267  }
268 
269  step = IMA_StepTable[*stepIndex];
270  effdiff = (step >> 3);
271  if (diff >= step)
272  {
273  code |= 4;
274  diff -= step;
275  effdiff += step;
276  }
277  step >>= 1;
278  if (diff >= step)
279  {
280  code |= 2;
281  diff -= step;
282  effdiff += step;
283  }
284  step >>= 1;
285  if (diff >= step)
286  {
287  code |= 1;
288  effdiff += step;
289  }
290  if (code & 8) *sample -= effdiff;
291  else *sample += effdiff;
292  clamp_sample(sample);
293  *stepIndex += IMA_IndexTable[code];
294  clamp_step_index(stepIndex);
295  return code;
296 }
static void clamp_sample(int *sample)
Definition: imaadp32.c:228
static const unsigned IMA_StepTable[89]
Definition: imaadp32.c:200
static const int IMA_IndexTable[16]
Definition: imaadp32.c:216
static void clamp_step_index(int *stepIndex)
Definition: imaadp32.c:222
int code
Definition: i386-dis.c:3591
GLuint in
Definition: glext.h:9616

Referenced by cvtMM16imaK(), and cvtSS16imaK().

◆ init_wfx_ima_adpcm()

static void init_wfx_ima_adpcm ( IMAADPCMWAVEFORMAT awfx)
static

Definition at line 134 of file imaadp32.c.

135 {
136  WAVEFORMATEX* pwfx = &awfx->wfx;
137 
138  /* we assume wFormatTag, nChannels, nSamplesPerSec and wBitsPerSample
139  * have been initialized... */
140 
141  if (pwfx->wFormatTag != WAVE_FORMAT_IMA_ADPCM) {FIXME("wrong FT\n"); return;}
142  if (ADPCM_GetFormatIndex(pwfx) == 0xFFFFFFFF) {FIXME("wrong fmt\n"); return;}
143 
144  switch (pwfx->nSamplesPerSec)
145  {
146  case 8000: pwfx->nBlockAlign = 256 * pwfx->nChannels; break;
147  case 11025: pwfx->nBlockAlign = 256 * pwfx->nChannels; break;
148  case 22050: pwfx->nBlockAlign = 512 * pwfx->nChannels; break;
149  case 44100: pwfx->nBlockAlign = 1024 * pwfx->nChannels; break;
150  default: /*pwfx->nBlockAlign = nba;*/ break;
151  }
152  pwfx->cbSize = sizeof(WORD);
153 
154  awfx->wSamplesPerBlock = (pwfx->nBlockAlign - (4 * pwfx->nChannels)) * (2 / pwfx->nChannels) + 1;
155  pwfx->nAvgBytesPerSec = (pwfx->nSamplesPerSec * pwfx->nBlockAlign) / awfx->wSamplesPerBlock;
156 }
#define FIXME(fmt,...)
Definition: debug.h:110
DWORD nSamplesPerSec
Definition: audioclient.idl:42
#define WAVE_FORMAT_IMA_ADPCM
Definition: mmreg.h:103
unsigned short WORD
Definition: ntddk_ex.h:93
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
static DWORD ADPCM_GetFormatIndex(const WAVEFORMATEX *wfx)
Definition: imaadp32.c:85
WAVEFORMATEX wfx
Definition: mmreg.h:187

Referenced by ADPCM_FormatDetails(), and ADPCM_FormatSuggest().

◆ process_nibble()

static void process_nibble ( unsigned char  code,
int stepIndex,
int sample 
)
inlinestatic

Definition at line 234 of file imaadp32.c.

235 {
236  unsigned step;
237  int diff;
238 
239  code &= 0x0F;
240 
241  step = IMA_StepTable[*stepIndex];
242  diff = step >> 3;
243  if (code & 1) diff += step >> 2;
244  if (code & 2) diff += step >> 1;
245  if (code & 4) diff += step;
246  if (code & 8) *sample -= diff;
247  else *sample += diff;
248  clamp_sample(sample);
249  *stepIndex += IMA_IndexTable[code];
250  clamp_step_index(stepIndex);
251 }
static void clamp_sample(int *sample)
Definition: imaadp32.c:228
static const unsigned IMA_StepTable[89]
Definition: imaadp32.c:200
static const int IMA_IndexTable[16]
Definition: imaadp32.c:216
static void clamp_step_index(int *stepIndex)
Definition: imaadp32.c:222
int code
Definition: i386-dis.c:3591

Referenced by cvtMMimaK(), and cvtSSima16K().

◆ R16()

static short R16 ( const unsigned char src)
inlinestatic

Definition at line 163 of file imaadp32.c.

164 {
165  return (short)((unsigned short)src[0] | ((unsigned short)src[1] << 8));
166 }
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:93
GLenum src
Definition: glext.h:6340

Referenced by cvtMM16imaK(), cvtMMimaK(), cvtSS16imaK(), and cvtSSima16K().

◆ W16()

static void W16 ( unsigned char dst,
short  s 
)
inlinestatic

Definition at line 173 of file imaadp32.c.

174 {
175  dst[0] = LOBYTE(s);
176  dst[1] = HIBYTE(s);
177 }
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
GLdouble s
Definition: gl.h:2039
GLenum GLenum dst
Definition: glext.h:6340

Referenced by cvtMM16imaK(), cvtSS16imaK(), cvtSSima16K(), and W8_16().

◆ W8()

static void W8 ( unsigned char dst,
short  s 
)
inlinestatic

Definition at line 184 of file imaadp32.c.

185 {
186  dst[0] = (unsigned char)((s + 32768) >> 8);
187 }
unsigned char
Definition: typeof.h:29
GLdouble s
Definition: gl.h:2039
GLenum GLenum dst
Definition: glext.h:6340

Referenced by W8_16().

◆ W8_16()

static void W8_16 ( unsigned char dst,
short  s,
int  bytes 
)
inlinestatic

Definition at line 190 of file imaadp32.c.

191 {
192  if(bytes == 1)
193  W8(dst, s);
194  else
195  W16(dst, s);
196 }
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
static void W16(unsigned char *dst, short s)
Definition: imaadp32.c:173
GLdouble s
Definition: gl.h:2039
static void W8(unsigned char *dst, short s)
Definition: imaadp32.c:184
GLenum GLenum dst
Definition: glext.h:6340

Referenced by cvtMMimaK().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( adpcm  )

Variable Documentation

◆ ADPCM_Formats

const Format ADPCM_Formats[]
static
Initial value:
=
{
{1, 4, 8000}, {2, 4, 8000}, {1, 4, 11025}, {2, 4, 11025},
{1, 4, 22050}, {2, 4, 22050}, {1, 4, 44100}, {2, 4, 44100},
}

Definition at line 76 of file imaadp32.c.

Referenced by ADPCM_FormatDetails(), ADPCM_FormatTagDetails(), and ADPCM_GetFormatIndex().

◆ IMA_IndexTable

const int IMA_IndexTable[16]
static
Initial value:
=
{
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
}

Definition at line 216 of file imaadp32.c.

Referenced by generate_nibble(), and process_nibble().

◆ IMA_StepTable

const unsigned IMA_StepTable[89]
static
Initial value:
=
{
7, 8, 9, 10, 11, 12, 13, 14,
16, 17, 19, 21, 23, 25, 28, 31,
34, 37, 41, 45, 50, 55, 60, 66,
73, 80, 88, 97, 107, 118, 130, 143,
157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658,
724, 796, 876, 963, 1060, 1166, 1282, 1411,
1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
32767
}

Definition at line 200 of file imaadp32.c.

Referenced by generate_nibble(), and process_nibble().

◆ PCM_Formats

const Format PCM_Formats[]
static
Initial value:
=
{
{1, 8, 8000}, {2, 8, 8000}, {1, 16, 8000}, {2, 16, 8000},
{1, 8, 11025}, {2, 8, 11025}, {1, 16, 11025}, {2, 16, 11025},
{1, 8, 22050}, {2, 8, 22050}, {1, 16, 22050}, {2, 16, 22050},
{1, 8, 44100}, {2, 8, 44100}, {1, 16, 44100}, {2, 16, 44100},
}

Definition at line 68 of file imaadp32.c.

Referenced by ADPCM_FormatDetails(), ADPCM_FormatTagDetails(), and ADPCM_GetFormatIndex().