blob: b4bda686fb198067b1378c82ba3e7bd33f9875c0 [file] [log] [blame]
Tim Yaoe8c0d4a2019-11-27 14:47:35 -08001#include <thread>
2#include <mutex>
3#include <cstdlib>
4
5#include <hardware/hardware.h>
6#include <hardware/audio.h>
7#include <pthread.h>
Tim Yaoe8c0d4a2019-11-27 14:47:35 -08008#include <cutils/log.h>
9
10#include <grpc/grpc.h>
11#include <grpcpp/channel.h>
12#include <grpcpp/client_context.h>
13#include <grpcpp/create_channel.h>
14#include <grpcpp/security/credentials.h>
15
16#include "audio_if_client.h"
17#include "audio_client.h"
18
19//#define TRACE_ENTRY() printf("[Client:%s] enter\n", __func__)
20#define TRACE_ENTRY()
21
22static AudioClient *client;
23static int inited = 0;
24static std::mutex client_mutex;
25
26static uint32_t stream_get_sample_rate(const struct audio_stream *stream)
27{
28 TRACE_ENTRY();
29 return client->stream_get_sample_rate(stream);
30}
31
32static size_t stream_get_buffer_size(const struct audio_stream *stream)
33{
34 TRACE_ENTRY();
35 return client->stream_get_buffer_size(stream);
36}
37
38static audio_channel_mask_t stream_get_channels(const struct audio_stream *stream)
39{
40 TRACE_ENTRY();
41 return client->stream_get_channels(stream);
42}
43
44static audio_format_t stream_get_format(const struct audio_stream *stream)
45{
46 TRACE_ENTRY();
47 return client->stream_get_format(stream);
48}
49
50static int stream_standby(struct audio_stream *stream)
51{
52 TRACE_ENTRY();
53 return client->stream_standby(stream);
54}
55
56static int stream_dump(const struct audio_stream *stream, int fd)
57{
58 TRACE_ENTRY();
59 return client->stream_dump(stream, fd);
60}
61
62static audio_devices_t stream_get_device(const struct audio_stream *stream)
63{
64 TRACE_ENTRY();
65 return client->stream_get_device(stream);
66}
67
68static int stream_set_parameters(struct audio_stream *stream, const char *kv_pairs)
69{
70 TRACE_ENTRY();
71 return client->stream_set_parameters(stream, kv_pairs);
72}
73
74static char * stream_get_parameters(const struct audio_stream *stream,
75 const char *keys)
76{
77 TRACE_ENTRY();
78 return client->stream_get_parameters(stream, keys);
79}
80
81static int stream_in_set_gain(struct audio_stream_in *stream, float gain)
82{
83 TRACE_ENTRY();
84 return client->stream_in_set_gain(stream, gain);
85}
86
87static ssize_t stream_in_read(struct audio_stream_in *stream, void* buffer,
88 size_t bytes)
89{
90 TRACE_ENTRY();
91 return client->stream_in_read(stream, buffer, bytes);
92}
93
94static uint32_t stream_in_get_input_frames_lost(struct audio_stream_in *stream)
95{
96 TRACE_ENTRY();
97 return client->stream_in_get_input_frames_lost(stream);
98}
99
100static int stream_in_get_capture_position(const struct audio_stream_in *stream,
101 int64_t *frames, int64_t *time)
102{
103 TRACE_ENTRY();
104 return client->stream_in_get_capture_position(stream, frames, time);
105}
106
107static uint32_t stream_out_get_latency(const struct audio_stream_out *stream)
108{
109 TRACE_ENTRY();
110 return client->stream_out_get_latency(stream);
111}
112
113static int stream_out_set_volume(struct audio_stream_out *stream, float left, float right)
114{
115 TRACE_ENTRY();
116 return client->stream_out_set_volume(stream, left, right);
117}
118
119static ssize_t stream_out_write(struct audio_stream_out *stream, const void* buffer,
120 size_t bytes)
121{
122 TRACE_ENTRY();
123 return client->stream_out_write(stream, buffer, bytes);
124}
125
126static int stream_out_get_render_position(const struct audio_stream_out *stream,
127 uint32_t *dsp_frames)
128{
129 TRACE_ENTRY();
130 return client->stream_out_get_render_position(stream, dsp_frames);
131}
132
133static int stream_out_get_next_write_timestamp(const struct audio_stream_out *stream,
134 int64_t *timestamp)
135{
136 TRACE_ENTRY();
137 return client->stream_out_get_next_write_timestamp(stream, timestamp);
138}
139
140static int stream_out_pause(struct audio_stream_out* stream)
141{
142 TRACE_ENTRY();
143 return client->stream_out_pause(stream);
144}
145
146static int stream_out_resume(struct audio_stream_out* stream)
147{
148 TRACE_ENTRY();
149 return client->stream_out_resume(stream);
150}
151
152static int stream_out_flush(struct audio_stream_out* stream)
153{
154 TRACE_ENTRY();
155 return client->stream_out_flush(stream);
156}
157
158static int stream_out_get_presentation_position(const struct audio_stream_out *stream,
159 uint64_t *frames, struct timespec *timestamp)
160{
161 TRACE_ENTRY();
162 return client->stream_out_get_presentation_position(stream, frames, timestamp);
163}
164
165struct audio_stream_in stream_in_template = {
166 .common = {
167 .get_sample_rate = stream_get_sample_rate,
168 .set_sample_rate = NULL,
169 .get_buffer_size = stream_get_buffer_size,
170 .get_channels = stream_get_channels,
171 .get_format = stream_get_format,
172 .set_format = NULL,
173 .standby = stream_standby,
174 .dump = stream_dump,
175 .get_device = stream_get_device,
176 .set_device = NULL,
177 .set_parameters = stream_set_parameters,
178 .get_parameters = stream_get_parameters,
179 .add_audio_effect = NULL,
180 .remove_audio_effect = NULL
181 },
182 .set_gain = stream_in_set_gain,
183 .read = stream_in_read,
184 .get_input_frames_lost = stream_in_get_input_frames_lost,
185 .get_capture_position = stream_in_get_capture_position,
186 .start = NULL,
187 .stop = NULL,
188 .create_mmap_buffer = NULL,
189 .get_mmap_position = NULL,
190 .get_active_microphones = NULL,
xingri.gaob6a384b2023-10-19 07:08:48 +0000191 .set_microphone_direction = NULL,
192 .set_microphone_field_dimension = NULL,
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800193 .update_sink_metadata = NULL
194};
195
196struct audio_stream_out stream_out_template = {
197 .common = {
198 .get_sample_rate = stream_get_sample_rate,
199 .set_sample_rate = NULL,
200 .get_buffer_size = stream_get_buffer_size,
201 .get_channels = stream_get_channels,
202 .get_format = stream_get_format,
203 .set_format = NULL,
204 .standby = stream_standby,
205 .dump = stream_dump,
206 .get_device = stream_get_device,
207 .set_device = NULL,
208 .set_parameters = stream_set_parameters,
209 .get_parameters = stream_get_parameters,
210 .add_audio_effect = NULL,
211 .remove_audio_effect = NULL
212 },
213 .get_latency = stream_out_get_latency,
214 .set_volume = stream_out_set_volume,
215 .write = stream_out_write,
216 .get_render_position = stream_out_get_render_position,
217 .get_next_write_timestamp = stream_out_get_next_write_timestamp,
218 .set_callback = NULL,
219 .pause = stream_out_pause,
220 .resume = stream_out_resume,
221 .drain = NULL,
222 .flush = stream_out_flush,
223 .get_presentation_position = stream_out_get_presentation_position,
224 .start = NULL,
225 .stop = NULL,
226 .create_mmap_buffer = NULL,
227 .get_mmap_position = NULL,
228 .update_source_metadata = NULL
229};
230
231static int Device_common_close(struct hw_device_t* device)
232{
233 // Server side audio hal device is constructed with
234 // server's life span. Skip Device_common_close for client
235 // The method is only needed when server really wants to exit.
236 // return client->Device_common_close(device);
237 return 0;
238}
239
240static int Device_init_check(const struct audio_hw_device *dev)
241{
242 TRACE_ENTRY();
243 return client->Device_init_check(dev);
244}
245
246static int Device_set_voice_volume(struct audio_hw_device *dev, float volume)
247{
248 TRACE_ENTRY();
249 return client->Device_set_voice_volume(dev, volume);
250}
251
252static int Device_set_master_volume(struct audio_hw_device *dev, float volume)
253{
254 TRACE_ENTRY();
255 return client->Device_set_master_volume(dev, volume);
256}
257
258static int Device_get_master_volume(struct audio_hw_device *dev, float *volume)
259{
260 TRACE_ENTRY();
261 return client->Device_get_master_volume(dev, volume);
262}
263
264static int Device_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
265{
266 TRACE_ENTRY();
267 return client->Device_set_mode(dev, mode);
268}
269
270static int Device_set_mic_mute(struct audio_hw_device *dev, bool state)
271{
272 TRACE_ENTRY();
273 return client->Device_set_mic_mute(dev, state);
274}
275
276static int Device_get_mic_mute(const struct audio_hw_device *dev, bool *state)
277{
278 TRACE_ENTRY();
279 return client->Device_get_mic_mute(dev, state);
280}
281
282static int Device_set_parameters(struct audio_hw_device *dev, const char *kv_pairs)
283{
284 TRACE_ENTRY();
285 return client->Device_set_parameters(dev, kv_pairs);
286}
287
288static char * Device_get_parameters(const struct audio_hw_device *dev,
289 const char *keys)
290{
291 TRACE_ENTRY();
292 return client->Device_get_parameters(dev, keys);
293}
294
295static size_t Device_get_input_buffer_size(const struct audio_hw_device *dev,
296 const struct audio_config *config)
297{
298 TRACE_ENTRY();
299 return client->Device_get_input_buffer_size(dev, config);
300}
301
302static int Device_open_output_stream(struct audio_hw_device *dev,
303 audio_io_handle_t handle,
304 audio_devices_t devices,
305 audio_output_flags_t flags,
306 struct audio_config *config,
307 struct audio_stream_out **stream_out,
308 const char *address)
309{
310 TRACE_ENTRY();
311
312 int r;
313 audio_stream_out_client_t *stream_out_client = (audio_stream_out_client_t *)calloc(1, sizeof(audio_stream_out_client_t));
314 if (!stream_out_client) return -ENOMEM;
315
316 r = client->Device_open_output_stream(dev, handle, devices, flags, config, stream_out_client, address);
317 if (r) {
318 free(stream_out);
319 return r;
320 }
321
322 stream_out_client->stream_out = stream_out_template;
323 *stream_out = &(stream_out_client->stream_out);
324 return r;
325}
326
327static void Device_close_output_stream(struct audio_hw_device *dev,
328 struct audio_stream_out* stream_out)
329{
330 TRACE_ENTRY();
331
332 client->Device_close_output_stream(dev, stream_out);
333 free(audio_stream_out_to_client(stream_out));
334}
335
336static int Device_open_input_stream(struct audio_hw_device *dev,
337 audio_io_handle_t handle,
338 audio_devices_t devices,
339 struct audio_config *config,
340 struct audio_stream_in **stream_in,
341 audio_input_flags_t flags,
342 const char *address,
343 audio_source_t source)
344{
345 TRACE_ENTRY();
346
347 int r;
348 audio_stream_in_client_t *stream_in_client = (audio_stream_in_client_t *)calloc(1, sizeof(audio_stream_in_client_t));
349 if (!stream_in_client) return -ENOMEM;
350
351 r = client->Device_open_input_stream(dev, handle, devices, config, stream_in_client, flags, address, source);
352 if (r) {
353 free(stream_in_client);
354 return r;
355 }
356
357 stream_in_client->stream_in = stream_in_template;
358 *stream_in = &(stream_in_client->stream_in);
359 return r;
360}
361
362static void Device_close_input_stream(struct audio_hw_device *dev,
363 struct audio_stream_in *stream_in)
364{
365 TRACE_ENTRY();
366
367 client->Device_close_input_stream(dev, stream_in);
368 free(audio_stream_in_to_client(stream_in));
369}
370
Tim Yaoab2a3a62020-10-29 15:33:55 -0700371static char * Device_dump(const struct audio_hw_device *dev, int fd)
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800372{
373 TRACE_ENTRY();
374
375 return client->Device_dump(dev, fd);
376}
377
378static int Device_set_master_mute(struct audio_hw_device *dev, bool mute)
379{
380 TRACE_ENTRY();
381
382 return client->Device_set_master_mute(dev, mute);
383}
384
385static int Device_get_master_mute(struct audio_hw_device *dev, bool *mute)
386{
387 TRACE_ENTRY();
388
389 return client->Device_get_master_mute(dev, mute);
390}
391
392static int Device_create_audio_patch(struct audio_hw_device *dev,
393 unsigned int num_sources,
394 const struct audio_port_config *sources,
395 unsigned int num_sinks,
396 const struct audio_port_config *sinks,
397 audio_patch_handle_t *handle)
398{
399 TRACE_ENTRY();
400
401 return client->Device_create_audio_patch(dev, num_sources, sources, num_sinks, sinks, handle);
402}
403
404static int Device_release_audio_patch(struct audio_hw_device *dev,
405 audio_patch_handle_t handle)
406{
407 TRACE_ENTRY();
408
409 return client->Device_release_audio_patch(dev, handle);
410}
411
412static int Device_set_audio_port_config(struct audio_hw_device *dev,
413 const struct audio_port_config *config)
414{
415 TRACE_ENTRY();
416
417 return client->Device_set_audio_port_config(dev, config);
418}
419
420static struct hw_module_t hw_module = {
421 .tag = HARDWARE_MODULE_TAG,
422 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
423 .hal_api_version = HARDWARE_HAL_API_VERSION,
424 .id = AUDIO_HARDWARE_MODULE_ID,
425 .name = "aml audio HW HAL",
426 .author = "amlogic, Corp.",
427};
428
429static audio_hw_device_t device = {
430 .common = {
431 .tag = HARDWARE_DEVICE_TAG,
432 .version = AUDIO_DEVICE_API_VERSION_3_0,
433 .module = &hw_module,
434 .reserved = {0},
435 .close = Device_common_close,
436 },
437 .get_supported_devices = NULL,
438 .init_check = Device_init_check,
439 .set_voice_volume = Device_set_voice_volume,
440 .set_master_volume = Device_set_master_volume,
441 .get_master_volume = Device_get_master_volume,
442 .set_mode = Device_set_mode,
443 .set_mic_mute = Device_set_mic_mute,
444 .get_mic_mute = Device_get_mic_mute,
445 .set_parameters = Device_set_parameters,
446 .get_parameters = Device_get_parameters,
447 .get_input_buffer_size = Device_get_input_buffer_size,
448 .open_output_stream = Device_open_output_stream,
449 .close_output_stream = Device_close_output_stream,
450 .open_input_stream = Device_open_input_stream,
451 .close_input_stream = Device_close_input_stream,
452 .get_microphones = NULL,
453 .dump = Device_dump,
454 .set_master_mute = Device_set_master_mute,
455 .get_master_mute = Device_get_master_mute,
456 .create_audio_patch = Device_create_audio_patch,
457 .release_audio_patch = Device_release_audio_patch,
458 .get_audio_port = NULL,
459 .set_audio_port_config = Device_set_audio_port_config,
460};
461
462extern "C" {
463
464int audio_hw_load_interface(audio_hw_device_t **dev)
465{
466 TRACE_ENTRY();
467 printf("PID = %d, inited = %d\n", ::getpid(), inited);
468
Tim Yao1b84e362020-08-24 12:51:36 -0700469 const char *url = std::getenv("AUDIO_SERVER_SOCKET");
470
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800471 std::lock_guard<std::mutex> lock(client_mutex);
472
473 if (inited++ > 0) {
474 *dev = &device;
475 return 0;
476 }
477
478 client = new AudioClient(
wei.duc64b06a2022-01-17 16:51:12 +0800479 grpc::CreateChannel((url) ? url : "unix:///tmp/audio_socket",
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800480 grpc::InsecureChannelCredentials()));
481
482 *dev = &device;
483 inited = 1;
484
485 return 0;
486}
487
488void audio_hw_unload_interface(audio_hw_device_t *dev)
489{
490 TRACE_ENTRY();
491
492 std::lock_guard<std::mutex> lock(client_mutex);
493
494 if (--inited == 0) {
495 delete client;
496 client = nullptr;
497 }
498}
499
cheng tong7d907882020-09-04 18:53:04 +0800500int audio_effect_set_parameters(aml_audio_effect_type_e type, effect_param_t *param)
501{
502 TRACE_ENTRY();
503
504 std::lock_guard<std::mutex> lock(client_mutex);
505
506 if (type >= AML_EFFECT_MAX || type < 0)
507 return -1;
508
509 if (param == NULL || param->psize == 0 || param->vsize == 0) {
510 return -1;
511 }
512
513 return client->Effect_set_parameters(type, param);
514}
515
516int audio_effect_get_parameters(aml_audio_effect_type_e type, effect_param_t *param)
517{
518 TRACE_ENTRY();
519
520 std::lock_guard<std::mutex> lock(client_mutex);
521
522 if (type >= AML_EFFECT_MAX || type < 0)
523 return -1;
524
525 if (param == NULL || param->psize == 0 || param->vsize == 0) {
526 return -1;
527 }
528
529 return client->Effect_get_parameters(type, param);
530}
531
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800532}