7 #define DEVICE_FILE_OBJECT "device-files"
8 #define DEVICE_TYPE_PROP_PLAYBACK_DEVICES "playback-devices"
9 #define DEVICE_TYPE_PROP_CAPTURE_DEVICES "capture-devices"
10 #define DEVICE_TYPE_PROP_DEVICE_STRING "device-string"
11 #define DEVICE_TYPE_PROP_ROLE "role"
13 /* device-files example
17 device-string : alsa:sprdphone,0,
18 role : { normal : rate=44100 }
21 device-string : alsa:VIRTUALAUDIOW,0,
22 role : { call-voice : rate=16000 channels=1 tsched=0 alternate_rate=16000 }
27 device-string : alsa:sprdphone,0,
28 role : { normal : rate=44100 }
36 class CDeviceMapParser
40 CDeviceMapParser(const char* map_file);
41 virtual ~CDeviceMapParser();
45 void get_playback(string& card, string& device_num, int& rate, int& channels);
46 void get_capture(string& card, string& device_num, int& rate, int& channels);
49 void open_json(const char* json_file);
51 void parse_device_string_object(json_object *device_string_o, string& device_string);
52 void parse_device_role_object(json_object *device_role_o, string& device_params);
53 void parse_device_file_object(json_object *device_file_o, pair<string, string>& device);
54 void parse_device_file_array_object(json_object *device_file_array_o, pair<string, string>& device);
56 void parse_playback();
58 void get_device(string& s, string& card, string& device_num);
59 void get_params(string& s, int& rate, int& channels);
60 void get_single_param(string& s, int& rate, int& channels);
62 // FixMe, pair doens't define what is paired clearly....
63 pair<string, string> m_playback; // device_string, device_params
64 pair<string, string> m_capture; // device_string, device_params
66 json_object *m_json_obj;
67 json_object *m_json_device_files_obj;
70 CDeviceMapParser::CDeviceMapParser()
72 open_json("/etc/pulse/device-map.json");
75 CDeviceMapParser::CDeviceMapParser(const char* map_file)
80 CDeviceMapParser::~CDeviceMapParser()
85 void CDeviceMapParser::open_json(const char* json_file)
87 m_json_obj = json_object_from_file(json_file);
89 cout << "Read device-map " << json_file << " failed" << endl;
93 if (!json_object_object_get_ex(m_json_obj, DEVICE_FILE_OBJECT, &m_json_device_files_obj)) {
94 cout << "Get device files object failed" << endl;
97 if (!json_object_is_type(m_json_device_files_obj, json_type_object)) {
98 cout << "json object type failed" << endl;
99 json_object_put(m_json_obj);
104 cout << DEVICE_FILE_OBJECT << " : {" << endl;
107 void CDeviceMapParser::close_json()
112 json_object_put(m_json_obj);
117 void CDeviceMapParser::parse_playback()
119 json_object *playback_devices_o = NULL;
121 if (!json_object_object_get_ex(m_json_device_files_obj, DEVICE_TYPE_PROP_PLAYBACK_DEVICES, &playback_devices_o)) {
122 cout << "failed to get playback" << endl;
126 cout << " " << DEVICE_TYPE_PROP_PLAYBACK_DEVICES << " : [" << endl;
127 parse_device_file_array_object(playback_devices_o, m_playback);
128 cout << " ]" << endl;
131 void CDeviceMapParser::parse_capture()
133 json_object *capture_devices_o = NULL;
135 if (!json_object_object_get_ex(m_json_device_files_obj, DEVICE_TYPE_PROP_CAPTURE_DEVICES, &capture_devices_o)) {
136 cout << "failed to get capture" << endl;
140 cout << " " << DEVICE_TYPE_PROP_CAPTURE_DEVICES << " : [" << endl;
141 parse_device_file_array_object(capture_devices_o, m_capture);
142 cout << " ]" << endl;
145 void CDeviceMapParser::get_device(string& s, string& card, string& device_num)
148 string delimiter = ",";
149 string s1(s.substr(s.find_last_of(':') + 1));
152 size_t pos = s1.find(delimiter);
153 string token(s1.substr(0, pos));
154 s1.erase(0, pos + delimiter.length());
157 device_num.assign(s1);
160 void CDeviceMapParser::get_single_param(string& s, int& rate, int& channels)
163 string delimiter = "=";
164 size_t pos = s.find(delimiter);
165 string token = s.substr(0, pos);
166 s.erase(0, pos + delimiter.length());
168 if (token.compare("rate") == 0)
170 else if (token.compare("channels") == 0)
174 void CDeviceMapParser::get_params(string& s, int& rate, int& channels)
176 // eg. rate=44100 channels=1
177 string delimiter = " ";
182 while ((pos = s1.find(delimiter)) != string::npos) {
183 token = s1.substr(0, pos);
184 get_single_param(token, rate, channels);
185 s1.erase(0, pos + delimiter.length());
187 get_single_param(s1, rate, channels);
191 void CDeviceMapParser::dump_devices()
193 string card, device_num;
194 int rate = -1, channels = -1;
196 get_playback(card, device_num, rate, channels);
197 get_capture(card, device_num, rate, channels);
200 void CDeviceMapParser::get_playback(string& card, string& device_num, int& rate, int& channels)
204 get_device(m_playback.first, card, device_num);
205 get_params(m_playback.second, rate, channels);
206 cout << " 1. PLAYBACK" << endl;
207 cout << " > card=" << card << ", device=" << device_num << endl;
208 cout << " > rate=" << rate << ", channels=" << channels << endl << endl;
211 void CDeviceMapParser::get_capture(string& card, string& device_num, int& rate, int& channels)
215 get_device(m_capture.first, card, device_num);
216 get_params(m_capture.second, rate, channels);
217 cout << " 2. CAPTURE" << endl;
218 cout << " > card=" << card << ", device=" << device_num << endl;
219 cout << " > rate=" << rate << ", channels=" << channels << endl;
222 void CDeviceMapParser::parse_device_string_object(json_object *device_string_o, string& device_string)
224 assert(device_string_o);
225 assert(json_object_is_type(device_string_o, json_type_string));
228 // device-string : alsa:sprdphone,0,
230 device_string.assign(json_object_get_string(device_string_o));
232 cout << " " << DEVICE_TYPE_PROP_DEVICE_STRING << " : " << device_string << "," << endl;
235 void CDeviceMapParser::parse_device_role_object(json_object *device_role_o, string& device_params)
237 struct json_object_iterator it, it_end;
239 assert(device_role_o);
240 assert(json_object_is_type(device_role_o, json_type_object));
243 // role : { normal : rate=44100 }
245 it = json_object_iter_begin(device_role_o);
246 it_end = json_object_iter_end(device_role_o);
248 while (!json_object_iter_equal(&it, &it_end)) {
249 if (strcmp(json_object_iter_peek_name(&it), "normal") == 0) {
250 device_params.assign(json_object_get_string(json_object_iter_peek_value(&it)));
251 cout << " " << DEVICE_TYPE_PROP_ROLE << " : { normal : " << device_params << " }" << endl;
255 json_object_iter_next(&it);
259 void CDeviceMapParser::parse_device_file_object(json_object *device_file_o, pair<string, string>& device)
261 json_object *device_file_prop_o = NULL;
262 string device_string, device_param;
264 assert(device_file_o);
265 assert(json_object_is_type(device_file_o, json_type_object));
268 // device-string : alsa:sprdphone,0,
269 // role : { normal : rate=44100 }
272 if (!json_object_object_get_ex(device_file_o, DEVICE_TYPE_PROP_ROLE, &device_file_prop_o)) {
273 cout << "Get device role object failed" << endl;
276 parse_device_role_object(device_file_prop_o, device_param);
278 if (device_param.empty()) {
279 cout << " " << "[E] This is not a normal device..skip" << endl;
283 // parse device-string
284 if (!json_object_object_get_ex(device_file_o, DEVICE_TYPE_PROP_DEVICE_STRING, &device_file_prop_o)) {
285 cout << "Get device-string object failed" << endl;
288 parse_device_string_object(device_file_prop_o, device_string);
290 // store device information
291 device = make_pair(device_string, device_param);
294 void CDeviceMapParser::parse_device_file_array_object(json_object *device_file_array_o, pair<string, string>& device)
297 json_object *device_file_o = NULL;
299 assert(device_file_array_o);
300 assert(json_object_is_type(device_file_array_o, json_type_array));
304 // device-string : alsa:sprdphone,0,
305 // role : { normal : rate=44100 }
308 // ToDo : this might be replaced with iterator such as foreach?
309 num = json_object_array_length(device_file_array_o);
310 for (idx = 0; idx < num; idx++) {
311 if (!(device_file_o = json_object_array_get_idx(device_file_array_o, idx))) {
312 cout << "Get device file object failed" << endl;
316 cout << " {" << endl;
317 parse_device_file_object(device_file_o, device);
318 cout << " }" << endl;