audio_hw.c revision 4b89e37ad290ef955abf8ac1d151728303311345
1/*
2 * Copyright (C) 2013-2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "audio_hw_primary"
18/*#define LOG_NDEBUG 0*/
19/*#define VERY_VERY_VERBOSE_LOGGING*/
20#ifdef VERY_VERY_VERBOSE_LOGGING
21#define ALOGVV ALOGV
22#else
23#define ALOGVV(a...) do { } while(0)
24#endif
25
26#include <errno.h>
27#include <pthread.h>
28#include <stdint.h>
29#include <sys/time.h>
30#include <stdlib.h>
31#include <math.h>
32#include <dlfcn.h>
33#include <sys/resource.h>
34#include <sys/prctl.h>
35
36#include <cutils/log.h>
37#include <cutils/str_parms.h>
38#include <cutils/properties.h>
39#include <cutils/atomic.h>
40#include <cutils/sched_policy.h>
41
42#include <hardware/audio_effect.h>
43#include <hardware/audio_alsaops.h>
44#include <system/thread_defs.h>
45#include <audio_effects/effect_aec.h>
46#include <audio_effects/effect_ns.h>
47#include "audio_hw.h"
48#include "audio_extn.h"
49#include "platform_api.h"
50#include <platform.h>
51#include "voice_extn.h"
52
53#include "sound/compress_params.h"
54
55#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
56#define COMPRESS_OFFLOAD_NUM_FRAGMENTS 4
57/* ToDo: Check and update a proper value in msec */
58#define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96
59#define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000
60
61static unsigned int configured_low_latency_capture_period_size =
62        LOW_LATENCY_CAPTURE_PERIOD_SIZE;
63
64/* This constant enables extended precision handling.
65 * TODO The flag is off until more testing is done.
66 */
67static const bool k_enable_extended_precision = false;
68
69struct pcm_config pcm_config_deep_buffer = {
70    .channels = 2,
71    .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
72    .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE,
73    .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT,
74    .format = PCM_FORMAT_S16_LE,
75    .start_threshold = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
76    .stop_threshold = INT_MAX,
77    .avail_min = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
78};
79
80struct pcm_config pcm_config_low_latency = {
81    .channels = 2,
82    .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
83    .period_size = LOW_LATENCY_OUTPUT_PERIOD_SIZE,
84    .period_count = LOW_LATENCY_OUTPUT_PERIOD_COUNT,
85    .format = PCM_FORMAT_S16_LE,
86    .start_threshold = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
87    .stop_threshold = INT_MAX,
88    .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
89};
90
91struct pcm_config pcm_config_hdmi_multi = {
92    .channels = HDMI_MULTI_DEFAULT_CHANNEL_COUNT, /* changed when the stream is opened */
93    .rate = DEFAULT_OUTPUT_SAMPLING_RATE, /* changed when the stream is opened */
94    .period_size = HDMI_MULTI_PERIOD_SIZE,
95    .period_count = HDMI_MULTI_PERIOD_COUNT,
96    .format = PCM_FORMAT_S16_LE,
97    .start_threshold = 0,
98    .stop_threshold = INT_MAX,
99    .avail_min = 0,
100};
101
102struct pcm_config pcm_config_audio_capture = {
103    .channels = 2,
104    .period_count = AUDIO_CAPTURE_PERIOD_COUNT,
105    .format = PCM_FORMAT_S16_LE,
106};
107
108const char * const use_case_table[AUDIO_USECASE_MAX] = {
109    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "deep-buffer-playback",
110    [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback",
111    [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "multi-channel-playback",
112    [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
113
114    [USECASE_AUDIO_RECORD] = "audio-record",
115    [USECASE_AUDIO_RECORD_LOW_LATENCY] = "low-latency-record",
116
117    [USECASE_AUDIO_HFP_SCO] = "hfp-sco",
118    [USECASE_AUDIO_HFP_SCO_WB] = "hfp-sco-wb",
119
120    [USECASE_VOICE_CALL] = "voice-call",
121    [USECASE_VOICE2_CALL] = "voice2-call",
122    [USECASE_VOLTE_CALL] = "volte-call",
123    [USECASE_QCHAT_CALL] = "qchat-call",
124    [USECASE_VOWLAN_CALL] = "vowlan-call",
125};
126
127
128#define STRING_TO_ENUM(string) { #string, string }
129
130struct string_to_enum {
131    const char *name;
132    uint32_t value;
133};
134
135static const struct string_to_enum out_channels_name_to_enum_table[] = {
136    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
137    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
138    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
139};
140
141static int set_voice_volume_l(struct audio_device *adev, float volume);
142
143static bool is_supported_format(audio_format_t format)
144{
145    if (format == AUDIO_FORMAT_MP3 ||
146            format == AUDIO_FORMAT_AAC)
147        return true;
148
149    return false;
150}
151
152static int get_snd_codec_id(audio_format_t format)
153{
154    int id = 0;
155
156    switch (format) {
157    case AUDIO_FORMAT_MP3:
158        id = SND_AUDIOCODEC_MP3;
159        break;
160    case AUDIO_FORMAT_AAC:
161        id = SND_AUDIOCODEC_AAC;
162        break;
163    default:
164        ALOGE("%s: Unsupported audio format", __func__);
165    }
166
167    return id;
168}
169
170int pcm_ioctl(void *pcm, int request, ...)
171{
172    va_list ap;
173    void * arg;
174    int pcm_fd = *(int*)pcm;
175
176    va_start(ap, request);
177    arg = va_arg(ap, void *);
178    va_end(ap);
179
180    return ioctl(pcm_fd, request, arg);
181}
182
183int enable_audio_route(struct audio_device *adev,
184                       struct audio_usecase *usecase)
185{
186    snd_device_t snd_device;
187    char mixer_path[50];
188
189    if (usecase == NULL)
190        return -EINVAL;
191
192    ALOGV("%s: enter: usecase(%d)", __func__, usecase->id);
193
194    if (usecase->type == PCM_CAPTURE)
195        snd_device = usecase->in_snd_device;
196    else
197        snd_device = usecase->out_snd_device;
198
199    strcpy(mixer_path, use_case_table[usecase->id]);
200    platform_add_backend_name(adev->platform, mixer_path, snd_device);
201    ALOGV("%s: apply and update mixer path: %s", __func__, mixer_path);
202    audio_route_apply_and_update_path(adev->audio_route, mixer_path);
203
204    ALOGV("%s: exit", __func__);
205    return 0;
206}
207
208int disable_audio_route(struct audio_device *adev,
209                        struct audio_usecase *usecase)
210{
211    snd_device_t snd_device;
212    char mixer_path[50];
213
214    if (usecase == NULL)
215        return -EINVAL;
216
217    ALOGV("%s: enter: usecase(%d)", __func__, usecase->id);
218    if (usecase->type == PCM_CAPTURE)
219        snd_device = usecase->in_snd_device;
220    else
221        snd_device = usecase->out_snd_device;
222    strcpy(mixer_path, use_case_table[usecase->id]);
223    platform_add_backend_name(adev->platform, mixer_path, snd_device);
224    ALOGV("%s: reset and update mixer path: %s", __func__, mixer_path);
225    audio_route_reset_and_update_path(adev->audio_route, mixer_path);
226
227    ALOGV("%s: exit", __func__);
228    return 0;
229}
230
231int enable_snd_device(struct audio_device *adev,
232                      snd_device_t snd_device)
233{
234    if (snd_device < SND_DEVICE_MIN ||
235        snd_device >= SND_DEVICE_MAX) {
236        ALOGE("%s: Invalid sound device %d", __func__, snd_device);
237        return -EINVAL;
238    }
239
240    adev->snd_dev_ref_cnt[snd_device]++;
241    if (adev->snd_dev_ref_cnt[snd_device] > 1) {
242        ALOGV("%s: snd_device(%d: %s) is already active",
243              __func__, snd_device, platform_get_snd_device_name(snd_device));
244        return 0;
245    }
246
247    if (platform_send_audio_calibration(adev->platform, snd_device) < 0) {
248        adev->snd_dev_ref_cnt[snd_device]--;
249        return -EINVAL;
250    }
251
252    const char * dev_path = platform_get_snd_device_name(snd_device);
253    ALOGV("%s: snd_device(%d: %s)", __func__, snd_device, dev_path);
254    audio_route_apply_and_update_path(adev->audio_route, dev_path);
255
256    return 0;
257}
258
259int disable_snd_device(struct audio_device *adev,
260                       snd_device_t snd_device)
261{
262    if (snd_device < SND_DEVICE_MIN ||
263        snd_device >= SND_DEVICE_MAX) {
264        ALOGE("%s: Invalid sound device %d", __func__, snd_device);
265        return -EINVAL;
266    }
267    if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
268        ALOGE("%s: device ref cnt is already 0", __func__);
269        return -EINVAL;
270    }
271    adev->snd_dev_ref_cnt[snd_device]--;
272    if (adev->snd_dev_ref_cnt[snd_device] == 0) {
273        const char * dev_path = platform_get_snd_device_name(snd_device);
274        ALOGV("%s: snd_device(%d: %s)", __func__,
275              snd_device, dev_path);
276        audio_route_reset_and_update_path(adev->audio_route, dev_path);
277    }
278    return 0;
279}
280
281static void check_usecases_codec_backend(struct audio_device *adev,
282                                          struct audio_usecase *uc_info,
283                                          snd_device_t snd_device)
284{
285    struct listnode *node;
286    struct audio_usecase *usecase;
287    bool switch_device[AUDIO_USECASE_MAX];
288    int i, num_uc_to_switch = 0;
289
290    /*
291     * This function is to make sure that all the usecases that are active on
292     * the hardware codec backend are always routed to any one device that is
293     * handled by the hardware codec.
294     * For example, if low-latency and deep-buffer usecases are currently active
295     * on speaker and out_set_parameters(headset) is received on low-latency
296     * output, then we have to make sure deep-buffer is also switched to headset,
297     * because of the limitation that both the devices cannot be enabled
298     * at the same time as they share the same backend.
299     */
300    /* Disable all the usecases on the shared backend other than the
301       specified usecase */
302    for (i = 0; i < AUDIO_USECASE_MAX; i++)
303        switch_device[i] = false;
304
305    list_for_each(node, &adev->usecase_list) {
306        usecase = node_to_item(node, struct audio_usecase, list);
307        if (usecase->type != PCM_CAPTURE &&
308                usecase != uc_info &&
309                usecase->out_snd_device != snd_device &&
310                usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
311            ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
312                  __func__, use_case_table[usecase->id],
313                  platform_get_snd_device_name(usecase->out_snd_device));
314            disable_audio_route(adev, usecase);
315            switch_device[usecase->id] = true;
316            num_uc_to_switch++;
317        }
318    }
319
320    if (num_uc_to_switch) {
321        list_for_each(node, &adev->usecase_list) {
322            usecase = node_to_item(node, struct audio_usecase, list);
323            if (switch_device[usecase->id]) {
324                disable_snd_device(adev, usecase->out_snd_device);
325            }
326        }
327
328        list_for_each(node, &adev->usecase_list) {
329            usecase = node_to_item(node, struct audio_usecase, list);
330            if (switch_device[usecase->id]) {
331                enable_snd_device(adev, snd_device);
332            }
333        }
334
335        /* Re-route all the usecases on the shared backend other than the
336           specified usecase to new snd devices */
337        list_for_each(node, &adev->usecase_list) {
338            usecase = node_to_item(node, struct audio_usecase, list);
339            /* Update the out_snd_device only before enabling the audio route */
340            if (switch_device[usecase->id] ) {
341                usecase->out_snd_device = snd_device;
342                enable_audio_route(adev, usecase);
343            }
344        }
345    }
346}
347
348static void check_and_route_capture_usecases(struct audio_device *adev,
349                                             struct audio_usecase *uc_info,
350                                             snd_device_t snd_device)
351{
352    struct listnode *node;
353    struct audio_usecase *usecase;
354    bool switch_device[AUDIO_USECASE_MAX];
355    int i, num_uc_to_switch = 0;
356
357    /*
358     * This function is to make sure that all the active capture usecases
359     * are always routed to the same input sound device.
360     * For example, if audio-record and voice-call usecases are currently
361     * active on speaker(rx) and speaker-mic (tx) and out_set_parameters(earpiece)
362     * is received for voice call then we have to make sure that audio-record
363     * usecase is also switched to earpiece i.e. voice-dmic-ef,
364     * because of the limitation that two devices cannot be enabled
365     * at the same time if they share the same backend.
366     */
367    for (i = 0; i < AUDIO_USECASE_MAX; i++)
368        switch_device[i] = false;
369
370    list_for_each(node, &adev->usecase_list) {
371        usecase = node_to_item(node, struct audio_usecase, list);
372        if (usecase->type != PCM_PLAYBACK &&
373                usecase != uc_info &&
374                usecase->in_snd_device != snd_device) {
375            ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
376                  __func__, use_case_table[usecase->id],
377                  platform_get_snd_device_name(usecase->in_snd_device));
378            disable_audio_route(adev, usecase);
379            switch_device[usecase->id] = true;
380            num_uc_to_switch++;
381        }
382    }
383
384    if (num_uc_to_switch) {
385        list_for_each(node, &adev->usecase_list) {
386            usecase = node_to_item(node, struct audio_usecase, list);
387            if (switch_device[usecase->id]) {
388                disable_snd_device(adev, usecase->in_snd_device);
389            }
390        }
391
392        list_for_each(node, &adev->usecase_list) {
393            usecase = node_to_item(node, struct audio_usecase, list);
394            if (switch_device[usecase->id]) {
395                enable_snd_device(adev, snd_device);
396            }
397        }
398
399        /* Re-route all the usecases on the shared backend other than the
400           specified usecase to new snd devices */
401        list_for_each(node, &adev->usecase_list) {
402            usecase = node_to_item(node, struct audio_usecase, list);
403            /* Update the in_snd_device only before enabling the audio route */
404            if (switch_device[usecase->id] ) {
405                usecase->in_snd_device = snd_device;
406                enable_audio_route(adev, usecase);
407            }
408        }
409    }
410}
411
412/* must be called with hw device mutex locked */
413static int read_hdmi_channel_masks(struct stream_out *out)
414{
415    int ret = 0;
416    int channels = platform_edid_get_max_channels(out->dev->platform);
417
418    switch (channels) {
419        /*
420         * Do not handle stereo output in Multi-channel cases
421         * Stereo case is handled in normal playback path
422         */
423    case 6:
424        ALOGV("%s: HDMI supports 5.1", __func__);
425        out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
426        break;
427    case 8:
428        ALOGV("%s: HDMI supports 5.1 and 7.1 channels", __func__);
429        out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
430        out->supported_channel_masks[1] = AUDIO_CHANNEL_OUT_7POINT1;
431        break;
432    default:
433        ALOGE("HDMI does not support multi channel playback");
434        ret = -ENOSYS;
435        break;
436    }
437    return ret;
438}
439
440struct audio_usecase *get_usecase_from_list(struct audio_device *adev,
441                                            audio_usecase_t uc_id)
442{
443    struct audio_usecase *usecase;
444    struct listnode *node;
445
446    list_for_each(node, &adev->usecase_list) {
447        usecase = node_to_item(node, struct audio_usecase, list);
448        if (usecase->id == uc_id)
449            return usecase;
450    }
451    return NULL;
452}
453
454int select_devices(struct audio_device *adev,
455                   audio_usecase_t uc_id)
456{
457    snd_device_t out_snd_device = SND_DEVICE_NONE;
458    snd_device_t in_snd_device = SND_DEVICE_NONE;
459    struct audio_usecase *usecase = NULL;
460    struct audio_usecase *vc_usecase = NULL;
461    struct audio_usecase *hfp_usecase = NULL;
462    audio_usecase_t hfp_ucid;
463    struct listnode *node;
464    int status = 0;
465
466    usecase = get_usecase_from_list(adev, uc_id);
467    if (usecase == NULL) {
468        ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
469        return -EINVAL;
470    }
471
472    if ((usecase->type == VOICE_CALL) ||
473        (usecase->type == PCM_HFP_CALL)) {
474        out_snd_device = platform_get_output_snd_device(adev->platform,
475                                                        usecase->stream.out->devices);
476        in_snd_device = platform_get_input_snd_device(adev->platform, usecase->stream.out->devices);
477        usecase->devices = usecase->stream.out->devices;
478    } else {
479        /*
480         * If the voice call is active, use the sound devices of voice call usecase
481         * so that it would not result any device switch. All the usecases will
482         * be switched to new device when select_devices() is called for voice call
483         * usecase. This is to avoid switching devices for voice call when
484         * check_usecases_codec_backend() is called below.
485         */
486        if (voice_is_in_call(adev)) {
487            vc_usecase = get_usecase_from_list(adev, USECASE_VOICE_CALL);
488            if ((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
489                (usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL)) {
490                in_snd_device = vc_usecase->in_snd_device;
491                out_snd_device = vc_usecase->out_snd_device;
492            }
493        } else if (audio_extn_hfp_is_active(adev)) {
494            hfp_ucid = audio_extn_hfp_get_usecase();
495            hfp_usecase = get_usecase_from_list(adev, hfp_ucid);
496            if (hfp_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
497                   in_snd_device = hfp_usecase->in_snd_device;
498                   out_snd_device = hfp_usecase->out_snd_device;
499            }
500        }
501        if (usecase->type == PCM_PLAYBACK) {
502            usecase->devices = usecase->stream.out->devices;
503            in_snd_device = SND_DEVICE_NONE;
504            if (out_snd_device == SND_DEVICE_NONE) {
505                out_snd_device = platform_get_output_snd_device(adev->platform,
506                                            usecase->stream.out->devices);
507                if (usecase->stream.out == adev->primary_output &&
508                        adev->active_input &&
509                        adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
510                    select_devices(adev, adev->active_input->usecase);
511                }
512            }
513        } else if (usecase->type == PCM_CAPTURE) {
514            usecase->devices = usecase->stream.in->device;
515            out_snd_device = SND_DEVICE_NONE;
516            if (in_snd_device == SND_DEVICE_NONE) {
517                if (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
518                        adev->primary_output && !adev->primary_output->standby) {
519                    in_snd_device = platform_get_input_snd_device(adev->platform,
520                                        adev->primary_output->devices);
521                } else {
522                    in_snd_device = platform_get_input_snd_device(adev->platform,
523                                                                  AUDIO_DEVICE_NONE);
524                }
525            }
526        }
527    }
528
529    if (out_snd_device == usecase->out_snd_device &&
530        in_snd_device == usecase->in_snd_device) {
531        return 0;
532    }
533
534    ALOGD("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
535          out_snd_device, platform_get_snd_device_name(out_snd_device),
536          in_snd_device,  platform_get_snd_device_name(in_snd_device));
537
538    /*
539     * Limitation: While in call, to do a device switch we need to disable
540     * and enable both RX and TX devices though one of them is same as current
541     * device.
542     */
543    if (usecase->type == VOICE_CALL) {
544        status = platform_switch_voice_call_device_pre(adev->platform);
545    }
546
547    /* Disable current sound devices */
548    if (usecase->out_snd_device != SND_DEVICE_NONE) {
549        disable_audio_route(adev, usecase);
550        disable_snd_device(adev, usecase->out_snd_device);
551    }
552
553    if (usecase->in_snd_device != SND_DEVICE_NONE) {
554        disable_audio_route(adev, usecase);
555        disable_snd_device(adev, usecase->in_snd_device);
556    }
557
558    /* Applicable only on the targets that has external modem.
559     * New device information should be sent to modem before enabling
560     * the devices to reduce in-call device switch time.
561     */
562    if (usecase->type == VOICE_CALL)
563        status = platform_switch_voice_call_enable_device_config(adev->platform,
564                                                                 out_snd_device,
565                                                                 in_snd_device);
566
567    /* Enable new sound devices */
568    if (out_snd_device != SND_DEVICE_NONE) {
569        if (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND)
570            check_usecases_codec_backend(adev, usecase, out_snd_device);
571        enable_snd_device(adev, out_snd_device);
572    }
573
574    if (in_snd_device != SND_DEVICE_NONE) {
575        check_and_route_capture_usecases(adev, usecase, in_snd_device);
576        enable_snd_device(adev, in_snd_device);
577    }
578
579    if (usecase->type == VOICE_CALL)
580        status = platform_switch_voice_call_device_post(adev->platform,
581                                                        out_snd_device,
582                                                        in_snd_device);
583
584    usecase->in_snd_device = in_snd_device;
585    usecase->out_snd_device = out_snd_device;
586
587    enable_audio_route(adev, usecase);
588
589    /* Applicable only on the targets that has external modem.
590     * Enable device command should be sent to modem only after
591     * enabling voice call mixer controls
592     */
593    if (usecase->type == VOICE_CALL)
594        status = platform_switch_voice_call_usecase_route_post(adev->platform,
595                                                               out_snd_device,
596                                                               in_snd_device);
597
598    return status;
599}
600
601static int stop_input_stream(struct stream_in *in)
602{
603    int i, ret = 0;
604    struct audio_usecase *uc_info;
605    struct audio_device *adev = in->dev;
606
607    adev->active_input = NULL;
608
609    ALOGV("%s: enter: usecase(%d: %s)", __func__,
610          in->usecase, use_case_table[in->usecase]);
611    uc_info = get_usecase_from_list(adev, in->usecase);
612    if (uc_info == NULL) {
613        ALOGE("%s: Could not find the usecase (%d) in the list",
614              __func__, in->usecase);
615        return -EINVAL;
616    }
617
618    /* 1. Disable stream specific mixer controls */
619    disable_audio_route(adev, uc_info);
620
621    /* 2. Disable the tx device */
622    disable_snd_device(adev, uc_info->in_snd_device);
623
624    list_remove(&uc_info->list);
625    free(uc_info);
626
627    ALOGV("%s: exit: status(%d)", __func__, ret);
628    return ret;
629}
630
631int start_input_stream(struct stream_in *in)
632{
633    /* 1. Enable output device and stream routing controls */
634    int ret = 0;
635    struct audio_usecase *uc_info;
636    struct audio_device *adev = in->dev;
637
638    ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
639    in->pcm_device_id = platform_get_pcm_device_id(in->usecase, PCM_CAPTURE);
640    if (in->pcm_device_id < 0) {
641        ALOGE("%s: Could not find PCM device id for the usecase(%d)",
642              __func__, in->usecase);
643        ret = -EINVAL;
644        goto error_config;
645    }
646
647    adev->active_input = in;
648    uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
649    uc_info->id = in->usecase;
650    uc_info->type = PCM_CAPTURE;
651    uc_info->stream.in = in;
652    uc_info->devices = in->device;
653    uc_info->in_snd_device = SND_DEVICE_NONE;
654    uc_info->out_snd_device = SND_DEVICE_NONE;
655
656    list_add_tail(&adev->usecase_list, &uc_info->list);
657    select_devices(adev, in->usecase);
658
659    ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
660          __func__, adev->snd_card, in->pcm_device_id, in->config.channels);
661    in->pcm = pcm_open(adev->snd_card, in->pcm_device_id,
662                           PCM_IN, &in->config);
663    if (in->pcm && !pcm_is_ready(in->pcm)) {
664        ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
665        pcm_close(in->pcm);
666        in->pcm = NULL;
667        ret = -EIO;
668        goto error_open;
669    }
670    ALOGV("%s: exit", __func__);
671    return ret;
672
673error_open:
674    stop_input_stream(in);
675
676error_config:
677    adev->active_input = NULL;
678    ALOGD("%s: exit: status(%d)", __func__, ret);
679
680    return ret;
681}
682
683/* must be called with out->lock locked */
684static int send_offload_cmd_l(struct stream_out* out, int command)
685{
686    struct offload_cmd *cmd = (struct offload_cmd *)calloc(1, sizeof(struct offload_cmd));
687
688    ALOGVV("%s %d", __func__, command);
689
690    cmd->cmd = command;
691    list_add_tail(&out->offload_cmd_list, &cmd->node);
692    pthread_cond_signal(&out->offload_cond);
693    return 0;
694}
695
696/* must be called iwth out->lock locked */
697static void stop_compressed_output_l(struct stream_out *out)
698{
699    out->offload_state = OFFLOAD_STATE_IDLE;
700    out->playback_started = 0;
701    out->send_new_metadata = 1;
702    if (out->compr != NULL) {
703        compress_stop(out->compr);
704        while (out->offload_thread_blocked) {
705            pthread_cond_wait(&out->cond, &out->lock);
706        }
707    }
708}
709
710static void *offload_thread_loop(void *context)
711{
712    struct stream_out *out = (struct stream_out *) context;
713    struct listnode *item;
714
715    out->offload_state = OFFLOAD_STATE_IDLE;
716    out->playback_started = 0;
717
718    setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
719    set_sched_policy(0, SP_FOREGROUND);
720    prctl(PR_SET_NAME, (unsigned long)"Offload Callback", 0, 0, 0);
721
722    ALOGV("%s", __func__);
723    pthread_mutex_lock(&out->lock);
724    for (;;) {
725        struct offload_cmd *cmd = NULL;
726        stream_callback_event_t event;
727        bool send_callback = false;
728
729        ALOGVV("%s offload_cmd_list %d out->offload_state %d",
730              __func__, list_empty(&out->offload_cmd_list),
731              out->offload_state);
732        if (list_empty(&out->offload_cmd_list)) {
733            ALOGV("%s SLEEPING", __func__);
734            pthread_cond_wait(&out->offload_cond, &out->lock);
735            ALOGV("%s RUNNING", __func__);
736            continue;
737        }
738
739        item = list_head(&out->offload_cmd_list);
740        cmd = node_to_item(item, struct offload_cmd, node);
741        list_remove(item);
742
743        ALOGVV("%s STATE %d CMD %d out->compr %p",
744               __func__, out->offload_state, cmd->cmd, out->compr);
745
746        if (cmd->cmd == OFFLOAD_CMD_EXIT) {
747            free(cmd);
748            break;
749        }
750
751        if (out->compr == NULL) {
752            ALOGE("%s: Compress handle is NULL", __func__);
753            pthread_cond_signal(&out->cond);
754            continue;
755        }
756        out->offload_thread_blocked = true;
757        pthread_mutex_unlock(&out->lock);
758        send_callback = false;
759        switch(cmd->cmd) {
760        case OFFLOAD_CMD_WAIT_FOR_BUFFER:
761            compress_wait(out->compr, -1);
762            send_callback = true;
763            event = STREAM_CBK_EVENT_WRITE_READY;
764            break;
765        case OFFLOAD_CMD_PARTIAL_DRAIN:
766            compress_next_track(out->compr);
767            compress_partial_drain(out->compr);
768            send_callback = true;
769            event = STREAM_CBK_EVENT_DRAIN_READY;
770            break;
771        case OFFLOAD_CMD_DRAIN:
772            compress_drain(out->compr);
773            send_callback = true;
774            event = STREAM_CBK_EVENT_DRAIN_READY;
775            break;
776        default:
777            ALOGE("%s unknown command received: %d", __func__, cmd->cmd);
778            break;
779        }
780        pthread_mutex_lock(&out->lock);
781        out->offload_thread_blocked = false;
782        pthread_cond_signal(&out->cond);
783        if (send_callback) {
784            out->offload_callback(event, NULL, out->offload_cookie);
785        }
786        free(cmd);
787    }
788
789    pthread_cond_signal(&out->cond);
790    while (!list_empty(&out->offload_cmd_list)) {
791        item = list_head(&out->offload_cmd_list);
792        list_remove(item);
793        free(node_to_item(item, struct offload_cmd, node));
794    }
795    pthread_mutex_unlock(&out->lock);
796
797    return NULL;
798}
799
800static int create_offload_callback_thread(struct stream_out *out)
801{
802    pthread_cond_init(&out->offload_cond, (const pthread_condattr_t *) NULL);
803    list_init(&out->offload_cmd_list);
804    pthread_create(&out->offload_thread, (const pthread_attr_t *) NULL,
805                    offload_thread_loop, out);
806    return 0;
807}
808
809static int destroy_offload_callback_thread(struct stream_out *out)
810{
811    pthread_mutex_lock(&out->lock);
812    stop_compressed_output_l(out);
813    send_offload_cmd_l(out, OFFLOAD_CMD_EXIT);
814
815    pthread_mutex_unlock(&out->lock);
816    pthread_join(out->offload_thread, (void **) NULL);
817    pthread_cond_destroy(&out->offload_cond);
818
819    return 0;
820}
821
822static bool allow_hdmi_channel_config(struct audio_device *adev)
823{
824    struct listnode *node;
825    struct audio_usecase *usecase;
826    bool ret = true;
827
828    list_for_each(node, &adev->usecase_list) {
829        usecase = node_to_item(node, struct audio_usecase, list);
830        if (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
831            /*
832             * If voice call is already existing, do not proceed further to avoid
833             * disabling/enabling both RX and TX devices, CSD calls, etc.
834             * Once the voice call done, the HDMI channels can be configured to
835             * max channels of remaining use cases.
836             */
837            if (usecase->id == USECASE_VOICE_CALL) {
838                ALOGD("%s: voice call is active, no change in HDMI channels",
839                      __func__);
840                ret = false;
841                break;
842            } else if (usecase->id == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
843                ALOGD("%s: multi channel playback is active, "
844                      "no change in HDMI channels", __func__);
845                ret = false;
846                break;
847            }
848        }
849    }
850    return ret;
851}
852
853static int check_and_set_hdmi_channels(struct audio_device *adev,
854                                       unsigned int channels)
855{
856    struct listnode *node;
857    struct audio_usecase *usecase;
858
859    /* Check if change in HDMI channel config is allowed */
860    if (!allow_hdmi_channel_config(adev))
861        return 0;
862
863    if (channels == adev->cur_hdmi_channels) {
864        ALOGD("%s: Requested channels are same as current", __func__);
865        return 0;
866    }
867
868    platform_set_hdmi_channels(adev->platform, channels);
869    adev->cur_hdmi_channels = channels;
870
871    /*
872     * Deroute all the playback streams routed to HDMI so that
873     * the back end is deactivated. Note that backend will not
874     * be deactivated if any one stream is connected to it.
875     */
876    list_for_each(node, &adev->usecase_list) {
877        usecase = node_to_item(node, struct audio_usecase, list);
878        if (usecase->type == PCM_PLAYBACK &&
879                usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
880            disable_audio_route(adev, usecase);
881        }
882    }
883
884    /*
885     * Enable all the streams disabled above. Now the HDMI backend
886     * will be activated with new channel configuration
887     */
888    list_for_each(node, &adev->usecase_list) {
889        usecase = node_to_item(node, struct audio_usecase, list);
890        if (usecase->type == PCM_PLAYBACK &&
891                usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
892            enable_audio_route(adev, usecase);
893        }
894    }
895
896    return 0;
897}
898
899static int stop_output_stream(struct stream_out *out)
900{
901    int i, ret = 0;
902    struct audio_usecase *uc_info;
903    struct audio_device *adev = out->dev;
904
905    ALOGV("%s: enter: usecase(%d: %s)", __func__,
906          out->usecase, use_case_table[out->usecase]);
907    uc_info = get_usecase_from_list(adev, out->usecase);
908    if (uc_info == NULL) {
909        ALOGE("%s: Could not find the usecase (%d) in the list",
910              __func__, out->usecase);
911        return -EINVAL;
912    }
913
914    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD &&
915            adev->visualizer_stop_output != NULL)
916        adev->visualizer_stop_output(out->handle);
917
918    /* 1. Get and set stream specific mixer controls */
919    disable_audio_route(adev, uc_info);
920
921    /* 2. Disable the rx device */
922    disable_snd_device(adev, uc_info->out_snd_device);
923
924    list_remove(&uc_info->list);
925    free(uc_info);
926
927    /* Must be called after removing the usecase from list */
928    if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
929        check_and_set_hdmi_channels(adev, DEFAULT_HDMI_OUT_CHANNELS);
930
931    ALOGV("%s: exit: status(%d)", __func__, ret);
932    return ret;
933}
934
935int start_output_stream(struct stream_out *out)
936{
937    int ret = 0;
938    struct audio_usecase *uc_info;
939    struct audio_device *adev = out->dev;
940
941    ALOGV("%s: enter: usecase(%d: %s) devices(%#x)",
942          __func__, out->usecase, use_case_table[out->usecase], out->devices);
943    out->pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
944    if (out->pcm_device_id < 0) {
945        ALOGE("%s: Invalid PCM device id(%d) for the usecase(%d)",
946              __func__, out->pcm_device_id, out->usecase);
947        ret = -EINVAL;
948        goto error_config;
949    }
950
951    uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
952    uc_info->id = out->usecase;
953    uc_info->type = PCM_PLAYBACK;
954    uc_info->stream.out = out;
955    uc_info->devices = out->devices;
956    uc_info->in_snd_device = SND_DEVICE_NONE;
957    uc_info->out_snd_device = SND_DEVICE_NONE;
958
959    /* This must be called before adding this usecase to the list */
960    if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
961        check_and_set_hdmi_channels(adev, out->config.channels);
962
963    list_add_tail(&adev->usecase_list, &uc_info->list);
964
965    select_devices(adev, out->usecase);
966
967    ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
968          __func__, adev->snd_card, out->pcm_device_id, out->config.format);
969    if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
970        out->pcm = pcm_open(adev->snd_card, out->pcm_device_id,
971                               PCM_OUT | PCM_MONOTONIC, &out->config);
972        if (out->pcm && !pcm_is_ready(out->pcm)) {
973            ALOGE("%s: %s", __func__, pcm_get_error(out->pcm));
974            pcm_close(out->pcm);
975            out->pcm = NULL;
976            ret = -EIO;
977            goto error_open;
978        }
979    } else {
980        out->pcm = NULL;
981        out->compr = compress_open(adev->snd_card, out->pcm_device_id,
982                                   COMPRESS_IN, &out->compr_config);
983        if (out->compr && !is_compress_ready(out->compr)) {
984            ALOGE("%s: %s", __func__, compress_get_error(out->compr));
985            compress_close(out->compr);
986            out->compr = NULL;
987            ret = -EIO;
988            goto error_open;
989        }
990        if (out->offload_callback)
991            compress_nonblock(out->compr, out->non_blocking);
992
993        if (adev->visualizer_start_output != NULL)
994            adev->visualizer_start_output(out->handle);
995    }
996    ALOGV("%s: exit", __func__);
997    return 0;
998error_open:
999    stop_output_stream(out);
1000error_config:
1001    return ret;
1002}
1003
1004static int check_input_parameters(uint32_t sample_rate,
1005                                  audio_format_t format,
1006                                  int channel_count)
1007{
1008    if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
1009
1010    if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
1011
1012    switch (sample_rate) {
1013    case 8000:
1014    case 11025:
1015    case 12000:
1016    case 16000:
1017    case 22050:
1018    case 24000:
1019    case 32000:
1020    case 44100:
1021    case 48000:
1022        break;
1023    default:
1024        return -EINVAL;
1025    }
1026
1027    return 0;
1028}
1029
1030static size_t get_input_buffer_size(uint32_t sample_rate,
1031                                    audio_format_t format,
1032                                    int channel_count)
1033{
1034    size_t size = 0;
1035
1036    if (check_input_parameters(sample_rate, format, channel_count) != 0)
1037        return 0;
1038
1039    size = (sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000;
1040    if (sample_rate == LOW_LATENCY_CAPTURE_SAMPLE_RATE)
1041        size = configured_low_latency_capture_period_size;
1042    /* ToDo: should use frame_size computed based on the format and
1043       channel_count here. */
1044    size *= sizeof(short) * channel_count;
1045
1046    /* make sure the size is multiple of 32 bytes
1047     * At 48 kHz mono 16-bit PCM:
1048     *  5.000 ms = 240 frames = 15*16*1*2 = 480, a whole multiple of 32 (15)
1049     *  3.333 ms = 160 frames = 10*16*1*2 = 320, a whole multiple of 32 (10)
1050     */
1051    size += 0x1f;
1052    size &= ~0x1f;
1053
1054    return size;
1055}
1056
1057static uint32_t out_get_sample_rate(const struct audio_stream *stream)
1058{
1059    struct stream_out *out = (struct stream_out *)stream;
1060
1061    return out->sample_rate;
1062}
1063
1064static int out_set_sample_rate(struct audio_stream *stream __unused, uint32_t rate __unused)
1065{
1066    return -ENOSYS;
1067}
1068
1069static size_t out_get_buffer_size(const struct audio_stream *stream)
1070{
1071    struct stream_out *out = (struct stream_out *)stream;
1072
1073    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
1074        return out->compr_config.fragment_size;
1075    }
1076
1077    return out->config.period_size * audio_stream_frame_size(stream);
1078}
1079
1080static uint32_t out_get_channels(const struct audio_stream *stream)
1081{
1082    struct stream_out *out = (struct stream_out *)stream;
1083
1084    return out->channel_mask;
1085}
1086
1087static audio_format_t out_get_format(const struct audio_stream *stream)
1088{
1089    struct stream_out *out = (struct stream_out *)stream;
1090
1091    return out->format;
1092}
1093
1094static int out_set_format(struct audio_stream *stream __unused, audio_format_t format __unused)
1095{
1096    return -ENOSYS;
1097}
1098
1099static int out_standby(struct audio_stream *stream)
1100{
1101    struct stream_out *out = (struct stream_out *)stream;
1102    struct audio_device *adev = out->dev;
1103
1104    ALOGV("%s: enter: usecase(%d: %s)", __func__,
1105          out->usecase, use_case_table[out->usecase]);
1106
1107    pthread_mutex_lock(&out->lock);
1108    if (!out->standby) {
1109        pthread_mutex_lock(&adev->lock);
1110        out->standby = true;
1111        if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
1112            if (out->pcm) {
1113                pcm_close(out->pcm);
1114                out->pcm = NULL;
1115            }
1116        } else {
1117            stop_compressed_output_l(out);
1118            out->gapless_mdata.encoder_delay = 0;
1119            out->gapless_mdata.encoder_padding = 0;
1120            if (out->compr != NULL) {
1121                compress_close(out->compr);
1122                out->compr = NULL;
1123            }
1124        }
1125        stop_output_stream(out);
1126        pthread_mutex_unlock(&adev->lock);
1127    }
1128    pthread_mutex_unlock(&out->lock);
1129    ALOGV("%s: exit", __func__);
1130    return 0;
1131}
1132
1133static int out_dump(const struct audio_stream *stream __unused, int fd __unused)
1134{
1135    return 0;
1136}
1137
1138static int parse_compress_metadata(struct stream_out *out, struct str_parms *parms)
1139{
1140    int ret = 0;
1141    char value[32];
1142    struct compr_gapless_mdata tmp_mdata;
1143
1144    if (!out || !parms) {
1145        return -EINVAL;
1146    }
1147
1148    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES, value, sizeof(value));
1149    if (ret >= 0) {
1150        tmp_mdata.encoder_delay = atoi(value); //whats a good limit check?
1151    } else {
1152        return -EINVAL;
1153    }
1154
1155    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES, value, sizeof(value));
1156    if (ret >= 0) {
1157        tmp_mdata.encoder_padding = atoi(value);
1158    } else {
1159        return -EINVAL;
1160    }
1161
1162    out->gapless_mdata = tmp_mdata;
1163    out->send_new_metadata = 1;
1164    ALOGV("%s new encoder delay %u and padding %u", __func__,
1165          out->gapless_mdata.encoder_delay, out->gapless_mdata.encoder_padding);
1166
1167    return 0;
1168}
1169
1170
1171static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
1172{
1173    struct stream_out *out = (struct stream_out *)stream;
1174    struct audio_device *adev = out->dev;
1175    struct audio_usecase *usecase;
1176    struct listnode *node;
1177    struct str_parms *parms;
1178    char value[32];
1179    int ret, val = 0;
1180    bool select_new_device = false;
1181    int status = 0;
1182
1183    ALOGD("%s: enter: usecase(%d: %s) kvpairs: %s",
1184          __func__, out->usecase, use_case_table[out->usecase], kvpairs);
1185    parms = str_parms_create_str(kvpairs);
1186    ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
1187    if (ret >= 0) {
1188        val = atoi(value);
1189        pthread_mutex_lock(&out->lock);
1190        pthread_mutex_lock(&adev->lock);
1191
1192        /*
1193         * When HDMI cable is unplugged the music playback is paused and
1194         * the policy manager sends routing=0. But the audioflinger
1195         * continues to write data until standby time (3sec).
1196         * As the HDMI core is turned off, the write gets blocked.
1197         * Avoid this by routing audio to speaker until standby.
1198         */
1199        if (out->devices == AUDIO_DEVICE_OUT_AUX_DIGITAL &&
1200                val == AUDIO_DEVICE_NONE) {
1201            val = AUDIO_DEVICE_OUT_SPEAKER;
1202        }
1203
1204        /*
1205         * select_devices() call below switches all the usecases on the same
1206         * backend to the new device. Refer to check_usecases_codec_backend() in
1207         * the select_devices(). But how do we undo this?
1208         *
1209         * For example, music playback is active on headset (deep-buffer usecase)
1210         * and if we go to ringtones and select a ringtone, low-latency usecase
1211         * will be started on headset+speaker. As we can't enable headset+speaker
1212         * and headset devices at the same time, select_devices() switches the music
1213         * playback to headset+speaker while starting low-lateny usecase for ringtone.
1214         * So when the ringtone playback is completed, how do we undo the same?
1215         *
1216         * We are relying on the out_set_parameters() call on deep-buffer output,
1217         * once the ringtone playback is ended.
1218         * NOTE: We should not check if the current devices are same as new devices.
1219         *       Because select_devices() must be called to switch back the music
1220         *       playback to headset.
1221         */
1222        if (val != 0) {
1223            out->devices = val;
1224
1225            if (!out->standby)
1226                select_devices(adev, out->usecase);
1227
1228            if ((adev->mode == AUDIO_MODE_IN_CALL) &&
1229                    !voice_is_in_call(adev) &&
1230                    (out == adev->primary_output)) {
1231                ret = voice_start_call(adev);
1232            } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
1233                            voice_is_in_call(adev) &&
1234                            (out == adev->primary_output)) {
1235                voice_update_devices_for_all_voice_usecases(adev);
1236            }
1237        }
1238
1239        if ((adev->mode == AUDIO_MODE_NORMAL) &&
1240                voice_is_in_call(adev) &&
1241                (out == adev->primary_output)) {
1242            ret = voice_stop_call(adev);
1243        }
1244
1245        pthread_mutex_unlock(&adev->lock);
1246        pthread_mutex_unlock(&out->lock);
1247    }
1248
1249    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
1250        parse_compress_metadata(out, parms);
1251    }
1252
1253    str_parms_destroy(parms);
1254    ALOGV("%s: exit: code(%d)", __func__, status);
1255    return status;
1256}
1257
1258static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
1259{
1260    struct stream_out *out = (struct stream_out *)stream;
1261    struct str_parms *query = str_parms_create_str(keys);
1262    char *str;
1263    char value[256];
1264    struct str_parms *reply = str_parms_create();
1265    size_t i, j;
1266    int ret;
1267    bool first = true;
1268    ALOGV("%s: enter: keys - %s", __func__, keys);
1269    ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
1270    if (ret >= 0) {
1271        value[0] = '\0';
1272        i = 0;
1273        while (out->supported_channel_masks[i] != 0) {
1274            for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
1275                if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
1276                    if (!first) {
1277                        strcat(value, "|");
1278                    }
1279                    strcat(value, out_channels_name_to_enum_table[j].name);
1280                    first = false;
1281                    break;
1282                }
1283            }
1284            i++;
1285        }
1286        str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
1287        str = str_parms_to_str(reply);
1288    } else {
1289        str = strdup(keys);
1290    }
1291    str_parms_destroy(query);
1292    str_parms_destroy(reply);
1293    ALOGV("%s: exit: returns - %s", __func__, str);
1294    return str;
1295}
1296
1297static uint32_t out_get_latency(const struct audio_stream_out *stream)
1298{
1299    struct stream_out *out = (struct stream_out *)stream;
1300
1301    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
1302        return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
1303
1304    return (out->config.period_count * out->config.period_size * 1000) /
1305           (out->config.rate);
1306}
1307
1308static int out_set_volume(struct audio_stream_out *stream, float left,
1309                          float right)
1310{
1311    struct stream_out *out = (struct stream_out *)stream;
1312    int volume[2];
1313
1314    if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
1315        /* only take left channel into account: the API is for stereo anyway */
1316        out->muted = (left == 0.0f);
1317        return 0;
1318    } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
1319        const char *mixer_ctl_name = "Compress Playback Volume";
1320        struct audio_device *adev = out->dev;
1321        struct mixer_ctl *ctl;
1322
1323        ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1324        if (!ctl) {
1325            ALOGE("%s: Could not get ctl for mixer cmd - %s",
1326                  __func__, mixer_ctl_name);
1327            return -EINVAL;
1328        }
1329        volume[0] = (int)(left * COMPRESS_PLAYBACK_VOLUME_MAX);
1330        volume[1] = (int)(right * COMPRESS_PLAYBACK_VOLUME_MAX);
1331        mixer_ctl_set_array(ctl, volume, sizeof(volume)/sizeof(volume[0]));
1332        return 0;
1333    }
1334
1335    return -ENOSYS;
1336}
1337
1338static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
1339                         size_t bytes)
1340{
1341    struct stream_out *out = (struct stream_out *)stream;
1342    struct audio_device *adev = out->dev;
1343    ssize_t ret = 0;
1344
1345    pthread_mutex_lock(&out->lock);
1346    if (out->standby) {
1347        out->standby = false;
1348        pthread_mutex_lock(&adev->lock);
1349        ret = start_output_stream(out);
1350        pthread_mutex_unlock(&adev->lock);
1351        /* ToDo: If use case is compress offload should return 0 */
1352        if (ret != 0) {
1353            out->standby = true;
1354            goto exit;
1355        }
1356    }
1357
1358    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
1359        ALOGVV("%s: writing buffer (%d bytes) to compress device", __func__, bytes);
1360        if (out->send_new_metadata) {
1361            ALOGVV("send new gapless metadata");
1362            compress_set_gapless_metadata(out->compr, &out->gapless_mdata);
1363            out->send_new_metadata = 0;
1364        }
1365
1366        ret = compress_write(out->compr, buffer, bytes);
1367        ALOGVV("%s: writing buffer (%d bytes) to compress device returned %d", __func__, bytes, ret);
1368        if (ret >= 0 && ret < (ssize_t)bytes) {
1369            send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
1370        }
1371        if (!out->playback_started) {
1372            compress_start(out->compr);
1373            out->playback_started = 1;
1374            out->offload_state = OFFLOAD_STATE_PLAYING;
1375        }
1376        pthread_mutex_unlock(&out->lock);
1377        return ret;
1378    } else {
1379        if (out->pcm) {
1380            if (out->muted)
1381                memset((void *)buffer, 0, bytes);
1382            ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
1383            ret = pcm_write(out->pcm, (void *)buffer, bytes);
1384            if (ret == 0)
1385                out->written += bytes / (out->config.channels * sizeof(short));
1386        }
1387    }
1388
1389exit:
1390    pthread_mutex_unlock(&out->lock);
1391
1392    if (ret != 0) {
1393        if (out->pcm)
1394            ALOGE("%s: error %d - %s", __func__, ret, pcm_get_error(out->pcm));
1395        out_standby(&out->stream.common);
1396        usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
1397               out_get_sample_rate(&out->stream.common));
1398    }
1399    return bytes;
1400}
1401
1402static int out_get_render_position(const struct audio_stream_out *stream,
1403                                   uint32_t *dsp_frames)
1404{
1405    struct stream_out *out = (struct stream_out *)stream;
1406    *dsp_frames = 0;
1407    if ((out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) && (dsp_frames != NULL)) {
1408        pthread_mutex_lock(&out->lock);
1409        if (out->compr != NULL) {
1410            compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
1411                    &out->sample_rate);
1412            ALOGVV("%s rendered frames %d sample_rate %d",
1413                   __func__, *dsp_frames, out->sample_rate);
1414        }
1415        pthread_mutex_unlock(&out->lock);
1416        return 0;
1417    } else
1418        return -EINVAL;
1419}
1420
1421static int out_add_audio_effect(const struct audio_stream *stream __unused,
1422                                effect_handle_t effect __unused)
1423{
1424    return 0;
1425}
1426
1427static int out_remove_audio_effect(const struct audio_stream *stream __unused,
1428                                   effect_handle_t effect __unused)
1429{
1430    return 0;
1431}
1432
1433static int out_get_next_write_timestamp(const struct audio_stream_out *stream __unused,
1434                                        int64_t *timestamp __unused)
1435{
1436    return -EINVAL;
1437}
1438
1439static int out_get_presentation_position(const struct audio_stream_out *stream,
1440                                   uint64_t *frames, struct timespec *timestamp)
1441{
1442    struct stream_out *out = (struct stream_out *)stream;
1443    int ret = -1;
1444    unsigned long dsp_frames;
1445
1446    pthread_mutex_lock(&out->lock);
1447
1448    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
1449        if (out->compr != NULL) {
1450            compress_get_tstamp(out->compr, &dsp_frames,
1451                    &out->sample_rate);
1452            ALOGVV("%s rendered frames %ld sample_rate %d",
1453                   __func__, dsp_frames, out->sample_rate);
1454            *frames = dsp_frames;
1455            ret = 0;
1456            /* this is the best we can do */
1457            clock_gettime(CLOCK_MONOTONIC, timestamp);
1458        }
1459    } else {
1460        if (out->pcm) {
1461            size_t avail;
1462            if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
1463                size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
1464                int64_t signed_frames = out->written - kernel_buffer_size + avail;
1465                // This adjustment accounts for buffering after app processor.
1466                // It is based on estimated DSP latency per use case, rather than exact.
1467                signed_frames -=
1468                    (platform_render_latency(out->usecase) * out->sample_rate / 1000000LL);
1469
1470                // It would be unusual for this value to be negative, but check just in case ...
1471                if (signed_frames >= 0) {
1472                    *frames = signed_frames;
1473                    ret = 0;
1474                }
1475            }
1476        }
1477    }
1478
1479    pthread_mutex_unlock(&out->lock);
1480
1481    return ret;
1482}
1483
1484static int out_set_callback(struct audio_stream_out *stream,
1485            stream_callback_t callback, void *cookie)
1486{
1487    struct stream_out *out = (struct stream_out *)stream;
1488
1489    ALOGV("%s", __func__);
1490    pthread_mutex_lock(&out->lock);
1491    out->offload_callback = callback;
1492    out->offload_cookie = cookie;
1493    pthread_mutex_unlock(&out->lock);
1494    return 0;
1495}
1496
1497static int out_pause(struct audio_stream_out* stream)
1498{
1499    struct stream_out *out = (struct stream_out *)stream;
1500    int status = -ENOSYS;
1501    ALOGV("%s", __func__);
1502    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
1503        pthread_mutex_lock(&out->lock);
1504        if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PLAYING) {
1505            status = compress_pause(out->compr);
1506            out->offload_state = OFFLOAD_STATE_PAUSED;
1507        }
1508        pthread_mutex_unlock(&out->lock);
1509    }
1510    return status;
1511}
1512
1513static int out_resume(struct audio_stream_out* stream)
1514{
1515    struct stream_out *out = (struct stream_out *)stream;
1516    int status = -ENOSYS;
1517    ALOGV("%s", __func__);
1518    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
1519        status = 0;
1520        pthread_mutex_lock(&out->lock);
1521        if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PAUSED) {
1522            status = compress_resume(out->compr);
1523            out->offload_state = OFFLOAD_STATE_PLAYING;
1524        }
1525        pthread_mutex_unlock(&out->lock);
1526    }
1527    return status;
1528}
1529
1530static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
1531{
1532    struct stream_out *out = (struct stream_out *)stream;
1533    int status = -ENOSYS;
1534    ALOGV("%s", __func__);
1535    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
1536        pthread_mutex_lock(&out->lock);
1537        if (type == AUDIO_DRAIN_EARLY_NOTIFY)
1538            status = send_offload_cmd_l(out, OFFLOAD_CMD_PARTIAL_DRAIN);
1539        else
1540            status = send_offload_cmd_l(out, OFFLOAD_CMD_DRAIN);
1541        pthread_mutex_unlock(&out->lock);
1542    }
1543    return status;
1544}
1545
1546static int out_flush(struct audio_stream_out* stream)
1547{
1548    struct stream_out *out = (struct stream_out *)stream;
1549    ALOGV("%s", __func__);
1550    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
1551        pthread_mutex_lock(&out->lock);
1552        stop_compressed_output_l(out);
1553        pthread_mutex_unlock(&out->lock);
1554        return 0;
1555    }
1556    return -ENOSYS;
1557}
1558
1559/** audio_stream_in implementation **/
1560static uint32_t in_get_sample_rate(const struct audio_stream *stream)
1561{
1562    struct stream_in *in = (struct stream_in *)stream;
1563
1564    return in->config.rate;
1565}
1566
1567static int in_set_sample_rate(struct audio_stream *stream __unused, uint32_t rate __unused)
1568{
1569    return -ENOSYS;
1570}
1571
1572static size_t in_get_buffer_size(const struct audio_stream *stream)
1573{
1574    struct stream_in *in = (struct stream_in *)stream;
1575
1576    return in->config.period_size * audio_stream_frame_size(stream);
1577}
1578
1579static uint32_t in_get_channels(const struct audio_stream *stream)
1580{
1581    struct stream_in *in = (struct stream_in *)stream;
1582
1583    return in->channel_mask;
1584}
1585
1586static audio_format_t in_get_format(const struct audio_stream *stream __unused)
1587{
1588    return AUDIO_FORMAT_PCM_16_BIT;
1589}
1590
1591static int in_set_format(struct audio_stream *stream __unused, audio_format_t format __unused)
1592{
1593    return -ENOSYS;
1594}
1595
1596static int in_standby(struct audio_stream *stream)
1597{
1598    struct stream_in *in = (struct stream_in *)stream;
1599    struct audio_device *adev = in->dev;
1600    int status = 0;
1601    ALOGV("%s: enter", __func__);
1602    pthread_mutex_lock(&in->lock);
1603    if (!in->standby) {
1604        pthread_mutex_lock(&adev->lock);
1605        in->standby = true;
1606        if (in->pcm) {
1607            pcm_close(in->pcm);
1608            in->pcm = NULL;
1609        }
1610        status = stop_input_stream(in);
1611        pthread_mutex_unlock(&adev->lock);
1612    }
1613    pthread_mutex_unlock(&in->lock);
1614    ALOGV("%s: exit:  status(%d)", __func__, status);
1615    return status;
1616}
1617
1618static int in_dump(const struct audio_stream *stream __unused, int fd __unused)
1619{
1620    return 0;
1621}
1622
1623static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
1624{
1625    struct stream_in *in = (struct stream_in *)stream;
1626    struct audio_device *adev = in->dev;
1627    struct str_parms *parms;
1628    char *str;
1629    char value[32];
1630    int ret, val = 0;
1631    int status = 0;
1632
1633    ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
1634    parms = str_parms_create_str(kvpairs);
1635
1636    ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
1637
1638    pthread_mutex_lock(&in->lock);
1639    pthread_mutex_lock(&adev->lock);
1640    if (ret >= 0) {
1641        val = atoi(value);
1642        /* no audio source uses val == 0 */
1643        if ((in->source != val) && (val != 0)) {
1644            in->source = val;
1645        }
1646    }
1647
1648    ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
1649
1650    if (ret >= 0) {
1651        val = atoi(value);
1652        if ((in->device != val) && (val != 0)) {
1653            in->device = val;
1654            /* If recording is in progress, change the tx device to new device */
1655            if (!in->standby)
1656                status = select_devices(adev, in->usecase);
1657        }
1658    }
1659
1660    pthread_mutex_unlock(&adev->lock);
1661    pthread_mutex_unlock(&in->lock);
1662
1663    str_parms_destroy(parms);
1664    ALOGV("%s: exit: status(%d)", __func__, status);
1665    return status;
1666}
1667
1668static char* in_get_parameters(const struct audio_stream *stream __unused,
1669                               const char *keys __unused)
1670{
1671    return strdup("");
1672}
1673
1674static int in_set_gain(struct audio_stream_in *stream __unused, float gain __unused)
1675{
1676    return 0;
1677}
1678
1679static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
1680                       size_t bytes)
1681{
1682    struct stream_in *in = (struct stream_in *)stream;
1683    struct audio_device *adev = in->dev;
1684    int i, ret = -1;
1685
1686    pthread_mutex_lock(&in->lock);
1687    if (in->standby) {
1688        pthread_mutex_lock(&adev->lock);
1689        ret = start_input_stream(in);
1690        pthread_mutex_unlock(&adev->lock);
1691        if (ret != 0) {
1692            goto exit;
1693        }
1694        in->standby = 0;
1695    }
1696
1697    if (in->pcm) {
1698        ret = pcm_read(in->pcm, buffer, bytes);
1699    }
1700
1701    /*
1702     * Instead of writing zeroes here, we could trust the hardware
1703     * to always provide zeroes when muted.
1704     */
1705    if (ret == 0 && voice_get_mic_mute(adev) && !voice_is_in_call(adev))
1706        memset(buffer, 0, bytes);
1707
1708exit:
1709    pthread_mutex_unlock(&in->lock);
1710
1711    if (ret != 0) {
1712        in_standby(&in->stream.common);
1713        ALOGV("%s: read failed - sleeping for buffer duration", __func__);
1714        usleep(bytes * 1000000 / audio_stream_frame_size(&in->stream.common) /
1715               in_get_sample_rate(&in->stream.common));
1716    }
1717    return bytes;
1718}
1719
1720static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream __unused)
1721{
1722    return 0;
1723}
1724
1725static int add_remove_audio_effect(const struct audio_stream *stream,
1726                                   effect_handle_t effect,
1727                                   bool enable)
1728{
1729    struct stream_in *in = (struct stream_in *)stream;
1730    int status = 0;
1731    effect_descriptor_t desc;
1732
1733    status = (*effect)->get_descriptor(effect, &desc);
1734    if (status != 0)
1735        return status;
1736
1737    pthread_mutex_lock(&in->lock);
1738    pthread_mutex_lock(&in->dev->lock);
1739    if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
1740            in->enable_aec != enable &&
1741            (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
1742        in->enable_aec = enable;
1743        if (!in->standby)
1744            select_devices(in->dev, in->usecase);
1745    }
1746    pthread_mutex_unlock(&in->dev->lock);
1747    pthread_mutex_unlock(&in->lock);
1748
1749    return 0;
1750}
1751
1752static int in_add_audio_effect(const struct audio_stream *stream,
1753                               effect_handle_t effect)
1754{
1755    ALOGV("%s: effect %p", __func__, effect);
1756    return add_remove_audio_effect(stream, effect, true);
1757}
1758
1759static int in_remove_audio_effect(const struct audio_stream *stream,
1760                                  effect_handle_t effect)
1761{
1762    ALOGV("%s: effect %p", __func__, effect);
1763    return add_remove_audio_effect(stream, effect, false);
1764}
1765
1766static int adev_open_output_stream(struct audio_hw_device *dev,
1767                                   audio_io_handle_t handle,
1768                                   audio_devices_t devices,
1769                                   audio_output_flags_t flags,
1770                                   struct audio_config *config,
1771                                   struct audio_stream_out **stream_out)
1772{
1773    struct audio_device *adev = (struct audio_device *)dev;
1774    struct stream_out *out;
1775    int i, ret;
1776
1777    ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
1778          __func__, config->sample_rate, config->channel_mask, devices, flags);
1779    *stream_out = NULL;
1780    out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
1781
1782    if (devices == AUDIO_DEVICE_NONE)
1783        devices = AUDIO_DEVICE_OUT_SPEAKER;
1784
1785    out->flags = flags;
1786    out->devices = devices;
1787    out->dev = adev;
1788    out->format = config->format;
1789    out->sample_rate = config->sample_rate;
1790    out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1791    out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
1792    out->handle = handle;
1793
1794    /* Init use case and pcm_config */
1795    if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT &&
1796            !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
1797        out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1798        pthread_mutex_lock(&adev->lock);
1799        ret = read_hdmi_channel_masks(out);
1800        pthread_mutex_unlock(&adev->lock);
1801        if (ret != 0)
1802            goto error_open;
1803
1804        if (config->sample_rate == 0)
1805            config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
1806        if (config->channel_mask == 0)
1807            config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
1808
1809        out->channel_mask = config->channel_mask;
1810        out->sample_rate = config->sample_rate;
1811        out->usecase = USECASE_AUDIO_PLAYBACK_MULTI_CH;
1812        out->config = pcm_config_hdmi_multi;
1813        out->config.rate = config->sample_rate;
1814        out->config.channels = popcount(out->channel_mask);
1815        out->config.period_size = HDMI_MULTI_PERIOD_BYTES / (out->config.channels * 2);
1816    } else if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
1817        if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
1818            config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
1819            ALOGE("%s: Unsupported Offload information", __func__);
1820            ret = -EINVAL;
1821            goto error_open;
1822        }
1823        if (!is_supported_format(config->offload_info.format)) {
1824            ALOGE("%s: Unsupported audio format", __func__);
1825            ret = -EINVAL;
1826            goto error_open;
1827        }
1828
1829        out->compr_config.codec = (struct snd_codec *)
1830                                    calloc(1, sizeof(struct snd_codec));
1831
1832        out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
1833        if (config->offload_info.channel_mask)
1834            out->channel_mask = config->offload_info.channel_mask;
1835        else if (config->channel_mask)
1836            out->channel_mask = config->channel_mask;
1837        out->format = config->offload_info.format;
1838        out->sample_rate = config->offload_info.sample_rate;
1839
1840        out->stream.set_callback = out_set_callback;
1841        out->stream.pause = out_pause;
1842        out->stream.resume = out_resume;
1843        out->stream.drain = out_drain;
1844        out->stream.flush = out_flush;
1845
1846        out->compr_config.codec->id =
1847                get_snd_codec_id(config->offload_info.format);
1848        out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
1849        out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
1850        out->compr_config.codec->sample_rate =
1851                    compress_get_alsa_rate(config->offload_info.sample_rate);
1852        out->compr_config.codec->bit_rate =
1853                    config->offload_info.bit_rate;
1854        out->compr_config.codec->ch_in =
1855                    popcount(config->channel_mask);
1856        out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
1857
1858        if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
1859            out->non_blocking = 1;
1860
1861        out->send_new_metadata = 1;
1862        create_offload_callback_thread(out);
1863        ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
1864                __func__, config->offload_info.version,
1865                config->offload_info.bit_rate);
1866    } else {
1867        if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
1868            out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
1869            out->config = pcm_config_deep_buffer;
1870        } else {
1871            out->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY;
1872            out->config = pcm_config_low_latency;
1873        }
1874        if (config->format != audio_format_from_pcm_format(out->config.format)) {
1875            if (k_enable_extended_precision
1876                    && pcm_params_format_test(adev->use_case_table[out->usecase],
1877                            pcm_format_from_audio_format(config->format))) {
1878                out->config.format = pcm_format_from_audio_format(config->format);
1879                /* out->format already set to config->format */
1880            } else {
1881                /* deny the externally proposed config format
1882                 * and use the one specified in audio_hw layer configuration.
1883                 * Note: out->format is returned by out->stream.common.get_format()
1884                 * and is used to set config->format in the code several lines below.
1885                 */
1886                out->format = audio_format_from_pcm_format(out->config.format);
1887            }
1888        }
1889        out->sample_rate = out->config.rate;
1890    }
1891    ALOGV("%s: Usecase(%s) config->format %#x  out->config.format %#x\n",
1892            __func__, use_case_table[out->usecase], config->format, out->config.format);
1893
1894    if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
1895        if(adev->primary_output == NULL)
1896            adev->primary_output = out;
1897        else {
1898            ALOGE("%s: Primary output is already opened", __func__);
1899            ret = -EEXIST;
1900            goto error_open;
1901        }
1902    }
1903
1904    /* Check if this usecase is already existing */
1905    pthread_mutex_lock(&adev->lock);
1906    if (get_usecase_from_list(adev, out->usecase) != NULL) {
1907        ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
1908        pthread_mutex_unlock(&adev->lock);
1909        ret = -EEXIST;
1910        goto error_open;
1911    }
1912    pthread_mutex_unlock(&adev->lock);
1913
1914    out->stream.common.get_sample_rate = out_get_sample_rate;
1915    out->stream.common.set_sample_rate = out_set_sample_rate;
1916    out->stream.common.get_buffer_size = out_get_buffer_size;
1917    out->stream.common.get_channels = out_get_channels;
1918    out->stream.common.get_format = out_get_format;
1919    out->stream.common.set_format = out_set_format;
1920    out->stream.common.standby = out_standby;
1921    out->stream.common.dump = out_dump;
1922    out->stream.common.set_parameters = out_set_parameters;
1923    out->stream.common.get_parameters = out_get_parameters;
1924    out->stream.common.add_audio_effect = out_add_audio_effect;
1925    out->stream.common.remove_audio_effect = out_remove_audio_effect;
1926    out->stream.get_latency = out_get_latency;
1927    out->stream.set_volume = out_set_volume;
1928    out->stream.write = out_write;
1929    out->stream.get_render_position = out_get_render_position;
1930    out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
1931    out->stream.get_presentation_position = out_get_presentation_position;
1932
1933    out->standby = 1;
1934    /* out->muted = false; by calloc() */
1935    /* out->written = 0; by calloc() */
1936
1937    pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
1938    pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
1939
1940    config->format = out->stream.common.get_format(&out->stream.common);
1941    config->channel_mask = out->stream.common.get_channels(&out->stream.common);
1942    config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
1943
1944    *stream_out = &out->stream;
1945    ALOGV("%s: exit", __func__);
1946    return 0;
1947
1948error_open:
1949    free(out);
1950    *stream_out = NULL;
1951    ALOGD("%s: exit: ret %d", __func__, ret);
1952    return ret;
1953}
1954
1955static void adev_close_output_stream(struct audio_hw_device *dev __unused,
1956                                     struct audio_stream_out *stream)
1957{
1958    struct stream_out *out = (struct stream_out *)stream;
1959    struct audio_device *adev = out->dev;
1960
1961    ALOGV("%s: enter", __func__);
1962    out_standby(&stream->common);
1963    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
1964        destroy_offload_callback_thread(out);
1965
1966        if (out->compr_config.codec != NULL)
1967            free(out->compr_config.codec);
1968    }
1969    pthread_cond_destroy(&out->cond);
1970    pthread_mutex_destroy(&out->lock);
1971    free(stream);
1972    ALOGV("%s: exit", __func__);
1973}
1974
1975static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
1976{
1977    struct audio_device *adev = (struct audio_device *)dev;
1978    struct str_parms *parms;
1979    char *str;
1980    char value[32];
1981    int val;
1982    int ret;
1983    int status = 0;
1984
1985    ALOGD("%s: enter: %s", __func__, kvpairs);
1986
1987    pthread_mutex_lock(&adev->lock);
1988
1989    parms = str_parms_create_str(kvpairs);
1990    status = voice_set_parameters(adev, parms);
1991    if (status != 0) {
1992        goto done;
1993    }
1994
1995    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
1996    if (ret >= 0) {
1997        /* When set to false, HAL should disable EC and NS
1998         * But it is currently not supported.
1999         */
2000        if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
2001            adev->bluetooth_nrec = true;
2002        else
2003            adev->bluetooth_nrec = false;
2004    }
2005
2006    ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
2007    if (ret >= 0) {
2008        if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
2009            adev->screen_off = false;
2010        else
2011            adev->screen_off = true;
2012    }
2013
2014    ret = str_parms_get_int(parms, "rotation", &val);
2015    if (ret >= 0) {
2016        bool reverse_speakers = false;
2017        switch(val) {
2018        // FIXME: note that the code below assumes that the speakers are in the correct placement
2019        //   relative to the user when the device is rotated 90deg from its default rotation. This
2020        //   assumption is device-specific, not platform-specific like this code.
2021        case 270:
2022            reverse_speakers = true;
2023            break;
2024        case 0:
2025        case 90:
2026        case 180:
2027            break;
2028        default:
2029            ALOGE("%s: unexpected rotation of %d", __func__, val);
2030            status = -EINVAL;
2031        }
2032        if (status == 0) {
2033            if (adev->speaker_lr_swap != reverse_speakers) {
2034                adev->speaker_lr_swap = reverse_speakers;
2035                // only update the selected device if there is active pcm playback
2036                struct audio_usecase *usecase;
2037                struct listnode *node;
2038                list_for_each(node, &adev->usecase_list) {
2039                    usecase = node_to_item(node, struct audio_usecase, list);
2040                    if (usecase->type == PCM_PLAYBACK) {
2041                        select_devices(adev, usecase->id);
2042                        break;
2043                    }
2044                }
2045            }
2046        }
2047    }
2048
2049    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_SCO_WB, value, sizeof(value));
2050    if (ret >= 0) {
2051        adev->bt_wb_speech_enabled = !strcmp(value, AUDIO_PARAMETER_VALUE_ON);
2052    }
2053
2054    audio_extn_hfp_set_parameters(adev, parms);
2055done:
2056    str_parms_destroy(parms);
2057    pthread_mutex_unlock(&adev->lock);
2058    ALOGV("%s: exit with code(%d)", __func__, status);
2059    return status;
2060}
2061
2062static char* adev_get_parameters(const struct audio_hw_device *dev,
2063                                 const char *keys)
2064{
2065    struct audio_device *adev = (struct audio_device *)dev;
2066    struct str_parms *reply = str_parms_create();
2067    struct str_parms *query = str_parms_create_str(keys);
2068    char *str;
2069
2070    pthread_mutex_lock(&adev->lock);
2071
2072    voice_get_parameters(adev, query, reply);
2073    str = str_parms_to_str(reply);
2074    str_parms_destroy(query);
2075    str_parms_destroy(reply);
2076
2077    pthread_mutex_unlock(&adev->lock);
2078    ALOGV("%s: exit: returns - %s", __func__, str);
2079    return str;
2080}
2081
2082static int adev_init_check(const struct audio_hw_device *dev __unused)
2083{
2084    return 0;
2085}
2086
2087static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
2088{
2089    int ret;
2090    struct audio_device *adev = (struct audio_device *)dev;
2091
2092    pthread_mutex_lock(&adev->lock);
2093    ret = voice_set_volume(adev, volume);
2094    pthread_mutex_unlock(&adev->lock);
2095
2096    return ret;
2097}
2098
2099static int adev_set_master_volume(struct audio_hw_device *dev __unused, float volume __unused)
2100{
2101    return -ENOSYS;
2102}
2103
2104static int adev_get_master_volume(struct audio_hw_device *dev __unused,
2105                                  float *volume __unused)
2106{
2107    return -ENOSYS;
2108}
2109
2110static int adev_set_master_mute(struct audio_hw_device *dev __unused, bool muted __unused)
2111{
2112    return -ENOSYS;
2113}
2114
2115static int adev_get_master_mute(struct audio_hw_device *dev __unused, bool *muted __unused)
2116{
2117    return -ENOSYS;
2118}
2119
2120static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
2121{
2122    struct audio_device *adev = (struct audio_device *)dev;
2123
2124    pthread_mutex_lock(&adev->lock);
2125    if (adev->mode != mode) {
2126        ALOGD("%s: mode %d\n", __func__, mode);
2127        adev->mode = mode;
2128    }
2129    pthread_mutex_unlock(&adev->lock);
2130    return 0;
2131}
2132
2133static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
2134{
2135    int ret;
2136    struct audio_device *adev = (struct audio_device *)dev;
2137
2138    ALOGD("%s: state %d\n", __func__, state);
2139    pthread_mutex_lock(&adev->lock);
2140    ret = voice_set_mic_mute(adev, state);
2141    pthread_mutex_unlock(&adev->lock);
2142
2143    return ret;
2144}
2145
2146static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
2147{
2148    *state = voice_get_mic_mute((struct audio_device *)dev);
2149    return 0;
2150}
2151
2152static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev __unused,
2153                                         const struct audio_config *config)
2154{
2155    int channel_count = popcount(config->channel_mask);
2156
2157    return get_input_buffer_size(config->sample_rate, config->format, channel_count);
2158}
2159
2160static int adev_open_input_stream(struct audio_hw_device *dev,
2161                                  audio_io_handle_t handle __unused,
2162                                  audio_devices_t devices,
2163                                  struct audio_config *config,
2164                                  struct audio_stream_in **stream_in)
2165{
2166    struct audio_device *adev = (struct audio_device *)dev;
2167    struct stream_in *in;
2168    int ret = 0, buffer_size, frame_size;
2169    int channel_count = popcount(config->channel_mask);
2170
2171    ALOGV("%s: enter", __func__);
2172    *stream_in = NULL;
2173    if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
2174        return -EINVAL;
2175
2176    in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
2177
2178    pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
2179
2180    in->stream.common.get_sample_rate = in_get_sample_rate;
2181    in->stream.common.set_sample_rate = in_set_sample_rate;
2182    in->stream.common.get_buffer_size = in_get_buffer_size;
2183    in->stream.common.get_channels = in_get_channels;
2184    in->stream.common.get_format = in_get_format;
2185    in->stream.common.set_format = in_set_format;
2186    in->stream.common.standby = in_standby;
2187    in->stream.common.dump = in_dump;
2188    in->stream.common.set_parameters = in_set_parameters;
2189    in->stream.common.get_parameters = in_get_parameters;
2190    in->stream.common.add_audio_effect = in_add_audio_effect;
2191    in->stream.common.remove_audio_effect = in_remove_audio_effect;
2192    in->stream.set_gain = in_set_gain;
2193    in->stream.read = in_read;
2194    in->stream.get_input_frames_lost = in_get_input_frames_lost;
2195
2196    in->device = devices;
2197    in->source = AUDIO_SOURCE_DEFAULT;
2198    in->dev = adev;
2199    in->standby = 1;
2200    in->channel_mask = config->channel_mask;
2201
2202    /* Update config params with the requested sample rate and channels */
2203    in->usecase = USECASE_AUDIO_RECORD;
2204#if LOW_LATENCY_CAPTURE_USE_CASE
2205    if (config->sample_rate == LOW_LATENCY_CAPTURE_SAMPLE_RATE)
2206        in->usecase = USECASE_AUDIO_RECORD_LOW_LATENCY;
2207#endif
2208    in->config = pcm_config_audio_capture;
2209    in->config.channels = channel_count;
2210    in->config.rate = config->sample_rate;
2211
2212    frame_size = audio_stream_frame_size((struct audio_stream *)in);
2213    buffer_size = get_input_buffer_size(config->sample_rate,
2214                                        config->format,
2215                                        channel_count);
2216    in->config.period_size = buffer_size / frame_size;
2217
2218    *stream_in = &in->stream;
2219    ALOGV("%s: exit", __func__);
2220    return 0;
2221
2222err_open:
2223    free(in);
2224    *stream_in = NULL;
2225    return ret;
2226}
2227
2228static void adev_close_input_stream(struct audio_hw_device *dev __unused,
2229                                    struct audio_stream_in *stream)
2230{
2231    ALOGV("%s", __func__);
2232
2233    in_standby(&stream->common);
2234    free(stream);
2235
2236    return;
2237}
2238
2239static int adev_dump(const audio_hw_device_t *device __unused, int fd __unused)
2240{
2241    return 0;
2242}
2243
2244/* verifies input and output devices and their capabilities.
2245 *
2246 * This verification is required when enabling extended bit-depth or
2247 * sampling rates, as not all qcom products support it.
2248 *
2249 * Suitable for calling only on initialization such as adev_open().
2250 * It fills the audio_device use_case_table[] array.
2251 *
2252 * Has a side-effect that it needs to configure audio routing / devices
2253 * in order to power up the devices and read the device parameters.
2254 * It does not acquire any hw device lock. Should restore the devices
2255 * back to "normal state" upon completion.
2256 */
2257static int adev_verify_devices(struct audio_device *adev)
2258{
2259    /* enumeration is a bit difficult because one really wants to pull
2260     * the use_case, device id, etc from the hidden pcm_device_table[].
2261     * In this case there are the following use cases and device ids.
2262     *
2263     * [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {0, 0},
2264     * [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {15, 15},
2265     * [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {1, 1},
2266     * [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {9, 9},
2267     * [USECASE_AUDIO_RECORD] = {0, 0},
2268     * [USECASE_AUDIO_RECORD_LOW_LATENCY] = {15, 15},
2269     * [USECASE_VOICE_CALL] = {2, 2},
2270     *
2271     * USECASE_AUDIO_PLAYBACK_OFFLOAD, USECASE_AUDIO_PLAYBACK_MULTI_CH omitted.
2272     * USECASE_VOICE_CALL omitted, but possible for either input or output.
2273     */
2274
2275    /* should be the usecases enabled in adev_open_input_stream() */
2276    static const int test_in_usecases[] = {
2277             USECASE_AUDIO_RECORD,
2278             USECASE_AUDIO_RECORD_LOW_LATENCY, /* does not appear to be used */
2279    };
2280    /* should be the usecases enabled in adev_open_output_stream()*/
2281    static const int test_out_usecases[] = {
2282            USECASE_AUDIO_PLAYBACK_DEEP_BUFFER,
2283            USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
2284    };
2285    static const usecase_type_t usecase_type_by_dir[] = {
2286            PCM_PLAYBACK,
2287            PCM_CAPTURE,
2288    };
2289    static const unsigned flags_by_dir[] = {
2290            PCM_OUT,
2291            PCM_IN,
2292    };
2293
2294    size_t i;
2295    unsigned dir;
2296    const unsigned card_id = adev->snd_card;
2297    char info[512]; /* for possible debug info */
2298
2299    for (dir = 0; dir < 2; ++dir) {
2300        const usecase_type_t usecase_type = usecase_type_by_dir[dir];
2301        const unsigned flags_dir = flags_by_dir[dir];
2302        const size_t testsize =
2303                dir ? ARRAY_SIZE(test_in_usecases) : ARRAY_SIZE(test_out_usecases);
2304        const int *testcases =
2305                dir ? test_in_usecases : test_out_usecases;
2306        const audio_devices_t audio_device =
2307                dir ? AUDIO_DEVICE_IN_BUILTIN_MIC : AUDIO_DEVICE_OUT_SPEAKER;
2308
2309        for (i = 0; i < testsize; ++i) {
2310            const audio_usecase_t audio_usecase = testcases[i];
2311            int device_id;
2312            snd_device_t snd_device;
2313            struct pcm_params **pparams;
2314            struct stream_out out;
2315            struct stream_in in;
2316            struct audio_usecase uc_info;
2317            int retval;
2318
2319            pparams = &adev->use_case_table[audio_usecase];
2320            pcm_params_free(*pparams); /* can accept null input */
2321            *pparams = NULL;
2322
2323            /* find the device ID for the use case (signed, for error) */
2324            device_id = platform_get_pcm_device_id(audio_usecase, usecase_type);
2325            if (device_id < 0)
2326                continue;
2327
2328            /* prepare structures for device probing */
2329            memset(&uc_info, 0, sizeof(uc_info));
2330            uc_info.id = audio_usecase;
2331            uc_info.type = usecase_type;
2332            if (dir) {
2333                adev->active_input = &in;
2334                memset(&in, 0, sizeof(in));
2335                in.device = audio_device;
2336                in.source = AUDIO_SOURCE_VOICE_COMMUNICATION;
2337                uc_info.stream.in = &in;
2338            }  else {
2339                adev->active_input = NULL;
2340            }
2341            memset(&out, 0, sizeof(out));
2342            out.devices = audio_device; /* only field needed in select_devices */
2343            uc_info.stream.out = &out;
2344            uc_info.devices = audio_device;
2345            uc_info.in_snd_device = SND_DEVICE_NONE;
2346            uc_info.out_snd_device = SND_DEVICE_NONE;
2347            list_add_tail(&adev->usecase_list, &uc_info.list);
2348
2349            /* select device - similar to start_(in/out)put_stream() */
2350            retval = select_devices(adev, audio_usecase);
2351            if (retval >= 0) {
2352                *pparams = pcm_params_get(card_id, device_id, flags_dir);
2353#if LOG_NDEBUG == 0
2354                if (*pparams) {
2355                    ALOGV("%s: (%s) card %d  device %d", __func__,
2356                            dir ? "input" : "output", card_id, device_id);
2357                    pcm_params_to_string(*pparams, info, ARRAY_SIZE(info));
2358                    ALOGV(info); /* print parameters */
2359                } else {
2360                    ALOGV("%s: cannot locate card %d  device %d", __func__, card_id, device_id);
2361                }
2362#endif
2363            }
2364
2365            /* deselect device - similar to stop_(in/out)put_stream() */
2366            /* 1. Get and set stream specific mixer controls */
2367            retval = disable_audio_route(adev, &uc_info);
2368            /* 2. Disable the rx device */
2369            retval = disable_snd_device(adev,
2370                    dir ? uc_info.in_snd_device : uc_info.out_snd_device);
2371            list_remove(&uc_info.list);
2372        }
2373    }
2374    adev->active_input = NULL; /* restore adev state */
2375    return 0;
2376}
2377
2378static int adev_close(hw_device_t *device)
2379{
2380    size_t i;
2381    struct audio_device *adev = (struct audio_device *)device;
2382    audio_route_free(adev->audio_route);
2383    free(adev->snd_dev_ref_cnt);
2384    platform_deinit(adev->platform);
2385    for (i = 0; i < ARRAY_SIZE(adev->use_case_table); ++i) {
2386        pcm_params_free(adev->use_case_table[i]);
2387    }
2388    free(device);
2389    return 0;
2390}
2391
2392/* This returns 1 if the input parameter looks at all plausible as a low latency period size,
2393 * or 0 otherwise.  A return value of 1 doesn't mean the value is guaranteed to work,
2394 * just that it _might_ work.
2395 */
2396static int period_size_is_plausible_for_low_latency(int period_size)
2397{
2398    switch (period_size) {
2399    case 160:
2400    case 240:
2401    case 320:
2402    case 480:
2403        return 1;
2404    default:
2405        return 0;
2406    }
2407}
2408
2409static int adev_open(const hw_module_t *module, const char *name,
2410                     hw_device_t **device)
2411{
2412    struct audio_device *adev;
2413    int i, ret;
2414
2415    ALOGD("%s: enter", __func__);
2416    if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
2417
2418    adev = calloc(1, sizeof(struct audio_device));
2419
2420    pthread_mutex_init(&adev->lock, (const pthread_mutexattr_t *) NULL);
2421
2422    adev->device.common.tag = HARDWARE_DEVICE_TAG;
2423    adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
2424    adev->device.common.module = (struct hw_module_t *)module;
2425    adev->device.common.close = adev_close;
2426
2427    adev->device.init_check = adev_init_check;
2428    adev->device.set_voice_volume = adev_set_voice_volume;
2429    adev->device.set_master_volume = adev_set_master_volume;
2430    adev->device.get_master_volume = adev_get_master_volume;
2431    adev->device.set_master_mute = adev_set_master_mute;
2432    adev->device.get_master_mute = adev_get_master_mute;
2433    adev->device.set_mode = adev_set_mode;
2434    adev->device.set_mic_mute = adev_set_mic_mute;
2435    adev->device.get_mic_mute = adev_get_mic_mute;
2436    adev->device.set_parameters = adev_set_parameters;
2437    adev->device.get_parameters = adev_get_parameters;
2438    adev->device.get_input_buffer_size = adev_get_input_buffer_size;
2439    adev->device.open_output_stream = adev_open_output_stream;
2440    adev->device.close_output_stream = adev_close_output_stream;
2441    adev->device.open_input_stream = adev_open_input_stream;
2442    adev->device.close_input_stream = adev_close_input_stream;
2443    adev->device.dump = adev_dump;
2444
2445    /* Set the default route before the PCM stream is opened */
2446    pthread_mutex_lock(&adev->lock);
2447    adev->mode = AUDIO_MODE_NORMAL;
2448    adev->active_input = NULL;
2449    adev->primary_output = NULL;
2450    adev->bluetooth_nrec = true;
2451    adev->acdb_settings = TTY_MODE_OFF;
2452    /* adev->cur_hdmi_channels = 0;  by calloc() */
2453    adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
2454    voice_init(adev);
2455    list_init(&adev->usecase_list);
2456    pthread_mutex_unlock(&adev->lock);
2457
2458    /* Loads platform specific libraries dynamically */
2459    adev->platform = platform_init(adev);
2460    if (!adev->platform) {
2461        free(adev->snd_dev_ref_cnt);
2462        free(adev);
2463        ALOGE("%s: Failed to init platform data, aborting.", __func__);
2464        *device = NULL;
2465        return -EINVAL;
2466    }
2467
2468    if (access(VISUALIZER_LIBRARY_PATH, R_OK) == 0) {
2469        adev->visualizer_lib = dlopen(VISUALIZER_LIBRARY_PATH, RTLD_NOW);
2470        if (adev->visualizer_lib == NULL) {
2471            ALOGE("%s: DLOPEN failed for %s", __func__, VISUALIZER_LIBRARY_PATH);
2472        } else {
2473            ALOGV("%s: DLOPEN successful for %s", __func__, VISUALIZER_LIBRARY_PATH);
2474            adev->visualizer_start_output =
2475                        (int (*)(audio_io_handle_t))dlsym(adev->visualizer_lib,
2476                                                        "visualizer_hal_start_output");
2477            adev->visualizer_stop_output =
2478                        (int (*)(audio_io_handle_t))dlsym(adev->visualizer_lib,
2479                                                        "visualizer_hal_stop_output");
2480        }
2481    }
2482
2483    adev->bt_wb_speech_enabled = false;
2484
2485    *device = &adev->device.common;
2486    if (k_enable_extended_precision)
2487        adev_verify_devices(adev);
2488
2489    char value[PROPERTY_VALUE_MAX];
2490    int trial;
2491    if (property_get("audio_hal.period_size", value, NULL) > 0) {
2492        trial = atoi(value);
2493        if (period_size_is_plausible_for_low_latency(trial)) {
2494            pcm_config_low_latency.period_size = trial;
2495            pcm_config_low_latency.start_threshold = trial / 4;
2496            pcm_config_low_latency.avail_min = trial / 4;
2497            configured_low_latency_capture_period_size = trial;
2498        }
2499    }
2500    if (property_get("audio_hal.in_period_size", value, NULL) > 0) {
2501        trial = atoi(value);
2502        if (period_size_is_plausible_for_low_latency(trial)) {
2503            configured_low_latency_capture_period_size = trial;
2504        }
2505    }
2506
2507    ALOGV("%s: exit", __func__);
2508    return 0;
2509}
2510
2511static struct hw_module_methods_t hal_module_methods = {
2512    .open = adev_open,
2513};
2514
2515struct audio_module HAL_MODULE_INFO_SYM = {
2516    .common = {
2517        .tag = HARDWARE_MODULE_TAG,
2518        .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
2519        .hal_api_version = HARDWARE_HAL_API_VERSION,
2520        .id = AUDIO_HARDWARE_MODULE_ID,
2521        .name = "QCOM Audio HAL",
2522        .author = "Code Aurora Forum",
2523        .methods = &hal_module_methods,
2524    },
2525};
2526