DirectSound播放PCM(可播放實時採集的音訊資料)
前言
該篇整理的原始來源為http://blog.csdn.net/leixiaohua1020/article/details/40540147。非常感謝該博主的無私奉獻,寫了不少關於不同多媒體庫的博文。讓我這個小白學習到不少。現在將其整理是為了收錄,以備自己檢視。
一、DirectSound簡介
DirectSound是微軟所開發DirectX的元件之一,可以在Windows 作業系統上錄音,並且記錄波形音效(waveform sound)。目前DirectSound 是一個成熟的API ,提供許多有用的功能,例如能夠在較高的解析度播放多聲道聲音。DirectSound3D(DS3D)最早是1993年與 DirectX 3 一起發表的。DirectX 8以後的DirectSound和DirectSound3D的(DS3D)被合稱DirectX Audio。
DirectSound有以下幾種物件:
圖1.DirectSound物件
二、DirectSound播放音訊的流程
使用DirectSound播放音訊一般情況下需要如下步驟:
1.初始化
- 建立一個IDirectSound8介面的物件
- 設定協作級
- 建立一個主緩衝物件
- 建立一個副緩衝物件
- 建立通知物件
- 設定通知位置
- 開始播放
2.迴圈播放聲音
- 資料填充至副緩衝區
- 等待播放完成
三、結合介面詳細分析
1.初始化
1)建立一個IDirectSound8介面的物件
通過DirectSoundCreate8()方法可以建立一個裝置物件。這個物件通常代表預設的播放裝置。DirectSoundCreate8()函式原型如下。
1 HRESULT DirectSoundCreate8(2 LPCGUID lpcGuidDevice, 3 LPDIRECTSOUND8 * ppDS8, 4 LPUNKNOWN pUnkOuter 5 )
引數的含義如下:
lpcGuidDevice:要建立的裝置物件的GUID。可以指定為NULL,代表預設的播放裝置。
ppDS8:返回的IDirectSound8物件的地址。
pUnkOuter:必須設為NULL。
例如如下程式碼即可建立一個IDirectSound8介面的物件
1 IDirectSound8 *m_pDS=NULL; 2 DirectSoundCreate8(NULL,&m_pDS,NULL);
2) 設定協作級
Windows 是一個多工環境,同一時間有多個應用程式去訪問裝置。通過使用協作級別,DirectSound可以確保應用程式不會在別的裝置使用時去訪問,每個 DirectSound應用程式都有一個協作級別,這個級別決定著訪問硬體的許可權。
在建立一個裝置物件以後,必須通過用IDirectSound8的SetCooperativeLevel()設定協作許可權,否則將聽不到聲音。SetCooperativeLevel()的原型如下
1 HRESULT SetCooperativeLevel( 2 HWND hwnd, 3 DWORD dwLevel 4 )
引數的含義如下:
hwnd:應用程式視窗控制代碼。
dwLevel:支援以下幾種級別:
DSSCL_EXCLUSIVE:與DSSCL_PRIORITY具有相同的作用。
DSSCL_NORMAL:正常的協調層級標誌,其他程式可共享音效卡裝置進行播放。
DSSCL_PRIORITY:設定音效卡裝置為當前程式獨佔。
DSSCL_WRITEPRIMAR:可寫主緩衝區,此時副緩衝區就不能進行播放處理,即不能將次緩衝區的資料送進混聲器,再輸出到主緩衝區上。這是最完全控制聲音播放的方式。
3) 建立一個主緩衝物件
使用IDirectSound8的CreateSoundBuffer()可以建立一個IDirectSoundBuffer介面的主緩衝區物件。CreateSoundBuffer()的原型如下。
1 HRESULT CreateSoundBuffer( 2 LPCDSBUFFERDESC pcDSBufferDesc, 3 LPDIRECTSOUNDBUFFER * ppDSBuffer, 4 LPUNKNOWN pUnkOuter 5 )
引數的含義如下:
pcDSBufferDesc:描述聲音緩衝的DSBUFFERDESC結構體的地址
ppDSBuffer:返回的IDirectSoundBuffer介面的物件的地址。
pUnkOuter:必須設定為NULL。
其中涉及到一個描述聲音緩衝的結構體DSBUFFERDESC,該結構體的定義如下:
1 typedef struct _DSBUFFERDESC 2 { 3 DWORD dwSize; 4 DWORD dwFlags; 5 DWORD dwBufferBytes; 6 DWORD dwReserved; 7 LPWAVEFORMATEX lpwfxFormat; 8 } DSBUFFERDESC
簡單解釋一下其中的變數的含義:
dwSize:結構體的大小。必須初始化該值。
dwFlags:設定聲音快取的屬性。有很多選項,可以組合使用,就不一一列出了。詳細的引數可以檢視文件。
dwBufferBytes:緩衝的大小。
dwReserved:保留引數,暫時沒有用。
lpwfxFormat:指向一個WAVE格式檔案頭的指標。
設定DSBUFFERDESC完畢後,就可以使用CreateSoundBuffer()建立主緩衝了。示例程式碼如下:
1 DSBUFFERDESC dsbd; 2 memset(&dsbd,0,sizeof(dsbd)); 3 dsbd.dwSize=sizeof(dsbd); 4 dsbd.dwFlags=DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY |DSBCAPS_GETCURRENTPOSITION2; 5 dsbd.dwBufferBytes=MAX_AUDIO_BUF*BUFFERNOTIFYSIZE; 6 //WAVE Header 7 dsbd.lpwfxFormat=(WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX)); 8 dsbd.lpwfxFormat->wFormatTag=WAVE_FORMAT_PCM; 9 /* format type */ 10 (dsbd.lpwfxFormat)->nChannels=channels; 11 /* number of channels (i.e. mono, stereo...) */ 12 (dsbd.lpwfxFormat)->nSamplesPerSec=sample_rate; 13 /* sample rate */ 14 (dsbd.lpwfxFormat)->nAvgBytesPerSec=sample_rate*(bits_per_sample/8)*channels; 15 /* for buffer estimation */ 16 (dsbd.lpwfxFormat)->nBlockAlign=(bits_per_sample/8)*channels; 17 /* block size of data */ 18 (dsbd.lpwfxFormat)->wBitsPerSample=bits_per_sample; 19 /* number of bits per sample of mono data */ 20 (dsbd.lpwfxFormat)->cbSize=0; 21 22 23 //Creates a sound buffer object to manage audio samples. 24 HRESULT hr1; 25 if( FAILED(m_pDS->CreateSoundBuffer(&dsbd,&m_pDSBuffer,NULL))){ 26 return FALSE; 27 }
4) 建立一個副緩衝物件
使用IDirectSoundBuffer的QueryInterface()可以得到一個IDirectSoundBuffer8介面的物件。IDirectSoundBuffer8的GUID為IID_IDirectSoundBuffer8。示例程式碼如下。
1 IDirectSoundBuffer *m_pDSBuffer=NULL; 2 IDirectSoundBuffer8 *m_pDSBuffer8=NULL; 3 ... 4 if( FAILED(m_pDSBuffer->QueryInterface(IID_IDirectSoundBuffer8,(LPVOID*)&m_pDSBuffer8))){ 5 return FALSE ; 6 }
5) 建立通知物件
使用IDirectSoundBuffer8的QueryInterface()可以得到一個IDirectSoundNotify8介面的物件。IDirectSoundBuffer8的GUID為IID_IDirectSoundNotify。示例程式碼如下。
1 IDirectSoundBuffer8 *m_pDSBuffer8=NULL; 2 IDirectSoundNotify8 *m_pDSNotify=NULL; 3 … 4 if(FAILED(m_pDSBuffer8->QueryInterface(IID_IDirectSoundNotify,(LPVOID*)&m_pDSNotify))){ 5 return FALSE ; 6 }
一句話概括一下通知物件的作用:當DirectSound緩衝區中的資料播放完畢後,告知系統應該填充新的資料。
6) 設定通知位置
使用IDirectSoundNotify8的SetNotificationPositions()可以設定通知的位置。SetNotificationPositions()的原型如下。
1 HRESULT SetNotificationPositions( 2 DWORD dwPositionNotifies, 3 LPCDSBPOSITIONNOTIFY pcPositionNotifies 4 )
引數含義如下。
dwPositionNotifies:DSBPOSITIONNOTIFY結構體的數量。既包含幾個通知的位置。
pcPositionNotifies:指向DSBPOSITIONNOTIFY結構體陣列的指標。
在這裡涉及到一個結構體DSBPOSITIONNOTIFY,它描述了通知的位置。DSBPOSITIONNOTIFY的定義如下。
1 typedef struct DSBPOSITIONNOTIFY { 2 DWORD dwOffset; 3 HANDLE hEventNotify; 4 } DSBPOSITIONNOTIFY;
它的成員的含義如下。
dwOffset:通知事件觸發的位置(距離緩衝開始位置的偏移量)。
hEventNotify:觸發的事件的控制代碼。
7) 開始播放
使用IDirectSoundBuffer8的SetCurrentPosition ()可以設定播放的位置。SetCurrentPosition ()原型如下
1 HRESULT SetCurrentPosition( 2 DWORD dwNewPosition 3 )
其中dwNewPosition是播放點與緩衝區首個位元組之間的偏移量。
使用IDirectSoundBuffer8的Play ()可以開始播放音訊資料。Play ()原型如下。
1 HRESULT Play( 2 DWORD dwReserved1, 3 DWORD dwPriority, 4 DWORD dwFlags 5 )
引數含義:
dwReserved1:保留引數,必須取0。
dwPriority:優先順序,一般情況下取0即可。
dwFlags:標誌位。目前常見的是DSBPLAY_LOOPING。當播放至緩衝區結尾的時候,重新從緩衝區開始處開始播放。
2. 迴圈播放聲音
1) 資料填充至副緩衝區
資料填充至副緩衝區之前,需要先使用Lock()鎖定緩衝區。然後就可以使用fread(),memcpy()等方法將PCM音訊取樣資料填充至緩衝區。資料填充完畢後,使用Unlock()取消對緩衝區的鎖定。如果是實時採集的音訊資料,只要將音訊資料複製到Lock()獲取到的ppvAudioPtr1指向的地址,大小為pdwAudioBytes1,就可以播放了。(我使用的方式就是如此,實現了實時音訊的播放,下文中的例子資料是讀取自檔案。)
Lock()函式的原型如下。
1 HRESULT Lock( 2 DWORD dwOffset, 3 DWORD dwBytes, 4 LPVOID * ppvAudioPtr1, 5 LPDWORD pdwAudioBytes1, 6 LPVOID * ppvAudioPtr2, 7 LPDWORD pdwAudioBytes2, 8 DWORD dwFlags 9 )
引數的含義如下。
dwOffset:鎖定的記憶體與緩衝區首地址之間的偏移量。
dwBytes:鎖定的快取的大小。
ppvAudioPtr1:獲取到的指向快取資料的指標。
pdwAudioBytes1:獲取到的快取資料的大小。
ppvAudioPtr2:沒有用到,設定為NULL。
pdwAudioBytes2:沒有用到,設定為0。
dwFlags:暫時沒有研究。
UnLock()函式的原型如下。
1 HRESULT Unlock( 2 LPVOID pvAudioPtr1, 3 DWORD dwAudioBytes1, 4 LPVOID pvAudioPtr2, 5 DWORD dwAudioBytes2 6 )
引數含義如下。
pvAudioPtr1:通過Lock()獲取到的指向快取資料的指標。
dwAudioBytes1:寫入的資料量。
pvAudioPtr2:沒有用到。
dwAudioBytes2:沒有用到。
2) 等待播放完成
根據此前設定的通知機制,使用WaitForMultipleObjects()等待緩衝區中的資料播放完畢,然後進入下一個迴圈。
四、播放音訊流程總結
DirectSound播放PCM音訊資料的流程如下圖所示。
圖2
其中涉及到的幾個結構體之間的關係如下圖所示。
圖3.結構體關係
五、使用示例程式碼
該程式碼也是直接使用的來自原博主的程式碼,如下
1 /** 2 * 最簡單的DirectSound播放音訊的例子(DirectSound播放PCM) 3 * Simplest Audio Play DirectSound (DirectSound play PCM) 4 * 5 * 雷霄驊 Lei Xiaohua 6 * [email protected] 7 * 中國傳媒大學/數字電視技術 8 * Communication University of China / Digital TV Technology 9 * http://blog.csdn.net/leixiaohua1020 10 * 11 * 本程式使用DirectSound播放PCM音訊取樣資料。 12 * 是最簡單的DirectSound播放音訊的教程。 13 * 14 * 函式呼叫步驟如下: 15 * 16 * [初始化] 17 * DirectSoundCreate8():建立一個DirectSound物件。 18 * SetCooperativeLevel():設定協作許可權,不然沒有聲音。 19 * IDirectSound8->CreateSoundBuffer():建立一個主緩衝區物件。 20 * IDirectSoundBuffer->QueryInterface(IID_IDirectSoundBuffer8..): 21 * 建立一個副緩衝區物件,用來儲存要播放的聲音資料檔案。 22 * IDirectSoundBuffer8->QueryInterface(IID_IDirectSoundNotify..): 23 * 建立通知物件,通知應用程式指定播放位置已經達到。 24 * IDirectSoundNotify8->SetNotificationPositions():設定通知位置。 25 * IDirectSoundBuffer8->SetCurrentPosition():設定播放的起始點。 26 * IDirectSoundBuffer8->Play():開始播放。 27 * 28 * [迴圈播放資料] 29 * IDirectSoundBuffer8->Lock():鎖定副緩衝區,準備寫入資料。 30 * fread():讀取資料。 31 * IDirectSoundBuffer8->Unlock():解鎖副緩衝區。 32 * WaitForMultipleObjects():等待“播放位置已經達到”的通知。 33 * 34 * This software plays PCM raw audio data using DirectSound. 35 * It's the simplest tutorial about DirectSound. 36 * 37 * The process is shown as follows: 38 * 39 * [Init] 40 * DirectSoundCreate8(): Init DirectSound object. 41 * SetCooperativeLevel(): Must set, or we won't hear sound. 42 * IDirectSound8->CreateSoundBuffer(): Create primary sound buffer. 43 * IDirectSoundBuffer->QueryInterface(IID_IDirectSoundBuffer8..): 44 * Create secondary sound buffer. 45 * IDirectSoundBuffer8->QueryInterface(IID_IDirectSoundNotify..): 46 * Create Notification object. 47 * IDirectSoundNotify8->SetNotificationPositions(): 48 * Set Notification Positions. 49 * IDirectSoundBuffer8->SetCurrentPosition(): Set position to start. 50 * IDirectSoundBuffer8->Play(): Begin to play. 51 * 52 * [Loop to play data] 53 * IDirectSoundBuffer8->Lock(): Lock secondary buffer. 54 * fread(): get PCM data. 55 * IDirectSoundBuffer8->Unlock(): UnLock secondary buffer. 56 * WaitForMultipleObjects(): Wait for Notifications. 57 */ 58 #include <stdio.h> 59 #include <stdlib.h> 60 #include <windows.h> 61 #include <dsound.h> 62 63 64 #define MAX_AUDIO_BUF 4 65 #define BUFFERNOTIFYSIZE 192000 66 67 68 int sample_rate=8000; //PCM sample rate 69 int channels=1; //PCM channel number 70 int bits_per_sample=16; //bits per sample 71 72 BOOL main(int argc,char * argv[]) 73 { 74 int i; 75 FILE * fp; 76 if((fp=fopen("../out.pcm","rb"))==NULL){ 77 printf("cannot open this file\n"); 78 return -1; 79 } 80 81 IDirectSound8 *m_pDS=0; 82 IDirectSoundBuffer8 *m_pDSBuffer8=NULL; //used to manage sound buffers. 83 IDirectSoundBuffer *m_pDSBuffer=NULL; 84 IDirectSoundNotify8 *m_pDSNotify=0; 85 DSBPOSITIONNOTIFY m_pDSPosNotify[MAX_AUDIO_BUF]; 86 HANDLE m_event[MAX_AUDIO_BUF]; 87 88 SetConsoleTitle(TEXT("Simplest Audio Play DirectSound"));//Console Title 89 //Init DirectSound 90 if(FAILED(DirectSoundCreate8(NULL,&m_pDS,NULL))) 91 return FALSE; 92 if(FAILED(m_pDS->SetCooperativeLevel(FindWindow(NULL,TEXT("Simplest Audio Play DirectSound")),DSSCL_NORMAL))) 93 return FALSE; 94 95 96 DSBUFFERDESC dsbd; 97 memset(&dsbd,0,sizeof(dsbd)); 98 dsbd.dwSize=sizeof(dsbd); 99 dsbd.dwFlags=DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY |DSBCAPS_GETCURRENTPOSITION2; 100 dsbd.dwBufferBytes=MAX_AUDIO_BUF*BUFFERNOTIFYSIZE; 101 dsbd.lpwfxFormat=(WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX)); 102 dsbd.lpwfxFormat->wFormatTag=WAVE_FORMAT_PCM; 103 /* format type */ 104 (dsbd.lpwfxFormat)->nChannels=channels; 105 /* number of channels (i.e. mono, stereo...) */ 106 (dsbd.lpwfxFormat)->nSamplesPerSec=sample_rate; 107 /* sample rate */ 108 (dsbd.lpwfxFormat)->nAvgBytesPerSec=sample_rate*(bits_per_sample/8)*channels; 109 /* for buffer estimation */ 110 (dsbd.lpwfxFormat)->nBlockAlign=(bits_per_sample/8)*channels; 111 /* block size of data */ 112 (dsbd.lpwfxFormat)->wBitsPerSample=bits_per_sample; 113 /* number of bits per sample of mono data */ 114 (dsbd.lpwfxFormat)->cbSize=0; 115 116 //Creates a sound buffer object to manage audio samples. 117 HRESULT hr1; 118 if( FAILED(m_pDS->CreateSoundBuffer(&dsbd,&m_pDSBuffer,NULL))){ 119 return FALSE; 120 } 121 if( FAILED(m_pDSBuffer->QueryInterface(IID_IDirectSoundBuffer8,(LPVOID*)&m_pDSBuffer8))){ 122 return FALSE ; 123 } 124 //Get IDirectSoundNotify8 125 if(FAILED(m_pDSBuffer8->QueryInterface(IID_IDirectSoundNotify,(LPVOID*)&m_pDSNotify))){ 126 return FALSE ; 127 } 128 for(i =0;i<MAX_AUDIO_BUF;i++){ 129 m_pDSPosNotify[i].dwOffset =i*BUFFERNOTIFYSIZE; 130 m_event[i]=::CreateEvent(NULL,false,false,NULL); 131 m_pDSPosNotify[i].hEventNotify=m_event[i]; 132 } 133 m_pDSNotify->SetNotificationPositions(MAX_AUDIO_BUF,m_pDSPosNotify); 134 m_pDSNotify->Release(); 135 136 //Start Playing 137 BOOL isPlaying =TRUE; 138 LPVOID buf=NULL; 139 DWORD buf_len=0; 140 DWORD res=WAIT_OBJECT_0; 141 DWORD offset=BUFFERNOTIFYSIZE; 142 143 m_pDSBuffer8->SetCurrentPosition(0); 144 m_pDSBuffer8->Play(0,0,DSBPLAY_LOOPING); 145 //Loop 146 while(isPlaying){ 147 if((res >=WAIT_OBJECT_0)&&(res <=WAIT_OBJECT_0+3)){ 148 m_pDSBuffer8->Lock(offset,BUFFERNOTIFYSIZE,&buf,&buf_len,NULL,NULL,0); 149 150 // 如果是實時音訊播放,那麼下面的資料就可以把記憶體中buf_len大小的資料複製到buf指向的地址即可 151 if(fread(buf,1,buf_len,fp)!=buf_len){相關推薦
DirectSound播放PCM(可播放實時採集的音訊資料)
前言 該篇整理的原始來源為http://blog.csdn.net/leixiaohua1020/article/details/40540147。非常感謝該博主的無私奉獻,寫了不少關於不同多媒體庫的博文。讓我這個小白學習到不少。現在將其整理是為了收錄,以備自己檢視。一、D
【四】Flume使用:監控檔案實時採集新增資料輸出到控制檯
agent選擇:exec source + memory channel + logger sinkexec source 執行一個給定的unix命令memory channel channel中的資料放在記憶體中logger sink 最終把採集到的資料列印到控制檯上建立測
Android端做RTP實時傳送音訊資料實現
如果你也在Android端做RTP傳送資料的話,通過網上查詢資料,相信你不難發現,在使用RTP/RTCP協議傳送資料是有現成的庫進行呼叫的,Jlibrtp這個庫就是Java實現的,但是這個庫是沒有說明文件的,比較摳腳,而且百度谷歌找到例子又很少,基本上都沒什麼卵
最簡單的OpenSL播放PCM實時音訊
這裡是c語言寫的給android用的,可以拿到其他平臺使用。既然是最簡單的,肯定使用起來就是超級簡單如回撥方法就一句程式碼。這裡簡單說一下使用要注意的地方: 1.如果想要使用opensl的一些功能如音量控制: 只是這樣是不可以的,拿到的bqPlayerV
使用AndroidTrack播放pcm音訊
package com.tlinux.mp3playeraudiotrack; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioTrack; imp
5.基於SDL2播放PCM音訊
接上一篇<基於FFMPEG將音訊解碼為PCM>,接下來就是需要將PCM音訊進行播放,查閱資料是通過SDL進行音視訊的播放,因此這裡記錄一下SDL相關的筆記。。。 一.簡介 摘抄自百度百科: SDL(Simple DirectMedia Layer)是一套開
(五) AudioTrack播放pcm音訊
java public class AudioTrackActivity extends BaseActivity { public static void startAudioTrackActivity(Activity activity) {
如何跨平臺python播放pcm音訊
本文首先要感謝以下兩篇部落格的指導: 本文依賴的程式碼請參考文章1,本文主要介紹在Windows,MacOS環境下如何搭建python依賴環境。 首先,需要使用pip命令安裝pysdl2擴充套件包:pip install pysdl2,如果不使用pip命令,則
使用 RK3399 搭載 Android 系統7.1.2,出現 AudioTrack 有時無法播放 PCM 音訊
RK3399 在 Android 系統 7.1.2,出現 AudioTrack 有時無法播放 PCM 音訊的問題 問題背景: 切換 rk3399 後,搭載系統為 Android 7.1.2,如果單獨使用 audiotrack 播放 PCM 音訊是沒有問題,但是應用在智慧家居上,一般都
linux下mono播放PCM音訊
測試環境: Ubuntu 14 MonoDevelop CodeBlocks 1、建立一個共享庫(shared library) 這裡用到了linux下的音訊播放庫,alsa-lib。 alsa是linux下的一個開源專案,它的全名是Advanced Linux
Android直播開發之旅(13):使用FFmpeg+OpenSL ES播放PCM音訊
在Android直播開發之旅(12):初探FFmpeg開源框架一文中,我們詳細介紹了FFmpeg框架的架構、音視訊相關術語以及重要的結構體。為了能夠對這些重要的結構體有個深入的理解,本文將在此基礎上,利用FFmpeg解析rtsp資料流以獲取AAC音訊資料,再對AAC進行解碼為PC
最簡單的視音訊播放示例9:SDL2播放PCM
最簡單的視音訊播放示例系列文章列表: ===================================================== 本文記錄SDL播放音訊的技術。在這裡使用的版本是SDL2。實際上SDL本身並不提供視音訊播放的功能,它只
iOS 簡單的視訊直播功能開發(實時視音訊流錄製編碼+RTMP傳輸+實時拉流解碼播放)
原生開發基本流程:AVFoundation獲取視訊流,得到未編碼的CMSampleBuffer,需要編碼成Mpeg-4格式。編碼分軟編碼和硬編碼,考慮到iOS8之後VideoToolBox開放使用,選用VideoToolBox進行編碼。坑爹的是針對它連文件都沒有。github上有
【android開發】實現語音資料實時採集/播放
今天無意中看到一篇關於android實現語音資料實時採集/播放的文章,感覺寫得非常棒,挺全面的,所以特地轉載了,還有其實還可以根據這篇部落格內容考慮下視訊資料實時採集、播放的實現。部落格原文地址http://blog.csdn.net/lantingshuxu/article/details/5352031
android中AudioRecord採集音訊的引數說明以及audioTrack的播放
在android中採集音訊的api是android.media.AudioRecord類 在android中播放音訊也是從api中的類分析 其中構造器的幾個引數就是標準的聲音採集引數 以下是引數的含義解釋 1. public AudioRecord (int audioSource, int sampleR
C# NAudio錄音和播放音訊檔案-實時繪製音訊波形圖(從音訊流資料獲取,而非裝置獲取)
NAudio的錄音和播放錄音都有對應的類,我在使用Wav格式進行錄音和播放錄音時使用的類時WaveIn和WaveOut,這兩個類是對功能的回撥和一些事件觸發。 在WaveIn和WaveOut之外還有對音訊流讀寫使用的WaveFileWriter和WaveFileReader類,具體細節可檢視其原始碼進
Android 音視頻深入 二 AudioTrack播放pcm(附源碼下載)
實例 固定 回放 chan pla ng- stream 需要 大小 本篇項目地址,名字是錄音和播放PCM,求starhttps://github.com/979451341/Audio-and-video-learning-materials 1.AudioTrack官方
Lily_music 網頁音樂播放器 -可搜尋(附歌詞聯動播放效果解說)
部落格地址:https://ainyi.com/#/59 寫在前面 這是我今年(2018)年初的小專案,當時也是手賤,不想用別的播放器,想著做一個自己的網頁播放器,有個歌曲列表、可關鍵詞搜尋、歌詞滾動播放的效果,於是乎,就做了這一個 Lily_music 當時的感慨 有好幾天沒有發表
C++ 採集音訊PCM流功能
#include "stdafx.h" #include <stdio.h> #include <Windows.h> #pragma comment(lib, "winmm.lib") HWAVEIN hWaveIn; //輸入裝置
html網頁中顯示並且播放一個視訊,+播放一個音訊
//src 為視訊路徑 height 為視訊高度 width為視訊寬度 <embed src="intro.swf" height=