📄 pflac_dec.c
字号:
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*
File : \Audio\FLACDec
Desc : FLAC解码。
Author : huangxd , Vincent Hisung
Date : 2007-08-xx
Notes :
$Log :
* huangxd 2007/08/xx 建立此文件
*
* vincent 2007/08/xx 修订完善
*
* huaugxd,vincent 2007/09/xx 增加INFO信息支持
*
*/
/****************************************************************/
#include "../include/audio_main.h"
#ifdef FLAC_DEC_INCLUDE
#include "../include/audio_globals.h"
#include "../include/file_access.h"
#include "pFLAC_DEC.h"
extern void *Flac_pclient_data ;
extern FLAC__BitBuffer *Flac_pinput ;
extern void *Flac_pReadBack ;
extern unsigned char* Flac_pInBuffer;//指向输入缓冲首地址
extern unsigned char* Flac_pPcmLeft;
extern unsigned char* Flac_pPcmRight;
extern FILE* Flac_fpInFileName;
extern unsigned long Flac_gSampleRate;
extern unsigned char Flac_gChannels;
extern unsigned long Flac_gBitRate;
extern unsigned long Flac_gTimeLength;
extern unsigned long Flac_gLength;
extern tFLACFileIo Flac_gFileOper;//定义文件操作结构体变量,成员为指向回调函数的函数指针
extern int Flac_gNumofSeekTablePoints;
extern int Flac_gCurUsedSeekTablePoints; // 当时快进快退的点
extern FLAC__StreamMetadata_SeekPoint Flac_gSeekTablePoints[MAX__SEEK_POINTS_NUM];
extern int Flac_gFlagRealloc ; // 快进快退的标记
unsigned char* Flac_pArtist;
unsigned char* Flac_pAlbum;
unsigned char* Flac_pTitle;
unsigned char* Flac_pGenre;
unsigned char* Flac_pDate;
unsigned char* Flac_pComment;
unsigned char* Flac_pTrackNumber;
static short *flac_OutLeft = NULL;//[FLAC_PCM_BUFFER_SIZE];
static short *flac_OutRight = NULL;//[FLAC_PCM_BUFFER_SIZE];
static long OutLength;
extern int flac_block_decoder_decframe(void);
extern int flac_block_decoder_finish(void);
//****************************************************************************
//
// The codec plug-in entry point for the FLAC decoder.
//
//****************************************************************************
//功能实现情况:
//SUBFN_CODEC_GETNAME : 不支持
//SUBFN_CODEC_GETARTIST: 得到艺术家名
//SUBFN_CODEC_GETTITLE : 得到曲名
//SUBFN_CODEC_GETBITRATE: 得到码率
//SUBFN_CODEC_GETSAMPLERATE: 得到采样率
//SUBFN_CODEC_GETCHANNELS: 得到声道数目
//SUBFN_CODEC_GETLENGTH : 得到时长 [单位:毫秒]
//SUBFN_CODEC_GETTIME : 得到当前播放时间 [单位:毫秒]
//SUBFN_CODEC_OPEN_DEC : 打开解码器(初始化)
//SUBFN_CODEC_DECODE : 解码
//SUBFN_CODEC_ENCODE : 不支持
//SUBFN_CODEC_SEEK : 按时间直接定位 [单位:毫秒]
//SUBFN_CODEC_CLOSE : 关闭解码器
/******************************************************
Name: FLACDecFunction
Desc: FLAC解码器接口函数
Param: ulIoctl 子功能号
ulParam1 子功能参数1
ulParam2 子功能参数2
ulParam3 子功能参数3
ulParam4 子功能参数4
Return: 0-失败 1-成功
Global: 无
Note: 无
Author: HXD
Log:
******************************************************/
int FlacBlockSize;
unsigned long
FLACDecFunction(unsigned long ulSubFn, unsigned long ulParam1, unsigned long ulParam2,
unsigned long ulParam3, unsigned long ulParam4)
{
unsigned int WaitCounter = 0;
switch (ulSubFn)
{
// Decode a frame of data.
case SUBFN_CODEC_DECODE:
{
tFLAC *pFLAC;
short *psLeft, *psRight;
long lLength;
int decStatus = 0;
pFLAC = (tFLAC *)ulParam1;
//解码结束标记就是当decStatus等于2,退出
decStatus = flac_block_decoder_decframe(); //0表示解码正确且不是最后一帧,2表示解码结束或读文件出错,1表示解码出错且填0于输出缓冲;
//输出----------------------------------
{
int i;
OutLength = FlacBlockSize;// lLength - 4;
if (OutLength == 0)
OutLength = 4096;
if(Flac_gChannels==2)
{
for (i = 0;i < OutLength;i++)
{
flac_OutLeft[i] = pFLAC->psLeft[2*i];
flac_OutRight[i] = pFLAC->psRight[2*i];
}
}
else if( Flac_gChannels==1)
{
for (i = 0;i < OutLength;i++)
{
flac_OutLeft[i] = pFLAC->psLeft[2*i];
flac_OutRight[i] = flac_OutLeft[i] ;
}
}
}
//---------------------------------------
if (decStatus == 2)//由于解码内部0表示解码正确,1表示解码错误,2表示解码结束;但解码外部0表示错误,1和2表示正确,故我们需要转换以下返回值
{
return 0;
}
else
{
pFLAC->ulTimePos += OutLength;
return 1;
}
}
// Prepare the codec to decode a file.
case SUBFN_CODEC_OPEN_DEC:
{
tFLAC* pFLAC;
// The first parameter is a pointer to the FLAC persistent data.
pFLAC = (tFLAC *)ulParam1;
//获取采样率,比特率,声道,文件时间总长度
pFLAC->usSampleRate = Flac_gSampleRate;
pFLAC->ucChannels = Flac_gChannels;
pFLAC->ulBitRate = Flac_gBitRate;
pFLAC->ulTimeLength = Flac_gTimeLength;//单位为毫秒
pFLAC->ulLength = Flac_gLength;//单位为Bytes
pFLAC->ulTimePos = 0;
flac_OutLeft = (short *) malloc(FLAC_PCM_BUFFER_SIZE * sizeof(short));
flac_OutRight = (short *) malloc(FLAC_PCM_BUFFER_SIZE * sizeof(short));
return 1;
}
// Seek to the specified time position.
case SUBFN_CODEC_SEEK:
{
tFLAC *pFLAC;
unsigned long ulPos;
unsigned long ulFileOffset;
// The first parameter is a pointer to the FLAC persistent data.
pFLAC = (tFLAC *)ulParam1;
if (ulParam2 > pFLAC->ulTimeLength)//ulParam2单位是毫秒,ulTimeLength单位也是毫秒
{
ulParam2 = pFLAC->ulTimeLength;
}
// Compute the number of frames that occur before the requested
// time position.
// Compute the time for the computed frame number.
pFLAC->ulTimePos = ulPos = ((ulParam2 / 1000) * pFLAC->usSampleRate) + (((ulParam2 % 1000) * pFLAC->usSampleRate) / 1000);//计算当前位置的对应的样本数目
// Compute the number of seek table points and the file position based on the actual seek time.
Flac_gCurUsedSeekTablePoints = 0;
while ((ulPos >= (unsigned long)Flac_gSeekTablePoints[Flac_gCurUsedSeekTablePoints].sample_number) && (Flac_gCurUsedSeekTablePoints < Flac_gNumofSeekTablePoints))
{
Flac_gCurUsedSeekTablePoints++;
}
if (Flac_gSeekTablePoints[Flac_gCurUsedSeekTablePoints].stream_offset == 0)
{
if (Flac_gCurUsedSeekTablePoints > 0)
Flac_gCurUsedSeekTablePoints--;
}
if (Flac_gCurUsedSeekTablePoints != 0)
{
pFLAC->ulTimePos = Flac_gSeekTablePoints[Flac_gCurUsedSeekTablePoints].sample_number;
//计算当前时间点对应的文件位置,单位为字节
ulFileOffset = (unsigned long)Flac_gSeekTablePoints[Flac_gCurUsedSeekTablePoints].stream_offset;
}
else
ulFileOffset = pFLAC->ulBitRate * (ulParam2 / 8);
if (ulFileOffset >= Flac_gLength)
ulFileOffset = Flac_gLength;
RKFIO_FSeek((MY_FILE*)Flac_fpInFileName, ulFileOffset, SEEK_SET);
/*
if(RKFIO_FSeek((MY_FILE*)Flac_fpInFileName, ulFileOffset, SEEK_SET) != 0)
{
return 0;
}
*/
Flac_gFlagRealloc = true;
return(1);
}
// Return the current position (in milliseconds) within the file.
case SUBFN_CODEC_GETTIME:
{
unsigned long *pulTime;
tFLAC *pFLAC;
// The first parameter is a pointer to the MP3 persistent data.
pFLAC = (tFLAC *)ulParam1;
// The second parameter is a pointer for the number of seconds.
pulTime = (unsigned long *)ulParam2;
if (pFLAC->usSampleRate)
{
// Determine the time based on the sample rate.
*pulTime = ((pFLAC->ulTimePos / pFLAC->usSampleRate) * 1000) +
(((pFLAC->ulTimePos % pFLAC->usSampleRate) * 1000) /
pFLAC->usSampleRate);
}
// Success.
return(1);
}
// Return the sample rate at which this file is encoded.
case SUBFN_CODEC_GETSAMPLERATE:
{
unsigned long *pulSampleRate;
tFLAC *pFLAC;
// The first parameter is a pointer to the MP3 persistent data.
pFLAC = (tFLAC *)ulParam1;
pulSampleRate = (unsigned long *)ulParam2;
// Return the sample rate of the file.
*pulSampleRate = pFLAC->usSampleRate;
// Success.
return(1);
}
// Return the number of channels in the file.
case SUBFN_CODEC_GETCHANNELS:
{
unsigned long *pulChannels;
tFLAC *pFLAC;
// The first parameter is a pointer to the MP3 persistent data.
pFLAC = (tFLAC *)ulParam1;
pulChannels = (unsigned long *)ulParam2;
// Return the number of channels in the file.
*pulChannels = pFLAC->ucChannels;
// Success.
return(1);
}
// Return the bitrate at which this file is encoded.
case SUBFN_CODEC_GETBITRATE:
{
unsigned long *pulBitRate;
tFLAC *pFLAC;
// The first parameter is a pointer to the MP3 persistent data.
pFLAC = (tFLAC *)ulParam1;
pulBitRate = (unsigned long *)ulParam2;
// Return the number of channels in the file.
*pulBitRate = pFLAC->ulBitRate * 1000;
// Success.
return(1);
}
// Return the length (in milliseconds) of the file.
case SUBFN_CODEC_GETLENGTH:
{
unsigned long *pulLength;
tFLAC *pFLAC;
// The first parameter is a pointer to the APE persistent data.
pFLAC = (tFLAC *)ulParam1;
pulLength = (unsigned long *)ulParam2;
// Return the length of the file.
*pulLength = pFLAC->ulTimeLength;
// Success.
return(1);
}
case SUBFN_CODEC_GETCAPTUREBUFFER:
{
*(unsigned long *)ulParam2 = (unsigned long) flac_OutLeft ;
*(unsigned long *)ulParam3 = (unsigned long) flac_OutRight;
*(unsigned long *)ulParam4 = (unsigned long) OutLength ;
return(1);
}
// Return the name of the artist.
case SUBFN_CODEC_GETARTIST:
{
char **ppcName;
tFLAC *pFLAC;
// The first parameter is a pointer to the FLAC persistent data.
pFLAC = (tFLAC *)ulParam1;
// The second parameter is a pointer for the name.
ppcName = (char **)ulParam2;
// Return the name of the artist.
*ppcName = (char *)pFLAC->ucArtist;
// Success.
return(1);
}
// Return the name of the song
case SUBFN_CODEC_GETTITLE:
{
char **ppcName;
tFLAC *pFLAC;
// The first parameter is a pointer to the FLAC persistent data.
pFLAC = (tFLAC *)ulParam1;
// The second parameter is a pointer for the name.
ppcName = (char **)ulParam2;
// Return the name of the song.
*ppcName = (char *)pFLAC->ucTitle;
// Success.
return(1);
}
// Cleanup after the codec.
case SUBFN_CODEC_CLOSE:
{
tFLAC *pFLAC;
pFLAC = (tFLAC *) ulParam1;
pFLAC->status = flac_block_decoder_finish() ;
if (flac_OutLeft != NULL)
{
free(flac_OutLeft);
flac_OutLeft = NULL;
}
if (flac_OutRight != NULL)
{
free(flac_OutRight);
flac_OutRight = NULL;
}
if (pFLAC->status == 0)//0表示正常结束,否则错误结束
{
return(1);
}
else
{
return(0);
}
}
default:
{
// Return a failure.
return(0);
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -