📄 msadpcm.c
字号:
//****************************************************************************//// 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 + -