⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msadpcm.c

📁 基于EP7312的MP3播放器源代码,包括MCU和PC端代码.
💻 C
📖 第 1 页 / 共 5 页
字号:
//****************************************************************************//// MSADPCM.C - Codec interface driver for the Microsoft ADPCM encoder/decoder.//// Copyright (c) 2000,2001 Cirrus Logic, Inc.////  msadpcm.c////   (C) Copyright Microsoft Corp. 1993.  All rights reserved.////   You have a royalty-free right to use, modify, reproduce and //   distribute the Sample Files (and/or any modified version) in //   any way you find useful, provided that you agree that //   Microsoft has no warranty obligations or liability for any //   Sample Application Files which are modified. ////   If you did not get this from Microsoft Sources, then it may not be the//   most current version.  This sample code in particular will be updated//   and include more documentation.  ////   Sources are://   	The MM Sys File Transfer BBS: The phone number is 206 936-4082.//      CompuServe: WINSDK forum, MDK section.//      Anonymous FTP from ftp.uu.net vendors\microsoft\multimedia////****************************************************************************#include "globals.h"#ifdef SUPPORT_MSADPCM#include "buffer/buffer.h"#include "src/src.h"//****************************************************************************//// The name of this codec.////****************************************************************************static const unsigned short pusCodecName[] ={    'A', 'P', 'C', 'M', 'M', 'i', 'c', 'r', 'o', 's', 'o', 'f',    't', ' ', 'A', 'D', 'P', 'C', 'M', '\0'};//****************************************************************************//// This structure contains the coefficients used by the MS ADPCM algorithm as// stored in the wave format structure in the "fmt " chunk of the WAVE file.////****************************************************************************typedef struct{    short iCoef1;    short iCoef2;} ADPCMCoefSet;//****************************************************************************//// This structure contains the definition of the wave format structure as// stored in the "fmt " chunk of the WAVE file.  Note that this is packed// to avoid having the compiler insert 2 bytes of padding between wNumCoef// and aCoef.////****************************************************************************#if defined(sdt25) || defined(ads)typedef __packed struct#elsetypedef struct#endif{    unsigned short wFormatTag;    unsigned short nChannels;    unsigned long nSamplesPerSec;    unsigned long nAvgBytesPerSec;    unsigned short nBlockAlign;    unsigned short wBitsPerSample;    unsigned short cbSize;    unsigned short wSamplesPerBlock;    unsigned short wNumCoef;    ADPCMCoefSet aCoef[7];#if defined(gcc)} __attribute ((packed)) ADPCMWaveFormat;#else} ADPCMWaveFormat;#endif//****************************************************************************////  constants used by the Microsoft 4 Bit ADPCM algorithm////****************************************************************************#define MSADPCM_CSCALE                          8#define MSADPCM_PSCALE                          8#define MSADPCM_CSCALE_NUM                      (1 << MSADPCM_CSCALE)#define MSADPCM_PSCALE_NUM                      (1 << MSADPCM_PSCALE)#define MSADPCM_DELTA4_MIN                      16#define MSADPCM_OUTPUT4_MAX                     7#define MSADPCM_OUTPUT4_MIN                     -8//****************************************************************************//// The maximum number of PCM samples per block which is supported by the// decoder.////****************************************************************************#define MSADPCM_MAX_PCM_LENGTH                  2048//****************************************************************************//// The coefficient pairs that should be in the wave format header for the// Microsoft 4 Bit ADPCM algorithm.////****************************************************************************static const short psCoefficient1[] = { 256,  512,  0, 192, 240,  460,  392 };static const short psCoefficient2[] = {   0, -256,  0,  64,   0, -208, -232 };//****************************************************************************//// Fixed point Delta adaption table:////     Next Delta = Delta * psP4[ this output ] / MSADPCM_PSCALE////****************************************************************************static const short psP4[] = { 230, 230, 230, 230, 307, 409, 512, 614,                              768, 614, 512, 409, 307, 230, 230, 230 };//****************************************************************************//// A structure which defines the perisitent state of the MS ADPCM encoder/// decoder.////****************************************************************************typedef struct{    //    // The file containing the encoded data.    //    tFile *pFile;    //    // The buffer containing MS ADPCM data.    //    unsigned char pucEncodedData[4096 + 512];    //    // The buffers containing PCM data.    //    short psLeft[(MSADPCM_MAX_PCM_LENGTH * 2) + NUMTAPS - 1];    short psRight[(MSADPCM_MAX_PCM_LENGTH * 2) + NUMTAPS - 1];    //    // The buffer from which we read the PCM audio stream when encoding or to    // which we write the PCM audio stream when decoding.    //    BufferState *pBuffer;    //    // The current offset into the encoded data buffer.    //    unsigned short usOffset;    //    // The number of valid bytes in the encoded data buffer.    //    unsigned short usValid;    //    // The offset into the file of the first byte of encoded data.    //    unsigned long ulDataStart;    //    // The length of the encoded data.    //    unsigned long ulLength;    //    // The number of bytes of encoded data remaining in the file.    //    unsigned long ulDataValid;    //    // The bit rate of the encoded file.    //    unsigned long ulBitRate;    //    // The sample rate of the decoded file.    //    unsigned short usSampleRate;    //    // The number of channels of audio in the file.    //    unsigned char ucChannels;    //    // An unused byte to pad the next member to a word boundary.    //    unsigned char ucUnused;    //    // The number of bytes in each encoded block of audio.    //    unsigned short usBytesPerBlock;    //    // The number of samples in each encoded block of audio.    //    unsigned short usSamplesPerBlock;    //    // The length of the file in milliseconds.    //    unsigned long ulTimeLength;    //    // The number of samples that have been encoded/decoded.    //    unsigned long ulTimePos;} tMSADPCM;//****************************************************************************//// Decodes a block of MS ADPCM into 16-bit PCM.////****************************************************************************unsigned longadpcmDecode4Bit(tMSADPCM *pMSADPCM, unsigned char *pucSrc, short *psLeft,                short *psRight, unsigned long ulSrcLen){    short   sInput;    short   sNextInput = 0;    short   sFirstNibble;    short   sDelta;    long    lSamp;    long    lPrediction;    unsigned char    ucChannel;    unsigned short   usSample;    unsigned short   usSamplesPerBlock;    short   psSamp1[2];    short   psSamp2[2];    short   psCoef1[2];    short   psCoef2[2];    short   psDelta[2];    //    //  the first thing we need to do with each block of ADPCM data is    //  to read the header which consists of 7 bytes of data per channel.    //  so our first check is to make sure that we have _at least_    //  enough input data for a complete ADPCM block header--if there    //  is not enough data for the header, then exit.    //    //  the header looks like this:    //      1 byte predictor per channel    //      2 byte delta per channel    //      2 byte first sample per channel    //      2 byte second sample per channel    //    //  this gives us (7 * pMSADPCM->ucChannels) bytes of header information.    //  note that as long as there is _at least_ (7 * pMSADPCM->ucChannels) of    //  header info, we will grab the two samples from the header (and if no    //  data exists following the header we will exit in the decode    //  loop below).    //    if(ulSrcLen < (pMSADPCM->ucChannels * 7))    {        return(0);    }                //    //  grab and validate the predictor for each channel    //    for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++)    {        unsigned char bPredictor;        bPredictor = *pucSrc++;        if(bPredictor >= 7)        {            //            //  the predictor is out of range--this is considered a            //  fatal error with the ADPCM data, so we fail by returning            //  zero bytes decoded            //            return(0);        }        //        //  get the coefficients for the predictor index        //        psCoef1[ucChannel] = psCoefficient1[bPredictor];        psCoef2[ucChannel] = psCoefficient2[bPredictor];    }            //    //  get the starting delta for each channel    //    for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++)    {        psDelta[ucChannel] = pucSrc[0] | (pucSrc[1] << 8);        pucSrc += 2;    }    //    //  get the sample just previous to the first encoded sample per    //  channel    //    for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++)    {        psSamp1[ucChannel] = pucSrc[0] | (pucSrc[1] << 8);        pucSrc += 2;    }    //    //  get the sample previous to psSamp1[x] per channel    //    for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++)    {        psSamp2[ucChannel] = pucSrc[0] | (pucSrc[1] << 8);        pucSrc += 2;    }    //    //  write out first 2 samples for each channel.    //    //  NOTE: the samples are written to the destination PCM buffer    //  in the _reverse_ order that they are in the header block:    //  remember that psSamp2[x] is the _previous_ sample to psSamp1[x].    //    *psLeft++ = psSamp2[0];    *psLeft++ = psSamp1[0];    if(pMSADPCM->ucChannels == 2)    {        *psRight++ = psSamp2[1];        *psRight++ = psSamp1[1];    }    //    //  determine the number of samples to be decoded.  this could be less than    //  the number specified in the wave header at the end of the file.    //    usSamplesPerBlock = (((ulSrcLen - (pMSADPCM->ucChannels * 7)) * 2) /                         pMSADPCM->ucChannels) + 2;    if(usSamplesPerBlock > pMSADPCM->usSamplesPerBlock)    {        usSamplesPerBlock = pMSADPCM->usSamplesPerBlock;    }    //    //  we now need to decode the 'data' section of the ADPCM block.    //  this consists of packed 4 bit nibbles.    //    //  NOTE: we start our count for the number of data bytes to decode    //  at 2 because we have already decoded the first 2 samples in    //  this block.    //    sFirstNibble = 1;    for(usSample = 2; usSample < usSamplesPerBlock; usSample++)    {        for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++)        {            if (sFirstNibble)            {                //                //  grab the next two nibbles and create sign extended                //  integers out of them:                //                //      sInput is the first nibble to decode                //      sNextInput will be the next nibble decoded                //                sNextInput  = (short)*pucSrc++;                sInput = (sNextInput << 24) >> 28;                sNextInput = (sNextInput << 28) >> 28;                sFirstNibble = 0;            }            else            {                //                //  put the next sign extended nibble into sInput and                //  decode it--also set sFirstNibble back to 1 so we                //  will read another byte from the source stream on                //  the next iteration...                //                sInput = sNextInput;                sFirstNibble = 1;            }            //            //  compute the next Adaptive Scale Factor (ASF) and put            //  this value in psDelta for the current channel.            //            sDelta = psDelta[ucChannel];            psDelta[ucChannel] = (short)((psP4[sInput & 15] * (long)sDelta) >>                                         MSADPCM_PSCALE);            if(psDelta[ucChannel] < MSADPCM_DELTA4_MIN)            {                psDelta[ucChannel] = MSADPCM_DELTA4_MIN;            }            //            //  decode sInput (the sign extended 4 bit nibble)--there are            //  two steps to this:            //            //  1.  predict the next sample using the previous two            //      samples and the predictor coefficients:            //            //      Prediction = (psSamp1[channel] * psCoef1[channel] +             //              psSamp2[channel] * psCoef2[channel]) / 256;            //            //  2.  reconstruct the original PCM sample using the encoded            //      sample (sInput), the Adaptive Scale Factor (psDelta)            //      and the prediction value computed in step 1 above.            //            //      Sample = (sInput * psDelta[channel]) + Prediction;            //            lPrediction = (((long)psSamp1[ucChannel] *                            (long)psCoef1[ucChannel]) +                           ((long)psSamp2[ucChannel] *                            (long)psCoef2[ucChannel])) >>                          MSADPCM_CSCALE;            lSamp = ((long)sInput * (long)sDelta) + lPrediction;            //            //  now we need to clamp lSamp to [-32768..32767]--this value            //  will then be a valid 16 bit sample.            //            if(lSamp > 32767)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -