📄 pwav.c
字号:
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*
File : \Audio\ADPCM
Desc : WAV解码。包括PCM WAV , IMA-ADPCM WAV , MS-ADPCM WAV 。
Author : FSH , Vincent Hisung
Date : 2007-08-xx
Notes :
$Log :
* vincent 2007/08/xx 建立此文件
*
*/
/****************************************************************/
#include "../include/audio_main.h"
#include "../include/audio_globals.h"
#ifdef WAV_INCLUDE
#include "../buffer/buffer.h"
#include "../include/file_access.h"
#include "PCM.H"
#include "mRECORD.H"
#include "../../video/AVI/AviFile.h"
#include <stdio.h>
#include <string.h>
#include "include.h"
#if ROCK_CAMERA
#include "../../camera/camInclude.h"
#endif
#include "..\AppGlobal.h"
static int ADPCM_ENC_RATE = 1;
extern MY_FILE* TRACK_GetFileHandleOfRecord(void);
static long OutLength;
static short *poutLeft, *poutRight;
#if ROCK_CAMERA&&CAM_FUN_DV
extern DV_GLOBAL_VAR m_dv_global_var;
extern CAM_DV gCamDv;
#endif
extern sPlayBuffer;
Fptr_ADPCM0 *IMAADPCMDECODE = DecodeIMAADPCM;
Fptr_ADPCM2 *ADPCMDECODE = DecodeMSADPCM;
Fptr_ADPCM3 *ADPCMENCODE = EncodeMSADPCM;
#define INFO_BYTE_SIZE 32
typedef struct
{
char Artist[INFO_BYTE_SIZE];
char Name[INFO_BYTE_SIZE];
char Product[INFO_BYTE_SIZE];
char Genre[INFO_BYTE_SIZE];
}tINFO;
#define ADPCM_FILL_HDR 90
unsigned char ADPCM_Hdr[ADPCM_FILL_HDR];
static unsigned long msadpcm_outsize = 0;
#ifdef PCM_ENC_INCLUDE
extern short RecordWriteBuf[];
#endif
#if defined(MP3_ENC_INCLUDE)||defined(ADPCM_ENC_INCLUDE)
extern char RecordWriteBuf[];
#endif
extern unsigned long RecordWriteIndex;
extern unsigned char SendFirstBufSign;
extern unsigned char SendSecondBufSign;
unsigned long Encode_Bitrate; // add by huangzf
extern UINT16 RecFisrtNoWrite;
#if ROCK_CAMERA&&CAM_FUN_DV
extern char * pCurDvAudioOutputBuf;
extern int curDvAudioOutputBufLen;
#endif
extern unsigned int audioChunkNum;
extern short VideoPlaying;
extern unsigned char ADPCM_Hdr[];
extern unsigned long ByteRateTemp;
// 初始化ADPCM解码器,从aviWavex中获得
// 目前只函数只验证过ADPCM, PCM会存在问题
int InitADPCMDecoder(tPCM *pPCM)
{
pPCM->sPCMHeader.uBitsPerSample = aviWavex.wBitsPerSample;
pPCM->sPCMHeader.ucChannels = aviWavex.nChannels;
pPCM->sPCMHeader.usSamplesPerBlock = (((aviWavex.nBlockAlign - (7 * aviWavex.nChannels)) * 8) /
(aviWavex.wBitsPerSample * aviWavex.nChannels)) + 2;
pPCM->wFormatTag = aviWavex.wFormatTag;
pPCM->uBitsPerSample = aviWavex.wBitsPerSample;
pPCM->ucChannels = aviWavex.nChannels;
pPCM->usByteRate = aviWavex.nAvgBytesPerSec;
pPCM->usBytesPerBlock = aviWavex.nBlockAlign; // ?
pPCM->usSampleRate = aviWavex.nSamplesPerSec;
pPCM->usSamplesPerBlock = pPCM->sPCMHeader.usSamplesPerBlock;
if (pPCM->wFormatTag == WAVE_FORMAT_PCM)
{
pPCM->usSamplesPerBlock = 512;
pPCM->usBytesPerBlock = pPCM->usSamplesPerBlock*pPCM->ucChannels*(pPCM->uBitsPerSample>>3);
pPCM->ulDataValid = 0x7FFFFFFF;//由于无法知道精确的PCM数据长度,把它置为最大//audioChunkNum * 7397;
pPCM->ulLength = pPCM->ulDataValid;
pPCM->ulTimeLength = 1000 * (long long)pPCM->ulLength / pPCM->usByteRate;
pPCM->usValid = 8;
}
else
{
pPCM->ulDataStart = 0;
pPCM->ulDataValid = 0x7FFFFFFF;//audioChunkNum * aviWavex.nBlockAlign;
pPCM->ulLength = pPCM->ulDataValid;
pPCM->ulTimeLength = 1000 * (long long)pPCM->ulLength / pPCM->usByteRate;
pPCM->usValid = RKFIO_FRead(NULL, pPCM->pucEncodedData, MSADPCM_MAX_ENCBUF_LENGTH);
}
GetInitDiff();
return 1;
}
//*************************************************************************************************************//
//功能实现情况:
//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: PCMDecFunction
Desc: PCM解码器接口函数
Param: ulIoctl 子功能号
ulParam1 子功能参数1
ulParam2 子功能参数2
ulParam3 子功能参数3
ulParam4 子功能参数4
Return: 0-失败 1-成功
Global: 无
Note: 无
Author: FSH,Vincent Hisung
Log:
******************************************************/
unsigned long
PCMFunction(unsigned long ulIoctl, unsigned long ulParam1,
unsigned long ulParam2, unsigned long ulParam3,
unsigned long ulParam4)
{
switch (ulIoctl)
{
case SUBFN_CODEC_GETNAME:
{
char **ppcName;
ppcName = (char **)ulParam2;
*ppcName = "PCM";
return(1);
}
case SUBFN_CODEC_GETARTIST:
{
char **ppcName;
ppcName = (char **)ulParam2;
*ppcName = 0;
return(1);
}
case SUBFN_CODEC_GETTITLE:
{
char **ppcName;
ppcName = (char **)ulParam2;
*ppcName = 0;
return(1);
}
case SUBFN_CODEC_GETBITRATE:
{
unsigned long *pulBitRate;
tPCM *pPCM;
pPCM = (tPCM *)ulParam1;
pulBitRate = (unsigned long *)ulParam2;
*pulBitRate = pPCM->usByteRate * 8;
return(1);
}
case SUBFN_CODEC_GETSAMPLERATE:
{
unsigned long *pulSampleRate;
tPCM *pPCM;
pPCM = (tPCM *)ulParam1;
pulSampleRate = (unsigned long *)ulParam2;
*pulSampleRate = pPCM->usSampleRate;
return(1);
}
case SUBFN_CODEC_GETCHANNELS:
{
unsigned long *pulChannels;
tPCM *pPCM;
pPCM = (tPCM *)ulParam1;
pulChannels = (unsigned long *)ulParam2;
*pulChannels = pPCM->ucChannels;
return(1);
}
case SUBFN_CODEC_GETLENGTH:
{
unsigned long *pulLength;
tPCM *pPCM;
pPCM = (tPCM *)ulParam1;
pulLength = (unsigned long *)ulParam2;
*pulLength = pPCM->ulTimeLength;
return(1);
}
case SUBFN_CODEC_GETTIME:
{
unsigned long *pulTime;
tPCM *pPCM;
pPCM = (tPCM *)ulParam1;
pulTime = (unsigned long *)ulParam2;
*pulTime = (((__int64)pPCM->ulTimePos * 1000 / pPCM->usSampleRate)) +
(((((__int64)pPCM->ulTimePos * 1000 % pPCM->usSampleRate)) / pPCM->usSampleRate));
//*pulTime = (pPCM->ulDataValid/pPCM->bitrates)<<3; // chang by huangzf
return(1);
}
case SUBFN_CODEC_STORETIME:
{
unsigned long *pulTime;
tPCM *pPCM;
pPCM = (tPCM *)ulParam1;
pulTime = (unsigned long *)ulParam2;
#if ROCK_CAMERA
if (DeskCurrItem == DV_Module) //modify by dengdl 20080627
{
*pulTime = (((__int64)pPCM->ulTimePos * 1000 / pPCM->usSampleRate)) +
(((((__int64)pPCM->ulTimePos * 1000 % pPCM->usSampleRate)) / pPCM->usSampleRate));
} else {
*pulTime = (pPCM->ulDataValid/(Encode_Bitrate))<<3; // chang by huangzf
}
#else
*pulTime = (pPCM->ulDataValid/(Encode_Bitrate))<<3; // chang by huangzf
#endif
return(1);
}
case SUBFN_CODEC_OPEN_ENC:
{
tPCM *pPCM;
PCMWAVEFORMAT sWaveFormat1;
unsigned long ulIdx1;
pPCM = (tPCM *)ulParam1;
#ifdef ADPCM_ENC_INCLUDE
if (REC_GetCurrCodec() == 2)
{
pPCM->usSampleRate = REC_GetSamplingFreq(); //8000;
pPCM->ucChannels = REC_GetChannel();
InitADPCMEncoder(pPCM);
if (pPCM->usSampleRate <= 16000)
ADPCM_ENC_RATE = 8;
else if (pPCM->usSampleRate <= 32000)
ADPCM_ENC_RATE = 4;
else
ADPCM_ENC_RATE = 1;
OutLength = pPCM->usSamplesPerBlock * ADPCM_ENC_RATE;
sWaveFormat1.wFormatTag = 2;
sWaveFormat1.nChannels = pPCM->ucChannels;
sWaveFormat1.nSamplesPerSec = pPCM->usSampleRate;
sWaveFormat1.nAvgBytesPerSec = pPCM->usByteRate;
sWaveFormat1.nBlockAlign = pPCM->usBytesPerBlock;
sWaveFormat1.wBitsPerSample = 4;
sWaveFormat1.cbSize = 32;
sWaveFormat1.wSamplesPerBlock = pPCM->usSamplesPerBlock;
sWaveFormat1.wNumCoef = 7;
for (ulIdx1 = 0; ulIdx1 < 7; ulIdx1++)
{
sWaveFormat1.aCoef[ulIdx1].iCoef1 = psCoefficient1[ulIdx1];
sWaveFormat1.aCoef[ulIdx1].iCoef2 = psCoefficient2[ulIdx1];
}
memcpy(&ADPCM_Hdr[20], (void *)&sWaveFormat1, 50);
}
#endif
#ifdef PCM_ENC_INCLUDE
if (REC_GetCurrCodec() == 1)
{
pPCM->usSampleRate = REC_GetSamplingFreq(); //8000;
pPCM->ucChannels = REC_GetChannel();
Init_LPCMEncoder(pPCM);
OutLength = pPCM->usSamplesPerBlock;
}
#endif
poutLeft = pPCM->FrameOutputLeft;
poutRight = pPCM->FrameOutputRight;
Encode_Bitrate = REC_GetgBitrate(); // chang by huangzf
pPCM->ulDataValid = 0;
return 1;
}
case SUBFN_CODEC_OPEN_DEC:
{
tPCM *pPCM;
tINFO pINFO;
int i;
int isErr;
pPCM = (tPCM *)ulParam1;
for (i = 0;i < WAV_IMAMAX_PCM_LENGTH*2;i++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -