ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

msgsm32.c
Go to the documentation of this file.
00001 /*
00002  * GSM 06.10 codec handling
00003  * Copyright (C) 2009 Maarten Lankhorst
00004  *
00005  * Based on msg711.acm
00006  * Copyright (C) 2002 Eric Pouech
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00021  */
00022 
00023 #include "config.h"
00024 #include <wine/port.h>
00025 
00026 #include <assert.h>
00027 #include <stdarg.h>
00028 #include <string.h>
00029 
00030 #ifdef HAVE_GSM_GSM_H
00031 #include <gsm/gsm.h>
00032 #elif defined(HAVE_GSM_H)
00033 #include <gsm.h>
00034 #endif
00035 
00036 #include "windef.h"
00037 #include "winbase.h"
00038 #include "wingdi.h"
00039 #include "winuser.h"
00040 #include "winnls.h"
00041 #include "mmsystem.h"
00042 #include "mmreg.h"
00043 #include "msacm.h"
00044 #include "msacmdrv.h"
00045 #include "wine/library.h"
00046 #include "wine/debug.h"
00047 
00048 WINE_DEFAULT_DEBUG_CHANNEL(gsm);
00049 
00050 #ifdef SONAME_LIBGSM
00051 
00052 static void *libgsm_handle;
00053 #define FUNCPTR(f) static typeof(f) * p##f
00054 FUNCPTR(gsm_create);
00055 FUNCPTR(gsm_destroy);
00056 FUNCPTR(gsm_option);
00057 FUNCPTR(gsm_encode);
00058 FUNCPTR(gsm_decode);
00059 
00060 #define LOAD_FUNCPTR(f) \
00061     if((p##f = wine_dlsym(libgsm_handle, #f, NULL, 0)) == NULL) { \
00062         wine_dlclose(libgsm_handle, NULL, 0); \
00063         libgsm_handle = NULL; \
00064         return 0; \
00065     }
00066 
00067 /***********************************************************************
00068  *           GSM_drvLoad
00069  */
00070 static LRESULT GSM_drvLoad(void)
00071 {
00072     char error[128];
00073 
00074     libgsm_handle = wine_dlopen(SONAME_LIBGSM, RTLD_NOW, error, sizeof(error));
00075     if (libgsm_handle)
00076     {
00077         LOAD_FUNCPTR(gsm_create);
00078         LOAD_FUNCPTR(gsm_destroy);
00079         LOAD_FUNCPTR(gsm_option);
00080         LOAD_FUNCPTR(gsm_encode);
00081         LOAD_FUNCPTR(gsm_decode);
00082         return 1;
00083     }
00084     else
00085     {
00086         ERR("Couldn't load " SONAME_LIBGSM ": %s\n", error);
00087         return 0;
00088     }
00089 }
00090 
00091 /***********************************************************************
00092  *           GSM_drvFree
00093  */
00094 static LRESULT GSM_drvFree(void)
00095 {
00096     if (libgsm_handle)
00097         wine_dlclose(libgsm_handle, NULL, 0);
00098     return 1;
00099 }
00100 
00101 #else
00102 
00103 static LRESULT GSM_drvFree(void)
00104 {
00105     return 1;
00106 }
00107 
00108 #endif
00109 
00110 /***********************************************************************
00111  *           GSM_DriverDetails
00112  *
00113  */
00114 static  LRESULT GSM_DriverDetails(PACMDRIVERDETAILSW add)
00115 {
00116     add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
00117     add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
00118     /* Details found from probing native msgsm32.acm */
00119     add->wMid = MM_MICROSOFT;
00120     add->wPid = 36;
00121     add->vdwACM = 0x3320000;
00122     add->vdwDriver = 0x4000000;
00123     add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
00124     add->cFormatTags = 2;
00125     add->cFilterTags = 0;
00126     add->hicon = NULL;
00127     MultiByteToWideChar( CP_ACP, 0, "Wine GSM 6.10", -1,
00128                          add->szShortName, sizeof(add->szShortName)/sizeof(WCHAR) );
00129     MultiByteToWideChar( CP_ACP, 0, "Wine GSM 6.10 libgsm codec", -1,
00130                          add->szLongName, sizeof(add->szLongName)/sizeof(WCHAR) );
00131     MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
00132                          add->szCopyright, sizeof(add->szCopyright)/sizeof(WCHAR) );
00133     MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
00134                          add->szLicensing, sizeof(add->szLicensing)/sizeof(WCHAR) );
00135     add->szFeatures[0] = 0;
00136     return MMSYSERR_NOERROR;
00137 }
00138 
00139 /* Validate a WAVEFORMATEX structure */
00140 static DWORD GSM_FormatValidate(const WAVEFORMATEX *wfx)
00141 {
00142     if (wfx->nChannels != 1)
00143         return 0;
00144 
00145     switch (wfx->wFormatTag)
00146     {
00147     case WAVE_FORMAT_PCM:
00148         if (wfx->wBitsPerSample != 16)
00149         {
00150             WARN("PCM wBitsPerSample %u\n", wfx->wBitsPerSample);
00151             return 0;
00152         }
00153         if (wfx->nBlockAlign != 2)
00154         {
00155             WARN("PCM nBlockAlign %u\n", wfx->nBlockAlign);
00156             return 0;
00157         }
00158         if (wfx->nAvgBytesPerSec != wfx->nBlockAlign * wfx->nSamplesPerSec)
00159         {
00160             WARN("PCM nAvgBytesPerSec %u/%u\n",
00161                  wfx->nAvgBytesPerSec,
00162                  wfx->nBlockAlign * wfx->nSamplesPerSec);
00163             return 0;
00164         }
00165         return 1;
00166     case WAVE_FORMAT_GSM610:
00167         if (wfx->cbSize < sizeof(WORD))
00168         {
00169             WARN("GSM cbSize %u\n", wfx->cbSize);
00170             return 0;
00171         }
00172         if (wfx->wBitsPerSample != 0)
00173         {
00174             WARN("GSM wBitsPerSample %u\n", wfx->wBitsPerSample);
00175             return 0;
00176         }
00177         if (wfx->nBlockAlign != 65)
00178         {
00179             WARN("GSM nBlockAlign %u\n", wfx->nBlockAlign);
00180             return 0;
00181         }
00182         if (((const GSM610WAVEFORMAT*)wfx)->wSamplesPerBlock != 320)
00183         {
00184             WARN("GSM wSamplesPerBlock %u\n",
00185                  ((const GSM610WAVEFORMAT*)wfx)->wSamplesPerBlock);
00186             return 0;
00187         }
00188         if (wfx->nAvgBytesPerSec != wfx->nSamplesPerSec * 65 / 320)
00189         {
00190             WARN("GSM nAvgBytesPerSec %d / %d\n",
00191                  wfx->nAvgBytesPerSec, wfx->nSamplesPerSec * 65 / 320);
00192             return 0;
00193         }
00194         return 1;
00195     default:
00196         return 0;
00197     }
00198     return 0;
00199 }
00200 
00201 static const DWORD gsm_rates[] = { 8000, 11025, 22050, 44100, 48000, 96000 };
00202 #define NUM_RATES (sizeof(gsm_rates)/sizeof(*gsm_rates))
00203 
00204 /***********************************************************************
00205  *           GSM_FormatTagDetails
00206  *
00207  */
00208 static  LRESULT GSM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
00209 {
00210     static const WCHAR szPcm[]={'P','C','M',0};
00211     static const WCHAR szGsm[]={'G','S','M',' ','6','.','1','0',0};
00212 
00213     switch (dwQuery)
00214     {
00215     case ACM_FORMATTAGDETAILSF_INDEX:
00216     if (aftd->dwFormatTagIndex > 1) return ACMERR_NOTPOSSIBLE;
00217     break;
00218     case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
00219     if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN)
00220         {
00221             aftd->dwFormatTagIndex = 1;
00222         break;
00223     }
00224     /* fall thru */
00225     case ACM_FORMATTAGDETAILSF_FORMATTAG:
00226     switch (aftd->dwFormatTag)
00227         {
00228     case WAVE_FORMAT_PCM: aftd->dwFormatTagIndex = 0; break;
00229     case WAVE_FORMAT_GSM610: aftd->dwFormatTagIndex = 1; break;
00230     default: return ACMERR_NOTPOSSIBLE;
00231     }
00232     break;
00233     default:
00234     WARN("Unsupported query %08x\n", dwQuery);
00235     return MMSYSERR_NOTSUPPORTED;
00236     }
00237 
00238     aftd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
00239     switch (aftd->dwFormatTagIndex)
00240     {
00241     case 0:
00242     aftd->dwFormatTag = WAVE_FORMAT_PCM;
00243     aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
00244     aftd->cStandardFormats = NUM_RATES;
00245         lstrcpyW(aftd->szFormatTag, szPcm);
00246         break;
00247     case 1:
00248     aftd->dwFormatTag = WAVE_FORMAT_GSM610;
00249     aftd->cbFormatSize = sizeof(GSM610WAVEFORMAT);
00250     aftd->cStandardFormats = NUM_RATES;
00251         lstrcpyW(aftd->szFormatTag, szGsm);
00252     break;
00253     }
00254     return MMSYSERR_NOERROR;
00255 }
00256 
00257 /***********************************************************************
00258  *           GSM_FormatDetails
00259  *
00260  */
00261 static  LRESULT GSM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
00262 {
00263     switch (dwQuery)
00264     {
00265     case ACM_FORMATDETAILSF_FORMAT:
00266     if (!GSM_FormatValidate(afd->pwfx)) return ACMERR_NOTPOSSIBLE;
00267     break;
00268     case ACM_FORMATDETAILSF_INDEX:
00269     afd->pwfx->wFormatTag = afd->dwFormatTag;
00270     switch (afd->dwFormatTag)
00271         {
00272     case WAVE_FORMAT_PCM:
00273         if (afd->dwFormatIndex >= NUM_RATES) return ACMERR_NOTPOSSIBLE;
00274         afd->pwfx->nChannels = 1;
00275         afd->pwfx->nSamplesPerSec = gsm_rates[afd->dwFormatIndex];
00276         afd->pwfx->wBitsPerSample = 16;
00277         afd->pwfx->nBlockAlign = 2;
00278         afd->pwfx->nAvgBytesPerSec = afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
00279         break;
00280     case WAVE_FORMAT_GSM610:
00281             if (afd->dwFormatIndex >= NUM_RATES) return ACMERR_NOTPOSSIBLE;
00282         afd->pwfx->nChannels = 1;
00283         afd->pwfx->nSamplesPerSec = gsm_rates[afd->dwFormatIndex];
00284         afd->pwfx->wBitsPerSample = 0;
00285         afd->pwfx->nBlockAlign = 65;
00286             afd->pwfx->nAvgBytesPerSec = afd->pwfx->nSamplesPerSec * 65 / 320;
00287             afd->pwfx->cbSize = sizeof(WORD);
00288             ((GSM610WAVEFORMAT*)afd->pwfx)->wSamplesPerBlock = 320;
00289         break;
00290     default:
00291             WARN("Unsupported tag %08x\n", afd->dwFormatTag);
00292         return MMSYSERR_INVALPARAM;
00293     }
00294     break;
00295     default:
00296     WARN("Unsupported query %08x\n", dwQuery);
00297     return MMSYSERR_NOTSUPPORTED;
00298     }
00299     afd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
00300     afd->szFormat[0] = 0; /* let MSACM format this for us... */
00301 
00302     return MMSYSERR_NOERROR;
00303 }
00304 
00305 /***********************************************************************
00306  *           GSM_FormatSuggest
00307  *
00308  */
00309 static  LRESULT GSM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
00310 {
00311     /* some tests ... */
00312     if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
00313     adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
00314     !GSM_FormatValidate(adfs->pwfxSrc)) return ACMERR_NOTPOSSIBLE;
00315     /* FIXME: should do those tests against the real size (according to format tag */
00316 
00317     /* If no suggestion for destination, then copy source value */
00318     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS))
00319     adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels;
00320     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC))
00321         adfs->pwfxDst->nSamplesPerSec = adfs->pwfxSrc->nSamplesPerSec;
00322 
00323     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE))
00324     {
00325     if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
00326             adfs->pwfxDst->wBitsPerSample = 0;
00327         else
00328             adfs->pwfxDst->wBitsPerSample = 16;
00329     }
00330     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG))
00331     {
00332     switch (adfs->pwfxSrc->wFormatTag)
00333         {
00334         case WAVE_FORMAT_PCM: adfs->pwfxDst->wFormatTag = WAVE_FORMAT_GSM610; break;
00335         case WAVE_FORMAT_GSM610: adfs->pwfxDst->wFormatTag = WAVE_FORMAT_PCM; break;
00336         }
00337     }
00338 
00339     /* recompute other values */
00340     switch (adfs->pwfxDst->wFormatTag)
00341     {
00342     case WAVE_FORMAT_PCM:
00343         adfs->pwfxDst->nBlockAlign = 2;
00344         adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * 2;
00345         break;
00346     case WAVE_FORMAT_GSM610:
00347         if (adfs->pwfxDst->cbSize < sizeof(WORD))
00348             return ACMERR_NOTPOSSIBLE;
00349         adfs->pwfxDst->nBlockAlign = 65;
00350         adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * 65 / 320;
00351         ((GSM610WAVEFORMAT*)adfs->pwfxDst)->wSamplesPerBlock = 320;
00352         break;
00353     default:
00354         return ACMERR_NOTPOSSIBLE;
00355     }
00356 
00357     /* check if result is ok */
00358     if (!GSM_FormatValidate(adfs->pwfxDst)) return ACMERR_NOTPOSSIBLE;
00359     return MMSYSERR_NOERROR;
00360 }
00361 
00362 #ifdef SONAME_LIBGSM
00363 /***********************************************************************
00364  *           GSM_StreamOpen
00365  *
00366  */
00367 static  LRESULT GSM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
00368 {
00369     int used = 1;
00370     gsm r;
00371     if (!GSM_FormatValidate(adsi->pwfxSrc) || !GSM_FormatValidate(adsi->pwfxDst))
00372         return MMSYSERR_NOTSUPPORTED;
00373 
00374     if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec)
00375         return MMSYSERR_NOTSUPPORTED;
00376 
00377     if (!GSM_drvLoad()) return MMSYSERR_NOTSUPPORTED;
00378 
00379     r = pgsm_create();
00380     if (!r)
00381         return MMSYSERR_NOMEM;
00382     if (pgsm_option(r, GSM_OPT_WAV49, &used) < 0)
00383     {
00384         FIXME("Your libgsm library doesn't support GSM_OPT_WAV49\n");
00385         FIXME("Please recompile libgsm with WAV49 support\n");
00386         pgsm_destroy(r);
00387         return MMSYSERR_NOTSUPPORTED;
00388     }
00389     adsi->dwDriver = (DWORD_PTR)r;
00390     return MMSYSERR_NOERROR;
00391 }
00392 
00393 /***********************************************************************
00394  *           GSM_StreamClose
00395  *
00396  */
00397 static  LRESULT GSM_StreamClose(PACMDRVSTREAMINSTANCE adsi)
00398 {
00399     pgsm_destroy((gsm)adsi->dwDriver);
00400     return MMSYSERR_NOERROR;
00401 }
00402 
00403 /***********************************************************************
00404  *           GSM_StreamSize
00405  *
00406  */
00407 static  LRESULT GSM_StreamSize(const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMSIZE adss)
00408 {
00409     switch (adss->fdwSize)
00410     {
00411     case ACM_STREAMSIZEF_DESTINATION:
00412     /* cbDstLength => cbSrcLength */
00413     if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
00414              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_GSM610)
00415         {
00416         adss->cbSrcLength = adss->cbDstLength / 65 * 640;
00417     }
00418         else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_GSM610 &&
00419                  adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
00420         {
00421         adss->cbSrcLength = adss->cbDstLength / 640 * 65;
00422     }
00423         else
00424         {
00425         return MMSYSERR_NOTSUPPORTED;
00426     }
00427     return MMSYSERR_NOERROR;
00428     case ACM_STREAMSIZEF_SOURCE:
00429     /* cbSrcLength => cbDstLength */
00430     if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
00431              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_GSM610)
00432         {
00433         adss->cbDstLength = (adss->cbSrcLength + 639) / 640 * 65;
00434     }
00435         else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_GSM610 &&
00436                  adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
00437         {
00438         adss->cbDstLength = adss->cbSrcLength / 65 * 640;
00439     }
00440         else
00441         {
00442         return MMSYSERR_NOTSUPPORTED;
00443     }
00444     return MMSYSERR_NOERROR;
00445     default:
00446     WARN("Unsupported query %08x\n", adss->fdwSize);
00447     return MMSYSERR_NOTSUPPORTED;
00448     }
00449 }
00450 
00451 /***********************************************************************
00452  *           GSM_StreamConvert
00453  *
00454  */
00455 static LRESULT GSM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
00456 {
00457     gsm r = (gsm)adsi->dwDriver;
00458     DWORD nsrc = 0;
00459     DWORD ndst = 0;
00460     BYTE *src = adsh->pbSrc;
00461     BYTE *dst = adsh->pbDst;
00462     int odd = 0;
00463 
00464     if (adsh->fdwConvert &
00465     ~(ACM_STREAMCONVERTF_BLOCKALIGN|
00466       ACM_STREAMCONVERTF_END|
00467       ACM_STREAMCONVERTF_START))
00468     {
00469     FIXME("Unsupported fdwConvert (%08x), ignoring it\n", adsh->fdwConvert);
00470     }
00471 
00472     /* Reset the index to 0, just to be sure */
00473     pgsm_option(r, GSM_OPT_FRAME_INDEX, &odd);
00474 
00475     /* The native ms codec writes 65 bytes, and this requires 2 libgsm calls.
00476      * First 32 bytes are written, or 33 bytes read
00477      * Second 33 bytes are written, or 32 bytes read
00478      */
00479 
00480     /* Decode */
00481     if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_GSM610)
00482     {
00483         if (adsh->cbSrcLength / 65 * 640 > adsh->cbDstLength)
00484         {
00485              return ACMERR_NOTPOSSIBLE;
00486         }
00487 
00488         while (nsrc + 65 <= adsh->cbSrcLength)
00489         {
00490             /* Decode data */
00491             if (pgsm_decode(r, src + nsrc, (gsm_signal*)(dst + ndst)) < 0)
00492                 FIXME("Couldn't decode data\n");
00493             ndst += 320;
00494             nsrc += 33;
00495 
00496             if (pgsm_decode(r, src + nsrc, (gsm_signal*)(dst + ndst)) < 0)
00497                 FIXME("Couldn't decode data\n");
00498             ndst += 320;
00499             nsrc += 32;
00500         }
00501     }
00502     else
00503     {
00504         /* Testing a little seems to reveal that despite being able to fit
00505          * inside the buffer if ACM_STREAMCONVERTF_BLOCKALIGN is set
00506          * it still rounds up
00507          */
00508         if ((adsh->cbSrcLength + 639) / 640 * 65 > adsh->cbDstLength)
00509         {
00510             return ACMERR_NOTPOSSIBLE;
00511         }
00512 
00513         /* The packing algorythm writes 32 bytes, then 33 bytes,
00514          * and it seems to pad to align to 65 bytes always
00515          * adding extra data where necessary
00516          */
00517         while (nsrc + 640 <= adsh->cbSrcLength)
00518         {
00519             /* Encode data */
00520             pgsm_encode(r, (gsm_signal*)(src+nsrc), dst+ndst);
00521             nsrc += 320;
00522             ndst += 32;
00523             pgsm_encode(r, (gsm_signal*)(src+nsrc), dst+ndst);
00524             nsrc += 320;
00525             ndst += 33;
00526         }
00527 
00528         /* If ACM_STREAMCONVERTF_BLOCKALIGN isn't set pad with zeros */
00529         if (!(adsh->fdwConvert & ACM_STREAMCONVERTF_BLOCKALIGN) &&
00530             nsrc < adsh->cbSrcLength)
00531         {
00532             char emptiness[320];
00533             int todo = adsh->cbSrcLength - nsrc;
00534 
00535             if (todo > 320)
00536             {
00537                 pgsm_encode(r, (gsm_signal*)(src+nsrc), dst+ndst);
00538                 ndst += 32;
00539                 todo -= 320;
00540                 nsrc += 320;
00541 
00542                 memcpy(emptiness, src+nsrc, todo);
00543                 memset(emptiness + todo, 0, 320 - todo);
00544                 pgsm_encode(r, (gsm_signal*)emptiness, dst+ndst);
00545                 ndst += 33;
00546             }
00547             else
00548             {
00549                 memcpy(emptiness, src+nsrc, todo);
00550                 memset(emptiness + todo, 0, 320 - todo);
00551                 pgsm_encode(r, (gsm_signal*)emptiness, dst+ndst);
00552                 ndst += 32;
00553 
00554                 memset(emptiness, 0, todo);
00555                 pgsm_encode(r, (gsm_signal*)emptiness, dst+ndst);
00556                 ndst += 33;
00557             }
00558             nsrc = adsh->cbSrcLength;
00559         }
00560     }
00561 
00562     adsh->cbSrcLengthUsed = nsrc;
00563     adsh->cbDstLengthUsed = ndst;
00564     TRACE("%d(%d) -> %d(%d)\n", nsrc, adsh->cbSrcLength, ndst, adsh->cbDstLength);
00565     return MMSYSERR_NOERROR;
00566 }
00567 
00568 #endif
00569 
00570 /**************************************************************************
00571  *          GSM_DriverProc          [exported]
00572  */
00573 LRESULT CALLBACK GSM_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
00574                      LPARAM dwParam1, LPARAM dwParam2)
00575 {
00576     TRACE("(%08lx %p %04x %08lx %08lx);\n",
00577           dwDevID, hDriv, wMsg, dwParam1, dwParam2);
00578 
00579     switch (wMsg)
00580     {
00581     case DRV_LOAD:      return 1;
00582     case DRV_FREE:      return GSM_drvFree();
00583     case DRV_OPEN:      return 1;
00584     case DRV_CLOSE:     return 1;
00585     case DRV_ENABLE:        return 1;
00586     case DRV_DISABLE:       return 1;
00587     case DRV_QUERYCONFIGURE:    return 1;
00588     case DRV_CONFIGURE:     MessageBoxA(0, "GSM 06.10 codec", "Wine Driver", MB_OK); return 1;
00589     case DRV_INSTALL:       return DRVCNF_RESTART;
00590     case DRV_REMOVE:        return DRVCNF_RESTART;
00591 
00592     case ACMDM_DRIVER_NOTIFY:
00593     /* no caching from other ACM drivers is done so far */
00594     return MMSYSERR_NOERROR;
00595 
00596     case ACMDM_DRIVER_DETAILS:
00597     return GSM_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
00598 
00599     case ACMDM_FORMATTAG_DETAILS:
00600     return GSM_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
00601 
00602     case ACMDM_FORMAT_DETAILS:
00603     return GSM_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
00604 
00605     case ACMDM_FORMAT_SUGGEST:
00606     return GSM_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
00607 
00608 #ifdef SONAME_LIBGSM
00609     case ACMDM_STREAM_OPEN:
00610     return GSM_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
00611 
00612     case ACMDM_STREAM_CLOSE:
00613     return GSM_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
00614 
00615     case ACMDM_STREAM_SIZE:
00616     return GSM_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
00617 
00618     case ACMDM_STREAM_CONVERT:
00619     return GSM_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2);
00620 #else
00621     case ACMDM_STREAM_OPEN: ERR("libgsm support not compiled in!\n");
00622     case ACMDM_STREAM_CLOSE:
00623     case ACMDM_STREAM_SIZE:
00624     case ACMDM_STREAM_CONVERT:
00625         return MMSYSERR_NOTSUPPORTED;
00626 #endif
00627 
00628     case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
00629     case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
00630     /* this converter is not a hardware driver */
00631     case ACMDM_FILTERTAG_DETAILS:
00632     case ACMDM_FILTER_DETAILS:
00633     /* this converter is not a filter */
00634     case ACMDM_STREAM_RESET:
00635     /* only needed for asynchronous driver... we aren't, so just say it */
00636     return MMSYSERR_NOTSUPPORTED;
00637     case ACMDM_STREAM_PREPARE:
00638     case ACMDM_STREAM_UNPREPARE:
00639     /* nothing special to do here... so don't do anything */
00640     return MMSYSERR_NOERROR;
00641 
00642     default:
00643     return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
00644     }
00645 }

Generated on Sat May 26 2012 04:23:23 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.