测试环境:
Ubuntu 14.04
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, 0) < 0 ) { printf(“pcm open error”); return 0; }
if (snd_pcm_set_params(handle, SND_PCM_FORMAT_U8, SND_PCM_ACCESS_RW_INTERLEAVED, 1, 8000, 1, 500000) < 0) //0.5sec 500000 { printf(“pcm set error”); return 0; }
return 1;}
void Play(unsigned char* buffer, int length){ frames = snd_pcm_writei(handle, buffer, length); if(frames < 0) { frames = snd_pcm_recover(handle, frames, 0); }}
int PcmClose(){ snd_pcm_close(handle); return 1;}
在编译的时候,记得链接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文件的一些简要说明
你可以用爱得到全世界,你也可以用恨失去全世界