• 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 

       附件下载   

  • 相关阅读:
    移动端屏幕适配解决方案
    ES6学习笔记(1)——模块化
    弹性盒布局学习总结
    阮一峰之webpack-demos(译)
    阮一峰的Git分支管理策略之学习总结
    移动端测试之服务器搭建
    webApp 移动Touch框架
    Javascript 严格模式详解
    caller和callee的区别
    avalon 中require.config源码分析
  • 原文地址:https://www.cnblogs.com/dehai/p/4320753.html
Copyright © 2020-2023  润新知