1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  *
4  */
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <stdarg.h>
11 #include <errno.h>
12 
13 #include "uvoice_types.h"
14 
15 #include "uvoice_os.h"
16 #include "uvoice_audio.h"
17 #include "uvoice_pcm.h"
18 #include "uvoice_common.h"
19 #include "audio_common.h"
20 #include "audio_stream.h"
21 #include "audio_mixer.h"
22 
23 
24 #define SPK_VOLUME_ID    "spk_vol"
25 #define HPH_VOLUME_ID    "hph_vol"
26 #define REC_VOLUME_ID    "rec_vol"
27 #define SPK_AND_HPH_VOLUME_ID    "spk_hph_vol"
28 
29 
device_select(struct audio_device * adev,snd_device_t device,bool force)30 int device_select(struct audio_device *adev, snd_device_t device,
31     bool force)
32 {
33     int volume;
34 
35     if (!adev) {
36         snd_err("adev null !\n");
37         return -1;
38     }
39 
40     if (device >= SND_DEVICE_OUT_BEGIN &&
41         device <= SND_DEVICE_OUT_END) {
42         if (adev->out_device != device || force) {
43             volume = volume_get(device);
44             if (volume >= VOLUME_LEVEL_MIN &&
45                     volume <= VOLUME_LEVEL_MAX)
46                 adev->out_volume = volume;
47             if (adev->out) {
48                 uvoice_set_path(&adev->out->pcm, device);
49                 volume_set(device, adev->out_volume);
50             }
51             adev->out_device = device;
52             snd_debug("out device %d\n", device);
53         }
54     } else if (device >= SND_DEVICE_IN_BEGIN &&
55         device <= SND_DEVICE_IN_END) {
56         if (adev->in_device != device || force) {
57             if (adev->in)
58                 uvoice_set_path(&adev->in->pcm, device);
59             adev->in_device = device;
60             snd_debug("in device %d\n", device);
61         }
62     } else {
63         snd_err("device %d invalid !\n", device);
64         return -1;
65     }
66 
67 __exit:
68     return 0;
69 }
70 
volume_set(snd_device_t device,int volume)71 int volume_set(snd_device_t device, int volume)
72 {
73     unsigned char curr_vol = VOLUME_LEVEL_MIN;
74     int len = sizeof(curr_vol);
75     char *key = NULL;
76     int ret;
77 
78     if (device == SND_DEVICE_OUT_SPEAKER)
79         key = SPK_VOLUME_ID;
80     else if (device == SND_DEVICE_OUT_HEADPHONE ||
81         device == SND_DEVICE_OUT_HEADSET)
82         key = HPH_VOLUME_ID;
83     else if (device == SND_DEVICE_OUT_RECEIVER)
84         key = REC_VOLUME_ID;
85     else if (device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONE)
86         key = SPK_AND_HPH_VOLUME_ID;
87     else
88         return -1;
89 
90     ret = uvoice_set_volume(device, volume);
91     if (ret) {
92         snd_err("set volume failed %d!\n", volume);
93         return -1;
94     }
95 
96     ret = os_kv_get(key, &curr_vol, &len);
97     if (ret == -ENOENT) {
98         snd_debug("%s not found\n", key);
99     } else if (ret) {
100         snd_err("get %s failed %d!\n", key, ret);
101         return -1;
102     }
103 
104     if (volume == curr_vol)
105         goto __exit;
106     curr_vol = volume;
107 
108     ret = os_kv_set(key, &curr_vol, len, 0);
109     if (ret) {
110         snd_err("set %s failed %d!\n", key, ret);
111         return -1;
112     }
113 
114 __exit:
115     return 0;
116 }
117 
volume_get(snd_device_t device)118 int volume_get(snd_device_t device)
119 {
120     unsigned char curr_vol = VOLUME_LEVEL_MIN;
121     int len = sizeof(curr_vol);
122     char *key = NULL;
123     int ret;
124 
125     if (device == SND_DEVICE_OUT_SPEAKER)
126         key = SPK_VOLUME_ID;
127     else if (device == SND_DEVICE_OUT_HEADPHONE ||
128         device == SND_DEVICE_OUT_HEADSET)
129         key = HPH_VOLUME_ID;
130     else if (device == SND_DEVICE_OUT_RECEIVER)
131         key = REC_VOLUME_ID;
132     else if (device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONE)
133         key = SPK_AND_HPH_VOLUME_ID;
134     else
135         return -1;
136 
137     ret = os_kv_get(key, &curr_vol, &len);
138     if (ret == -ENOENT) {
139         snd_debug("%s not found\n", key);
140         return -1;
141     } else if (ret) {
142         snd_err("get %s failed %d!\n", key, ret);
143         return -1;
144     }
145 
146     return curr_vol;
147 }
148 
149