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 + -
显示快捷键?