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"
30 #include "tizen-audio-impl.h"
33 static const char* AUDIO_LATENCY_LOW = "low";
34 static const char* AUDIO_LATENCY_MID = "mid";
35 static const char* AUDIO_LATENCY_HIGH = "high";
36 static const char* AUDIO_LATENCY_VOIP = "voip";
39 static const unsigned int PERIOD_TIME_FOR_ULOW_LATENCY_MSEC = 20;
40 static const unsigned int PERIOD_TIME_FOR_LOW_LATENCY_MSEC = 25;
41 static const unsigned int PERIOD_TIME_FOR_MID_LATENCY_MSEC = 50;
42 static const unsigned int PERIOD_TIME_FOR_HIGH_LATENCY_MSEC = 75;
43 static const unsigned int PERIOD_TIME_FOR_UHIGH_LATENCY_MSEC = 150;
44 static const unsigned int PERIOD_TIME_FOR_VOIP_LATENCY_MSEC = 20;
46 static const uint32_t g_size_table[] = {
47 [AUDIO_SAMPLE_U8] = 1,
48 [AUDIO_SAMPLE_ULAW] = 1,
49 [AUDIO_SAMPLE_ALAW] = 1,
50 [AUDIO_SAMPLE_S16LE] = 2,
51 [AUDIO_SAMPLE_S16BE] = 2,
52 [AUDIO_SAMPLE_FLOAT32LE] = 4,
53 [AUDIO_SAMPLE_FLOAT32BE] = 4,
54 [AUDIO_SAMPLE_S32LE] = 4,
55 [AUDIO_SAMPLE_S32BE] = 4,
56 [AUDIO_SAMPLE_S24LE] = 3,
57 [AUDIO_SAMPLE_S24BE] = 3,
58 [AUDIO_SAMPLE_S24_32LE] = 4,
59 [AUDIO_SAMPLE_S24_32BE] = 4
62 static int __sample_spec_valid(uint32_t rate, audio_sample_format_t format, uint32_t channels)
68 format >= AUDIO_SAMPLE_MAX ||
69 format < AUDIO_SAMPLE_U8))
72 AUDIO_LOG_ERROR("hal-latency - __sample_spec_valid() -> return true");
77 static uint32_t __usec_to_bytes(uint64_t t, uint32_t rate, audio_sample_format_t format, uint32_t channels)
79 uint32_t ret = (uint32_t) (((t * rate) / 1000000ULL)) * (g_size_table[format] * channels);
80 AUDIO_LOG_DEBUG("hal-latency - return %d", ret);
84 static uint32_t __sample_size(audio_sample_format_t format)
86 return g_size_table[format];
89 audio_return_t _audio_stream_init(audio_hal_t *ah)
91 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
96 audio_return_t _audio_stream_deinit(audio_hal_t *ah)
98 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
103 audio_return_t audio_notify_stream_connection_changed(void *audio_handle, audio_stream_info_t *info, uint32_t is_connected)
105 audio_return_t audio_ret = AUDIO_RET_OK;
106 audio_hal_t *ah = (audio_hal_t *)audio_handle;
108 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
109 AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER);
111 AUDIO_LOG_INFO("role:%s, direction:%u, idx:%u, is_connected:%d", info->role, info->direction, info->idx, is_connected);
112 if (streq(info->role, "radio")) {
114 ah->device.is_radio_on = 1;
116 ah->device.is_radio_on = 0;
122 audio_return_t audio_get_buffer_attr(void *audio_handle,
126 audio_sample_format_t format,
134 AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER);
135 AUDIO_RETURN_VAL_IF_FAIL(latency, AUDIO_ERR_PARAMETER);
136 AUDIO_RETURN_VAL_IF_FAIL(maxlength, AUDIO_ERR_PARAMETER);
137 AUDIO_RETURN_VAL_IF_FAIL(tlength, AUDIO_ERR_PARAMETER);
138 AUDIO_RETURN_VAL_IF_FAIL(prebuf, AUDIO_ERR_PARAMETER);
139 AUDIO_RETURN_VAL_IF_FAIL(minreq, AUDIO_ERR_PARAMETER);
140 AUDIO_RETURN_VAL_IF_FAIL(fragsize, AUDIO_ERR_PARAMETER);
142 AUDIO_LOG_DEBUG("hal-latency - audio_get_buffer_attr(direction:%d, latency:%s, samplerate:%d, format:%d, channels:%d)", direction, latency, samplerate, format, channels);
144 uint32_t period_time = 0,
145 sample_per_period = 0;
147 if (__sample_spec_valid(samplerate, format, channels) == 0) {
148 return AUDIO_ERR_PARAMETER;
151 if (direction == AUDIO_DIRECTION_IN) {
152 if (!strcmp(latency, AUDIO_LATENCY_LOW)) {
153 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_LOW");
154 period_time = PERIOD_TIME_FOR_LOW_LATENCY_MSEC;
155 sample_per_period = (samplerate * period_time) / 1000;
160 *fragsize = sample_per_period * __sample_size(format);
161 } else if (!strcmp(latency, AUDIO_LATENCY_MID)) {
162 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_MID");
163 period_time = PERIOD_TIME_FOR_MID_LATENCY_MSEC;
164 sample_per_period = (samplerate * period_time) / 1000;
169 *fragsize = sample_per_period * __sample_size(format);
170 } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) {
171 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_HIGH");
172 period_time = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC;
173 sample_per_period = (samplerate * period_time) / 1000;
178 *fragsize = sample_per_period * __sample_size(format);
179 } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) {
180 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_VOIP");
181 period_time = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC;
182 sample_per_period = (samplerate * period_time) / 1000;
187 *fragsize = sample_per_period * __sample_size(format);
189 AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency);
190 return AUDIO_ERR_UNDEFINED;
192 } else { /* AUDIO_DIRECTION_OUT */
193 if (!strcmp(latency, AUDIO_LATENCY_LOW)) {
194 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_LOW");
195 period_time = PERIOD_TIME_FOR_LOW_LATENCY_MSEC;
196 sample_per_period = (samplerate * period_time) / 1000;
199 *tlength = (samplerate / 10) * __sample_size(format) * channels; /* 100ms */
202 } else if (!strcmp(latency, AUDIO_LATENCY_MID)) {
203 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_MID");
204 period_time = PERIOD_TIME_FOR_MID_LATENCY_MSEC;
205 sample_per_period = (samplerate * period_time) / 1000;
208 *tlength = (uint32_t) __usec_to_bytes(200000, samplerate, format, channels);
211 } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) {
212 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_HIGH");
213 period_time = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC;
214 sample_per_period = (samplerate * period_time) / 1000;
217 *tlength = (uint32_t) __usec_to_bytes(400000, samplerate, format, channels);
220 } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) {
221 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_VOIP");
222 period_time = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC;
223 sample_per_period = (samplerate * period_time) / 1000;
225 *minreq = __usec_to_bytes(20000, samplerate, format, channels);
226 *tlength = __usec_to_bytes(100000, samplerate, format, channels);
230 AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency);
231 return AUDIO_ERR_UNDEFINED;
235 AUDIO_LOG_INFO("hal-latency - return attr --> prebuf:%d, minreq:%d, tlength:%d, maxlength:%d, fragsize:%d", *prebuf, *minreq, *tlength, *maxlength, *fragsize);