-
-
Notifications
You must be signed in to change notification settings - Fork 17
/
PortAudio.cs
160 lines (153 loc) · 5.31 KB
/
PortAudio.cs
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Xml;
namespace FSClient {
public class PortAudio {
private static int cur_guid = 1000;
private class InternalAudioDevice {
public AudioDevice device;
public int id;
public bool is_alive;
}
private static List<InternalAudioDevice> _devices = new List<InternalAudioDevice>();
private static AudioDevice[] _pub_devices;
public class AudioDevice {
public readonly string name;
public readonly int inputs;
public readonly int outputs;
public readonly int guid;
public AudioDevice(int guid, string name, int inputs, int outputs) {
this.name = name;
this.guid = guid;
this.inputs = inputs;
this.outputs = outputs;
}
public override string ToString() {
return name;
}
public void SetInDev() {
PortAudio.SetInDev(guid);
}
public void SetOutDev() {
PortAudio.SetOutDev(guid);
}
public void SetRingDev() {
PortAudio.SetRingDev(guid);
}
}
public static void Hangup(int call_id) {
Utils.bgapi_exec("pa", "hangup " + call_id);
}
public static void Call(string dest) {
Utils.bgapi_exec("pa", "call " + dest);
}
public static void HoldAll() {
Utils.bgapi_exec("pa", "switch none");
}
public static void SwitchTo(int call_id) {
Utils.bgapi_exec("pa", "switch " + call_id);
}
private static int guid_to_id(int guid) {
return (from I in _devices where I.device.guid == guid select I.id).FirstOrDefault();
}
private static void SetInDev(int guid) {
Utils.bgapi_exec("pa", "indev #" + guid_to_id(guid));
}
private static void SetOutDev(int guid) {
Utils.bgapi_exec("pa", "outdev #" + guid_to_id(guid));
}
public static void ClearRingDev() {
Utils.bgapi_exec("pa", "ringdev #" + -1);
}
private static void SetRingDev(int guid) {
Utils.bgapi_exec("pa", "ringdev #" + guid_to_id(guid));
}
public static void SetInAndOutDev(AudioDevice indev, AudioDevice outdev) {
if (indev != null && outdev != null)
SetInAndOutDev(indev.guid, outdev.guid);
else if (indev != null)
indev.SetInDev();
else if (outdev != null)
outdev.SetOutDev();
}
public static void PrepareStream(AudioDevice indev, AudioDevice outdev) {
Utils.bgapi_exec("pa", "preparestream #" + guid_to_id(indev.guid) + " #" + guid_to_id(outdev.guid));
}
private static void SetInAndOutDev(int indev_guid, int outdev_guid) {
Utils.bgapi_exec("pa", "switchstream #" + guid_to_id(indev_guid) + " #" + guid_to_id(outdev_guid));
}
public static void PlayDTMF(char dtmf, string uuid, bool no_close=false) {
if (uuid == null)
Utils.bgapi_exec("pa", "play tone_stream://d=150;v=-5;" + dtmf + (no_close ? " -1 no_close" : ""));
else
PlayInUUID(uuid, "tone_stream://d=150;v=-5;" + dtmf);
}
public static void CloseStreams(){
Utils.bgapi_exec("pa", "closestreams");
}
public static void PlayInUUID(string uuid, string to_play) {
Utils.bgapi_exec("uuid_displace", uuid + " start " + to_play + " 0 mux");
}
public static void SendDTMF(string dtmf) {
char[] chars = dtmf.ToCharArray();
foreach (char c in chars)
Utils.bgapi_exec("pa", "dtmf " + c);
}
public static void set_mute(bool muted) {
if (muted)
Utils.bgapi_exec("pa", "flags off mouth");
else
Utils.bgapi_exec("pa", "flags on mouth");
}
public static AudioDevice[] get_devices(bool refresh) {
if (refresh || _pub_devices == null)
refresh_devices(true);
return _pub_devices;
}
public static void refresh_devices(bool force=false) {
if (! force && !Broker.get_instance().fully_loaded)
return;
foreach (InternalAudioDevice device in _devices)
device.is_alive = false;
Utils.api_exec("pa", "rescan");
XmlDocument doc=null;
try{
doc = XmlUtils.GetDocument(Utils.api_exec("pa", "devlist xml"));
}catch(KeyNotFoundException){
MessageBox.Show("Portaudio did not return a device list most likely because it cannot find an active microphone or speaker it can use, FSClient will now exit.", "Missing Device List", MessageBoxButton.OK, MessageBoxImage.Error);
Environment.Exit(-1);
return;
}
XmlNode node = XmlUtils.GetNode(doc, "devices", 0);
foreach (XmlNode child in node.ChildNodes) {
AudioDevice dev = new AudioDevice(
cur_guid, XmlUtils.GetNodeAttrib(child, "name"),
int.Parse(XmlUtils.GetNodeAttrib(child, "inputs")),
int.Parse(XmlUtils.GetNodeAttrib(child, "outputs"))
);
int dev_id = int.Parse(XmlUtils.GetNodeAttrib(child, "id"));
bool found_device = false;
foreach (InternalAudioDevice device in _devices)//TODO: Probably should sort here
{
if (device.device.name == dev.name && device.is_alive == false) {
device.is_alive = true;
device.id = dev_id;
found_device = true;
break;
}
}
if (!found_device) {
InternalAudioDevice new_device = new InternalAudioDevice { device = dev, is_alive = true, id = dev_id };
cur_guid++;
_devices.Add(new_device);
}
}
_pub_devices = (from c in _devices where c.is_alive select c.device).ToArray();
}
internal static void Answer(int call_id) {
Utils.bgapi_exec("pa", "answer " + call_id);
}
}
}