Restructure files
[platform/adaptation/emulator/audio-hal-emul.git] / tizen-audio-stream.c
1 /*
2  * audio-hal
3  *
4  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdbool.h>
28
29 #include "tizen-audio-internal.h"
30
31 /* Audio latency */
32 static const char* AUDIO_LATENCY_LOW  = "low";
33 static const char* AUDIO_LATENCY_MID  = "mid";
34 static const char* AUDIO_LATENCY_HIGH = "high";
35 static const char* AUDIO_LATENCY_VOIP = "voip";
36
37 /* Latency msec */
38 static const unsigned int PERIOD_TIME_FOR_ULOW_LATENCY_MSEC  = 20;
39 static const unsigned int PERIOD_TIME_FOR_LOW_LATENCY_MSEC   = 25;
40 static const unsigned int PERIOD_TIME_FOR_MID_LATENCY_MSEC   = 50;
41 static const unsigned int PERIOD_TIME_FOR_HIGH_LATENCY_MSEC  = 75;
42 static const unsigned int PERIOD_TIME_FOR_UHIGH_LATENCY_MSEC = 150;
43 static const unsigned int PERIOD_TIME_FOR_VOIP_LATENCY_MSEC  = 20;
44
45 static const uint32_t g_size_table[] = {
46     [AUDIO_SAMPLE_U8]        = 1,
47     [AUDIO_SAMPLE_ULAW]      = 1,
48     [AUDIO_SAMPLE_ALAW]      = 1,
49     [AUDIO_SAMPLE_S16LE]     = 2,
50     [AUDIO_SAMPLE_S16BE]     = 2,
51     [AUDIO_SAMPLE_FLOAT32LE] = 4,
52     [AUDIO_SAMPLE_FLOAT32BE] = 4,
53     [AUDIO_SAMPLE_S32LE]     = 4,
54     [AUDIO_SAMPLE_S32BE]     = 4,
55     [AUDIO_SAMPLE_S24LE]     = 3,
56     [AUDIO_SAMPLE_S24BE]     = 3,
57     [AUDIO_SAMPLE_S24_32LE]  = 4,
58     [AUDIO_SAMPLE_S24_32BE]  = 4
59 };
60
61 static int __sample_spec_valid(uint32_t rate, audio_sample_format_t format, uint32_t channels)
62 {
63     if ((rate <= 0                 ||
64         rate > (48000U*4U)         ||
65         channels <= 0              ||
66         channels > 32U             ||
67         format >= AUDIO_SAMPLE_MAX ||
68         format <  AUDIO_SAMPLE_U8))
69         return 0;
70
71     AUDIO_LOG_ERROR("hal-latency - __sample_spec_valid() -> return true");
72
73     return 1;
74 }
75
76 static uint32_t __usec_to_bytes(uint64_t t, uint32_t rate, audio_sample_format_t format, uint32_t channels)
77 {
78     uint32_t ret = (uint32_t) (((t * rate) / 1000000ULL)) * (g_size_table[format] * channels);
79     AUDIO_LOG_DEBUG("hal-latency - return %d", ret);
80     return ret;
81 }
82
83 static uint32_t __sample_size(audio_sample_format_t format)
84 {
85     return g_size_table[format];
86 }
87
88 audio_return_t _audio_stream_init(audio_hal_t *ah)
89 {
90     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
91
92     return AUDIO_RET_OK;
93 }
94
95 audio_return_t _audio_stream_deinit(audio_hal_t *ah)
96 {
97     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
98
99     return AUDIO_RET_OK;
100 }
101
102 audio_return_t audio_notify_stream_connection_changed(void *audio_handle, audio_stream_info_t *info, uint32_t is_connected)
103 {
104     audio_return_t audio_ret = AUDIO_RET_OK;
105     audio_hal_t *ah = (audio_hal_t *)audio_handle;
106
107     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
108     AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER);
109
110     AUDIO_LOG_INFO("role:%s, direction:%u, idx:%u, is_connected:%d", info->role, info->direction, info->idx, is_connected);
111
112     return audio_ret;
113 }
114
115 audio_return_t audio_get_buffer_attr(void                  *audio_handle,
116                                      uint32_t              direction,
117                                      const char            *latency,
118                                      uint32_t              samplerate,
119                                      audio_sample_format_t format,
120                                      uint32_t              channels,
121                                      uint32_t              *maxlength,
122                                      uint32_t              *tlength,
123                                      uint32_t              *prebuf,
124                                      uint32_t              *minreq,
125                                      uint32_t              *fragsize)
126 {
127     AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER);
128     AUDIO_RETURN_VAL_IF_FAIL(latency, AUDIO_ERR_PARAMETER);
129     AUDIO_RETURN_VAL_IF_FAIL(maxlength, AUDIO_ERR_PARAMETER);
130     AUDIO_RETURN_VAL_IF_FAIL(tlength, AUDIO_ERR_PARAMETER);
131     AUDIO_RETURN_VAL_IF_FAIL(prebuf, AUDIO_ERR_PARAMETER);
132     AUDIO_RETURN_VAL_IF_FAIL(minreq, AUDIO_ERR_PARAMETER);
133     AUDIO_RETURN_VAL_IF_FAIL(fragsize, AUDIO_ERR_PARAMETER);
134
135     AUDIO_LOG_DEBUG("hal-latency - audio_get_buffer_attr(direction:%d, latency:%s, samplerate:%d, format:%d, channels:%d)", direction, latency, samplerate, format, channels);
136
137     uint32_t period_time        = 0,
138              sample_per_period  = 0;
139
140     if (__sample_spec_valid(samplerate, format, channels) == 0) {
141         return AUDIO_ERR_PARAMETER;
142     }
143
144     if (direction == AUDIO_DIRECTION_IN) {
145         if (!strcmp(latency, AUDIO_LATENCY_LOW)) {
146             AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_LOW");
147             period_time        = PERIOD_TIME_FOR_LOW_LATENCY_MSEC;
148             sample_per_period  = (samplerate * period_time) / 1000;
149             *prebuf            = 0;
150             *minreq            = -1;
151             *tlength           = -1;
152             *maxlength         = -1;
153             *fragsize          = sample_per_period * __sample_size(format);
154         } else if (!strcmp(latency, AUDIO_LATENCY_MID)) {
155             AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_MID");
156             period_time        = PERIOD_TIME_FOR_MID_LATENCY_MSEC;
157             sample_per_period  = (samplerate * period_time) / 1000;
158             *prebuf            = 0;
159             *minreq            = -1;
160             *tlength           = -1;
161             *maxlength         = -1;
162             *fragsize          = sample_per_period * __sample_size(format);
163         } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) {
164             AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_HIGH");
165             period_time        = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC;
166             sample_per_period  = (samplerate * period_time) / 1000;
167             *prebuf            = 0;
168             *minreq            = -1;
169             *tlength           = -1;
170             *maxlength         = -1;
171             *fragsize          = sample_per_period * __sample_size(format);
172         } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) {
173             AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_VOIP");
174             period_time        = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC;
175             sample_per_period  = (samplerate * period_time) / 1000;
176             *prebuf            = 0;
177             *minreq            = -1;
178             *tlength           = -1;
179             *maxlength         = -1;
180             *fragsize          = sample_per_period * __sample_size(format);
181         } else {
182             AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency);
183             return AUDIO_ERR_UNDEFINED;
184         }
185     } else {  /* AUDIO_DIRECTION_OUT */
186         if (!strcmp(latency, AUDIO_LATENCY_LOW)) {
187             AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_LOW");
188             period_time        = PERIOD_TIME_FOR_LOW_LATENCY_MSEC;
189             sample_per_period  = (samplerate * period_time) / 1000;
190             *prebuf            = 0;
191             *minreq            = -1;
192             *tlength           = (samplerate / 10) * __sample_size(format) * channels;  /* 100ms */
193             *maxlength         = -1;
194             *fragsize          = 0;
195         } else if (!strcmp(latency, AUDIO_LATENCY_MID)) {
196             AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_MID");
197             period_time        = PERIOD_TIME_FOR_MID_LATENCY_MSEC;
198             sample_per_period  = (samplerate * period_time) / 1000;
199             *prebuf            = 0;
200             *minreq            = -1;
201             *tlength           = (uint32_t) __usec_to_bytes(200000, samplerate, format, channels);
202             *maxlength         = -1;
203             *fragsize          = -1;
204         } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) {
205             AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_HIGH");
206             period_time        = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC;
207             sample_per_period  = (samplerate * period_time) / 1000;
208             *prebuf            = 0;
209             *minreq            = -1;
210             *tlength           = (uint32_t) __usec_to_bytes(400000, samplerate, format, channels);
211             *maxlength         = -1;
212             *fragsize          = -1;
213         } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) {
214             AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_VOIP");
215             period_time        = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC;
216             sample_per_period  = (samplerate * period_time) / 1000;
217             *prebuf            = 0;
218             *minreq            = __usec_to_bytes(20000, samplerate, format, channels);
219             *tlength           = __usec_to_bytes(100000, samplerate, format, channels);
220             *maxlength         = -1;
221             *fragsize          = 0;
222         } else {
223             AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency);
224             return AUDIO_ERR_UNDEFINED;
225         }
226     }
227
228     AUDIO_LOG_INFO("hal-latency - return attr --> prebuf:%d, minreq:%d, tlength:%d, maxlength:%d, fragsize:%d", *prebuf, *minreq, *tlength, *maxlength, *fragsize);
229     return AUDIO_RET_OK;
230 }