📄 msadpcm.c
字号:
{ lSamp = 32767; } else if(lSamp < -32768) { lSamp = -32768; } // // lSamp contains the decoded sInput sample--now write it // out to the destination buffer // if(ucChannel == 0) { *psLeft++ = (short)lSamp; } else { *psRight++ = (short)lSamp; } // // ripple our previous samples down making the new psSamp1 // equal to the sample we just decoded // psSamp2[ucChannel] = psSamp1[ucChannel]; psSamp1[ucChannel] = (short)lSamp; } } // // if this is a short block, then fill the remainder of the output block // with silence. // if(usSamplesPerBlock < pMSADPCM->usSamplesPerBlock) { memset(psLeft, 0, (pMSADPCM->usSamplesPerBlock - usSamplesPerBlock) * 2); if(pMSADPCM->ucChannels == 2) { memset(psRight, 0, (pMSADPCM->usSamplesPerBlock - usSamplesPerBlock) * 2); } } // // we're done decoding the input data. return the number of samples // decoded. // return(usSamplesPerBlock);}//****************************************************************************//// Computes the first delta value for a MS ADPCM block.////****************************************************************************shortadpcmEncode4Bit_FirstDelta(short iCoef1, short iCoef2, short iP5, short iP4, short iP3, short iP2, short iP1){ long lTotal; short iRtn; long lTemp; // // use average of 3 predictions // lTemp = (((long)iP5 * iCoef2) + ((long)iP4 * iCoef1)) >> MSADPCM_CSCALE; lTotal = (lTemp > iP3) ? (lTemp - iP3) : (iP3 - lTemp); lTemp = (((long)iP4 * iCoef2) + ((long)iP3 * iCoef1)) >> MSADPCM_CSCALE; lTotal += (lTemp > iP2) ? (lTemp - iP2) : (iP2 - lTemp); lTemp = (((long)iP3 * iCoef2) + ((long)iP2 * iCoef1)) >> MSADPCM_CSCALE; lTotal += (lTemp > iP1) ? (lTemp - iP1) : (iP1 - lTemp); // // optimal iDelta is 1/4 of prediction error // iRtn = (short)(lTotal / 12); if(iRtn < MSADPCM_DELTA4_MIN) { iRtn = MSADPCM_DELTA4_MIN; } return(iRtn);}//****************************************************************************//// Encodes a block of 16-bit PCM into MS ADPCM.////****************************************************************************unsigned longadpcmEncode4Bit(tMSADPCM *pMSADPCM, short *psLeft, short *psRight, unsigned char *pucDst){ short *ppsSamples[2]; unsigned char pucBestPredictor[2]; unsigned long ppulTotalError[7][2]; short ppsFirstDelta[7][2]; short psDelta[2]; short psSamp1[2]; short psSamp2[2]; short sCoef1; short sCoef2; short sDelta; short sSample; short sOutput; long lSamp; unsigned long ulTemp; unsigned long ulTotalConverted; long lError; long lPrediction; unsigned char ucNextWrite = 0; unsigned char ucFirstNibble; unsigned short usSample; unsigned char ucChannel; unsigned char ucPredictor; // // save the pointers to the left and right channel data // ppsSamples[0] = psLeft; ppsSamples[1] = psRight; // // initialize the number of output bytes to zero // ulTotalConverted = 0; // // find the optimal predictor for each channel: to do this, we // must step through and encode using each coefficient set (one // at a time) and determine which one has the least error from // the original data. the one with the least error is then used // for the final encode (the 8th pass done below). // // NOTE: keeping the encoded data of the one that has the least // error at all times is an obvious optimization that should be // done. in this way, we only need to do 7 passes instead of 8. // for(ucPredictor = 0; ucPredictor < 7; ucPredictor++) { // // copy the coefficient pair for the current coefficient set // we are using into more convenient/cheaper variables // sCoef1 = psCoefficient1[ucPredictor]; sCoef2 = psCoefficient2[ucPredictor]; // // now choose the first iDelta and setup the first two samples // for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++) { // // reset total error calculation for new block // ppulTotalError[ucPredictor][ucChannel] = 0; // // first 2 samples will come from real data--compute // starting from there // psSamp1[ucChannel] = ppsSamples[ucChannel][1]; psSamp2[ucChannel] = ppsSamples[ucChannel][0]; // // calculate initial iDelta // sDelta = adpcmEncode4Bit_FirstDelta(sCoef1, sCoef2, ppsSamples[ucChannel][0], ppsSamples[ucChannel][1], ppsSamples[ucChannel][2], ppsSamples[ucChannel][3], ppsSamples[ucChannel][4]); psDelta[ucChannel] = sDelta; ppsFirstDelta[ucPredictor][ucChannel] = sDelta; } // // now encode the rest of the PCM data in this block--note // we start 2 samples ahead because the first two samples are // simply copied into the ADPCM block header... // for(usSample = 2; usSample < pMSADPCM->usSamplesPerBlock; usSample++) { // // each channel gets encoded independently... obviously. // for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++) { // // yes, copy into cheaper variables because we access // them a lot // sDelta = psDelta[ucChannel]; // // calculate the prediction based on the previous two // samples // lPrediction = (((long)psSamp1[ucChannel] * sCoef1) + ((long)psSamp2[ucChannel] * sCoef2)) >> MSADPCM_CSCALE; // // grab the sample (for the current channel) to encode // from the source // sSample = ppsSamples[ucChannel][usSample]; // // encode it // lError = (long)sSample - lPrediction; sOutput = (short)(lError / sDelta); if(sOutput > MSADPCM_OUTPUT4_MAX) { sOutput = MSADPCM_OUTPUT4_MAX; } else if(sOutput < MSADPCM_OUTPUT4_MIN) { sOutput = MSADPCM_OUTPUT4_MIN; } lSamp = lPrediction + ((long)sDelta * sOutput); if(lSamp > 32767) { lSamp = 32767; } else if(lSamp < -32768) { lSamp = -32768; } // // compute the next iDelta // sDelta = (short)((psP4[sOutput & 15] * (long)sDelta) >> MSADPCM_PSCALE); if(sDelta < MSADPCM_DELTA4_MIN) { sDelta = MSADPCM_DELTA4_MIN; } // // save updated values for this channel back into the // original arrays... // psDelta[ucChannel] = sDelta; psSamp2[ucChannel] = psSamp1[ucChannel]; psSamp1[ucChannel] = (short)lSamp; // // keep a running status on the error for the current // coefficient pair for this channel // lError = lSamp - sSample; ppulTotalError[ucPredictor][ucChannel] += (lError * lError) >> 7; } } } // // WHEW! we have now made 7 passes over the data and calculated // the error for each--so it's time to find the one that produced // the lowest error and use that predictor (this is for each // channel of course) // for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++) { pucBestPredictor[ucChannel] = 0; ulTemp = ppulTotalError[0][ucChannel]; for(ucPredictor = 1; ucPredictor < 7; ucPredictor++) { if(ppulTotalError[ucPredictor][ucChannel] < ulTemp) { pucBestPredictor[ucChannel] = ucPredictor; ulTemp = ppulTotalError[ucPredictor][ucChannel]; } } } // // grab first iDelta from our precomputed first deltas that we // calculated above // for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++) { ucPredictor = pucBestPredictor[ucChannel]; psDelta[ucChannel] = ppsFirstDelta[ucPredictor][ucChannel]; } // // get the first two samples from the source data (so we can write // them into the ADPCM block header and use them in our prediction // calculation when encoding the rest of the data). // for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++) { psSamp2[ucChannel] = ppsSamples[ucChannel][0]; psSamp1[ucChannel] = ppsSamples[ucChannel][1]; } // // write the block header for the encoded data // // the block header is composed of the following data: // 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 * nChannels) bytes of header information // // so first write the 1 byte predictor for each channel into the // destination buffer // for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++) { *pucDst++ = pucBestPredictor[ucChannel]; } // // now write the 2 byte delta per channel... // for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++) { *pucDst++ = psDelta[ucChannel] & 255; *pucDst++ = psDelta[ucChannel] >> 8; } // // finally, write the first two samples (2 bytes each per channel) // for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++) { *pucDst++ = psSamp1[ucChannel] & 255; *pucDst++ = psSamp1[ucChannel] >> 8; } for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++) { *pucDst++ = psSamp2[ucChannel] & 255; *pucDst++ = psSamp2[ucChannel] >> 8; } // // the number of bytes that we have written to the destination // buffer is (7 * nChannels)--so add this to our total number of // bytes written to the destination.. for our return value. // ulTotalConverted += pMSADPCM->ucChannels * 7; // // we have written the header for this block--now write the data // chunk (which consists of a bunch of encoded nibbles). note that // we start our count at 2 because we already wrote the first // two samples into the destination buffer as part of the header // ucFirstNibble = 1; for(usSample = 2; usSample < pMSADPCM->usSamplesPerBlock; usSample++) { // // each channel gets encoded independently... obviously. // for(ucChannel = 0; ucChannel < pMSADPCM->ucChannels; ucChannel++) { // // use our chosen best predictor and grab the coefficient // pair to use for this channel... // ucPredictor = pucBestPredictor[ucChannel]; sCoef1 = psCoefficient1[ucPredictor]; sCoef2 = psCoefficient2[ucPredictor]; // // copy into cheaper variables because we access them a lot // sDelta = psDelta[ucChannel]; // // calculate the prediction based on the previous two samples // lPrediction = (((long)psSamp1[ucChannel] * sCoef1) + ((long)psSamp2[ucChannel] * sCoef2)) >> MSADPCM_CSCALE; // // grab the sample to encode // sSample = ppsSamples[ucChannel][usSample]; // // encode the sample // lError = (long)sSample - lPrediction; sOutput = (short)(lError / sDelta); if(sOutput > MSADPCM_OUTPUT4_MAX) { sOutput = MSADPCM_OUTPUT4_MAX; } else if(sOutput < MSADPCM_OUTPUT4_MIN) { sOutput = MSADPCM_OUTPUT4_MIN; } lSamp = lPrediction + ((long)sDelta * sOutput); if(lSamp > 32767) { lSamp = 32767; } else if(lSamp < -32768)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -