blob: 41a1fa180431cdac9a472eb855f09823792d808b [file] [log] [blame]
Tim Yaoe8c0d4a2019-11-27 14:47:35 -08001#include <unistd.h>
2#include <atomic>
3#include <hardware/hardware.h>
4#include <hardware/audio.h>
5
6#include "CircularBuffer.h"
7#include "audio_client.h"
8
9#define LOG_TAG "audio_client"
10#include <cutils/log.h>
11
12//#define DEBUG__
13
14#ifdef DEBUG__
15#define TRACE_ENTRY() ALOGI("%s enter\n", __func__)
16#define TRACE_EXIT() ALOGI("%s exit\n", __func__)
17#else
18#define TRACE_ENTRY()
19#define TRACE_EXIT()
20#endif
21
22Volume MakeVolume(float vol)
23{
24 Volume v;
25 v.set_vol(vol);
26 return v;
27}
28
29Mode MakeMode(audio_mode_t mode)
30{
31 Mode m;
32 m.set_mode(mode);
33 return m;
34}
35
36Mute MakeMute(bool state)
37{
38 Mute m;
39 m.set_mute(state);
40 return m;
41}
42
43Kv_pairs MakeKv_pairs(const char *pairs)
44{
45 Kv_pairs p;
46 p.set_params(std::string(pairs));
47 return p;
48}
49
50Keys MakeKeys(const char *keys)
51{
52 Keys k;
53 k.set_keys(std::string(keys));
54 return k;
55}
56
57StreamReadWrite MakeStreamReadWrite(char *name, size_t bytes)
58{
59 StreamReadWrite rw;
60 rw.set_name(std::string(name));
61 rw.set_size(bytes);
62 return rw;
63}
64
65AudioConfig MakeAudioConfig(const struct audio_config *config)
66{
67 AudioConfig c;
68 c.set_sample_rate(config->sample_rate);
69 c.set_channel_mask(config->channel_mask);
70 c.set_format(config->format);
71 c.set_frame_count(config->frame_count);
72 return c;
73}
74
75Handle MakeHandle(int32_t handle)
76{
77 Handle h;
78 h.set_handle(handle);
79 return h;
80}
81
82StreamOutSetVolume MakeStreamOutSetVolume(char *name, float left, float right)
83{
84 StreamOutSetVolume v;
85 v.set_name(std::string(name));
86 v.set_left(left);
87 v.set_right(right);
88 return v;
89}
90
91OpenOutputStream MakeOpenOutputStream(std::string name,
92 uint32_t size,
93 uint32_t handle,
94 uint32_t devices,
95 uint32_t flags,
96 const struct audio_config *config,
97 const char *address)
98{
99 OpenOutputStream opt;
100 opt.set_name(name);
101 opt.set_size(size);
102 opt.set_handle(handle);
103 opt.set_devices(devices);
104 opt.mutable_config()->CopyFrom(MakeAudioConfig(config));
105 opt.set_flags(flags);
106 opt.set_address(address ? std::string(address) : std::string(""));
107 return opt;
108}
109
110OpenInputStream MakeOpenInputStream(std::string name,
111 uint32_t size,
112 uint32_t handle,
113 uint32_t devices,
114 const struct audio_config *config,
115 uint32_t flags,
116 const char *address,
117 uint32_t source)
118{
119 OpenInputStream opt;
120 opt.set_name(name);
121 opt.set_size(size);
122 opt.set_handle(handle);
123 opt.set_devices(devices);
124 opt.mutable_config()->CopyFrom(MakeAudioConfig(config));
125 opt.set_flags(flags);
126 opt.set_address(std::string(address));
127 opt.set_source(source);
128 return opt;
129}
130
131Stream MakeStream(std::string name)
132{
133 Stream stream;
134 stream.set_name(name);
135 return stream;
136}
137
138AudioPortConfig MakeAudioPortConfig(const struct audio_port_config *config)
139{
140 AudioPortConfig c;
141 c.set_id(config->id);
142 c.set_role(config->role);
143 c.set_type(config->type);
144 c.set_config_mask(config->config_mask);
145 c.set_sample_rate(config->sample_rate);
146 c.set_channel_mask(config->channel_mask);
147 c.set_format(config->format);
148 AudioGainConfig *gain = c.mutable_gain();
149 gain->set_index(config->gain.index);
150 gain->set_mode(config->gain.mode);
151 gain->set_channel_mask(config->gain.channel_mask);
152 for (int i = 0; i < sizeof(config->gain.values) / sizeof(int); i++) {
153 gain->add_values(config->gain.values[i]);
154 }
155 gain->set_ramp_duration_ms(config->gain.ramp_duration_ms);
156 if (config->type == AUDIO_PORT_TYPE_DEVICE) {
157 c.mutable_device()->set_hw_module(config->ext.device.hw_module);
158 c.mutable_device()->set_type(config->ext.device.type);
159 c.mutable_device()->set_address(std::string("null"));
160 } else if (config->type == AUDIO_PORT_TYPE_MIX) {
161 c.mutable_mix()->set_hw_module(config->ext.mix.hw_module);
162 c.mutable_mix()->set_handle(config->ext.mix.handle);
163 c.mutable_mix()->set_stream_source(config->ext.mix.usecase.stream);
164 } else if (config->type == AUDIO_PORT_TYPE_SESSION) {
165 c.mutable_session()->set_session(config->ext.session.session);
166 }
167 return c;
168}
169
170StreamSetParameters MakeStreamSetParameters(char *name, const char *kv_pairs)
171{
172 StreamSetParameters p;
173 p.set_name(std::string(name));
174 p.set_kv_pairs(std::string(kv_pairs));
175 return p;
176}
177
178StreamGetParameters MakeStreamGetParameters(char *name, const char *keys)
179{
180 StreamGetParameters p;
181 p.set_name(std::string(name));
182 p.set_keys(std::string(keys));
183 return p;
184}
185
186std::atomic_int AudioClient::stream_seq_;
187
188int AudioClient::Device_common_close(struct hw_device_t* device)
189{
190 TRACE_ENTRY();
191 ClientContext context;
192 StatusReturn r;
193 Status status = stub_->Device_common_close(&context, Empty(), &r);
194 return r.ret();
195}
196
197int AudioClient::Device_init_check(const struct audio_hw_device *dev)
198{
199 TRACE_ENTRY();
200 ClientContext context;
201 StatusReturn r;
202 Status status = stub_->Device_init_check(&context, Empty(), &r);
203 return r.ret();
204}
205
206int AudioClient::Device_set_voice_volume(struct audio_hw_device *dev, float volume)
207{
208 TRACE_ENTRY();
209 ClientContext context;
210 StatusReturn r;
211 Status status = stub_->Device_set_voice_volume(&context, MakeVolume(volume), &r);
212 return r.ret();
213}
214
215int AudioClient::Device_set_master_volume(struct audio_hw_device *dev, float volume)
216{
217 TRACE_ENTRY();
218 ClientContext context;
219 StatusReturn r;
220 Status status = stub_->Device_set_master_volume(&context, MakeVolume(volume), &r);
221 return r.ret();
222}
223
224int AudioClient::Device_get_master_volume(struct audio_hw_device *dev, float *volume)
225{
226 TRACE_ENTRY();
227 ClientContext context;
228 StatusReturn r;
229 Status status = stub_->Device_get_master_volume(&context, Empty(), &r);
230 *volume = r.status_float();
231 return r.ret();
232}
233
234int AudioClient::Device_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
235{
236 TRACE_ENTRY();
237 ClientContext context;
238 StatusReturn r;
239 Status status = stub_->Device_set_mode(&context, MakeMode(mode), &r);
240 return r.ret();
241}
242
243int AudioClient::Device_set_mic_mute(struct audio_hw_device *dev, bool state)
244{
245 TRACE_ENTRY();
246 ClientContext context;
247 StatusReturn r;
248 Status status = stub_->Device_set_mic_mute(&context, MakeMute(state), &r);
249 return r.ret();
250}
251
252int AudioClient::Device_get_mic_mute(const struct audio_hw_device *dev, bool *state)
253{
254 TRACE_ENTRY();
255 ClientContext context;
256 StatusReturn r;
257 Status status = stub_->Device_get_mic_mute(&context, Empty(), &r);
258 *state = r.status_bool();
259 return r.ret();
260}
261
262int AudioClient::Device_set_parameters(struct audio_hw_device *dev, const char *kv_pairs)
263{
264 TRACE_ENTRY();
265 ClientContext context;
266 StatusReturn r;
267 Status status = stub_->Device_set_parameters(&context, MakeKv_pairs(kv_pairs), &r);
268 return r.ret();
269}
270
271char * AudioClient::Device_get_parameters(const struct audio_hw_device *dev, const char *keys)
272{
273 TRACE_ENTRY();
274 ClientContext context;
275 StatusReturn r;
276 Status status = stub_->Device_get_parameters(&context, MakeKeys(keys), &r);
277 char *p = (char *)malloc(r.status_string().size() + 1);
278 if (p) {
279 strcpy(p, r.status_string().c_str());
280 }
281 return p;
282}
283
284size_t AudioClient::Device_get_input_buffer_size(const struct audio_hw_device *dev,
285 const struct audio_config *config)
286{
287 TRACE_ENTRY();
288 ClientContext context;
289 StatusReturn r;
290 Status status = stub_->Device_get_input_buffer_size(&context, MakeAudioConfig(config), &r);
291 return r.ret();
292}
293
294int AudioClient::Device_open_output_stream(struct audio_hw_device *dev,
295 audio_io_handle_t handle,
296 audio_devices_t devices,
297 audio_output_flags_t flags,
298 struct audio_config *config,
299 audio_stream_out_client_t *stream_out,
300 const char *address)
301{
302 TRACE_ENTRY();
303 ClientContext context;
304 StatusReturn r;
305 Status status = stub_->Device_open_output_stream(&context,
306 MakeOpenOutputStream(new_stream_name(stream_out->name, sizeof(stream_out->name)),
307 kSharedBufferSize,
308 handle,
309 devices,
310 flags,
311 config,
312 address), &r);
313 return r.ret();
314}
315
316void AudioClient::Device_close_output_stream(struct audio_hw_device *dev,
317 struct audio_stream_out* stream_out)
318{
319 TRACE_ENTRY();
320 struct audio_stream_out_client *out = audio_stream_out_to_client(stream_out);
321 ClientContext context;
322 StatusReturn r;
323 Status status = stub_->Device_close_output_stream(&context, MakeStream(std::string(out->name)), &r);
324 return;
325}
326
327int AudioClient::Device_open_input_stream(struct audio_hw_device *dev,
328 audio_io_handle_t handle,
329 audio_devices_t devices,
330 struct audio_config *config,
331 struct audio_stream_in_client *stream_in,
332 audio_input_flags_t flags,
333 const char *address,
334 audio_source_t source)
335{
336 TRACE_ENTRY();
337 ClientContext context;
338 StatusReturn r;
339 Status status = stub_->Device_open_input_stream(&context,
340 MakeOpenInputStream(new_stream_name(stream_in->name, sizeof(stream_in->name)),
341 kSharedBufferSize,
342 handle,
343 devices,
344 config,
345 flags,
346 address,
347 source), &r);
348 return r.ret();
349}
350
351void AudioClient::Device_close_input_stream(struct audio_hw_device *dev,
352 struct audio_stream_in *stream_in)
353{
354 TRACE_ENTRY();
355 struct audio_stream_in_client *in = audio_stream_in_to_client(stream_in);
356 ClientContext context;
357 StatusReturn r;
358 Status status = stub_->Device_close_input_stream(&context, MakeStream(std::string(in->name)), &r);
359}
360
361int AudioClient::Device_dump(const struct audio_hw_device *dev, int fd)
362{
363 TRACE_ENTRY();
364 ClientContext context;
365 StatusReturn r;
366 Status status = stub_->Device_dump(&context, Empty(), &r);
367 write(fd, r.status_string().c_str(), r.status_string().size());
368 return r.ret();
369}
370
371int AudioClient::Device_set_master_mute(struct audio_hw_device *dev, bool mute)
372{
373 TRACE_ENTRY();
374 ClientContext context;
375 StatusReturn r;
376 Status status = stub_->Device_set_master_mute(&context, MakeMute(mute), &r);
377 return r.ret();
378}
379
380int AudioClient::Device_get_master_mute(struct audio_hw_device *dev, bool *mute)
381{
382 TRACE_ENTRY();
383 ClientContext context;
384 StatusReturn r;
385 Status status = stub_->Device_get_master_mute(&context, Empty(), &r);
386 *mute = r.status_bool();
387 return r.ret();
388}
389
390int AudioClient::Device_create_audio_patch(struct audio_hw_device *dev,
391 unsigned int num_sources,
392 const struct audio_port_config *sources,
393 unsigned int num_sinks,
394 const struct audio_port_config *sinks,
395 audio_patch_handle_t *handle)
396{
397 TRACE_ENTRY();
398 ClientContext context;
399 StatusReturn r;
400 CreateAudioPatch request;
401 const struct audio_port_config *c;
402
403 c = sources;
404 for (int i = 0; i < num_sources; i++, c++) {
405 AudioPortConfig *config = request.add_sources();
406 config->CopyFrom(MakeAudioPortConfig(c));
407 }
408
409 c = sinks;
410 for (int i = 0; i < num_sinks; i++, c++) {
411 AudioPortConfig *config = request.add_sinks();
412 config->CopyFrom(MakeAudioPortConfig(c));
413 }
414
415 Status status = stub_->Device_create_audio_patch(&context, request, &r);
416 *handle = r.status_32();
417 return r.ret();
418}
419
420int AudioClient::Device_release_audio_patch(struct audio_hw_device *dev,
421 audio_patch_handle_t handle)
422{
423 TRACE_ENTRY();
424 ClientContext context;
425 StatusReturn r;
426 Status status = stub_->Device_release_audio_patch(&context, MakeHandle(handle), &r);
427 return r.ret();
428}
429
430int AudioClient::Device_set_audio_port_config(struct audio_hw_device *dev,
431 const struct audio_port_config *config)
432{
433 TRACE_ENTRY();
434 ClientContext context;
435 StatusReturn r;
436 Status status = stub_->Device_set_audio_port_config(&context, MakeAudioPortConfig(config), &r);
437 return r.ret();
438}
439
440int AudioClient::stream_in_set_gain(struct audio_stream_in *stream, float gain)
441{
442 TRACE_ENTRY();
443 ClientContext context;
444 StatusReturn r;
445 StreamGain request;
446 char *name = (audio_stream_in_to_client(stream))->name;
447 request.set_name(std::string(name));
448 request.set_gain(gain);
449 Status status = stub_->StreamIn_set_gain(&context, request, &r);
450 return r.ret();
451}
452
453ssize_t AudioClient::stream_in_read(struct audio_stream_in *stream,
454 void* buffer,
455 size_t bytes)
456{
457 TRACE_ENTRY();
458 ClientContext context;
459 StatusReturn r;
460 char *name = (audio_stream_in_to_client(stream))->name;
461 Status status = stub_->StreamIn_read(&context, MakeStreamReadWrite(name, bytes), &r);
462 if (r.ret() > 0) {
463 CircularBuffer *cb = shm_->find<CircularBuffer>(name).first;
464 if (cb) {
465 memcpy(buffer, cb->start_ptr(*shm_), r.ret());
466 }
467 }
468 return r.ret();
469}
470
471uint32_t AudioClient::stream_in_get_input_frames_lost(struct audio_stream_in *stream)
472{
473 TRACE_ENTRY();
474 ClientContext context;
475 StatusReturn r;
476 char *name = (audio_stream_in_to_client(stream))->name;
477 Status status = stub_->StreamIn_get_input_frames_lost(&context, MakeStream(name), &r);
478 return r.ret();
479}
480
481int AudioClient::stream_in_get_capture_position(const struct audio_stream_in *stream,
482 int64_t *frames, int64_t *time)
483{
484 TRACE_ENTRY();
485 ClientContext context;
486 GetCapturePositionReturn r;
487 char *name = (audio_stream_in_to_client(stream))->name;
488 Status status = stub_->StreamIn_get_capture_position(&context, MakeStream(name), &r);
489 *frames = r.frames();
490 *time = r.time();
491 return r.ret();
492}
493
494uint32_t AudioClient::stream_out_get_latency(const struct audio_stream_out *stream)
495{
496 TRACE_ENTRY();
497 ClientContext context;
498 StatusReturn r;
499 char *name = (audio_stream_out_to_client(stream))->name;
500 Status status = stub_->StreamOut_get_latency(&context, MakeStream(name), &r);
501 return r.ret();
502}
503
504int AudioClient::stream_out_set_volume(struct audio_stream_out *stream, float left, float right)
505{
506 TRACE_ENTRY();
507 ClientContext context;
508 StatusReturn r;
509 char *name = (audio_stream_out_to_client(stream))->name;
510 Status status = stub_->StreamOut_set_volume(&context, MakeStreamOutSetVolume(name, left, right), &r);
511 return r.ret();
512}
513
514ssize_t AudioClient::stream_out_write(struct audio_stream_out *stream, const void* buffer,
515 size_t bytes)
516{
517 TRACE_ENTRY();
518 ClientContext context;
519 StatusReturn r;
520 char *name = (audio_stream_out_to_client(stream))->name;
521 CircularBuffer *cb = shm_->find<CircularBuffer>(name).first;
522 if (cb) {
523 memcpy(cb->start_ptr(*shm_), buffer, std::min(bytes, cb->capacity()));
524 }
525 Status status = stub_->StreamOut_write(&context, MakeStreamReadWrite(name, bytes), &r);
526 return r.ret();
527}
528
529int AudioClient::stream_out_get_render_position(const struct audio_stream_out *stream,
530 uint32_t *dsp_frames)
531{
532 TRACE_ENTRY();
533 ClientContext context;
534 StatusReturn r;
535 char *name = (audio_stream_out_to_client(stream))->name;
536 Status status = stub_->StreamOut_get_render_position(&context, MakeStream(name), &r);
537 *dsp_frames = r.status_32();
538 return r.ret();
539}
540
541int AudioClient::stream_out_get_next_write_timestamp(const struct audio_stream_out *stream,
542 int64_t *timestamp)
543{
544 TRACE_ENTRY();
545 ClientContext context;
546 StatusReturn r;
547 char *name = (audio_stream_out_to_client(stream))->name;
548 Status status = stub_->StreamOut_get_next_write_timestamp(&context, MakeStream(name), &r);
549 *timestamp = r.status_64();
550 return r.ret();
551}
552
553int AudioClient::stream_out_pause(struct audio_stream_out* stream)
554{
555 TRACE_ENTRY();
556 ClientContext context;
557 StatusReturn r;
558 char *name = (audio_stream_out_to_client(stream))->name;
559 Status status = stub_->StreamOut_pause(&context, MakeStream(name), &r);
560 return r.ret();
561}
562
563int AudioClient::stream_out_resume(struct audio_stream_out* stream)
564{
565 TRACE_ENTRY();
566 ClientContext context;
567 StatusReturn r;
568 char *name = (audio_stream_out_to_client(stream))->name;
569 Status status = stub_->StreamOut_resume(&context, MakeStream(name), &r);
570 return r.ret();
571}
572
573int AudioClient::stream_out_flush(struct audio_stream_out* stream)
574{
575 TRACE_ENTRY();
576 ClientContext context;
577 StatusReturn r;
578 char *name = (audio_stream_out_to_client(stream))->name;
579 Status status = stub_->StreamOut_flush(&context, MakeStream(name), &r);
580 return r.ret();
581}
582
583int AudioClient::stream_out_get_presentation_position(const struct audio_stream_out *stream,
584 uint64_t *frames,
585 struct timespec *timestamp)
586{
587 TRACE_ENTRY();
588 ClientContext context;
589 GetFrameTimestampReturn r;
590 char *name = (audio_stream_out_to_client(stream))->name;
591 Status status = stub_->StreamOut_get_presentation_position(&context, MakeStream(name), &r);
592 *frames = r.frames();
593 timestamp->tv_sec = r.timestamp().seconds();
594 timestamp->tv_nsec = r.timestamp().nanos();
595 return r.ret();
596}
597
598uint32_t AudioClient::stream_get_sample_rate(const struct audio_stream *stream)
599{
600 TRACE_ENTRY();
601 ClientContext context;
602 StatusReturn r;
603 char *name = (audio_stream_to_client(stream))->name;
604 Status status = stub_->Stream_get_sample_rate(&context, MakeStream(name), &r);
605 return r.ret();
606}
607
608size_t AudioClient::stream_get_buffer_size(const struct audio_stream *stream)
609{
610 TRACE_ENTRY();
611 ClientContext context;
612 StatusReturn r;
613 char *name = (audio_stream_to_client(stream))->name;
614 Status status = stub_->Stream_get_buffer_size(&context, MakeStream(name), &r);
615 return r.ret();
616}
617
618audio_channel_mask_t AudioClient::stream_get_channels(const struct audio_stream *stream)
619{
620 TRACE_ENTRY();
621 ClientContext context;
622 StatusReturn r;
623 char *name = (audio_stream_to_client(stream))->name;
624 Status status = stub_->Stream_get_channels(&context, MakeStream(name), &r);
625 return r.ret();
626}
627
628audio_format_t AudioClient::stream_get_format(const struct audio_stream *stream)
629{
630 TRACE_ENTRY();
631 ClientContext context;
632 StatusReturn r;
633 char *name = (audio_stream_to_client(stream))->name;
634 Status status = stub_->Stream_get_format(&context, MakeStream(name), &r);
635 return (audio_format_t)(r.ret());
636}
637
638int AudioClient::stream_standby(struct audio_stream *stream)
639{
640 TRACE_ENTRY();
641 ClientContext context;
642 StatusReturn r;
643 char *name = (audio_stream_to_client(stream))->name;
644 Status status = stub_->Stream_standby(&context, MakeStream(name), &r);
645 return r.ret();
646}
647
648int AudioClient::stream_dump(const struct audio_stream *stream, int fd)
649{
650 TRACE_ENTRY();
651 //TODO
652 return 0;
653}
654
655audio_devices_t AudioClient::stream_get_device(const struct audio_stream *stream)
656{
657 TRACE_ENTRY();
658 ClientContext context;
659 StatusReturn r;
660 char *name = (audio_stream_to_client(stream))->name;
661 Status status = stub_->Stream_get_device(&context, MakeStream(name), &r);
662 return r.ret();
663}
664
665int AudioClient::stream_set_parameters(struct audio_stream *stream, const char *kv_pairs)
666{
667 TRACE_ENTRY();
668 ClientContext context;
669 StatusReturn r;
670 char *name = (audio_stream_to_client(stream))->name;
671 Status status = stub_->Stream_set_parameters(&context, MakeStreamSetParameters(name, kv_pairs), &r);
672 return r.ret();
673}
674
675char * AudioClient::stream_get_parameters(const struct audio_stream *stream,
676 const char *keys)
677{
678 TRACE_ENTRY();
679 ClientContext context;
680 StatusReturn r;
681 char *name = (audio_stream_to_client(stream))->name;
682 Status status = stub_->Stream_get_parameters(&context, MakeStreamGetParameters(name, keys), &r);
683 char *p = (char *)malloc(r.status_string().size() + 1);
684 if (p) {
685 strcpy(p, r.status_string().c_str());
686 }
687 return p;
688}