测试环境:

Ubuntu 14

MonoDevelop

CodeBlocks

1、建立一个共享库(shared library)

这里用到了linux下的音频播放库,alsa-lib。 alsa是linux下的一个开源项目,它的全名是Advanced Linux Sound Architecture。它的安装命令如下:

sudo apt-get install libasound2-dev

使用 Coceblocks 建立一个 shared library 项目,命名为libTest2,编程语言选择C。在main中加入下代码:

 #include <alsa/asoundlib.h>
#include<stdio.h> snd_pcm_t *handle;
snd_pcm_sframes_t frames; int PcmOpen()
{ if ( snd_pcm_open(&handle, "hw:0,0", SND_PCM_STREAM_PLAYBACK, ) < )
{
printf("pcm open error");
return ;
} if (snd_pcm_set_params(handle, SND_PCM_FORMAT_U8, SND_PCM_ACCESS_RW_INTERLEAVED, , , , ) < ) //0.5sec 500000
{
printf("pcm set error");
return 0;
} return ;
} void Play(unsigned char* buffer, int length)
{
frames = snd_pcm_writei(handle, buffer, length);
if(frames < )
{
frames = snd_pcm_recover(handle, frames, );
}
} int PcmClose()
{
snd_pcm_close(handle);
return ;
}

在编译的时候,记得链接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[]; PcmOpen(); while (true)
{
int readcount = fs.Read(data, , data.Length);
if (readcount > )
{
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

附件下载

linux下mono播放PCM音频的更多相关文章

  1. 使用AudioTrack播放PCM音频数据(android)

    众所周知,Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlayer实现的.MediaPl ...

  2. 使用WindowsAPI实现播放PCM音频的方法

    这篇文章主要介绍了使用WindowsAPI实现播放PCM音频的方法,很实用的一个功能,需要的朋友可以参考下 本文介绍了使用WindowsAPI实现播放PCM音频的方法,同前面一篇使用WindowsAP ...

  3. Linux下从视频提取音频的方法

    Linux下可以利用mencoder将视频里的音频提取出来.方法如下: 1.首先安装mencoder.对于Ubuntu来说,软件仓库里就有mencoder,可直接输入如下命令安装 sudo apt-g ...

  4. Android 音视频开发(三):使用 AudioTrack 播放PCM音频

    一.AudioTrack 基本使用 AudioTrack 类可以完成Android平台上音频数据的输出任务.AudioTrack有两种数据加载模式(MODE_STREAM和MODE_STATIC),对 ...

  5. linux下mono的安装与卸载

    我很遗憾的告诉你,这里没有安装,为什么标题里加入安装俩字呢,因为如果不加的话你会搜到这篇文章吗?哈哈!别气馁,这里会给你些安装的tips! 源码安装,git安装:建议安装路径如下,至于为什么,我也讲不 ...

  6. 控制Linux下 mono 服务的启动停止

    当Window下的服务部署到Linux的时候,我们一般用Mono.service 来启动停止.参数比较多,不太好用.于是有个这个Shell脚本. 用法:moa s1 start #启动         ...

  7. AudioRecord 录制播放PCM音频

    AudioRecord 与 MediaRecorder 区别 AudioRecord 基于字节流录制,输出的是pcm数据,未进行压缩,直接保存的pcm文件不能被播放器识别播放. 可以对音频文件进行实时 ...

  8. linux下mono,powershell安装教程

    1简介 简单来说pash就是bash+powershell 2官网 https://github.com/Pash-Project/Pash 3下载fedora20---lxde桌面---32位版. ...

  9. 使用WindowsAPI播放PCM音频

    这一篇文章同上一篇<使用WindowsAPI获取录音音频>原理具有相似之处,不再详细介绍函数与结构体的参数 1. waveOutGetNumDevs 2. waveOutGetDevCap ...

随机推荐

  1. 先说IEnumerable,我们每天用的foreach你真的懂它吗?

    我们先思考几个问题: 为什么在foreach中不能修改item的值? 要实现foreach需要满足什么条件? 为什么Linq to Object中要返回IEnumerable? 接下来,先开始我们的正 ...

  2. Android指纹解锁

    Android6.0及以上系统支持指纹识别解锁功能:项目中用到,特此抽离出来,备忘. 功能是这样的:在用户将app切换到后台运行(超过一定的时长,比方说30秒),再进入程序中的时候就会弹出指纹识别的界 ...

  3. 07.LoT.UI 前后台通用框架分解系列之——强大的文本编辑器

    LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:https://github.com/du ...

  4. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  5. scrapy爬虫docker部署

    spider_docker 接我上篇博客,为爬虫引用创建container,包括的模块:scrapy, mongo, celery, rabbitmq,连接https://github.com/Liu ...

  6. vue入门学习(基础篇)

    vue入门学习总结: vue的一个组件包括三部分:template.style.script. vue的数据在data中定义使用. 数据渲染指令:v-text.v-html.{{}}. 隐藏未编译的标 ...

  7. css3更改input单选和多选的样式

    在项目开发中我们经常会遇到需要更改input单选和多选样式的情况,今天就给大家介绍一种简单改变input单选和多选样式的办法. 在这之前先简单介绍一下:before伪类 :before 选择器向选定的 ...

  8. arcgis api for js入门开发系列八聚合效果(含源代码)

    上一篇实现了demo的图层控制模块,本篇新增聚合效果,截图如下(源代码见文章底部): 聚合效果实现的思路如下: 1.map.html引用聚合包,项目已经包含进来了的聚合文件夹: <script ...

  9. Android studio使用gradle动态构建APP(不同的包,不同的icon、label)

    最近有个需求,需要做两个功能相似的APP,大部分代码是一样的,只是界面不一样,以前要维护两套代码,比较麻烦,最近在网上找资料,发现可以用gradle使用同一套代码构建两个APP.下面介绍使用方法: 首 ...

  10. AngularJS 系列 学习笔记 目录篇

    目录: AngularJS 系列 01 - HelloWorld和数据绑定 AngularJS 系列 02 - 模块 (持续更新)