record.c
来自「好记星的控件,包括button,list,对文件操作」· C语言 代码 · 共 457 行
C
457 行
/*************************************************************************/
/* */
/* Copyright (c) 2005, 名人电脑科技有限公司深圳研发中心 */
/* All rights reserved. */
/* */
/* 文件名称: Record.C */
/* 文件描述: 录音模块 */
/* */
/* 当前版本: 1.0 */
/* 作 者: Bingle */
/* 完成日期: 2005年05月25日 */
/* */
/* 函数列表: */
/* */
/* 更改记录: */
/* ===================================================================== */
/* 日期 人员 版本 描述 */
/* ===================================================================== */
/* 2005-02-22 Bingle 1.0 create */
/* 2005-05-21 Bingle 2.0 modified for ed136 */
/*************************************************************************/
#include "kernel.h"
#include "..\\voice\\VoiceIn.h"
#ifdef ADPCM_FORMAT
#define RECORD_FILE_HEADER ADPCM_WAVEFILEHEADER
#else
#define RECORD_FILE_HEADER WAVEFILEHEADER
#endif
static RECORD_FILE_HEADER g_waveFileHdr;
static WAVEFORMATEX g_wavePcmFmt;
static MRecord *g_hRecord = NULL;
static int g_nRecErrCode = 0;
extern NU_QUEUE g_VoiceQueue;
int RecordGetError()
{
return g_nRecErrCode;
}
VOID _RecordSetBuffer(MRecord *handle, WAVEHDR *pwh)
{
NU_DRIVER_REQUEST request;
request.nu_function = NU_OUTPUT;
pwh->dwFlags = 0;
pwh->dwLoops = 0;
request.nu_supplemental_ptr = (VOID *)pwh;
NU_Request_Driver(handle->pRecordDrv, &request);
}
unsigned int Adpcm_EncData(unsigned char *pSrcBuf, unsigned int dwSrcBufLen);
BOOL RecordWrite(MRecord *handle, WAVEHDR *pwh)
{
UINT32 dwTime;
INT nCount;
if (!handle || !pwh || handle != g_hRecord) {
return FALSE;
}
if (handle->hFile < 0) {
return FALSE;
}
else
{
if (handle->writeData < 2)
{
handle->writeData ++;
pwh->dwBufferLength = RECORD_BUFLEN;
_RecordSetBuffer(handle, pwh);
return TRUE;
}
#ifdef ADPCM_FORMAT
nCount = Adpcm_EncData(pwh->lpData, pwh->dwBytesRecorded);
nCount = FileWrite(handle->hFile, (INT8*)pwh->lpData, nCount);
#else
nCount = FileWrite(handle->hFile, (INT8*)pwh->lpData,
pwh->dwBytesRecorded);
#endif
if (nCount < 0) {
RecordStop(handle);
if (nCount == NUF_NOSPC) {
if (handle->pCallBackFunc) {
((VOICECALLBACKPROC)handle->pCallBackFunc)
(RECORD_DISK_FULL, (UINT32)handle);
}
else {
SendVoiceMsg(RECORD_DISK_FULL);
}
}
g_nRecErrCode = nCount;
return FALSE;
}
}
_RecordSetBuffer(handle, pwh);
handle->dwTotalLen += nCount;
dwTime = handle->dwTotalLen / handle->dwBytesPerSec;
if (dwTime > handle->dwSumTime) {
handle->dwSumTime = dwTime;
SendVoiceMsg(RECORD_REFRESH);
}
return TRUE;
}
VOID _RecordCallbackFunction(WAVEHDR *pwh, DWORD dwUser)
{
MEvent ev;
ev.dwMsgType = VOICE_COMMAND_INPUT;
ev.xParam = dwUser;
ev.yParam = 0;
ev.pvInfoPtr = (VOID *)pwh;
// NU_Change_Preemption(NU_PREEMPT);
NU_Send_To_Queue(&g_VoiceQueue, &ev, EVENT_QUEUE_MSG_SIZE, NU_NO_SUSPEND);
/*
if (pwh == &g_hRecord->recordHdr1) {
SendVoiceMsg(RECORD_BUFFER1_FULL);
}
else if (pwh == &g_hRecord->recordHdr2) {
SendVoiceMsg(RECORD_BUFFER2_FULL);
}
else {
// set breakpoint here
dwUser = 0;
}*/
}
BOOL RecordInit()
{
strcpy(g_waveFileHdr.RIFF, "RIFF");
strcpy(g_waveFileHdr.Format, "WAVEfmt ");
strcpy(g_waveFileHdr.data, "data");
g_waveFileHdr.uFileLen = 0;
memset(&g_waveFileHdr.uDataLen, 0x0, 4);
g_waveFileHdr.uWFMT_Size = sizeof(WAVEFORMATEX);
g_wavePcmFmt.wFormatTag = WAVE_FORMAT_PCM;
g_wavePcmFmt.wBitsPerSample = 16;
g_wavePcmFmt.nSamplesPerSec = 8000;
g_wavePcmFmt.nChannels = 1;
g_wavePcmFmt.nBlockAlign = g_wavePcmFmt.nChannels * sizeof(g_wavePcmFmt.wBitsPerSample);
g_wavePcmFmt.nAvgBytesPerSec = g_wavePcmFmt.nSamplesPerSec * g_wavePcmFmt.nBlockAlign;
g_wavePcmFmt.cbSize = 0;
memcpy(&g_waveFileHdr.wfx, &g_wavePcmFmt, sizeof(g_wavePcmFmt));
#ifdef ADPCM_FORMAT
g_waveFileHdr.uWFMT_Size = sizeof(ADPCMWaveFormat);
if(Adpcm_EncInit(&g_wavePcmFmt, &g_waveFileHdr.wfx) == 0)
return FALSE;
#endif
return TRUE;
}
UINT32 RecordGetBPS()
{
return g_waveFileHdr.wfx.nAvgBytesPerSec;
}
MRecord *RecordOpen(UINT8 *fileName, UINT16 wMode)
{
INT hFile;
AUDIODS_OPEN open;
NU_DRIVER_REQUEST request;
MRecord *handle;
INT32 nCount;
//create file
hFile = FileOpen(fileName, FILEMODE_CREATEWRITE);
if (hFile < 0) {
g_nRecErrCode = hFile;
return NULL;
}
// check the file
if (wMode == RECORD_MODE_APPEND && FileLength(hFile) > 0) {
RECORD_FILE_HEADER head;
g_nRecErrCode = FileRead(hFile, (char *)&head, sizeof(RECORD_FILE_HEADER));
if (g_nRecErrCode != sizeof(RECORD_FILE_HEADER)) {
FileClose(hFile);
return NULL;
}
g_waveFileHdr.uFileLen = head.uFileLen;
memcpy(g_waveFileHdr.uDataLen, head.uDataLen, 4);
if (memcmp(&g_waveFileHdr, &head, sizeof(RECORD_FILE_HEADER)) != 0)
{
FileClose(hFile);
g_nRecErrCode = RECORD_FILE_FORMAT_ERROR;
return NULL;
}
}
//alloc memory
handle = MemAlloc(sizeof(MRecord));
if (!handle) {
FileClose(hFile);
g_nRecErrCode = NUF_NO_MEMORY;
return NULL;
}
memset(handle, 0, sizeof(MRecord));
handle->hFile = hFile;
strcpy(handle->fileName, fileName);
#ifdef ADPCM_FORMAT
Adpcm_EncStart();
#endif
//find drv
handle->pRecordDrv = GetIODriverFromName((UINT8*)DRV_NAME_AUDIO);
open.dwAudioCommand = AUDIO_RECORD;
open.pwfx = &(g_wavePcmFmt);
open.dwCallback = (VOID*)_RecordCallbackFunction;
open.dwCallbackInstance = (DWORD)handle;
open.fdwOpen = 0;
request.nu_function = NU_ASSIGN;
request.nu_supplemental_ptr = (VOID *)&open;
NU_Request_Driver(handle->pRecordDrv, &request);
if (request.nu_status != MMSYSERR_NOERROR) {
RecordClose(handle);
return NULL;
}
//get head info
g_waveFileHdr.uFileLen = sizeof(g_waveFileHdr) - 8 - 1;//(int)-1 + sizeof(g_waveFileHdr) - 8
memset(&g_waveFileHdr.uDataLen, 0xFF, 4);
//write head
FileSeek(handle->hFile, 0, FILESEEK_BEGIN);
nCount = FileWrite(handle->hFile, (UINT8 *)&g_waveFileHdr, sizeof(g_waveFileHdr));
if (nCount != (int)sizeof(g_waveFileHdr)) {
RecordClose(handle);
g_nRecErrCode = nCount;
return NULL;
}
//get average bytes per second
handle->dwBytesPerSec = g_waveFileHdr.wfx.nAvgBytesPerSec;
//prepare two buffer
handle->recordHdr1.lpData = handle->recordBuf1;
handle->recordHdr1.dwBufferLength = RECORD_HEAD_LEN;
handle->recordHdr2.lpData = handle->recordBuf2;
handle->recordHdr2.dwBufferLength = RECORD_HEAD_LEN;
_RecordSetBuffer(handle, &handle->recordHdr1);
_RecordSetBuffer(handle, &handle->recordHdr2);
if (wMode == RECORD_MODE_APPEND) {
handle->dwTotalLen = FileLength(handle->hFile) - sizeof(g_waveFileHdr);
handle->dwSumTime = handle->dwTotalLen / handle->dwBytesPerSec;
FileSeek(handle->hFile, 0, FILESEEK_END);
}
else {
handle->dwTotalLen = 0;
handle->dwSumTime = 0;
}
handle->status = RECORD_STATUS_STOP;
return handle;
}
BOOL RecordStart(MRecord *handle)
{
NU_DRIVER_REQUEST request;
if (g_hRecord || !handle || !handle->pRecordDrv) {
return FALSE;
}
if (handle->status == RECORD_STATUS_RECORD) {
return TRUE;
}
//record start
request.nu_function = NU_STATUS;
request.nu_supplemental_ptr = (VOID *)"record";
NU_Request_Driver(handle->pRecordDrv, &request);
if (request.nu_status != MMSYSERR_NOERROR) {
return FALSE;
}
g_hRecord = handle;
handle->status = RECORD_STATUS_RECORD;
return TRUE;
}
BOOL RecordPause(MRecord *handle)
{
NU_DRIVER_REQUEST request;
int nCount;
if (g_hRecord != handle || !handle || !handle->pRecordDrv) {
return FALSE;
}
if (handle->status == RECORD_STATUS_RECORD) {
request.nu_function = NU_STATUS;
request.nu_supplemental_ptr = (VOID *)"stop";
NU_Request_Driver(handle->pRecordDrv, &request);
if (request.nu_status != MMSYSERR_NOERROR) {
return FALSE;
}
}
//get head info actually
g_waveFileHdr.uFileLen = handle->dwTotalLen + sizeof(g_waveFileHdr) - 8;
memcpy(&g_waveFileHdr.uDataLen, &handle->dwTotalLen, 4);;
//write head info actually
FileSeek(handle->hFile, 0, FILESEEK_BEGIN);
nCount = FileWrite(handle->hFile, (UINT8 *)&g_waveFileHdr, sizeof(g_waveFileHdr));
if (nCount != (int)sizeof(g_waveFileHdr))
{
g_nRecErrCode = nCount;
return FALSE;
}
FileClose(handle->hFile);
handle->hFile = -1;
handle->status = RECORD_STATUS_PAUSE;
return TRUE;
}
BOOL RecordResume(MRecord *handle)
{
NU_DRIVER_REQUEST request;
if (g_hRecord != handle || !handle || !handle->pRecordDrv) {
return FALSE;
}
handle->hFile = FileOpen(handle->fileName, FILEMODE_CREATEWRITE);
if (handle->hFile < 0) {
g_nRecErrCode = handle->hFile;
return FALSE;
}
FileSeek(handle->hFile, 0, FILESEEK_END);
if (handle->recordHdr1.dwFlags == 3) {
_RecordSetBuffer(handle, &handle->recordHdr1);
}
else if (handle->recordHdr2.dwFlags == 3) {
_RecordSetBuffer(handle, &handle->recordHdr2);
}
if (handle->status == RECORD_STATUS_PAUSE) {
request.nu_function = NU_STATUS;
request.nu_supplemental_ptr = (VOID *)"record";
NU_Request_Driver(handle->pRecordDrv, &request);
if (request.nu_status != MMSYSERR_NOERROR) {
return FALSE;
}
}
handle->status = RECORD_STATUS_RECORD;
return TRUE;
}
BOOL RecordStop(MRecord *handle)
{
NU_DRIVER_REQUEST request;
int nCount;
g_hRecord = NULL;
if (!handle || !handle->pRecordDrv) {
return FALSE;
}
if (handle->status == RECORD_STATUS_STOP) {
return TRUE;
}
if (handle->status == RECORD_STATUS_RECORD) {
//record stop
request.nu_function = NU_STATUS;
request.nu_supplemental_ptr = (VOID *)"stop";
NU_Request_Driver(handle->pRecordDrv, &request);
if (request.nu_status != MMSYSERR_NOERROR) {
return FALSE;
}
}
//get head info actually
g_waveFileHdr.uFileLen = handle->dwTotalLen + sizeof(g_waveFileHdr) - 8;
memcpy(&g_waveFileHdr.uDataLen, &handle->dwTotalLen, 4);;
//write head info actually
if (handle->hFile < 0) {
handle->hFile = FileOpen(handle->fileName, FILEMODE_CREATEWRITE);
}
if (handle->hFile < 0) {
g_nRecErrCode = handle->hFile;
return FALSE;
}
FileSeek(handle->hFile, 0, FILESEEK_BEGIN);
nCount = FileWrite(handle->hFile, (UINT8 *)&g_waveFileHdr, sizeof(g_waveFileHdr));
if (nCount != (int)sizeof(g_waveFileHdr))
{
g_nRecErrCode = nCount;
return FALSE;
}
handle->status = RECORD_STATUS_STOP;
return TRUE;
}
BOOL RecordClose(MRecord *handle)
{
NU_DRIVER_REQUEST request;
if (handle == NULL) {
return TRUE;
}
if (handle->pRecordDrv) {
request.nu_function = NU_RELEASE;
NU_Request_Driver(handle->pRecordDrv, &request);
if (request.nu_status != MMSYSERR_NOERROR) return FALSE;
}
if (handle->hFile >= 0) {
FileClose(handle->hFile);
}
MemFree(handle);
return TRUE;
}
BOOL RecordIsRun()
{
if (g_hRecord && g_hRecord->status == RECORD_STATUS_RECORD) {
return TRUE;
}
else {
return FALSE;
}
}
VOID SendVoiceMsg(UINT wParam)
{
if (&g_quEventQueue)
{
UINT aEvent[2];
aEvent[0] = EVENT_VOICE;
aEvent[1] = (UINT)wParam;
NU_Send_To_Queue( &g_quEventQueue, aEvent, 2, NU_NO_SUSPEND);
}
}
void RecordSetCallBack(MRecord *handle, UINT8 *pCallBack)
{
handle->pCallBackFunc = pCallBack;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?