📄 pac3_dec.c
字号:
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*
File : \Audio\Ac3Dec
Desc : ac3解码。
Author : FANGSAIHONG
Date : 2007-12-17
Notes :
$Log :
* FANGSAIHONG 2007/12/17 建立此文件
*
*
*
*
*
*/
/****************************************************************/
#include "../include/audio_main.h"
#ifdef AC3_DEC_INCLUDE
#include "../include/audio_globals.h"
#include "../include/file_access.h"
#include "pAC3_DEC.h"
#define BUFFER_SIZE 4096
#define A52_SAMPLESPERFRAME (6*256)
a52_state_t *state;
unsigned long samplesdone;
unsigned long frequency;
unsigned char in_buf[BUFFER_SIZE];
int flags, sample_rate, bit_rate, n;
int Ac3Length;
short *leftpcm, *rightpcm;
int BuffLeftPcmData;
void output_audio(sample_t *samples)
{
#if 1
int i = 0;
short tmp;
for (i = 0 ; i < 256; i++)
{
/*
fwrite(&samples[i],sizeof(sample_t),1,file_out);
fwrite(&samples[i],sizeof(sample_t),1,file_out);
*/
tmp = (samples[i] >> 16) & 0xffff;
*leftpcm++ = tmp;
tmp = (samples[i+256] >> 16) & 0xffff;
*rightpcm++ = tmp;
//fwrite(&tmp,1,2,file_out);
}
BuffLeftPcmData += 256;
#endif
}
//****************************************************************************
//
// 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: AC3DecFunction
Desc: AC3解码器接口函数
Param: ulIoctl 子功能号
ulParam1 子功能参数1
ulParam2 子功能参数2
ulParam3 子功能参数3
ulParam4 子功能参数4
Return: 0-失败 1-成功
Global: 无
Note: 无
Author: HXD
Log:
******************************************************/
/*
short Ac3Left[0x5000];
short Ac3Right[0x5000];
*/
short *Ac3Left = NULL;
short *Ac3Right = NULL;
unsigned long
AC3DecFunction(unsigned long ulSubFn, unsigned long ulParam1, unsigned long ulParam2,
unsigned long ulParam3, unsigned long ulParam4)
{
switch (ulSubFn)
{
// Decode a frame of data.
case SUBFN_CODEC_DECODE:
{
tAC3 *pAC3;
pAC3 = (tAC3 *)ulParam1;
while (BuffLeftPcmData < 0x1800)
{
a52_decode_data(in_buf, in_buf + n);
//printf ("samplesdone %i\n",samplesdone);
n = RKFIO_FRead(pRawFileCache, in_buf, BUFFER_SIZE);
if (n == 0) /* End of Stream */
return 0;
}
BuffLeftPcmData -= 0x1800;
leftpcm = &Ac3Left[BuffLeftPcmData];
rightpcm = &Ac3Right[BuffLeftPcmData];
memcpy(pAC3->AC3left, Ac3Left, 0x1800*2);
memcpy(pAC3->AC3right, Ac3Right, 0x1800*2);
memcpy(&Ac3Left[0], &Ac3Left[0x1800], BuffLeftPcmData*2);
memcpy(&Ac3Right[0], &Ac3Right[0x1800], BuffLeftPcmData*2);
pAC3->ulTimePos += 0x1800;
return 1;
}
// Prepare the codec to decode a file.
case SUBFN_CODEC_OPEN_DEC:
{
tAC3 *pAC3;
pAC3 = (tAC3 *)ulParam1;
if (Ac3Left == NULL)
{
Ac3Left = malloc(0x5000 * sizeof(short));
if (Ac3Left == NULL)
return 0;
}
if (Ac3Right == NULL)
{
Ac3Right = malloc(0x5000 * sizeof(short));
if (Ac3Right == NULL)
return 0;
}
pAC3->ulLength = (unsigned long)RKFIO_FLength(pRawFileCache);
BuffLeftPcmData = 0;
n = 0;
state = a52_init(0);
if (state == NULL)
{
// fprintf (stderr, "A52 init failed\n");
return 0;
}
samplesdone = 0;
{
int pos = 0;
int flag = 1;
while (flag)
{
int i ;
pos += n;
if (pos > 20 * 1024)
return 0;
n = RKFIO_FRead(pRawFileCache, in_buf, BUFFER_SIZE);
if (n < BUFFER_SIZE) /* End of Stream */
return 0;
for (i = 0; i < BUFFER_SIZE - 1 ; i ++)
{
if (in_buf[i] == 0x0b)
{
if (in_buf[i+1] == 0x77)
{
if (a52_syncinfo(&in_buf[i], &flags, &sample_rate, &bit_rate) > 0)
{
flag = 0;
pos += i;
break;
}
}
}
}
}
RKFIO_FSeek(pRawFileCache, pos, SEEK_SET);
pAC3->ulLength -= pos;
}
n = RKFIO_FRead(pRawFileCache, in_buf, BUFFER_SIZE);
if (n == 0) /* End of Stream */
return 0;
if (0 == a52_syncinfo(in_buf, &flags, &sample_rate, &bit_rate))
{
return 0;
}
//printf("sr: %i , br: %i \n",sample_rate,bit_rate);
pAC3->ulTimePos = 0;
pAC3->ulBitRate = bit_rate;
pAC3->usSampleRate = sample_rate;
pAC3->ucChannels = 2;
leftpcm = Ac3Left;
rightpcm = Ac3Right;
// a52_decode_data(in_buf, in_buf + n);
// n = RKFIO_FRead(pRawFileCache, in_buf, BUFFER_SIZE);
Ac3Length = 0x1800;
pAC3->ulTimeLength = ((((unsigned long long)pAC3->ulLength * 8) / pAC3->ulBitRate) * 1000) +
(((((unsigned long long)pAC3->ulLength * 8) % pAC3->ulBitRate) * 1000) /
pAC3->ulBitRate);
return 1;
}
// Seek to the specified time position.
case SUBFN_CODEC_SEEK:
{
unsigned long ulPos, ulFrameSize;
tAC3 *pAC3;
pAC3 = (tAC3 *)ulParam1;
ulFrameSize = 4608;
// Compute the number of frames that occur before the requested
// time position.
ulPos = (((ulParam2 / 1000) * pAC3->usSampleRate) /
ulFrameSize) +
(((ulParam2 % 1000) * pAC3->usSampleRate) /
(ulFrameSize * 1000));
// Compute the time for the computed frame number.
pAC3->ulTimePos = ulPos = ulPos * ulFrameSize;
samplesdone = pAC3->ulTimePos;
// Compute the file position based on the actual seek time.
if (pAC3->usSampleRate)
{
ulPos = ((ulPos / pAC3->usSampleRate) *
(pAC3->ulBitRate / 8)) +
(((ulPos % pAC3->usSampleRate) *
(pAC3->ulBitRate / 8)) / pAC3->usSampleRate);
}
// Seek to the specified position.
RKFIO_FSeek(pRawFileCache, ulPos, SEEK_SET);
return(1);
}
// Return the current position (in milliseconds) within the file.
case SUBFN_CODEC_GETTIME:
{
unsigned long *pulTime;
tAC3 *pAC3;
// The first parameter is a pointer to the MP3 persistent data.
pAC3 = (tAC3 *)ulParam1;
// The second parameter is a pointer for the number of seconds.
pulTime = (unsigned long *)ulParam2;
if (pAC3->usSampleRate)
{
// Determine the time based on the sample rate.
*pulTime = ((pAC3->ulTimePos / pAC3->usSampleRate) * 1000) +
(((pAC3->ulTimePos % pAC3->usSampleRate) * 1000) /
pAC3->usSampleRate);
}
// Success.
return(1);
}
// Return the sample rate at which this file is encoded.
case SUBFN_CODEC_GETSAMPLERATE:
{
unsigned long *pulSampleRate;
tAC3 *pAC3;
// The first parameter is a pointer to the MP3 persistent data.
pAC3 = (tAC3 *)ulParam1;
pulSampleRate = (unsigned long *)ulParam2;
// Return the sample rate of the file.
*pulSampleRate = pAC3->usSampleRate;
// Success.
return(1);
}
// Return the number of channels in the file.
case SUBFN_CODEC_GETCHANNELS:
{
unsigned long *pulChannels;
tAC3 *pAC3;
// The first parameter is a pointer to the MP3 persistent data.
pAC3 = (tAC3 *)ulParam1;
pulChannels = (unsigned long *)ulParam2;
// Return the number of channels in the file.
*pulChannels = pAC3->ucChannels;
// Success.
return(1);
}
// Return the bitrate at which this file is encoded.
case SUBFN_CODEC_GETBITRATE:
{
unsigned long *pulBitRate;
tAC3 *pAC3;
// The first parameter is a pointer to the MP3 persistent data.
pAC3 = (tAC3 *)ulParam1;
pulBitRate = (unsigned long *)ulParam2;
// Return the number of channels in the file.
*pulBitRate = pAC3->ulBitRate;
// Success.
return(1);
}
// Return the length (in milliseconds) of the file.
case SUBFN_CODEC_GETLENGTH:
{
unsigned long *pulLength;
tAC3 *pAC3;
// The first parameter is a pointer to the MP3 persistent data.
pAC3 = (tAC3 *)ulParam1;
pulLength = (unsigned long *)ulParam2;
// Return the length of the file.
*pulLength = pAC3->ulTimeLength;
// Success.
return(1);
}
case SUBFN_CODEC_GETCAPTUREBUFFER:
{
tAC3 *pAC3;
// The first parameter is a pointer to the MP3 persistent data.
pAC3 = (tAC3 *)ulParam1;
*(unsigned long *)ulParam2 = (unsigned long) pAC3->AC3left ;
*(unsigned long *)ulParam3 = (unsigned long) pAC3->AC3right;
*(unsigned long *)ulParam4 = (unsigned long) Ac3Length ;
return(1);
}
// Return the name of the artist.
case SUBFN_CODEC_GETARTIST:
{
// Success.
return(1);
}
// Return the name of the song
case SUBFN_CODEC_GETTITLE:
{
// Success.
return(1);
}
// Cleanup after the codec.
case SUBFN_CODEC_CLOSE:
{
if (Ac3Left != NULL)
{
free(Ac3Left);
Ac3Left = NULL;
}
if (Ac3Right != NULL)
{
free(Ac3Right);
Ac3Right = NULL;
}
a52_free(state);
}
default:
{
// Return a failure.
return(0);
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -