audio-io sync branch of tizen_2.4
[platform/core/api/audio-io.git] / src / audio_io.c
index 6b29ada..54a7f1e 100644 (file)
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
-* limitations under the License. 
+* limitations under the License.
 */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <mm.h>
-#include <audio_io_private.h>
+#include "audio_io_private.h"
 #include <dlog.h>
 
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
 #define LOG_TAG "TIZEN_N_AUDIO_IO"
-/* TODO : it will be added after updating libmm-sound */
-//#include <mm_sound_pcm_async.h>
+
+#include <mm_sound_pcm_async.h>
 /*
 * Internal Implementation
 */
 /* Audio In */
 int audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input)
 {
-       return audio_in_create_private (sample_rate, channel, type, input);
+       return audio_in_create_private (sample_rate, channel, type, SUPPORT_SOURCE_TYPE_DEFAULT, input);
 }
 
 int audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h* input)
 {
-       return audio_in_create_private (sample_rate, channel, type, input);
+       return audio_in_create_private (sample_rate, channel, type, SUPPORT_SOURCE_TYPE_LOOPBACK, input);
 }
 
 int audio_in_destroy(audio_in_h input)
@@ -53,7 +53,11 @@ int audio_in_destroy(audio_in_h input)
        audio_in_s *handle = (audio_in_s *) input;
        int ret = MM_ERROR_NONE;
 
