4 * Copyright (c) 2000 - 2013 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.
24 #include "tizen-audio-internal.h"
27 static const char* AUDIO_LATENCY_LOW = "low";
28 static const char* AUDIO_LATENCY_MID = "mid";
29 static const char* AUDIO_LATENCY_HIGH = "high";
30 static const char* AUDIO_LATENCY_VOIP = "voip";
32 audio_return_t audio_init (void **audio_handle)
35 audio_return_t ret = AUDIO_RET_OK;
37 AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER);
39 if (!(ah = malloc(sizeof(audio_hal_t)))) {
40 AUDIO_LOG_ERROR("am malloc failed");
41 return AUDIO_ERR_RESOURCE;
43 if (AUDIO_IS_ERROR((ret = _audio_device_init(ah)))) {
44 AUDIO_LOG_ERROR("device init failed");
47 if (AUDIO_IS_ERROR((ret = _audio_volume_init(ah)))) {
48 AUDIO_LOG_ERROR("stream init failed");
51 if (AUDIO_IS_ERROR((ret = _audio_ucm_init(ah)))) {
52 AUDIO_LOG_ERROR("ucm init failed");
55 if (AUDIO_IS_ERROR((ret = _audio_util_init(ah)))) {
56 AUDIO_LOG_ERROR("mixer init failed");
60 *audio_handle = (void *)ah;
70 audio_return_t audio_deinit (void *audio_handle)
72 audio_hal_t *ah = (audio_hal_t *)audio_handle;
74 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
76 _audio_device_deinit(ah);
77 _audio_volume_deinit(ah);
78 _audio_ucm_deinit(ah);
79 _audio_util_deinit(ah);
87 static const unsigned int PERIOD_TIME_FOR_ULOW_LATENCY_MSEC = 20;
88 static const unsigned int PERIOD_TIME_FOR_LOW_LATENCY_MSEC = 25;
89 static const unsigned int PERIOD_TIME_FOR_MID_LATENCY_MSEC = 50;
90 static const unsigned int PERIOD_TIME_FOR_HIGH_LATENCY_MSEC = 75;
91 static const unsigned int PERIOD_TIME_FOR_UHIGH_LATENCY_MSEC = 150;
92 static const unsigned int PERIOD_TIME_FOR_VOIP_LATENCY_MSEC = 20;
94 static const uint32_t g_size_table[] = {
95 [AUDIO_SAMPLE_U8] = 1,
96 [AUDIO_SAMPLE_ULAW] = 1,
97 [AUDIO_SAMPLE_ALAW] = 1,
98 [AUDIO_SAMPLE_S16LE] = 2,
99 [AUDIO_SAMPLE_S16BE] = 2,
100 [AUDIO_SAMPLE_FLOAT32LE] = 4,
101 [AUDIO_SAMPLE_FLOAT32BE] = 4,
102 [AUDIO_SAMPLE_S32LE] = 4,
103 [AUDIO_SAMPLE_S32BE] = 4,
104 [AUDIO_SAMPLE_S24LE] = 3,
105 [AUDIO_SAMPLE_S24BE] = 3,
106 [AUDIO_SAMPLE_S24_32LE] = 4,
107 [AUDIO_SAMPLE_S24_32BE] = 4
110 int _sample_spec_valid(uint32_t rate, audio_sample_format_t format, uint32_t channels)
113 rate > (48000U*4U) ||
116 format >= AUDIO_SAMPLE_MAX ||
117 format < AUDIO_SAMPLE_U8))
120 AUDIO_LOG_ERROR("hal-latency - _sample_spec_valid() -> return true");
125 uint32_t _audio_usec_to_bytes(uint64_t t, uint32_t rate, audio_sample_format_t format, uint32_t channels)
127 uint32_t ret = (uint32_t) (((t * rate) / 1000000ULL)) * (g_size_table[format] * channels);
128 AUDIO_LOG_DEBUG("hal-latency - return %d", ret);
132 uint32_t _audio_sample_size(audio_sample_format_t format)
134 return g_size_table[format];
136 audio_return_t audio_get_buffer_attr(void *audio_handle,
140 audio_sample_format_t format,
148 AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER);
149 AUDIO_RETURN_VAL_IF_FAIL(latency, AUDIO_ERR_PARAMETER);
150 AUDIO_RETURN_VAL_IF_FAIL(maxlength, AUDIO_ERR_PARAMETER);
151 AUDIO_RETURN_VAL_IF_FAIL(tlength, AUDIO_ERR_PARAMETER);
152 AUDIO_RETURN_VAL_IF_FAIL(prebuf, AUDIO_ERR_PARAMETER);
153 AUDIO_RETURN_VAL_IF_FAIL(minreq, AUDIO_ERR_PARAMETER);
154 AUDIO_RETURN_VAL_IF_FAIL(fragsize, AUDIO_ERR_PARAMETER);
156 AUDIO_LOG_DEBUG("hal-latency - audio_get_buffer_attr(direction:%d, latency:%s, samplerate:%d, format:%d, channels:%d)", direction, latency, samplerate, format, channels);
158 uint32_t period_time = 0,
159 sample_per_period = 0;
161 if (_sample_spec_valid(samplerate, format, channels) == 0) {
162 return AUDIO_ERR_PARAMETER;
165 if (direction == AUDIO_DIRECTION_IN) {
166 if (!strcmp(latency, AUDIO_LATENCY_LOW)) {
167 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_LOW");
168 period_time = PERIOD_TIME_FOR_LOW_LATENCY_MSEC;
169 sample_per_period = (samplerate * period_time) / 1000;
174 *fragsize = sample_per_period * _audio_sample_size(format);
175 } else if (!strcmp(latency, AUDIO_LATENCY_MID)) {
176 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_MID");
177 period_time = PERIOD_TIME_FOR_MID_LATENCY_MSEC;
178 sample_per_period = (samplerate * period_time) / 1000;
183 *fragsize = sample_per_period * _audio_sample_size(format);
184 } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) {
185 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_HIGH");
186 period_time = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC;
187 sample_per_period = (samplerate * period_time) / 1000;
192 *fragsize = sample_per_period * _audio_sample_size(format);
193 } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) {
194 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_VOIP");
195 period_time = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC;
196 sample_per_period = (samplerate * period_time) / 1000;
201 *fragsize = sample_per_period * _audio_sample_size(format);
203 AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency);
204 return AUDIO_ERR_UNDEFINED;
206 } else { /* AUDIO_DIRECTION_OUT */
207 if (!strcmp(latency, AUDIO_LATENCY_LOW)) {
208 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_LOW");
209 period_time = PERIOD_TIME_FOR_LOW_LATENCY_MSEC;
210 sample_per_period = (samplerate * period_time) / 1000;
213 *tlength = (samplerate / 10) * _audio_sample_size(format) * channels; /* 100ms */
216 } else if (!strcmp(latency, AUDIO_LATENCY_MID)) {
217 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_MID");
218 period_time = PERIOD_TIME_FOR_MID_LATENCY_MSEC;
219 sample_per_period = (samplerate * period_time) / 1000;
222 *tlength = (uint32_t) _audio_usec_to_bytes(200000, samplerate, format, channels);
225 } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) {
226 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_HIGH");
227 period_time = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC;
228 sample_per_period = (samplerate * period_time) / 1000;
231 *tlength = (uint32_t) _audio_usec_to_bytes(400000, samplerate, format, channels);
234 } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) {
235 AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_VOIP");
236 period_time = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC;
237 sample_per_period = (samplerate * period_time) / 1000;
239 *minreq = _audio_usec_to_bytes(20000, samplerate, format, channels);
240 *tlength = _audio_usec_to_bytes(100000, samplerate, format, channels);
244 AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency);
245 return AUDIO_ERR_UNDEFINED;
249 AUDIO_LOG_INFO("hal-latency - return attr --> prebuf:%d, minreq:%d, tlength:%d, maxlength:%d, fragsize:%d", *prebuf, *minreq, *tlength, *maxlength, *fragsize);