4 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
29 #include "tizen-audio-internal.h"
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";
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;
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
61 static int __sample_spec_valid(uint32_t rate, audio_sample_format_t format, uint32_t channels)
67 format >= AUDIO_SAMPLE_MAX ||
68 format < AUDIO_SAMPLE_U8))
71 AUDIO_LOG_ERROR("hal-latency - __sample_spec_valid() -> return true");
76 static uint32_t __usec_to_bytes(uint64_t t, uint32_t rate, audio_sample_format_t format, uint32_t channels)
78 uint32_t ret = (uint32_t) (((t * rate) / 1000000ULL)) * (g_size_table[format] * channels);
79 AUDIO_LOG_DEBUG("hal-latency - return %d", ret);
83 static uint32_t __sample_size(audio_sample_format_t format)
85 return g_size_table[format];
88 audio_return_t _audio_stream_init(audio_hal_t *ah)
90 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
95 audio_return_t _audio_stream_deinit(audio_hal_t *ah)
97 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
102 audio_return_t audio_notify_stream_connection_changed(void *audio_handle, audio_stream_info_t *info, uint32_t is_connected)
104 audio_return_t audio_ret = AUDIO_RET_OK;
105 audio_hal_t *ah = (audio_hal_t *)audio_handle;
107 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
108 AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER);
110 AUDIO_LOG_INFO("role:%s, direction:%u, idx:%u, is_connected:%d", info->role, info->direction, info->idx, is_connected);
115 audio_return_t audio_get_buffer_attr(void *audio_handle,
119 audio_sample_format_t format,
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);
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);
137 uint32_t period_time = 0,
138 sample_per_period = 0;
140 if (__sample_spec_valid(samplerate, format, channels) == 0) {
141 return AUDIO_ERR_PARAMETER;
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;
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;
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;
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;
180 *fragsize = sample_per_period * __sample_size(format);
182 AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency);
183 return AUDIO_ERR_UNDEFINED;
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;
192 *tlength = (samplerate / 10) * __sample_size(format) * channels; /* 100ms */
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;
201 *tlength = (uint32_t) __usec_to_bytes(200000, samplerate, format, channels);
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;
210 *tlength = (uint32_t) __usec_to_bytes(400000, samplerate, format, channels);
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;
218 *minreq = __usec_to_bytes(20000, samplerate, format, channels);
219 *tlength = __usec_to_bytes(100000, samplerate, format, channels);
223 AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency);
224 return AUDIO_ERR_UNDEFINED;
228 AUDIO_LOG_INFO("hal-latency - return attr --> prebuf:%d, minreq:%d, tlength:%d, maxlength:%d, fragsize:%d", *prebuf, *minreq, *tlength, *maxlength, *fragsize);