linux下mono播放PCM音頻


     測試環境:

    Ubuntu 14

    MonoDevelop

    CodeBlocks

 

1、建立一個共享庫(shared library

   這里用到了linux下的音頻播放庫,alsa-libalsalinux下的一個開源項目,它的全名是Advanced Linux Sound Architecture。它的安裝命令如下:

sudo apt-get install libasound2-dev

   使用 Coceblocks 建立一個 shared library 項目,命名為libTest2,編程語言選擇C。在main中加入下代碼:

 1 #include <alsa/asoundlib.h>
 2 #include<stdio.h>
 3 
 4 
 5 snd_pcm_t *handle;
 6 snd_pcm_sframes_t frames;
 7 
 8 
 9 int PcmOpen()
10 {
11 
12     if ( snd_pcm_open(&handle, "hw:0,0", SND_PCM_STREAM_PLAYBACK, 0) < 0 )
13     {
14         printf("pcm open error");
15         return 0;
16     }
17 
18     if (snd_pcm_set_params(handle, SND_PCM_FORMAT_U8, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 8000, 1, 500000) < 0)   //0.5sec 500000
19     {
20         printf("pcm set error");
21         return 0;
22 } 23 24 return 1; 25 } 26 27 28 29 void Play(unsigned char* buffer, int length) 30 { 31 frames = snd_pcm_writei(handle, buffer, length); 32 if(frames < 0) 33 { 34 frames = snd_pcm_recover(handle, frames, 0); 35 } 36 } 37 38 39 40 41 int PcmClose() 42 { 43 snd_pcm_close(handle); 44 return 1; 45 }

 

    在編譯的時候,記得鏈接alsa-lib庫。具體方法是在codeblocks的編譯對話框中,找到linker settings選項,在Other linker options中輸入:-lasound

如圖所示:

 

 

    當然,也可以手工編譯。cd main.c所在的目錄,執行以下命令:

gcc -o main.o -c main.c

gcc -o libTest1.so -shared main.o -lasound

 

2、在mono中調用共享庫

    與.net調用動態庫一樣,使用DllImport特性來調用。關於mono調用共享庫,mono官方有一篇文章介紹得很詳細:《Interop with Native Libraries》。

    使用monoDevolop建立一個控制台項目,並將上一步中生成的libTest1.so文件拷貝到/bin/Debug下。

    在Program.cs文件中輸入以下代碼:

using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading;

namespace helloworld
{
    class MainClass
    {

        public static void Main(string[] args)
        {
            Console.WriteLine("the app is started ");
            PlayPCM();

            Thread thread = new Thread(new ThreadStart(PlayPCM));
            thread.Start();
            while (true)
            {
                if (Console.ReadLine() == "quit")
                {
                    thread.Abort(); 
                    Console.WriteLine("the app is stopped ");
                    return;
                }
            }

        }

        /// <summary>
        /// Plaies the PC.
        /// </summary>
        static void PlayPCM()
        {
            using (FileStream fs = File.OpenRead("Ireland.pcm"))
            {
                byte[] data = new byte[4000];

                PcmOpen();

                while (true)
                {
                    int readcount = fs.Read(data, 0, data.Length);
                    if (readcount > 0)
                    {
                        Play(data, data.Length);
                    }
                    else
                    {

                        break;
                    }
                }

                PcmClose();
            }
        }

        [DllImport("libTest1.so")]
        static extern int PcmOpen();

        [DllImport("libTest1.so")]
        static extern int Play(byte[] buffer, int length);

        [DllImport("libTest1.so")]
        static extern int PcmClose();
    }
}

 

     為了便於測試,附件中包含了一個聲音文件,可以直接使用這個聲音文件。

 

3、有關PCM文件的一些簡要說明

    附件中的Ireland.pcm,采用的是PCMU編碼,采樣率為8000Hz,采樣深度為1字節,聲道數為1。這些對應於snd_pcm_set_params函數,這個函數用於以較簡單的方式來設定pcm的播放參數。要正確地播放聲音文件,必須使PCM的參數與聲音文件的參數一致。

  

    更多有關alsa的信息,請查看官方網站。http://www.alsa-project.org/main/index.php/Main_Page 

 

   附件下載   

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM