blob: 19b8738d43b00efb6ea8c1e28f977226bc289e3c [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
Tim Yaoab2a3a62020-10-29 15:33:55 -0700361char *AudioClient::Device_dump(const struct audio_hw_device *dev, int fd)
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800362{
363 TRACE_ENTRY();
364 ClientContext context;
365 StatusReturn r;
366 Status status = stub_->Device_dump(&context, Empty(), &r);
Tim Yaoab2a3a62020-10-29 15:33:55 -0700367 char *p = (char *)malloc(r.status_string().size() + 1);
368 if (p) {
369 strcpy(p, r.status_string().c_str());
370 }
371 return p;
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800372}
373
374int AudioClient::Device_set_master_mute(struct audio_hw_device *dev, bool mute)
375{
376 TRACE_ENTRY();
377 ClientContext context;
378 StatusReturn r;
379 Status status = stub_->Device_set_master_mute(&context, MakeMute(mute), &r);
380 return r.ret();
381}
382
383int AudioClient::Device_get_master_mute(struct audio_hw_device *dev, bool *mute)
384{
385 TRACE_ENTRY();
386 ClientContext context;
387 StatusReturn r;
388 Status status = stub_->Device_get_master_mute(&context, Empty(), &r);
389 *mute = r.status_bool();
390 return r.ret();
391}
392
393int AudioClient::Device_create_audio_patch(struct audio_hw_device *dev,
394 unsigned int num_sources,
395 const struct audio_port_config *sources,
396 unsigned int num_sinks,
397 const struct audio_port_config *sinks,
398 audio_patch_handle_t *handle)
399{
400 TRACE_ENTRY();
401 ClientContext context;
402 StatusReturn r;
403 CreateAudioPatch request;
404 const struct audio_port_config *c;
405
406 c = sources;
407 for (int i = 0; i < num_sources; i++, c++) {
408 AudioPortConfig *config = request.add_sources();
409 config->CopyFrom(MakeAudioPortConfig(c));
410 }
411
412 c = sinks;
413 for (int i = 0; i < num_sinks; i++, c++) {
414 AudioPortConfig *config = request.add_sinks();
415 config->CopyFrom(MakeAudioPortConfig(c));
416 }
417
418 Status status = stub_->Device_create_audio_patch(&context, request, &r);
419 *handle = r.status_32();
420 return r.ret();
421}
422
423int AudioClient::Device_release_audio_patch(struct audio_hw_device *dev,
424 audio_patch_handle_t handle)
425{
426 TRACE_ENTRY();
427 ClientContext context;
428 StatusReturn r;
429 Status status = stub_->Device_release_audio_patch(&context, MakeHandle(handle), &r);
430 return r.ret();
431}
432
433int AudioClient::Device_set_audio_port_config(struct audio_hw_device *dev,
434 const struct audio_port_config *config)
435{
436 TRACE_ENTRY();
437 ClientContext context;
438 StatusReturn r;
439 Status status = stub_->Device_set_audio_port_config(&context, MakeAudioPortConfig(config), &r);
440 return r.ret();
441}
442
443int AudioClient::stream_in_set_gain(struct audio_stream_in *stream, float gain)
444{
445 TRACE_ENTRY();
446 ClientContext context;
447 StatusReturn r;
448 StreamGain request;
449 char *name = (audio_stream_in_to_client(stream))->name;
450 request.set_name(std::string(name));
451 request.set_gain(gain);
452 Status status = stub_->StreamIn_set_gain(&context, request, &r);
453 return r.ret();
454}
455
456ssize_t AudioClient::stream_in_read(struct audio_stream_in *stream,
457 void* buffer,
458 size_t bytes)
459{
460 TRACE_ENTRY();
461 ClientContext context;
462 StatusReturn r;
463 char *name = (audio_stream_in_to_client(stream))->name;
464 Status status = stub_->StreamIn_read(&context, MakeStreamReadWrite(name, bytes), &r);
465 if (r.ret() > 0) {
466 CircularBuffer *cb = shm_->find<CircularBuffer>(name).first;
467 if (cb) {
468 memcpy(buffer, cb->start_ptr(*shm_), r.ret());
469 }
470 }
471 return r.ret();
472}
473
474uint32_t AudioClient::stream_in_get_input_frames_lost(struct audio_stream_in *stream)
475{
476 TRACE_ENTRY();
477 ClientContext context;
478 StatusReturn r;
479 char *name = (audio_stream_in_to_client(stream))->name;
480 Status status = stub_->StreamIn_get_input_frames_lost(&context, MakeStream(name), &r);
481 return r.ret();
482}
483
484int AudioClient::stream_in_get_capture_position(const struct audio_stream_in *stream,
485 int64_t *frames, int64_t *time)
486{
487 TRACE_ENTRY();
488 ClientContext context;
489 GetCapturePositionReturn r;
490 char *name = (audio_stream_in_to_client(stream))->name;
491 Status status = stub_->StreamIn_get_capture_position(&context, MakeStream(name), &r);
492 *frames = r.frames();
493 *time = r.time();
494 return r.ret();
495}
496
497uint32_t AudioClient::stream_out_get_latency(const struct audio_stream_out *stream)
498{
499 TRACE_ENTRY();
500 ClientContext context;
501 StatusReturn r;
502 char *name = (audio_stream_out_to_client(stream))->name;
503 Status status = stub_->StreamOut_get_latency(&context, MakeStream(name), &r);
504 return r.ret();
505}
506
507int AudioClient::stream_out_set_volume(struct audio_stream_out *stream, float left, float right)
508{
509 TRACE_ENTRY();
510 ClientContext context;
511 StatusReturn r;
512 char *name = (audio_stream_out_to_client(stream))->name;
513 Status status = stub_->StreamOut_set_volume(&context, MakeStreamOutSetVolume(name, left, right), &r);
514 return r.ret();
515}
516
517ssize_t AudioClient::stream_out_write(struct audio_stream_out *stream, const void* buffer,
518 size_t bytes)
519{
520 TRACE_ENTRY();
521 ClientContext context;
522 StatusReturn r;
523 char *name = (audio_stream_out_to_client(stream))->name;
524 CircularBuffer *cb = shm_->find<CircularBuffer>(name).first;
525 if (cb) {
526 memcpy(cb->start_ptr(*shm_), buffer, std::min(bytes, cb->capacity()));
527 }
528 Status status = stub_->StreamOut_write(&context, MakeStreamReadWrite(name, bytes), &r);
529 return r.ret();
530}
531
532int AudioClient::stream_out_get_render_position(const struct audio_stream_out *stream,
533 uint32_t *dsp_frames)
534{
535 TRACE_ENTRY();
536 ClientContext context;
537 StatusReturn r;
538 char *name = (audio_stream_out_to_client(stream))->name;
539 Status status = stub_->StreamOut_get_render_position(&context, MakeStream(name), &r);
540 *dsp_frames = r.status_32();
541 return r.ret();
542}
543
544int AudioClient::stream_out_get_next_write_timestamp(const struct audio_stream_out *stream,
545 int64_t *timestamp)
546{
547 TRACE_ENTRY();
548 ClientContext context;
549 StatusReturn r;
550 char *name = (audio_stream_out_to_client(stream))->name;
551 Status status = stub_->StreamOut_get_next_write_timestamp(&context, MakeStream(name), &r);
552 *timestamp = r.status_64();
553 return r.ret();
554}
555
556int AudioClient::stream_out_pause(struct audio_stream_out* stream)
557{
558 TRACE_ENTRY();
559 ClientContext context;
560 StatusReturn r;
561 char *name = (audio_stream_out_to_client(stream))->name;
562 Status status = stub_->StreamOut_pause(&context, MakeStream(name), &r);
563 return r.ret();
564}
565
566int AudioClient::stream_out_resume(struct audio_stream_out* stream)
567{
568 TRACE_ENTRY();
569 ClientContext context;
570 StatusReturn r;
571 char *name = (audio_stream_out_to_client(stream))->name;
572 Status status = stub_->StreamOut_resume(&context, MakeStream(name), &r);
573 return r.ret();
574}
575
576int AudioClient::stream_out_flush(struct audio_stream_out* stream)
577{
578 TRACE_ENTRY();
579 ClientContext context;
580 StatusReturn r;
581 char *name = (audio_stream_out_to_client(stream))->name;
582 Status status = stub_->StreamOut_flush(&context, MakeStream(name), &r);
583 return r.ret();
584}
585
586int AudioClient::stream_out_get_presentation_position(const struct audio_stream_out *stream,
587 uint64_t *frames,
588 struct timespec *timestamp)
589{
590 TRACE_ENTRY();
591 ClientContext context;
592 GetFrameTimestampReturn r;
593 char *name = (audio_stream_out_to_client(stream))->name;
594 Status status = stub_->StreamOut_get_presentation_position(&context, MakeStream(name), &r);
595 *frames = r.frames();
596 timestamp->tv_sec = r.timestamp().seconds();
597 timestamp->tv_nsec = r.timestamp().nanos();
598 return r.ret();
599}
600
601uint32_t AudioClient::stream_get_sample_rate(const struct audio_stream *stream)
602{
603 TRACE_ENTRY();
604 ClientContext context;
605 StatusReturn r;
606 char *name = (audio_stream_to_client(stream))->name;
607 Status status = stub_->Stream_get_sample_rate(&context, MakeStream(name), &r);
608 return r.ret();
609}
610
611size_t AudioClient::stream_get_buffer_size(const struct audio_stream *stream)
612{
613 TRACE_ENTRY();
614 ClientContext context;
615 StatusReturn r;
616 char *name = (audio_stream_to_client(stream))->name;
617 Status status = stub_->Stream_get_buffer_size(&context, MakeStream(name), &r);
618 return r.ret();
619}
620
621audio_channel_mask_t AudioClient::stream_get_channels(const struct audio_stream *stream)
622{
623 TRACE_ENTRY();
624 ClientContext context;
625 StatusReturn r;
626 char *name = (audio_stream_to_client(stream))->name;
627 Status status = stub_->Stream_get_channels(&context, MakeStream(name), &r);
628 return r.ret();
629}
630
631audio_format_t AudioClient::stream_get_format(const struct audio_stream *stream)
632{
633 TRACE_ENTRY();
634 ClientContext context;
635 StatusReturn r;
636 char *name = (audio_stream_to_client(stream))->name;
637 Status status = stub_->Stream_get_format(&context, MakeStream(name), &r);
638 return (audio_format_t)(r.ret());
639}
640
641int AudioClient::stream_standby(struct audio_stream *stream)
642{
643 TRACE_ENTRY();
644 ClientContext context;
645 StatusReturn r;
646 char *name = (audio_stream_to_client(stream))->name;
647 Status status = stub_->Stream_standby(&context, MakeStream(name), &r);
648 return r.ret();
649}
650
651int AudioClient::stream_dump(const struct audio_stream *stream, int fd)
652{
653 TRACE_ENTRY();
654 //TODO
655 return 0;
656}
657
658audio_devices_t AudioClient::stream_get_device(const struct audio_stream *stream)
659{
660 TRACE_ENTRY();
661 ClientContext context;
662 StatusReturn r;
663 char *name = (audio_stream_to_client(stream))->name;
664 Status status = stub_->Stream_get_device(&context, MakeStream(name), &r);
665 return r.ret();
666}
667
668int AudioClient::stream_set_parameters(struct audio_stream *stream, const char *kv_pairs)
669{
670 TRACE_ENTRY();
671 ClientContext context;
672 StatusReturn r;
673 char *name = (audio_stream_to_client(stream))->name;
674 Status status = stub_->Stream_set_parameters(&context, MakeStreamSetParameters(name, kv_pairs), &r);
675 return r.ret();
676}
677
678char * AudioClient::stream_get_parameters(const struct audio_stream *stream,
679 const char *keys)
680{
681 TRACE_ENTRY();
682 ClientContext context;
683 StatusReturn r;
684 char *name = (audio_stream_to_client(stream))->name;
685 Status status = stub_->Stream_get_parameters(&context, MakeStreamGetParameters(name, keys), &r);
686 char *p = (char *)malloc(r.status_string().size() + 1);
687 if (p) {
688 strcpy(p, r.status_string().c_str());
689 }
690 return p;
691}