zoukankan      html  css  js  c++  java
  • 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 

       附件下载   

  • 相关阅读:
    September 17th 2016 Week 38th Saturday
    【2016-09-16】UbuntuServer14.04或更高版本安装问题记录
    September 16th 2016 Week 38th Friday
    September 11th 2016 Week 38th Sunday
    September 12th 2016 Week 38th Monday
    September 10th 2016 Week 37th Saturday
    September 9th 2016 Week 37th Friday
    c++暂停
    八皇后问题
    ( 转转)Android初级开发第九讲--Intent最全用法(打开文件跳转页面等)
  • 原文地址:https://www.cnblogs.com/dehai/p/4320753.html
Copyright © 2011-2022 走看看