Windows音頻編程:Win32 Wave API 的使用

來源:互聯網
上載者:User

[轉自:http://blog.csdn.net/zhi_qiu_yi_ye/article/details/6663366]

    使用 Wave API 進行Windows音頻編程可以保持很大的自由度,而且與Linux中的OSS編程模式很像。下面我簡單介紹函數的調用順序,具體的用法參見MSDN(VS2008)。

  •     錄音:

        waveInOpen -> waveInPrepareHeader -> waveInAddBuffer -> waveInStart -> waveInStop -> waveInReset ->waveInUnprepareHeader -> waveInClose

    錄音的回呼函數只需要處理WIM_DATA訊息,拷貝資料及重新調用waveInAddBuffer將此緩衝排入佇列。

  •     放音:

        waveOutOpen -> waveOutPrepareHeader -> waveOutWrite -> waveOutReset -> waveOutUnprepareHeader -> waveOutClose

    下面是一個Win32控制台程式的源碼,環境VS2008,建立一個空的Win32控制台項目,加入此檔案編譯即可,功能為錄製5秒並回放。注意不要選擇Unicode字元集,不然裝置名稱會出現亂碼。

#include "stdafx.h"////WaveAPI.cpp//// by: 知秋一葉//#include <windows.h>#include <stdio.h>#include <stdlib.h>#include <mmsystem.h>#pragma comment(lib, "winmm.lib")#define BUFFER_SIZE (44100*16*2/8*5)// 錄製聲音長度#define FRAGMENT_SIZE 1024// 緩衝區大小#define FRAGMENT_NUM 4// 緩衝區個數static unsigned char buffer[BUFFER_SIZE] = {0};static int buf_count = 0;// 函數定義void CALLBACK waveInProc(HWAVEIN hwi,       UINT uMsg,          DWORD_PTR dwInstance,   DWORD_PTR dwParam1,   DWORD_PTR dwParam2     );void CALLBACK waveOutProc(  HWAVEOUT hwo,     UINT uMsg,           DWORD_PTR dwInstance,     DWORD_PTR dwParam1,      DWORD_PTR dwParam2     );// 入口int main(){/* 錄音 */// Deviceint nReturn = waveInGetNumDevs();printf("輸入裝置數目:%d\n", nReturn);for (int i=0; i<nReturn; i++){WAVEINCAPS wic;waveInGetDevCaps(i, &wic, sizeof(WAVEINCAPS));printf("#%d\t裝置名稱:%s\n", i, wic.szPname);}// openHWAVEIN hWaveIn;WAVEFORMATEX wavform;wavform.wFormatTag = WAVE_FORMAT_PCM;wavform.nChannels = 2;wavform.nSamplesPerSec = 44100;wavform.nAvgBytesPerSec = 44100*16*2/8;wavform.nBlockAlign = 4;wavform.wBitsPerSample = 16;wavform.cbSize = 0;waveInOpen(&hWaveIn, WAVE_MAPPER, &wavform, (DWORD_PTR)waveInProc, 0, CALLBACK_FUNCTION);WAVEINCAPS wic;waveInGetDevCaps((UINT_PTR)hWaveIn, &wic, sizeof(WAVEINCAPS));printf("開啟的輸入裝置:%s\n", wic.szPname);// prepare bufferstatic WAVEHDR wh[FRAGMENT_NUM];for (int i=0; i<FRAGMENT_NUM; i++){wh[i].lpData = new char[FRAGMENT_SIZE];wh[i].dwBufferLength = FRAGMENT_SIZE;wh[i].dwBytesRecorded = 0;wh[i].dwUser = NULL;wh[i].dwFlags = 0;wh[i].dwLoops = 1;wh[i].lpNext = NULL;wh[i].reserved = 0;waveInPrepareHeader(hWaveIn, &wh[i], sizeof(WAVEHDR));waveInAddBuffer(hWaveIn, &wh[i], sizeof(WAVEHDR));}// recordprintf("Start to Record...\n");buf_count = 0;waveInStart(hWaveIn);while (buf_count < BUFFER_SIZE){Sleep(1);}printf("Record Over!\n\n");// cleanwaveInStop(hWaveIn);waveInReset(hWaveIn);for (int i=0; i<FRAGMENT_NUM; i++){waveInUnprepareHeader(hWaveIn, &wh[i], sizeof(WAVEHDR));delete wh[i].lpData;}waveInClose(hWaveIn);system("pause");printf("\n");/* 放音 */// DevicenReturn = waveOutGetNumDevs();printf("\n輸出裝置數目:%d\n", nReturn);for (int i=0; i<nReturn; i++){WAVEOUTCAPS woc;waveOutGetDevCaps(i, &woc, sizeof(WAVEOUTCAPS));printf("#%d\t裝置名稱:%s\n", i, wic.szPname);}// openHWAVEOUT hWaveOut;waveOutOpen(&hWaveOut, WAVE_MAPPER, &wavform, (DWORD_PTR)waveOutProc, 0, CALLBACK_FUNCTION);WAVEOUTCAPS woc;waveOutGetDevCaps((UINT_PTR)hWaveOut, &woc, sizeof(WAVEOUTCAPS));printf("開啟的輸出裝置:%s\n", wic.szPname);// prepare bufferWAVEHDR wavhdr;wavhdr.lpData = (LPSTR)buffer;wavhdr.dwBufferLength = BUFFER_SIZE;wavhdr.dwFlags = 0;wavhdr.dwLoops = 0;waveOutPrepareHeader(hWaveOut, &wavhdr, sizeof(WAVEHDR));// playprintf("Start to Play...\n");buf_count = 0;waveOutWrite(hWaveOut, &wavhdr, sizeof(WAVEHDR));while (buf_count < BUFFER_SIZE){Sleep(1);}// cleanwaveOutReset(hWaveOut);waveOutUnprepareHeader(hWaveOut, &wavhdr, sizeof(WAVEHDR));waveOutClose(hWaveOut);printf("Play Over!\n\n");return 0;}// 錄音回呼函數void CALLBACK waveInProc(HWAVEIN hwi,       UINT uMsg,          DWORD_PTR dwInstance,   DWORD_PTR dwParam1,   DWORD_PTR dwParam2     ){LPWAVEHDR pwh = (LPWAVEHDR)dwParam1;if ((WIM_DATA==uMsg) && (buf_count<BUFFER_SIZE)){int temp = BUFFER_SIZE - buf_count;temp = (temp>pwh->dwBytesRecorded) ? pwh->dwBytesRecorded : temp;memcpy(buffer+buf_count, pwh->lpData, temp);buf_count += temp;waveInAddBuffer(hwi, pwh, sizeof(WAVEHDR));}}// 放音回呼函數void CALLBACK waveOutProc(  HWAVEOUT hwo,     UINT uMsg,           DWORD_PTR dwInstance,     DWORD_PTR dwParam1,      DWORD_PTR dwParam2     ){if (WOM_DONE == uMsg){buf_count = BUFFER_SIZE;}}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.