fixup! Fix SVACE defects (DEREF_OF_NULL.RET.ALLOC)
[platform/adaptation/spreadtrum/audio-hal-sc7727.git] / tizen-audio.c
index b7df609..2023991 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * audio-hal
  *
- * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 #include "tizen-audio-internal.h"
 
-audio_return_t audio_init (void **userdata)
+audio_return_t audio_init(void **audio_handle)
 {
-    audio_mgr_t *am;
+    audio_hal_t *ah;
     audio_return_t ret = AUDIO_RET_OK;
 
-    if (!(am = malloc(sizeof(audio_mgr_t)))) {
-        AUDIO_LOG_ERROR("am malloc failed");
+    AUDIO_RETURN_VAL_IF_FAIL(audio_handle, AUDIO_ERR_PARAMETER);
+
+    if (!(ah = calloc(1, sizeof(audio_hal_t)))) {
+        AUDIO_LOG_ERROR("failed to alloc errno(%d)", errno);
         return AUDIO_ERR_RESOURCE;
     }
-    if (AUDIO_IS_ERROR((ret = _audio_device_init(am)))) {
-        AUDIO_LOG_ERROR("device init failed");
+
+    if ((ret = _audio_ctrl_init(ah))) {
+        AUDIO_LOG_ERROR("failed to _audio_ctrl_init(), ret(0x%x)", ret);
         goto error_exit;
     }
-    if (AUDIO_IS_ERROR((ret = _audio_volume_init(am)))) {
-        AUDIO_LOG_ERROR("stream init failed");
+    if ((ret = _audio_volume_init(ah))) {
+        AUDIO_LOG_ERROR("failed to _audio_volume_init(), ret(0x%x)", ret);
         goto error_exit;
     }
-    if (AUDIO_IS_ERROR((ret = _audio_ucm_init(am)))) {
-        AUDIO_LOG_ERROR("ucm init failed");
+    if ((ret = _audio_routing_init(ah))) {
+        AUDIO_LOG_ERROR("failed to _audio_routing_init(), ret(0x%x)", ret);
         goto error_exit;
     }
-    if (AUDIO_IS_ERROR((ret = _audio_util_init(am)))) {
-        AUDIO_LOG_ERROR("mixer init failed");
+    if ((ret = _audio_stream_init(ah))) {
+        AUDIO_LOG_ERROR("failed to _audio_stream_init(), ret(0x%x)", ret);
         goto error_exit;
     }
-
-    *userdata = (void *)am;
-    return AUDIO_RET_OK;
-
-error_exit:
-    if (am)
-        free(am);
-
-    return ret;
-}
-
-audio_return_t audio_deinit (void **userdata)
-{
-    audio_mgr_t *am = (audio_mgr_t *)*userdata;
-
-    if (am) {
-        _audio_device_deinit(am);
-        _audio_volume_deinit(am);
-        _audio_ucm_deinit(am);
-        _audio_util_deinit(am);
-        free(am);
-        *userdata = NULL;
+    if ((ret = _audio_pcm_init(ah))) {
+        AUDIO_LOG_ERROR("failed to _audio_pcm_init(), ret(0x%x)", ret);
+        goto error_exit;
+    }
+    if ((ret = _audio_modem_init(ah))) {
+        AUDIO_LOG_ERROR("failed to _audio_modem_init(), ret(0x%x)", ret);
+        goto error_exit;
+    }
+    if ((ret = _audio_comm_init(ah))) {
+        AUDIO_LOG_ERROR("failed to _audio_comm_init(), ret(0x%x)", ret);
+        goto error_exit;
     }
 
+    *audio_handle = (void *)ah;
     return AUDIO_RET_OK;
-}
-
-static const unsigned int SAMPLES_PER_PERIOD_DEFAULT         = 1536; /* Frames */
-static const unsigned int PERIODS_PER_BUFFER_FASTMODE        = 4;
-static const unsigned int PERIODS_PER_BUFFER_DEFAULT         = 6;
-static const unsigned int PERIODS_PER_BUFFER_VOIP            = 2;
-static const unsigned int PERIODS_PER_BUFFER_PLAYBACK        = 8;
-static const unsigned int PERIODS_PER_BUFFER_CAPTURE         = 12;
-static const unsigned int PERIODS_PER_BUFFER_VIDEO           = 10;
-
-
-/* Latency msec */
-static const unsigned int PERIOD_TIME_FOR_ULOW_LATENCY_MSEC  = 20;
-static const unsigned int PERIOD_TIME_FOR_LOW_LATENCY_MSEC   = 25;
-static const unsigned int PERIOD_TIME_FOR_MID_LATENCY_MSEC   = 50;
-static const unsigned int PERIOD_TIME_FOR_HIGH_LATENCY_MSEC  = 75;
-static const unsigned int PERIOD_TIME_FOR_UHIGH_LATENCY_MSEC = 150;
-static const unsigned int PERIOD_TIME_FOR_VOIP_LATENCY_MSEC  = 20;
-
-static const uint32_t g_size_table[] = {
-    [AUDIO_SAMPLE_U8]        = 1,
-    [AUDIO_SAMPLE_ULAW]      = 1,
-    [AUDIO_SAMPLE_ALAW]      = 1,
-    [AUDIO_SAMPLE_S16LE]     = 2,
-    [AUDIO_SAMPLE_S16BE]     = 2,
-    [AUDIO_SAMPLE_FLOAT32LE] = 4,
-    [AUDIO_SAMPLE_FLOAT32BE] = 4,
-    [AUDIO_SAMPLE_S32LE]     = 4,
-    [AUDIO_SAMPLE_S32BE]     = 4,
-    [AUDIO_SAMPLE_S24LE]     = 3,
-    [AUDIO_SAMPLE_S24BE]     = 3,
-    [AUDIO_SAMPLE_S24_32LE]  = 4,
-    [AUDIO_SAMPLE_S24_32BE]  = 4
-};
 
-int _sample_spec_valid(uint32_t rate, audio_sample_format_t format, uint32_t channels)
-{
-    if ((rate <= 0                 ||
-        rate > (48000U*4U)         ||
-        channels <= 0              ||
-        channels > 32U             ||
-        format >= AUDIO_SAMPLE_MAX ||
-        format <  AUDIO_SAMPLE_U8))
-        return 0;
-
-    AUDIO_LOG_ERROR("hal-latency - _sample_spec_valid() -> return true");
-
-    return 1;
-}
+error_exit:
+    if (ah)
+        free(ah);
 
-uint32_t _audio_usec_to_bytes(uint64_t t, uint32_t rate, audio_sample_format_t format, uint32_t channels)
-{
-    uint32_t ret = (uint32_t) (((t * rate) / 1000000ULL)) * (g_size_table[format] * channels);
-    AUDIO_LOG_DEBUG("hal-latency - return %d", ret);
     return ret;
 }
 
-uint32_t _audio_sample_size(audio_sample_format_t format)
-{
-    return g_size_table[format];
-}
-audio_return_t audio_get_buffer_attr(void                  *userdata,
-                                     uint32_t              direction,
-                                     const char            *latency,
-                                     uint32_t              samplerate,
-                                     audio_sample_format_t format,
-                                     uint32_t              channels,
-                                     uint32_t              *maxlength,
-                                     uint32_t              *tlength,
-                                     uint32_t              *prebuf,
-                                     uint32_t              *minreq,
-                                     uint32_t              *fragsize)
+audio_return_t audio_deinit(void *audio_handle)
 {
-    assert(userdata);
-    assert(latency);
-    assert(maxlength);
-    assert(tlength);
-    assert(prebuf);
-    assert(minreq);
-    assert(fragsize);
+    audio_hal_t *ah = (audio_hal_t *)audio_handle;
 
-    AUDIO_LOG_DEBUG("hal-latency - audio_get_buffer_attr(direction:%d, latency:%s, samplerate:%d, format:%d, channels:%d)", direction, latency, samplerate, format, channels);
+    AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
 
-    audio_mgr_t *am = (audio_mgr_t *)userdata;
+    _audio_volume_deinit(ah);
+    _audio_routing_deinit(ah);
+    _audio_stream_deinit(ah);
+    _audio_pcm_deinit(ah);
+    _audio_modem_deinit(ah);
+    _audio_comm_deinit(ah);
+    _audio_ctrl_deinit(ah);
 
-    uint32_t period_time        = 0,
-             sample_per_period  = 0,
-             periods_per_buffer = 0;
-
-    if (_sample_spec_valid(samplerate, format, channels) == 0) {
-        return AUDIO_ERR_PARAMETER;
-    }
-
-    if (direction == AUDIO_DIRECTION_IN) {
-        if (!strcmp(latency, AUDIO_LATENCY_LOW)) {
-            AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_LOW");
-            period_time        = PERIOD_TIME_FOR_LOW_LATENCY_MSEC;
-            sample_per_period  = (samplerate * period_time) / 1000;
-            periods_per_buffer = PERIODS_PER_BUFFER_FASTMODE;
-            *prebuf            = 0;
-            *minreq            = -1;
-            *tlength           = -1;
-            *maxlength         = -1;
-            *fragsize          = sample_per_period * _audio_sample_size(format);
-        } else if (!strcmp(latency, AUDIO_LATENCY_MID)) {
-            AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_MID");
-            period_time        = PERIOD_TIME_FOR_MID_LATENCY_MSEC;
-            sample_per_period  = (samplerate * period_time) / 1000;
-            periods_per_buffer = PERIODS_PER_BUFFER_DEFAULT;
-            *prebuf            = 0;
-            *minreq            = -1;
-            *tlength           = -1;
-            *maxlength         = -1;
-            *fragsize          = sample_per_period * _audio_sample_size(format);
-        } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) {
-            AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_HIGH");
-            period_time        = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC;
-            sample_per_period  = (samplerate * period_time) / 1000;
-            periods_per_buffer = PERIODS_PER_BUFFER_CAPTURE;
-            *prebuf            = 0;
-            *minreq            = -1;
-            *tlength           = -1;
-            *maxlength         = -1;
-            *fragsize          = sample_per_period * _audio_sample_size(format);
-        } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) {
-            AUDIO_LOG_DEBUG("AUDIO_DIRECTION_IN, AUDIO_LATENCY_VOIP");
-            period_time        = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC;
-            sample_per_period  = (samplerate * period_time) / 1000;
-            periods_per_buffer = PERIODS_PER_BUFFER_VOIP;
-            *prebuf            = 0;
-            *minreq            = -1;
-            *tlength           = -1;
-            *maxlength         = -1;
-            *fragsize          = sample_per_period * _audio_sample_size(format);
-        } else {
-            AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency);
-            return AUDIO_ERR_UNDEFINED;
-        }
-    } else {  /* AUDIO_DIRECTION_OUT */
-        if (!strcmp(latency, AUDIO_LATENCY_LOW)) {
-            AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_LOW");
-            period_time        = PERIOD_TIME_FOR_LOW_LATENCY_MSEC;
-            sample_per_period  = (samplerate * period_time) / 1000;
-            periods_per_buffer = PERIODS_PER_BUFFER_FASTMODE;
-            *prebuf            = 0;
-            *minreq            = -1;
-            *tlength           = (samplerate / 10) * _audio_sample_size(format) * channels;  /* 100ms */
-            *maxlength         = -1;
-            *fragsize          = 0;
-        } else if (!strcmp(latency, AUDIO_LATENCY_MID)) {
-            AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_MID");
-            period_time        = PERIOD_TIME_FOR_MID_LATENCY_MSEC;
-            sample_per_period  = (samplerate * period_time) / 1000;
-            periods_per_buffer = PERIODS_PER_BUFFER_DEFAULT;
-            *prebuf            = 0;
-            *minreq            = -1;
-            *tlength           = (uint32_t) _audio_usec_to_bytes(200000, samplerate, format, channels);
-            *maxlength         = -1;
-            *fragsize          = -1;
-        } else if (!strcmp(latency, AUDIO_LATENCY_HIGH)) {
-            AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_HIGH");
-            period_time        = PERIOD_TIME_FOR_HIGH_LATENCY_MSEC;
-            sample_per_period  = (samplerate * period_time) / 1000;
-            periods_per_buffer = PERIODS_PER_BUFFER_PLAYBACK;
-            *prebuf            = 0;
-            *minreq            = -1;
-            *tlength           = (uint32_t) _audio_usec_to_bytes(400000, samplerate, format, channels);
-            *maxlength         = -1;
-            *fragsize          = -1;
-        } else if (!strcmp(latency, AUDIO_LATENCY_VOIP)) {
-            AUDIO_LOG_DEBUG("AUDIO_DIRECTION_OUT, AUDIO_LATENCY_VOIP");
-            period_time        = PERIOD_TIME_FOR_VOIP_LATENCY_MSEC;
-            sample_per_period  = (samplerate * period_time) / 1000;
-            periods_per_buffer = PERIODS_PER_BUFFER_VOIP;
-            *prebuf            = 0;
-            *minreq            = _audio_usec_to_bytes(20000, samplerate, format, channels);
-            *tlength           = _audio_usec_to_bytes(100000, samplerate, format, channels);
-            *maxlength         = -1;
-            *fragsize          = 0;
-        } else {
-            AUDIO_LOG_ERROR("hal-latency - The latency(%s) is undefined", latency);
-            return AUDIO_ERR_UNDEFINED;
-        }
-    }
+    free(ah);
+    ah = NULL;
 
-    AUDIO_LOG_INFO("hal-latency - return attr --> prebuf:%d, minreq:%d, tlength:%d, maxlength:%d, fragsize:%d", *prebuf, *minreq, *tlength, *maxlength, *fragsize);
     return AUDIO_RET_OK;
 }