-       ret = mm_sound_pcm_capture_close(handle->mm_handle);
+       if (handle->is_async) {
+               ret = mm_sound_pcm_capture_close_async(handle->mm_handle);
+       } else {
+               ret = mm_sound_pcm_capture_close(handle->mm_handle);
+       }
        if (ret != MM_ERROR_NONE) {
                free(handle);
                return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
@@ -70,7 +74,12 @@ int audio_in_prepare(audio_in_h input)
        audio_in_s *handle = (audio_in_s *) input;
        int ret = MM_ERROR_NONE;
 
-       ret = mm_sound_pcm_capture_start(handle->mm_handle);
+       if (handle->is_async) {
+               ret = mm_sound_pcm_capture_start_async(handle->mm_handle);
+       } else {
+               ret = mm_sound_pcm_capture_start(handle->mm_handle);
+       }
+
        if (ret != MM_ERROR_NONE) {
                return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
        }
@@ -85,7 +94,11 @@ int audio_in_unprepare(audio_in_h input)
        audio_in_s *handle = (audio_in_s *) input;
        int ret = MM_ERROR_NONE;
 
-       ret = mm_sound_pcm_capture_stop(handle->mm_handle);
+       if (handle->is_async) {
+               ret = mm_sound_pcm_capture_stop_async(handle->mm_handle);
+       } else {
+               ret = mm_sound_pcm_capture_stop(handle->mm_handle);
+       }
        if (ret != MM_ERROR_NONE) {
                return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
        }
@@ -100,7 +113,11 @@ int audio_in_flush(audio_in_h input)
        audio_in_s *handle = (audio_in_s *) input;
        int ret = MM_ERROR_NONE;
 
-       ret = mm_sound_pcm_capture_flush(handle->mm_handle);
+       if (handle->is_async) {
+               ret = mm_sound_pcm_capture_flush_async(handle->mm_handle);
+       } else {
+               ret = mm_sound_pcm_capture_flush(handle->mm_handle);
+       }
        if (ret != MM_ERROR_NONE) {
                return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
        }
@@ -117,6 +134,11 @@ int audio_in_read(audio_in_h input, void *buffer, unsigned int length )
        int ret = 0;
        int result = 0;
 
+       if (handle->is_async) {
+               LOGE ("audio_in_read doesn't operate in async mode!!!, use audio_in_peek/audio_in_drop instead");
+               return AUDIO_IO_ERROR_INVALID_OPERATION;
+       }
+
        ret = mm_sound_pcm_capture_read(handle->mm_handle, (void*) buffer, length);
        if (ret > 0)
                return ret;
@@ -214,6 +236,11 @@ int audio_in_ignore_session(audio_in_h input)
        audio_in_s  * handle = (audio_in_s  *) input;
        int ret = 0;
 
+       if (handle->is_async) {
+               LOGE ("Not supported in async mode");
+               return AUDIO_IO_ERROR_INVALID_OPERATION;
+       }
+
        ret = mm_sound_pcm_capture_ignore_session(handle->mm_handle);
        if (ret != MM_ERROR_NONE) {
                return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
@@ -225,26 +252,74 @@ int audio_in_ignore_session(audio_in_h input)
 
 int audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* userdata)
 {
-/* TODO : it will be added after updating libmm-sound */
-       return AUDIO_IO_ERROR_NONE;
+       AUDIO_IO_NULL_ARG_CHECK(input);
+       AUDIO_IO_NULL_ARG_CHECK(callback);
+       return audio_in_set_callback_private(input, callback, userdata);
 }
 
 int audio_in_unset_stream_cb(audio_in_h input)
 {
-/* TODO : it will be added after updating libmm-sound */
-       return AUDIO_IO_ERROR_NONE;
+       AUDIO_IO_NULL_ARG_CHECK(input);
+       return audio_in_set_callback_private(input, NULL, NULL);
 }
 
 int audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length)
 {
-/* TODO : it will be added after updating libmm-sound */
-       return AUDIO_IO_ERROR_NONE;
+       AUDIO_IO_NULL_ARG_CHECK(input);
+       AUDIO_IO_NULL_ARG_CHECK(buffer);
+       audio_in_s *handle = (audio_in_s *) input;
+       int ret = 0;
+       int result = 0;
+       LOGE("handle->is_async : %d", handle->is_async);
+       if (!handle->is_async) {
+               LOGE ("audio_in_peek doesn't operate in poll mode!!!, use audio_in_read instead");
+               return AUDIO_IO_ERROR_INVALID_OPERATION;
+       }
+
+       LOGE("before mm_sound_pcm_capture_peek(handle[%p], buffer[%p], length[%d])", handle->mm_handle, buffer, length);
+       ret = mm_sound_pcm_capture_peek(handle->mm_handle, buffer, length);
+       LOGE("after mm_sound_pcm_capture_peek() ret[%d]", ret);
+       switch(ret)
+       {
+       case MM_ERROR_SOUND_INVALID_STATE:
+               result = AUDIO_IO_ERROR_INVALID_OPERATION;
+               LOGE("[%s] (0x%08x) : Not recording started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION);
+               break;
+       default:
+               result = __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
+               break;
+       }
+       return result;
 }
 
 int audio_in_drop(audio_in_h input)
 {
-/* TODO : it will be added after updating libmm-sound */
-       return AUDIO_IO_ERROR_NONE;
+       AUDIO_IO_NULL_ARG_CHECK(input);
+       audio_in_s *handle = (audio_in_s *) input;
+       int ret = 0;
+       int result = 0;
+
+       if (!handle->is_async) {
+               LOGE ("audio_in_drop doesn't operate in poll mode!!!, use audio_in_read instead");
+               return AUDIO_IO_ERROR_INVALID_OPERATION;
+       }
+
+       ret = mm_sound_pcm_capture_drop(handle->mm_handle);
+       if (ret == MM_ERROR_NONE) {
+               return ret;
+       }
+
+       switch(ret)
+       {
+       case MM_ERROR_SOUND_INVALID_STATE:
+               result = AUDIO_IO_ERROR_INVALID_OPERATION;
+               LOGE("[%s] (0x%08x) : Not recording started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION);
+               break;
+       default:
+               result = __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
+               break;
+       }
+       return result;
 }
 
 
@@ -260,7 +335,11 @@ int audio_out_destroy(audio_out_h output)
        audio_out_s *handle = (audio_out_s *) output;
        int ret = MM_ERROR_NONE;
 
-       ret = mm_sound_pcm_play_close(handle->mm_handle);
+       if (handle->is_async) {
+               ret = mm_sound_pcm_play_close_async(handle->mm_handle);
+       } else {
+               ret = mm_sound_pcm_play_close(handle->mm_handle);
+       }
        if (ret != MM_ERROR_NONE) {
                free(handle);
                return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
@@ -277,7 +356,12 @@ int audio_out_prepare(audio_out_h output)
        audio_out_s *handle = (audio_out_s *) output;
        int ret = MM_ERROR_NONE;
 
-       ret = mm_sound_pcm_play_start(handle->mm_handle);
+       if (handle->is_async) {
+               ret = mm_sound_pcm_play_start_async(handle->mm_handle);
+       } else {
+               ret = mm_sound_pcm_play_start(handle->mm_handle);
+       }
+
        if (ret != MM_ERROR_NONE) {
                return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
        }
@@ -292,7 +376,12 @@ int audio_out_unprepare(audio_out_h output)
        audio_out_s *handle = (audio_out_s *) output;
        int ret = MM_ERROR_NONE;
 
-       ret = mm_sound_pcm_play_stop(handle->mm_handle);
+       if (handle->is_async) {
+               ret = mm_sound_pcm_play_stop_async(handle->mm_handle);
+       } else {
+               ret = mm_sound_pcm_play_stop(handle->mm_handle);
+       }
+
        if (ret != MM_ERROR_NONE) {
                return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
        }
@@ -307,7 +396,12 @@ int audio_out_drain(audio_out_h output)
        audio_out_s *handle = (audio_out_s *) output;
        int ret = MM_ERROR_NONE;
 
-       ret = mm_sound_pcm_play_drain(handle->mm_handle);
+       if (handle->is_async) {
+               ret = mm_sound_pcm_play_drain_async(handle->mm_handle);
+       } else {
+               ret = mm_sound_pcm_play_drain(handle->mm_handle);
+       }
+
        if (ret != MM_ERROR_NONE) {
                return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
        }
@@ -322,7 +416,12 @@ int audio_out_flush(audio_out_h output)
        audio_out_s *handle = (audio_out_s *) output;
        int ret = MM_ERROR_NONE;
 
-       ret = mm_sound_pcm_play_flush(handle->mm_handle);
+       if (handle->is_async) {
+               ret = mm_sound_pcm_play_flush_async(handle->mm_handle);
+       } else {
+               ret = mm_sound_pcm_play_flush(handle->mm_handle);
+       }
+
        if (ret != MM_ERROR_NONE) {
                return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
        }
@@ -338,11 +437,15 @@ int audio_out_write(audio_out_h output, void* buffer, unsigned int length)
        audio_out_s *handle = (audio_out_s *) output;
        int ret = MM_ERROR_NONE;
 
-       ret = mm_sound_pcm_play_write(handle->mm_handle, (void*) buffer, length);
-       if (ret > 0) {
-               LOGI("[%s] (%d/%d) bytes written" ,__FUNCTION__, ret, length);
-               return ret;
+       if (handle->is_async) {
+               ret = mm_sound_pcm_play_write_async(handle->mm_handle, (void*) buffer, length);
+       } else {
+               ret = mm_sound_pcm_play_write(handle->mm_handle, (void*) buffer, length);
        }
+
+       if (ret > 0)
+               return ret;
+
        switch(ret)
        {
                case MM_ERROR_SOUND_INVALID_STATE:
@@ -356,7 +459,6 @@ int audio_out_write(audio_out_h output, void* buffer, unsigned int length)
        return ret;
 }
 
-
 int audio_out_get_buffer_size(audio_out_h output, int *size)
 {
        AUDIO_IO_NULL_ARG_CHECK(output);
@@ -369,7 +471,6 @@ int audio_out_get_buffer_size(audio_out_h output, int *size)
        return AUDIO_IO_ERROR_NONE;
 }
 
-
 int audio_out_get_sample_rate(audio_out_h output, int *sample_rate)
 {
        AUDIO_IO_NULL_ARG_CHECK(output);
@@ -382,7 +483,6 @@ int audio_out_get_sample_rate(audio_out_h output, int *sample_rate)
        return AUDIO_IO_ERROR_NONE;
 }
 
-
 int audio_out_get_channel(audio_out_h output, audio_channel_e *channel)
 {
        AUDIO_IO_NULL_ARG_CHECK(output);
@@ -395,7 +495,6 @@ int audio_out_get_channel(audio_out_h output, audio_channel_e *channel)
        return AUDIO_IO_ERROR_NONE;
 }
 
-
 int audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type)
 {
        AUDIO_IO_NULL_ARG_CHECK(output);
@@ -408,7 +507,6 @@ int audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type)
        return AUDIO_IO_ERROR_NONE;
 }
 
-
 int audio_out_get_sound_type(audio_out_h output, sound_type_e *type)
 {
        AUDIO_IO_NULL_ARG_CHECK(output);
@@ -452,6 +550,11 @@ int audio_out_ignore_session(audio_out_h output)
        audio_out_s *handle = (audio_out_s *) output;
        int ret = 0;
 
+       if (handle->is_async) {
+               LOGE ("Not supported in async mode");
+               return AUDIO_IO_ERROR_INVALID_OPERATION;
+       }
+
        ret = mm_sound_pcm_play_ignore_session(handle->mm_handle);
        if (ret != MM_ERROR_NONE) {
                return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
@@ -463,12 +566,13 @@ int audio_out_ignore_session(audio_out_h output)
 
 int audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* userdata)
 {
-/* TODO : it will be added after updating libmm-sound */
-       return AUDIO_IO_ERROR_NONE;
+       AUDIO_IO_NULL_ARG_CHECK(output);
+       AUDIO_IO_NULL_ARG_CHECK(callback);
+       return audio_out_set_callback_private(output, callback, userdata);
 }
 
 int audio_out_unset_stream_cb(audio_out_h output)
 {
-/* TODO : it will be added after updating libmm-sound */
-       return AUDIO_IO_ERROR_NONE;
+       AUDIO_IO_NULL_ARG_CHECK(output);
+       return audio_out_set_callback_private(output, NULL, NULL);
 }