a9c5609b2de31aa2ce16e4a508c2965e3724679d
[platform/core/multimedia/mm-hal-interface.git] / testcase / audio / parser.cpp
1 #include <iostream>
2 #include <json.h>
3 #include <assert.h>
4 #include <string.h>
5 #include <string>
6
7 #include <parser.hh>
8
9 #define DEVICE_FILE_OBJECT                  "device-files"
10 #define DEVICE_TYPE_PROP_PLAYBACK_DEVICES   "playback-devices"
11 #define DEVICE_TYPE_PROP_CAPTURE_DEVICES    "capture-devices"
12 #define DEVICE_TYPE_PROP_DEVICE_STRING      "device-string"
13 #define DEVICE_TYPE_PROP_ROLE               "role"
14
15 /* device-files example
16         device-files : {
17                 playback-devices : [
18                         {
19                                 device-string : alsa:sprdphone,0,
20                                 role : { normal : rate=44100 }
21                         }
22                         {
23                                 device-string : alsa:VIRTUALAUDIOW,0,
24                                 role : { call-voice : rate=16000 channels=1 tsched=0 alternate_rate=16000 }
25                         }
26                 ]
27                 capture-devices : [
28                         {
29                                 device-string : alsa:sprdphone,0,
30                                 role : { normal : rate=44100 }
31                         }
32                 ]
33         }
34 */
35
36 using namespace std;
37
38 CDeviceMapParser::CDeviceMapParser()
39 {
40         open_json("/etc/pulse/device-map.json");
41 }
42
43 CDeviceMapParser::CDeviceMapParser(const char* map_file)
44 {
45         open_json(map_file);
46 }
47
48 CDeviceMapParser::~CDeviceMapParser()
49 {
50         close_json();
51 }
52
53 void CDeviceMapParser::open_json(const char* json_file)
54 {
55         m_json_obj = json_object_from_file(json_file);
56         if (!m_json_obj) {
57                 cout << "Read device-map " << json_file << " failed" << endl;
58                 return;
59         }
60
61         if (!json_object_object_get_ex(m_json_obj, DEVICE_FILE_OBJECT, &m_json_device_files_obj)) {
62                 cout << "Get device files object failed" << endl;
63                 return;
64         }
65         if (!json_object_is_type(m_json_device_files_obj, json_type_object)) {
66                 cout << "json object type failed" << endl;
67                 json_object_put(m_json_obj);
68                 m_json_obj = NULL;
69                 return;
70         }
71
72         cout << DEVICE_FILE_OBJECT << " : {" << endl;
73 }
74
75 void CDeviceMapParser::close_json()
76 {
77         if (!m_json_obj)
78                 return;
79
80         json_object_put(m_json_obj);
81
82         cout << "}" << endl;
83 }
84
85 void CDeviceMapParser::parse_playback()
86 {
87         json_object *playback_devices_o = NULL;
88
89         if (!json_object_object_get_ex(m_json_device_files_obj, DEVICE_TYPE_PROP_PLAYBACK_DEVICES, &playback_devices_o)) {
90                 cout << "failed to get playback" << endl;
91                 return;
92         }
93
94         cout << "  " << DEVICE_TYPE_PROP_PLAYBACK_DEVICES << " : ["  << endl;
95         parse_device_file_array_object(playback_devices_o, m_playback);
96         cout << "  ]" << endl;
97 }
98
99 void CDeviceMapParser::parse_capture()
100 {
101         json_object *capture_devices_o = NULL;
102
103         if (!json_object_object_get_ex(m_json_device_files_obj, DEVICE_TYPE_PROP_CAPTURE_DEVICES, &capture_devices_o)) {
104                 cout << "failed to get capture" << endl;
105                 return;
106         }
107
108         cout << "  " << DEVICE_TYPE_PROP_CAPTURE_DEVICES << " : ["  << endl;
109         parse_device_file_array_object(capture_devices_o, m_capture);
110         cout << "  ]" << endl;
111 }
112
113 void CDeviceMapParser::get_device(string& s, string& card, string& device_num)
114 {
115         // eg. alsa:0,0
116         string delimiter = ",";
117         string s1(s.substr(s.find_last_of(':') + 1));
118
119         // eg. 0,0
120         size_t pos = s1.find(delimiter);
121         string token(s1.substr(0, pos));
122         s1.erase(0, pos + delimiter.length());
123
124         card.assign(token);
125         device_num.assign(s1);
126 }
127
128 void CDeviceMapParser::get_single_param(string& s, int& rate, int& channels)
129 {
130         // eg. rate=44100
131         string delimiter = "=";
132         size_t pos = s.find(delimiter);
133         string token = s.substr(0, pos);
134         s.erase(0, pos + delimiter.length());
135
136         if (token.compare("rate") == 0)
137                 rate = stoi(s);
138         else if (token.compare("channels") == 0)
139                 channels = stoi(s);
140 }
141
142 void CDeviceMapParser::get_params(string& s, int& rate, int& channels)
143 {
144         // eg. rate=44100 channels=1
145         string delimiter = " ";
146         size_t pos = 0;
147         string token;
148         string s1(s);
149
150         while ((pos = s1.find(delimiter)) != string::npos) {
151                 token = s1.substr(0, pos);
152                 get_single_param(token, rate, channels);
153                 s1.erase(0, pos + delimiter.length());
154         }
155         get_single_param(s1, rate, channels);
156 }
157
158
159 void CDeviceMapParser::dump_devices()
160 {
161         string card, device_num;
162         int rate = -1, channels = -1;
163
164         get_playback(card, device_num, rate, channels);
165         get_capture(card, device_num, rate, channels);
166 }
167
168 void CDeviceMapParser::get_playback(string& card, string& device_num, int& rate, int& channels)
169 {
170         parse_playback();
171
172         get_device(m_playback.first, card, device_num);
173         get_params(m_playback.second, rate, channels);
174         cout << "  1. PLAYBACK" << endl;
175         cout << "     > card=" << card << ", device=" << device_num << endl;
176         cout << "     > rate=" << rate << ", channels=" << channels << endl << endl;
177 }
178
179 void CDeviceMapParser::get_capture(string& card, string& device_num, int& rate, int& channels)
180 {
181         parse_capture();
182
183         get_device(m_capture.first, card, device_num);
184         get_params(m_capture.second, rate, channels);
185         cout << "  2. CAPTURE" << endl;
186         cout << "     > card=" << card << ", device=" << device_num << endl;
187         cout << "     > rate=" << rate << ", channels=" << channels << endl;
188 }
189
190 void CDeviceMapParser::parse_device_string_object(json_object *device_string_o, string& device_string)
191 {
192         assert(device_string_o);
193         assert(json_object_is_type(device_string_o, json_type_string));
194
195         // object example
196         //   device-string : alsa:sprdphone,0,
197
198         device_string.assign(json_object_get_string(device_string_o));
199
200         cout << "      " << DEVICE_TYPE_PROP_DEVICE_STRING << " : " << device_string << "," << endl;
201 }
202
203 void CDeviceMapParser::parse_device_role_object(json_object *device_role_o, string& device_params)
204 {
205         struct json_object_iterator it, it_end;
206
207         assert(device_role_o);
208         assert(json_object_is_type(device_role_o, json_type_object));
209
210         // <object example>
211         //   role : { normal : rate=44100 }
212
213         it = json_object_iter_begin(device_role_o);
214         it_end = json_object_iter_end(device_role_o);
215
216         while (!json_object_iter_equal(&it, &it_end)) {
217                 if (strcmp(json_object_iter_peek_name(&it), "normal") == 0) {
218                         device_params.assign(json_object_get_string(json_object_iter_peek_value(&it)));
219                         cout << "      " << DEVICE_TYPE_PROP_ROLE << " : {  normal : " << device_params << " }" << endl;
220                         break;
221                 }
222
223                 json_object_iter_next(&it);
224         }
225 }
226
227 void CDeviceMapParser::parse_device_file_object(json_object *device_file_o, pair<string, string>& device)
228 {
229         json_object *device_file_prop_o = NULL;
230         string device_string, device_param;
231
232         assert(device_file_o);
233         assert(json_object_is_type(device_file_o, json_type_object));
234
235         // <object example>
236         //      device-string : alsa:sprdphone,0,
237         //      role : { normal : rate=44100 }
238
239         // parse role
240         if (!json_object_object_get_ex(device_file_o, DEVICE_TYPE_PROP_ROLE, &device_file_prop_o)) {
241                 cout << "Get device role object failed" << endl;
242                 return;
243         }
244         parse_device_role_object(device_file_prop_o, device_param);
245
246         if (device_param.empty()) {
247                 cout << "      " << "[E] This is not a normal device..skip" << endl;
248                 return;
249         }
250
251         // parse device-string
252         if (!json_object_object_get_ex(device_file_o, DEVICE_TYPE_PROP_DEVICE_STRING, &device_file_prop_o)) {
253                 cout << "Get device-string object failed" << endl;
254                 return;
255         }
256         parse_device_string_object(device_file_prop_o, device_string);
257
258         // store device information
259         device = make_pair(device_string, device_param);
260 }
261
262 void CDeviceMapParser::parse_device_file_array_object(json_object *device_file_array_o, pair<string, string>& device)
263 {
264         int num, idx;
265         json_object *device_file_o = NULL;
266
267         assert(device_file_array_o);
268         assert(json_object_is_type(device_file_array_o, json_type_array));
269
270         // <object example>
271         //  {
272         //        device-string : alsa:sprdphone,0,
273         //        role : { normal : rate=44100 }
274         //  }
275
276         // ToDo : this might be replaced with iterator such as foreach?
277         num = json_object_array_length(device_file_array_o);
278         for (idx = 0; idx < num; idx++) {
279                 if (!(device_file_o = json_object_array_get_idx(device_file_array_o, idx))) {
280                         cout << "Get device file object failed" << endl;
281                         return;
282                 }
283
284                 cout << "    {" << endl;
285                 parse_device_file_object(device_file_o, device);
286                 cout << "    }" << endl;
287         }
288 }