1. 程式人生 > >使用第三方類庫n-audio播放MP3檔案

使用第三方類庫n-audio播放MP3檔案

DirectX由於期末考試,暫時先不研究了.這學期的期末考試估計得掛幾科了,英語依然是個鬧啊,其實我本來初中英語挺好的,哎~~現在完啦.越來越發現英語的重要性,但英語水平卻越來越跟不上同齡人,矛盾啊.不過矛盾是激勵社會發展的動力,希望也能夠成為我學習英語的動力吧.

前兩天看了看c#實現MP3功能的程式碼.網上不是很多,大體上分三種方法.呼叫windowsAPI,使用DirectX sound,和第三方類庫.前兩個比較簡單.但第三方類庫一來不好找,而來很複雜,而且都是外國人寫的.我英語就很差,幫助文件對我來說就是抓瞎.研究了幾天有一點小小的心得,希望能給英語一樣和我不好的"同志"一點幫助~~

好進入正題我不說別的,只說N-Audio這套類庫,是個外國人寫的,程式碼安全,全面,而且是個開源的類庫,你使用不用擔心突然有一天法院一個傳票過去說懷疑你對某某公司涉嫌侵權~~哈哈,這套類庫在我釋出的資源裡有,解壓後大約有20兆左右.

解壓後共有三個資料夾,分別是Binaries,SampleApp,SourceCode分別是N-audio的類庫Dll檔案,例項應用,和原始碼,如果你想在你的專案中使用n-audio就要在引用中新增Binaries裡的n-audio.dll檔案了.至於怎麼使用,我們直接看原始碼:

開啟解決方案後,一共有8個專案,有音訊文件檢視,音訊文件轉換,n-audio的例項,其中n-audio的專案就是你引用的n-audio.dll檔案的原始碼了;

作為播放Mp3檔案們介紹幾個核心類:

Mp3fileReader,繼承自WaveStream它有兩種構造形勢,一是通過傳入檔名來構造Mp3FileReader另一個就是傳入流來構造它了,形勢分別是:Mp3FileReader(string filename)和Mp3FileReader(stream _stream);讓我們來看一下它的類關係圖:

熟習設計模式的人也許很快就會發現,MP3FileReader就是那個可以生產具體產品的車間通過構造它你就可以構造出可以讀取MP3問件的例項來~~

接著我們來說明MP3format類:

在說此類之前不得不先介紹一下關於MP3檔案的一些知識,我們知道,硬碟式用來儲存數字訊號,也就是二進位制訊號的,而聲音卻是模擬訊號,要想在硬碟中儲存聲音就必須將模擬訊號數字化,那麼如何將模擬訊號進行數字化呢?我們知道,模擬訊號時連續不離散的,而數字訊號是不能儲存非離散資訊的,記得小時候學過怎麼計算圓的面積嗎?我們將圓分成很多小三角形,然後將三角形拼成正方形來計算面積,小三角形越多,所計算出的面積就越接近真實值.儲存音訊訊號也是這個原理,它每隔一段時間(一般都是毫秒級)記錄一次此時的波形幅值這樣當你間隔的實間足夠小就可以模擬出清晰的音訊訊號了.這裡只要大概瞭解就可以,想知道詳細的,網上有的是解釋.我們接著說,但是用這中方法儲存的檔案時很大的,一份中大約要10兆的空間,於是便出現了MP3各式檔案,它將音訊檔案分成若干塊,將每塊按照一定的演算法壓縮,這樣可以將問件壓縮至原來的十分之一.

MP3Format主要記錄MP3檔案的各式資訊,繼承自waveFormat類.用於支援MP3Filereader類讀寫MP3流和MP3檔案.類關係圖如下:

下面我們就說明一下如何具體的播放一個MP3檔案:

IWavePlayer waveOut;
        string fileName = null;
        WaveStream mainOutputStream;
        WaveChannel32 volumeStream;

 private WaveStream CreateInputStream(string fileName)
        {

                 WaveChannel32 inputStream;  

                WaveStream mp3Reader = new Mp3FileReader(fileName);
                WaveStream pcmStream = WaveFormatConversionStream.CreatePcmStream(mp3Reader);
                WaveStream blockAlignedStream = new BlockAlignReductionStream(pcmStream);
                inputStream = new WaveChannel32(blockAlignedStream);

            lumeStream = inputStream;
            var meteringStream = new MeteringStream(inputStream, inputStream.WaveFormat.SampleRate / 10);            
            return meteringStream;

}

        private void CreateWaveOut()
        {

                CloseWaveOut();

                WaveOut outputDevice = new WaveOut(callbackInfo);
                outputDevice.DesiredLatency = latency;
                waveOut = outputDevice;

}

public void play()

{

                  try
            {
                CreateWaveOut();
            }
            catch (Exception driverCreateException)
            {
                MessageBox.Show(String.Format("{0}", driverCreateException.Message));
                return;
            }

            mainOutputStream = CreateInputStream(fileName);

 try
            {
                waveOut.Init(mainOutputStream);
            }
            catch (Exception initException)
            {
                MessageBox.Show(String.Format("{0}", initException.Message), "Error Initializing Output");
                return;
            }
            waveOut.Play();

}