📄 pmp3_dec.c
字号:
if (!bitstreamDataToProcess) goto return_decode;
if (OkDecoder < 3)
{
//byfsh
OkDecoder++;
memset(pMP3->psLeft, 0, MP3_PCM_BUFFER_SIZE);
memset(pMP3->psRight, 0, MP3_PCM_BUFFER_SIZE);
return (1); ///ERROR
}
//当采样率小于32K时帧长为576,否则为1152
lLength = pMP3->usSampleRate >= 32000 ? 1152 : 576;
pMP3->ulTimePos += lLength;
if (pMP3->ucChannels == 1)
{
int i;
for (i = 0;i < lLength;i++)
pMP3->psRight[i] = pMP3->psLeft[i];
}
//输出------------------------------------
OutLength = lLength;
//成功
return(1);
return_decode:
{
memset(pMP3->psLeft, 0, MP3_PCM_BUFFER_SIZE);
memset(pMP3->psRight, 0, MP3_PCM_BUFFER_SIZE);
return (0); ///ERROR
}
}
OutLength = 1152;
return (0); ///ERROR
}
// Prepare the codec to decode a file.
case SUBFN_CODEC_OPEN_DEC:
{
tMP3 *pMP3;
long int test;
unsigned char mp2headercheck;
bitstreamDataToProcess = (-1);//ADD BY VINCENT.
// The first parameter is a pointer to the MP3 persistent state.
pMP3 = (tMP3 *)ulParam1;
pMP3->workspace = &AudioDecoders[0];
pMP3->pmInstance = (tmInstance *)((unsigned long)pMP3 + sizeof(tMP3));
pMP3->pmScratch = (tmScratch *)((unsigned long)pMP3->pmInstance + sizeof(tmInstance));
test = (((unsigned long)pMP3->pmScratch + sizeof(tmScratch)) & 0xFFFF) ;
////////////////////////////////////////////////////////////////////
test = GetHeaderPosition(pMP3);
if (test == 2)
return 2;
else if (test == 0)
return 0;
pMP3->workspace->instancestate = pMP3->pmInstance;
pMP3->workspace->scratch = pMP3->pmScratch;
pMP3->workspace->formats->outputFormats = OUTPUT_FORMAT_16BIT | OUTPUT_FORMAT_CHANNEL_COUNT_MASK; // All channels
pMP3->workspace->formats->decoderFeatures = DECODER_FEATURE_NONE;
pMP3->status = pMP3->workspace->Decoder->DecoderRequirements(pMP3->workspace->Decoder->DecoderReference,
pMP3->workspace->requirements,
pMP3->workspace->formats);
pMP3->ulLength = (unsigned long)RKFIO_FLength(pRawFileCache) - pMP3->ulFirstFrame;
if ((pMP3->status == kDecoderStatus_NoError) || (pMP3->status == kDecoderStatus_UnsupportedFeature))
{
pMP3->workspace->handle = (oDecoderHandle *)pMP3->workspace->Decoder->DecoderCreate(pMP3->workspace->Decoder->DecoderReference,
pMP3->workspace->instancestate,
pMP3->workspace->scratch,
pMP3->workspace->formats);
}
pMP3->status = pMP3->workspace->Decoder->DecoderOpenBitstream(pMP3->workspace->handle,
pMP3->workspace->scratch,
&(pMP3->bitstream),
pMP3->workspace->formats);
RKFIO_FSeek(pRawFileCache, pMP3->ulFirstFrame, 0);
bitstreamDataToProcess = -1;
buffer_size = 1500;
// put data into the buffer at first
RKFIO_FRead(pRawFileCache, pENCODED_DATA, buffer_size);
pMP3->bitstream.data = pENCODED_DATA; // buffer is global variable.
pMP3->bitstream.dataLength = buffer_size;
pMP3->bitstream.dataOffset = 0;
pMP3->bitstream.dataRequired = pMP3->workspace->requirements->maxInputSize;
mp2headercheck = 0;
do
{
FillBitstream(pMP3, 0);
if (!bitstreamDataToProcess) break;
pMP3->status = pMP3->workspace->Decoder->DecodeHeader(pMP3->workspace->handle,
pMP3->workspace->scratch,
&(pMP3->bitstream));
}
while ((pMP3->status != kDecoderStatus_NoError && bitstreamDataToProcess));
if (pMP3->status != 0)
{
return(0);
}
if (!bitstreamDataToProcess)
{
return(1);
}
if (pMP3->status == kDecoderStatus_NoError) FirstHeaderDecoded = 1;
//////////////////////////////////////////////////
CountToSkip = 0;
ConntTest = 0;
sp = pMP3->bitstream.sampleRate;
pMP3->usSampleRate = (unsigned short)(pMP3->bitstream.sampleRate);
pMP3->ucChannels = (unsigned char)pMP3->bitstream.channels.total;
pMP3->output.channelsRequired = NULL;
pMP3->output.numberOfChannels = (unsigned int)pMP3->bitstream.channels.total;
pMP3->output.maxNumberOfSamples = (unsigned int)pMP3->workspace->requirements->maxOutputSize;
pMP3->output.channels = (short**) pMP3->buffer_ptr;
if (pMP3->ulBitRate == 0)
{
return(0);
}
pMP3->ulTimeLength = ((((unsigned long long)pMP3->ulLength * 8) / pMP3->ulBitRate) * 1000) +
(((((unsigned long long)pMP3->ulLength * 8) % pMP3->ulBitRate) * 1000) /
pMP3->ulBitRate);
pMP3->ulTimePos = 0;
pMP3->pOutput = 0;
return(1);//return success message.
}
// Seek to the specified time position.
case SUBFN_CODEC_SEEK:
{
//以毫秒为单位
tMP3 *pMP3;
unsigned long ulPos, ulFrameSize;
// The first parameter is a pointer to the MP3 persistent data.
pMP3 = (tMP3 *)ulParam1;
if (pMP3->usSampleRate >= 32000)
{
ulFrameSize = 1152;
}
else
{
ulFrameSize = 576;
}
// Compute the number of frames that occur before the requested
// time position.
ulPos = (((ulParam2 / 1000) * pMP3->usSampleRate) /
ulFrameSize) +
(((ulParam2 % 1000) * pMP3->usSampleRate) /
(ulFrameSize * 1000));
// Compute the time for the computed frame number.
pMP3->ulTimePos = ulPos = ulPos * ulFrameSize;
// Compute the file position based on the actual seek time.
if (pMP3->usSampleRate)
{
ulPos = ((ulPos / pMP3->usSampleRate) *
(pMP3->ulBitRate / 8)) +
(((ulPos % pMP3->usSampleRate) *
(pMP3->ulBitRate / 8)) / pMP3->usSampleRate);
}
if (ulPos)
{
ulPos--;
}
// search valid header
do
{
FillBitstream(pMP3, 0);
if (!bitstreamDataToProcess) break;
pMP3->status = pMP3->workspace->Decoder->DecodeHeader(pMP3->workspace->handle,
pMP3->workspace->scratch,
&(pMP3->bitstream));
}
while ((pMP3->status == kDecoderStatus_MoreData && bitstreamDataToProcess) ||
(pMP3->status != kDecoderStatus_NoError));
do
{
pMP3->status = Seek(ulPos, SEEK_BY_BYTES, pMP3, ulPos + pMP3->ulFirstFrame, 0);
}
while (pMP3->status != kDecoderStatus_NoError);
if (pMP3->status == 0)
{
pMP3->status = DECODERSTATUS_FASTFORWARD;
return(1);
}
else
{
return(0);
}
return(1);
}
// Return the current position (in milliseconds) within the file.
case SUBFN_CODEC_GETTIME:
{
// additional code needed
unsigned long *pulTime;
tMP3 *pMP3;
// The first parameter is a pointer to the MP3 persistent data.
pMP3 = (tMP3 *)ulParam1;
// The second parameter is a pointer for the number of seconds.
pulTime = (unsigned long *)ulParam2;
if (pMP3->usSampleRate)
{
// Determine the time based on the sample rate.
*pulTime = ((pMP3->ulTimePos / pMP3->usSampleRate) * 1000) +
(((pMP3->ulTimePos % pMP3->usSampleRate) * 1000) /
pMP3->usSampleRate);
}
// Success.
return(1);
}
// Return the sample rate at which this file is encoded.
case SUBFN_CODEC_GETSAMPLERATE:
{
unsigned long *pulSampleRate;
tMP3 *pMP3;
// The first parameter is a pointer to the MP3 persistent data.
pMP3 = (tMP3 *)ulParam1;
pulSampleRate = (unsigned long *)ulParam2;
// Return the sample rate of the file.
*pulSampleRate = pMP3->usSampleRate;
// Success.
return(1);
}
// Return the number of channels in the file.
case SUBFN_CODEC_GETCHANNELS:
{
unsigned long *pulChannels;
tMP3 *pMP3;
// The first parameter is a pointer to the MP3 persistent data.
pMP3 = (tMP3 *)ulParam1;
pulChannels = (unsigned long *)ulParam2;
// Return the number of channels in the file.
*pulChannels = pMP3->ucChannels;
// Success.
return(1);
}
// Return the bitrate at which this file is encoded.
case SUBFN_CODEC_GETBITRATE:
{
unsigned long *pulBitRate;
tMP3 *pMP3;
// The first parameter is a pointer to the MP3 persistent data.
pMP3 = (tMP3 *)ulParam1;
pulBitRate = (unsigned long *)ulParam2;
// Return the number of channels in the file.
if (pMP3->ucIsVBR == 0)
*pulBitRate = pMP3->ulBitRate;
else
*pulBitRate = 0xffffffff;//vbr fsh 08.01.11
// Success.
return(1);
}
// Return the length (in milliseconds) of the file.
case SUBFN_CODEC_GETLENGTH:
{
unsigned long *pulLength;
tMP3 *pMP3;
// The first parameter is a pointer to the MP3 persistent data.
pMP3 = (tMP3 *)ulParam1;
pulLength = (unsigned long *)ulParam2;
// Return the length of the file.
*pulLength = pMP3->ulTimeLength;
// Success.
return(1);
}
// Return the name of the artist.
case SUBFN_CODEC_GETARTIST:
{
char **ppcName;
tMP3 *pMP3;
// The first parameter is a pointer to the FLAC persistent data.
pMP3 = (tMP3 *)ulParam1;
// The second parameter is a pointer for the name.
ppcName = (char **)ulParam2;
// Return the name of the artist.
*ppcName = (char *)ID3V2XInfo.mMetaData[ID3_ARTIST];
// Success.
return(1);
}
// Return the name of the song
case SUBFN_CODEC_GETTITLE:
{
char **ppcName;
tMP3 *pMP3;
// The first parameter is a pointer to the FLAC persistent data.
pMP3 = (tMP3*)ulParam1;
// The second parameter is a pointer for the name.
ppcName = (char **)ulParam2;
// Return the name of the song.
*ppcName = (char *)ID3V2XInfo.mMetaData[ID3_TITLE];
// Success.
return(1);
}
// Cleanup after the codec.
case SUBFN_CODEC_CLOSE:
{
tMP3 *pMP3;
pMP3 = (tMP3 *) ulParam1;
pMP3->status = pMP3->workspace->Decoder->DecoderDestroy(pMP3->workspace->handle, pMP3->workspace->scratch);
if (pMP3->status == kDecoderStatus_NoError) return(1);
else return(0);
}
default:
{
// Return a failure.
return(0);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -