📄 acelpnet.c
字号:
//****************************************************************************//// ACELPNET.C - Codec interface driver for the ACELP.net decoder.//// This material is strictly confidential and shall remain as such.//// Copyright (c) 1999 VoiceAge Corporation. All Rights Reserved. Any// unauthorized use, distribution, reproduction or storage of this material or// any part thereof is strictly prohibited.//// ACELP is registered trademark of VoiceAge Corporation in Canada and/or// other countries.//// Copyright (c) 2000,2001 Cirrus Logic, Inc.////****************************************************************************#include "globals.h"#ifdef SUPPORT_ACELPNET#include "acelpnet/acelp.h"#include "acelpnet/acelpdec.h"#include "buffer/buffer.h"#include "src/src.h"//****************************************************************************//// The name of this codec.////****************************************************************************static const unsigned short pusCodecName[] ={ 'A', 'N', 'E', 'T', 'A', 'C', 'E', 'L', 'P', '.', 'n', 'e', 't', '\0'};//****************************************************************************//// A structure which defines the persistent state of the ACELP.net decoder.////****************************************************************************typedef struct{ // // The persistent internal state of the ACELP.net decoder library. // tANETInstance sANETInstance; // // The file from which we read data. // tFile *pFile; // // A buffer to contain the encoded ACELP.net audio. // char pcEncodedData[512 + 64]; // // A buffer to contain the decoded ACELP.net audio. // short psPCM[(L_FRAME_5K0 * 4) + NUMTAPS - 1]; // // The buffer to which we write decoded ACELP.net data. // BufferState *pOutput; // // The length of the encoded ACELP.net file. // unsigned long ulLength; // // The number of bytes in pcEncodedData which contain valid encoded // ACELP.net audio. // unsigned short usValid; // // The offset into pcEncodedData of the next ACELP.net frame to be // processed. // unsigned short usOffset; // // The length of the file in milliseconds. // unsigned long ulTimeLength; // // The number of samples that have been played. // unsigned long ulTimePos; // // The current offset into the ACELP.net file, indicating the number of // bytes which have been read from the file into the encoded data buffer. // unsigned long ulFilePos; // // The sample rate of the file. // unsigned short usSampleRate; // // The bit rate of the file. // unsigned short usBitRate; // // The number of samples per frame. // unsigned short usSamplesPerFrame;} tANET;//****************************************************************************//// The number of bits in the various fields of a frame of a 5kbps stream.////****************************************************************************#ifdef SUPPORT_ACELPNET_5K0static const char bit_5k0[NB_PRM_5K0] = BIT_5K0;#endif//****************************************************************************//// The number of bits in the various fields of a frame of a 6.5kbps stream.////****************************************************************************#ifdef SUPPORT_ACELPNET_6K5static const char bit_6k5[NB_PRM_6K5] = BIT_6K5;#endif//****************************************************************************//// The number of bits in the various fields of a frame of a 8.5kbps stream.////****************************************************************************#ifdef SUPPORT_ACELPNET_8K5static const char bit_8k5[NB_PRM_8K5] = BIT_8K5;#endif//****************************************************************************//// The number of bits in the various fields of a frame of a 16kbps stream.////****************************************************************************#ifdef SUPPORT_ACELPNET_16K0static const char bit_16k0[NB_PRM_16K0] = BIT_16K0;#endif//****************************************************************************//// copybits performs a bit copy from one arbitrary bit position to another.////****************************************************************************static voidcopybits(unsigned char *toPtr, unsigned char *fromPtr, int bitOffsetTo, int bitOffsetFrom, int numBits){ int i; int currBitOffsetTo, currBitOffsetFrom; int currBitOffsetToMod8, currBitOffsetFromMod8; unsigned char *currToPtr, *currFromPtr; currToPtr = toPtr + (bitOffsetTo >> 3); currBitOffsetTo = bitOffsetTo; currBitOffsetToMod8 = currBitOffsetTo % 8; currFromPtr = fromPtr + (bitOffsetFrom >> 3); currBitOffsetFrom = bitOffsetFrom; currBitOffsetFromMod8 = currBitOffsetFrom % 8; for(i = 0; i < numBits; i++) { if((0x01 & ((*currFromPtr) >> currBitOffsetFromMod8)) == 0x01) { (*currToPtr) |= ((unsigned char)(1 << currBitOffsetToMod8)); } else { (*currToPtr) &= ((unsigned char)~(1 << currBitOffsetToMod8)); } if(++currBitOffsetFromMod8 == 8) { currBitOffsetFromMod8 = 0; currFromPtr++; } if(++currBitOffsetToMod8 == 8) { currBitOffsetToMod8 = 0; currToPtr++; } }}//****************************************************************************//// binary2prm converts the input bitstream into a parameter vector, based on// the bitrate of the input bitstream.////****************************************************************************static voidbinary2prm(short prm[], unsigned char bits[], int numPrm, int startPrm, const char bitsTable[]){ int i, totBits = 0; unsigned char tmpPrm[4]; for(i = startPrm; i < numPrm; i++) { *((int *)tmpPrm) = 0; copybits(tmpPrm, bits, 0, totBits, bitsTable[i]); prm[i] = (short)(*((int *)(tmpPrm))); totBits += bitsTable[i]; }}//****************************************************************************//// Decode5k0 decodes two frames from a 5kbps stream.////****************************************************************************#ifdef SUPPORT_ACELPNET_5K0static longDecode5k0(tANET *pANET, short *psOutput){ short sPRM[NB_PRM_5K0]; if((pANET->usOffset + BLOCK_ALIGNMENT_5K0) > pANET->usValid) { pANET->usOffset = pANET->usValid; return(0); } binary2prm(sPRM, (unsigned char *)pANET->pcEncodedData + pANET->usOffset, NB_PRM_5K0, 0, bit_5k0); decoder_5k(sPRM, psOutput, 0, &(pANET->sANETInstance)); copybits((unsigned char *)pANET->pcEncodedData + pANET->usOffset, (unsigned char *)pANET->pcEncodedData + pANET->usOffset, 0, 148, 148); binary2prm(sPRM, (unsigned char *)pANET->pcEncodedData + pANET->usOffset, NB_PRM_5K0, 0, bit_5k0); decoder_5k(sPRM, psOutput + L_FRAME_5K0, 0, &(pANET->sANETInstance)); pANET->usOffset += BLOCK_ALIGNMENT_5K0; return(L_FRAME_5K0 * 2);}#endif//****************************************************************************//// Decode6k5 decodes two frames from a 6.5kbps stream.////****************************************************************************#ifdef SUPPORT_ACELPNET_6K5static longDecode6k5(tANET *pANET, short *psOutput){ short sPRM[NB_PRM_6K5]; if((pANET->usOffset + BLOCK_ALIGNMENT_6K5) > pANET->usValid) { pANET->usOffset = pANET->usValid; return(0); } sPRM[0] = RATE_6K5; binary2prm(sPRM, (unsigned char *)pANET->pcEncodedData + pANET->usOffset, NB_PRM_6K5, 1, bit_6k5); dec_swt(sPRM, psOutput, 0, &(pANET->sANETInstance)); copybits((unsigned char *)pANET->pcEncodedData + pANET->usOffset, (unsigned char *)pANET->pcEncodedData + pANET->usOffset, 0, 116, 116); binary2prm(sPRM, (unsigned char *)pANET->pcEncodedData + pANET->usOffset, NB_PRM_6K5, 1, bit_6k5); dec_swt(sPRM, psOutput + L_FRAME_6K5, 0, &(pANET->sANETInstance)); pANET->usOffset += BLOCK_ALIGNMENT_6K5; return(L_FRAME_6K5 * 2);}#endif//****************************************************************************//// Decode8k5 decodes two frames from a 8.5kbps stream.////****************************************************************************#ifdef SUPPORT_ACELPNET_8K5static longDecode8k5(tANET *pANET, short *psOutput){ short sPRM[NB_PRM_8K5]; if((pANET->usOffset + (BLOCK_ALIGNMENT_8K5 * 2)) > pANET->usValid) { pANET->usOffset = pANET->usValid; return(0); } sPRM[0] = RATE_8K5; binary2prm(sPRM, (unsigned char *)pANET->pcEncodedData + pANET->usOffset, NB_PRM_8K5, 1, bit_8k5); dec_swt(sPRM, psOutput, 0, &(pANET->sANETInstance)); pANET->usOffset += BLOCK_ALIGNMENT_8K5; binary2prm(sPRM, (unsigned char *)pANET->pcEncodedData + pANET->usOffset, NB_PRM_8K5, 1, bit_8k5); dec_swt(sPRM, psOutput + L_FRAME_8K5, 0, &(pANET->sANETInstance)); pANET->usOffset += BLOCK_ALIGNMENT_8K5; return(L_FRAME_8K5 * 2);}#endif//****************************************************************************//// Decode16k0 decodes two frames from a 16kbps stream.////****************************************************************************#ifdef SUPPORT_ACELPNET_16K0static longDecode16k0(tANET *pANET, short *psOutput){ short sPRM[NB_PRM_16K0]; if((pANET->usOffset + (BLOCK_ALIGNMENT_16K0 * 2)) > pANET->usValid) { pANET->usOffset = pANET->usValid; return(0); } binary2prm(sPRM, (unsigned char *)pANET->pcEncodedData + pANET->usOffset, NB_PRM_16K0, 0, bit_16k0); decod_wb(sPRM, psOutput, 0, &(pANET->sANETInstance)); pANET->usOffset += BLOCK_ALIGNMENT_16K0; binary2prm(sPRM, (unsigned char *)pANET->pcEncodedData + pANET->usOffset, NB_PRM_16K0, 0, bit_16k0); decod_wb(sPRM, psOutput + L_FRAME_16K0, 0, &(pANET->sANETInstance)); pANET->usOffset += BLOCK_ALIGNMENT_16K0; return(L_FRAME_16K0 * 2);}#endif//****************************************************************************//// The codec plug-in entry point for the ACELP.net decoder.////****************************************************************************unsigned longACELPnetIoctl(unsigned long ulIoctl, unsigned long ulParam1, unsigned long ulParam2, unsigned long ulParam3, unsigned long ulParam4){ // // Determine what to do based on the specified IOCTL. // switch(ulIoctl) { // // Return the name for this codec. // case IOCTL_CODEC_GETNAME: { const unsigned short **ppusName; // // The second parameter is a pointer for the name. // ppusName = (const unsigned short **)ulParam2; // // Return the name of this codec. The first four characters are // the short name and the string starting at the fifth character // is the long name. // *ppusName = pusCodecName; // // Success. // return(1); } // // Return the name of the artist. // case IOCTL_CODEC_GETARTIST: { unsigned short **ppusName; // // The second parameter is a pointer for the name. // ppusName = (unsigned short **)ulParam2; // // There is no way to store the artist name in an ACELP.net file. // *ppusName = 0; // // Success. // return(1); } // // Return the name of the song // case IOCTL_CODEC_GETTITLE: { unsigned short **ppusName; // // The second parameter is a pointer for the name. // ppusName = (unsigned short **)ulParam2; // // There is no way to store the song title in an ACELP.net file. // *ppusName = 0; // // Success. // return(1); } // // Return the bitrate at which this file is encoded. // case IOCTL_CODEC_GETBITRATE: { unsigned long *pulBitRate; tANET *pANET; // // The first parameter is a pointer to the ACELP.net persistent // data. // pANET = (tANET *)ulParam1; // // The second parameter is a pointer for the bitrate. // pulBitRate = (unsigned long *)ulParam2; // // Return the bitrate of the file. // *pulBitRate = pANET->usBitRate; // // Success. // return(1); } // // Return the sample rate at which this file is encoded. // case IOCTL_CODEC_GETSAMPLERATE: { unsigned long *pulSampleRate; tANET *pANET; // // The first parameter is a pointer to the ACELP.net persistent // data. // pANET = (tANET *)ulParam1; // // The second parameter is a pointer for the sample rate. // pulSampleRate = (unsigned long *)ulParam2; // // Return the sample rate of the file. // *pulSampleRate = pANET->usSampleRate; // // Success. // return(1); } //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -