首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

用waveInOpen采摘到的mic音频流,不保存到文件,可以直接播放吗

2013-01-07 
用waveInOpen采集到的mic音频流,不保存到文件,可以直接播放吗我是把采集到的数据保存到TMemorystream里面

用waveInOpen采集到的mic音频流,不保存到文件,可以直接播放吗
我是把采集到的数据保存到TMemorystream里面的,可不可以直接回放采集到的音频流呢?如果可以,怎么回放?

[解决办法]
花了点时间给你抄了段代码,直接放到你上次贴子那段里面就能测试了。

//------------------------------
#define BLOCK_SIZE  8192
#define BLOCK_COUNT 20

/*
 * function prototypes
 */ 
static void CALLBACK waveOutProc(HWAVEOUT, UINT, DWORD, DWORD, DWORD);
static WAVEHDR* allocateBlocks(int size, int count);
static void freeBlocks(WAVEHDR* blockArray);
static void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size);

/*
 * module level variables
 */
static CRITICAL_SECTION waveCriticalSection;
static WAVEHDR*         waveBlocks;
static volatile int     waveFreeBlockCount;
static int              waveCurrentBlock;
//----------------------

void __fastcall TForm1::PlaySoundFormStream( TMemoryStream *pmem)
{
    HWAVEOUT hWaveOut; /* device handle */
    WAVEFORMATEX wfx;  /* look this up in your documentation */
    int i;
    waveBlocks         = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT);
    waveFreeBlockCount = BLOCK_COUNT;
    waveCurrentBlock   = 0;
    
    InitializeCriticalSection(&waveCriticalSection);
        /*
     * set up the WAVEFORMATEX structure.
     */
    wfx.nSamplesPerSec  = 44100;  /* sample rate */
    wfx.wBitsPerSample  = 16;     /* sample size */
    wfx.nChannels       = 2;      /* channels    */
    wfx.cbSize          = 0;      /* size of _extra_ info */
    wfx.wFormatTag      = WAVE_FORMAT_PCM;
    wfx.nBlockAlign     = (wfx.wBitsPerSample * wfx.nChannels) >> 3;
    wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;

    /*
     * try to open the default wave device. WAVE_MAPPER is
     * a constant defined in mmsystem.h, it always points to the
     * default wave device on the system (some people have 2 or
     * more sound cards).
     */
    if(waveOutOpen(
        &hWaveOut, 
        WAVE_MAPPER, 
        &wfx, 


        (DWORD_PTR)waveOutProc, 
        (DWORD_PTR)&waveFreeBlockCount, 
        CALLBACK_FUNCTION
    ) != MMSYSERR_NOERROR) {
        Application->MessageBox( "Error", "unable to open wave mapper device\n", MB_OK);
        Application->Terminate();
    }

        
        writeAudio(hWaveOut, (char *)pmem->Memory,pmem->Size);
      while(waveFreeBlockCount < BLOCK_COUNT)
        Sleep(10);

    /*
     * unprepare any blocks that are still prepared
     */
    for(i = 0; i < waveFreeBlockCount; i++) 
        if(waveBlocks[i].dwFlags & WHDR_PREPARED)
            waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof(WAVEHDR));

    
    DeleteCriticalSection(&waveCriticalSection);
    freeBlocks(waveBlocks);
    waveOutClose(hWaveOut);
}
static void CALLBACK waveOutProc(
    HWAVEOUT hWaveOut, 
    UINT uMsg, 
    DWORD dwInstance,  
    DWORD dwParam1,    
    DWORD dwParam2     
)
{
    /*
     * pointer to free block counter
     */
    int* freeBlockCounter = (int*)dwInstance;
    /*
     * ignore calls that occur due to openining and closing the
     * device.
     */
    if(uMsg != WOM_DONE)
        return;

    EnterCriticalSection(&waveCriticalSection);
    (*freeBlockCounter)++;
    LeaveCriticalSection(&waveCriticalSection);
}
//---------------------------------------
WAVEHDR* allocateBlocks(int size, int count)
{
    unsigned char* buffer;
    int i;
    WAVEHDR* blocks;
    DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count;
    
    /*
     * allocate memory for the entire set in one go
     */
    if((buffer = (unsigned char*)HeapAlloc(
        GetProcessHeap(), 
        HEAP_ZERO_MEMORY, 
        totalBufferSize
    )) == NULL) {
        fprintf(stderr, "Memory allocation error\n");


        ExitProcess(1);
    }

    /*
     * and set up the pointers to each bit
     */
    blocks = (WAVEHDR*)buffer;
    buffer += sizeof(WAVEHDR) * count;
    for(i = 0; i < count; i++) {
        blocks[i].dwBufferLength = size;
        blocks[i].lpData = buffer;
        buffer += size;
    }
    
    return blocks;
}
//
void freeBlocks(WAVEHDR* blockArray)
{
    /* 
     * and this is why allocateBlocks works the way it does
     */ 
    HeapFree(GetProcessHeap(), 0, blockArray);
}
//
void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size)
{
    WAVEHDR* current;
    int remain;

    current = &waveBlocks[waveCurrentBlock];
    
    while(size > 0) {
        /* 
         * first make sure the header we're going to use is unprepared
         */
        if(current->dwFlags & WHDR_PREPARED) 
            waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR));

        if(size < (int)(BLOCK_SIZE - current->dwUser)) {
            memcpy(current->lpData + current->dwUser, data, size);
            current->dwUser += size;
            break;
        }

        remain = BLOCK_SIZE - current->dwUser;
        memcpy(current->lpData + current->dwUser, data, remain);
        size -= remain;
        data += remain;
        current->dwBufferLength = BLOCK_SIZE;
       
        waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR));
        waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));
        
        EnterCriticalSection(&waveCriticalSection);
        waveFreeBlockCount--;
        LeaveCriticalSection(&waveCriticalSection);
        
        /*


         * wait for a block to become free
         */
        while(!waveFreeBlockCount)
            Sleep(10);

        /*
         * point to the next block
         */
        waveCurrentBlock++;
        waveCurrentBlock %= BLOCK_COUNT;

        current = &waveBlocks[waveCurrentBlock];
        current->dwUser = 0;
    }
}

void __fastcall TForm1::Button3Click(TObject *Sender)
{
waveInStop(hWaveIn);
bRecordingStarted = false;
pms->Position = 0;
PlaySoundFormStream(pms);
}

热点排行