1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
#if NET_2_0
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Mono.Audio {
/* these are the values used by alsa */
#if PUBLIC_API
public
#else
internal
#endif
enum AudioFormat {
S8,
U8,
S16_LE,
S16_BE,
U16_LE,
U16_BE,
S24_LE,
S24_BE,
U24_LE,
U24_BE,
S32_LE,
S32_BE,
U32_LE,
U32_BE,
FLOAT_LE,
FLOAT_BE,
FLOAT64_LE,
FLOAT64_BE,
IEC958_SUBFRAME_LE,
IEC958_SUBFRAME_BE,
MU_LAW,
A_LAW,
IMA_ADPCM,
MPEG,
GSM
}
#if PUBLIC_API
public
#else
internal
#endif
class AudioDevice {
static AudioDevice TryAlsa (string name) {
AudioDevice dev;
try {
dev = new AlsaDevice (name);
return dev;
} catch {
return null;
}
}
public static AudioDevice CreateDevice (string name) {
AudioDevice dev;
dev = TryAlsa (name);
/* if no option is found, return a silent device */
if (dev == null)
dev = new AudioDevice ();
return dev;
}
public virtual bool SetFormat (AudioFormat format, int channels, int rate) {
return true;
}
public virtual int PlaySample (byte[] buffer, int num_frames) {
return num_frames;
}
public virtual void Wait () {
}
}
class AlsaDevice: AudioDevice, IDisposable {
IntPtr handle;
[DllImport ("libasound.so.2")]
static extern int snd_pcm_open (ref IntPtr handle, string pcm_name, int stream, int mode);
[DllImport ("libasound.so.2")]
static extern int snd_pcm_close (IntPtr handle);
[DllImport ("libasound.so.2")]
static extern int snd_pcm_drain (IntPtr handle);
[DllImport ("libasound.so.2")]
static extern int snd_pcm_writei (IntPtr handle, byte[] buf, int size);
[DllImport ("libasound.so.2")]
static extern int snd_pcm_set_params (IntPtr handle, int format, int access, int channels, int rate, int soft_resample, int latency);
public AlsaDevice (string name) {
if (name == null)
name = "default";
int err = snd_pcm_open (ref handle, name, 0, 0);
if (err < 0)
throw new Exception ("no open " + err);
}
~AlsaDevice () {
Dispose (false);
}
public void Dispose () {
Dispose (true);
GC.SuppressFinalize (this);
}
protected virtual void Dispose (bool disposing) {
if (disposing) {
}
if (handle != IntPtr.Zero)
snd_pcm_close (handle);
handle = IntPtr.Zero;
}
public override bool SetFormat (AudioFormat format, int channels, int rate) {
int err = snd_pcm_set_params (handle, (int)format, 3, channels, rate, 1, 500000);
return err == 0;
}
public override int PlaySample (byte[] buffer, int num_frames) {
int frames = snd_pcm_writei (handle, buffer, num_frames);
return frames;
}
public override void Wait () {
snd_pcm_drain (handle);
}
}
}
#endif
|