[Feature][ZXW-134][audio]Add audio playback recording validation api
Only Configure:No
Affected branch:master
Affected module:audio
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update:Yes
Change-Id: I955bdf51d5e8084406bbbf56d6f28ee0ce3b5ce9
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/LICENSE
new file mode 100644
index 0000000..605b7ea
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MobileTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MobileTek Inc. and/or its licensors. Without
+the prior written permission of MobileTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MobileTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MobileTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MobileTek SOFTWARE")
+RECEIVED FROM MobileTek AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MobileTek EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MobileTek PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MobileTek SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MobileTek
+SOFTWARE. MobileTek SHALL ALSO NOT BE RESPONSIBLE FOR ANY MobileTek SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MobileTek'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MobileTek SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MobileTek'S OPTION, TO REVISE OR REPLACE THE
+MobileTek SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MobileTek FOR SUCH MobileTek SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/include/lynq-qser-audio.h b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/include/lynq-qser-audio.h
new file mode 100644
index 0000000..cc37b2e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/include/lynq-qser-audio.h
@@ -0,0 +1,45 @@
+/*******************************************************
+*
+* @brief: Add audio api
+* @details: add liblynq-qser-audio api
+* @author: yu.dong
+* @date: 2023.9.28
+* @version: V1.0
+* @copyright:Copyright (c) MobileTek
+*
+*********************************************/
+#ifndef LYNQ_QSER_AUDIO
+#define LYNQ_QSER_AUDIO
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sc_audio.h"
+
+sc_audio_handle_t playback_handle = SC_AUDIO_INVALID_HANDLE;
+sc_audio_handle_t capture_handle = SC_AUDIO_INVALID_HANDLE;
+
+typedef void (*_cb_onPlayer)(int);
+
+int qser_AudPlayer_Open(char* device, _cb_onPlayer cb_fun);
+int qser_AudPlayer_PlayFrmFile(int hdl, const char *fd, int offset);
+int qser_AudPlayer_Pause(int hdl);
+int qser_AudPlayer_Resume(int hdl);
+void qser_AudPlayer_Stop(int hdl);
+void qser_AudPlayer_Close(int hdl);
+
+int qser_AudRecorder_Open(char* device, _cb_onPlayer cb_fun);
+int qser_AudRecorder_StartRecord(int hdl, const char *fd, int offset);
+int qser_AudRecorder_Pause(void);
+int qser_AudRecorder_Resume(void);
+void qser_AudRecorder_Stop(void);
+void qser_AudRecorder_Close(void);
+
+void qser_Audio_Deinit(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/lynq-qser-audio.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/lynq-qser-audio.cpp
new file mode 100644
index 0000000..70b4e43
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/lynq-qser-audio.cpp
@@ -0,0 +1,546 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "liblog/lynq_deflog.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sc_audio.h"
+#include "lynq-qser-audio.h"
+
+#define AUDIO_INIT_MAX_TRY_CNT 100
+
+#define SC_AUDIO_BE_DAI_MIN -1
+#define SC_AUDIO_STREAM_FORMAT_INVALID 0
+
+/********************************************************************
+* @brief: _cb_onPlayer, typedef for a callback function that is called
+ when an audio operation is performed
+* @param int [IN]: The result of the audio operation, 0 if successful, non-zero if failed
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+typedef void (*_cb_onPlayer)(int);
+
+/********************************************************************
+* @brief: playback_state_cb, callback function that is called when the audio playback state changes
+* @param handle [IN]: sc_audio_handle_t, the handle of the audio device
+* @param params [IN]: void*, parameters for the callback function
+* @param state [IN]: sc_audio_playback_state_e, the current state of audio playback
+* @return : int, 0 if successful, non-zero if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int playback_state_cb (sc_audio_handle_t handle, void *params, sc_audio_playback_state_e state)
+{
+ LYINFLOG("playback_state_cb handle:0x%lx state:%d\n", handle, state);
+ return 0;
+}
+
+/********************************************************************
+* @brief: capture_state_cb, callback function that is called when the audio capture state changes
+* @param handle [IN]: sc_audio_handle_t, the handle of the audio device
+* @param params [IN]: void*, parameters for the callback function
+* @param state [IN]: sc_audio_capture_state_e, the current state of audio capture
+* @return : int, 0 if successful, non-zero if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int capture_state_cb (sc_audio_handle_t handle, void *params, sc_audio_capture_state_e state)
+{
+ LYINFLOG("capture_state_cb handle:0x%lx state:%d\n", handle, state);
+
+ return 0;
+}
+
+/********************************************************************
+* @brief: get_device_enum, function to convert a device string to its corresponding enum
+* @param device [IN]: const char*, the name of the device
+* @return : sc_audio_fe_pcm_dev_e, the enum corresponding to the device name
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+sc_audio_fe_pcm_dev_e get_device_enum(const char* device)
+{
+ if (strcmp(device, "device1") == 0)
+ {
+ return SC_AUDIO_FE_PCM_DEV_MULTIMEDIA1;
+ }
+ else if (strcmp(device, "device2") == 0)
+ {
+ return SC_AUDIO_FE_PCM_DEV_MULTIMEDIA2;
+ }
+ else
+ {
+ return SC_AUDIO_INVALID_HANDLE;
+ }
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_Open, open the audio device for playback
+* @param device [IN]: char* device, the audio device to be opened for playback
+* @param cb_fun [IN]: _cb_onPlayer, callback function to be called when the audio device is opened
+* @return : int, 0 if successful, non-zero if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudPlayer_Open(char* device, _cb_onPlayer cb_fun)
+{
+ int ret = SC_ERR_SUCCESS;
+ int retry_cnt = 0;
+ int audio_is_init = 0;
+
+ sc_audio_fe_pcm_dev_e device_enum = get_device_enum(device); // Convert device string to enum
+
+ while (AUDIO_INIT_MAX_TRY_CNT > retry_cnt)
+ {
+ ret = sc_audio_init();
+ if (SC_ERR_NOT_READY == ret)
+ {
+ LYINFLOG("audio service is not ready, try again, try count = %d\n", (retry_cnt + 1));
+ usleep(200 * 1000);
+ retry_cnt++;
+ }
+ else if (SC_ERR_SUCCESS == ret)
+ {
+ LYINFLOG("Success to initialize audio service\n");
+ audio_is_init = 1;
+ break;
+ }
+ else
+ {
+ LYINFLOG("Failed to initialize audio service, ret = %d\n", ret);
+ break;
+ }
+ }
+ if (1 != audio_is_init)
+ {
+ LYINFLOG("Failed to initialize audio service\n");
+ if (cb_fun != NULL)
+ {
+ cb_fun(-1);
+ }
+ return -1;
+ }
+
+ sc_audio_handle_t device_handle = sc_audio_playback_open(device_enum, SC_AUDIO_FE_PCM_DEV_MIN, SC_AUDIO_OWNER_ID_PLAYER);
+ if (SC_AUDIO_INVALID_HANDLE == device_handle)
+ {
+ LYINFLOG("Failed to open device: %s\n", device);
+ if (cb_fun != NULL)
+ {
+ cb_fun(-1);
+ }
+ return -1;
+ }
+
+ if (cb_fun != NULL)
+ {
+ cb_fun(0);
+ }
+ return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_PlayFrmFile, play audio from file
+* @param hdl [IN]: int, handle for the audio device or stream
+* @param fd [IN]: const char*, file descriptor of the audio file
+* @param offset [IN]: int, offset in the audio file
+* @return : success 0, failed -1
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudPlayer_PlayFrmFile(int hdl, const char *fd, int offset)
+{
+ int error_line;
+ sc_audio_pcm_config_t pcm_config;
+ int ret = 0;
+ sc_audio_owner_id owner_id = hdl;
+
+ if(NULL== fd || 0 == strlen(fd))
+ {
+ error_line = __LINE__;
+ goto exit;
+ }
+
+ playback_handle = sc_audio_playback_open(SC_AUDIO_FE_PCM_DEV_MULTIMEDIA2,SC_AUDIO_FE_PCM_DEV_MIN,owner_id);
+ if (SC_AUDIO_INVALID_HANDLE == playback_handle)
+ {
+ error_line = __LINE__;
+ goto exit;
+ }
+
+ if(strlen(fd))
+ {
+ ret = sc_audio_playback_file_prepare(playback_handle, fd, NULL, playback_state_cb, NULL);
+ if (SC_ERR_SUCCESS != ret)
+ {
+ error_line = __LINE__;
+ goto exit;
+ }
+ }
+
+ ret = sc_audio_playback_play(playback_handle);
+ if (SC_ERR_SUCCESS != ret)
+ {
+ error_line = __LINE__;
+ goto exit;
+ }
+
+ return 0;
+exit:
+ LYINFLOG("qser_AudPlayer_PlayFrmFile error_line=%d\n",error_line);
+ return -1;
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_Pause, pause the audio playback
+* @param hdl [IN]: int, handle for the audio device or stream
+* @return : success 0, failed -1
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudPlayer_Pause(int hdl)
+{
+ if (SC_AUDIO_INVALID_HANDLE == playback_handle)
+ {
+ LYINFLOG("qser_AudPlayer_Pause handle is invalid.\n");
+ return -1;
+ }
+ if( sc_audio_playback_pause(playback_handle))
+ {
+ LYINFLOG("qser_AudPlayer_Pause sc_audio_playback_pause fail.\n");
+ return -1;
+ }
+ return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_Resume, resume the audio playback
+* @param hdl [IN]: int, handle for the audio device or stream
+* @return : success 0, failed -1
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudPlayer_Resume(int hdl)
+{
+ if (SC_AUDIO_INVALID_HANDLE == playback_handle)
+ {
+ LYINFLOG("qser_AudPlayer_Resume handle is invalid.\n");
+ return -1;
+ }
+ if( sc_audio_playback_resume(playback_handle))
+ {
+ LYINFLOG("qser_AudPlayer_Resume sc_audio_playback_resume fail.\n");
+ return -1;
+ }
+ return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_Stop, stop the audio playback
+* @param hdl [IN]: int, handle for the audio device or stream
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+void qser_AudPlayer_Stop(int hdl)
+{
+ if (SC_AUDIO_INVALID_HANDLE == playback_handle)
+ {
+ LYINFLOG("qser_AudPlayer_Stop handle is invalid.\n");
+ return;
+ }
+
+ if( sc_audio_playback_stop(playback_handle))
+ {
+ LYINFLOG("qser_AudPlayer_Stop sc_audio_playback_stop fail.\n");
+ return;
+ }
+}
+
+/********************************************************************
+* @brief: qser_AudPlayer_Close, close the audio playback
+* @param hdl [IN]: int, handle for the audio device or stream
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+void qser_AudPlayer_Close(int hdl)
+{
+ if (SC_AUDIO_INVALID_HANDLE == playback_handle)
+ {
+ LYINFLOG("qser_AudPlayer_Close handle is invalid.\n");
+ return;
+ }
+ if( sc_audio_playback_stop(playback_handle))
+ {
+ LYINFLOG("qser_AudPlayer_Close sc_audio_playback_stop fail.\n");
+ return;
+ }
+ if( sc_audio_playback_close(playback_handle))
+ {
+ LYINFLOG("qser_AudPlayer_Close sc_audio_playback_close fail.\n");
+ return;
+ }
+
+ playback_handle = SC_AUDIO_INVALID_HANDLE;
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_Open, open the audio device for recording
+* @param device [IN]: char* device, the audio device to be opened for recording
+* @param cb_fun [IN]: _cb_onPlayer, callback function to be called when the audio device is opened
+* @return : int, 0 if successful, non-zero if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudRecorder_Open(char* device, _cb_onPlayer cb_fun)
+{
+ int ret = SC_ERR_SUCCESS;
+ int retry_cnt = 0;
+ int audio_is_init = 0;
+
+ sc_audio_fe_pcm_dev_e device_enum = get_device_enum(device); // Convert device string to enum
+
+ while (AUDIO_INIT_MAX_TRY_CNT > retry_cnt)
+ {
+ ret = sc_audio_init();
+ if (SC_ERR_NOT_READY == ret)
+ {
+ LYINFLOG("audio service is not ready, try again, try count = %d\n", (retry_cnt + 1));
+ usleep(200 * 1000);
+ retry_cnt++;
+ }
+ else if (SC_ERR_SUCCESS == ret)
+ {
+ LYINFLOG("Success to initialize audio service\n");
+ audio_is_init = 1;
+ break;
+ }
+ else
+ {
+ LYINFLOG("Failed to initialize audio service, ret = %d\n", ret);
+ break;
+ }
+ }
+ if (1 != audio_is_init)
+ {
+ LYINFLOG("Failed to initialize audio service\n");
+ if (cb_fun != NULL)
+ {
+ cb_fun(-1);
+ }
+ return -1;
+ }
+
+ sc_audio_handle_t device_handle = sc_audio_playback_open(device_enum, SC_AUDIO_FE_PCM_DEV_MIN, SC_AUDIO_OWNER_ID_PLAYER);
+ if (SC_AUDIO_INVALID_HANDLE == device_handle)
+ {
+ LYINFLOG("Failed to open device: %s\n", device);
+ if (cb_fun != NULL)
+ {
+ cb_fun(-1);
+ }
+ return -1;
+ }
+
+ if (cb_fun != NULL)
+ {
+ cb_fun(0);
+ }
+ return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_StartRecord, play a file with capture
+* @param hdl [IN]: int, handle for the audio device or stream
+* @param fd [IN]: const char*, file descriptor of the audio file
+* @param offset [IN]: int, offset in the audio file
+* @return : int, 0 if successful, -1 if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudRecorder_StartRecord(int hdl, const char *fd, int offset)
+{
+ int error_line;
+ sc_audio_pcm_config_t pcm_config;
+ int ret = 0;
+ sc_audio_owner_id owner_id = hdl;
+
+ if(NULL== fd || 0 == strlen(fd))
+ {
+ error_line = __LINE__;
+ goto exit;
+ }
+
+ capture_handle = sc_audio_capture_open(SC_AUDIO_FE_PCM_DEV_MULTIMEDIA1,SC_AUDIO_BE_DAI_MIN);
+ if (SC_AUDIO_INVALID_HANDLE == capture_handle)
+ {
+ error_line = __LINE__;
+ goto exit;
+ }
+
+ memset(&pcm_config, 0, sizeof(sc_audio_pcm_config_t));
+
+ ret = sc_audio_capture_file_prepare(capture_handle, fd, SC_AUDIO_STREAM_FORMAT_INVALID, NULL, capture_state_cb, NULL);
+ if (SC_ERR_SUCCESS != ret)
+ {
+ error_line = __LINE__;
+ goto exit;
+ }
+
+ ret = sc_audio_capture_record(capture_handle);
+ if (SC_ERR_SUCCESS != ret)
+ {
+ error_line = __LINE__;
+ goto exit;
+ }
+
+ return 0;
+exit:
+ LYINFLOG("qser_AudRecorder_StartRecord error_line=%d\n",error_line);
+ return -1;
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_Pause, pause the audio capture
+* @return : int, 0 if successful, -1 if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudRecorder_Pause(void)
+{
+ if (SC_AUDIO_INVALID_HANDLE == capture_handle)
+ {
+ LYINFLOG("qser_AudRecorder_Pause capture_handle is invalid.\n");
+ return -1;
+ }
+ if( sc_audio_capture_pause(capture_handle))
+ {
+ LYINFLOG("qser_AudRecorder_Pause sc_audio_capture_pause fail.\n");
+ return -1;
+ }
+ return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_Resume, resume the audio capture
+* @return : int, 0 if successful, -1 if failed
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+int qser_AudRecorder_Resume(void)
+{
+ if (SC_AUDIO_INVALID_HANDLE == capture_handle)
+ {
+ LYINFLOG("qser_AudRecorder_Resume capture_handle is invalid.\n");
+ return -1;
+ }
+ if( sc_audio_capture_resume(capture_handle))
+ {
+ LYINFLOG("qser_AudRecorder_Resume sc_audio_capture_resume fail.\n");
+ return -1;
+ }
+ return 0;
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_Stop, stop the audio capture
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+void qser_AudRecorder_Stop(void)
+{
+ if (SC_AUDIO_INVALID_HANDLE == capture_handle)
+ {
+ LYINFLOG("qser_AudRecorder_Stop capture_handle is invalid.\n");
+ return;
+ }
+ if( sc_audio_capture_stop(capture_handle))
+ {
+ LYINFLOG("qser_AudRecorder_Stop sc_audio_capture_stop fail.\n");
+ return;
+ }
+}
+
+/********************************************************************
+* @brief: qser_AudRecorder_Close, close the audio capture
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+void qser_AudRecorder_Close(void)
+{
+ if (SC_AUDIO_INVALID_HANDLE == capture_handle)
+ {
+ LYINFLOG("qser_AudRecorder_Close capture_handle is invalid.\n");
+ return;
+ }
+ if( sc_audio_capture_stop(capture_handle))
+ {
+ LYINFLOG("qser_AudRecorder_Close sc_audio_capture_stop fail.\n");
+ return;
+ }
+ if( sc_audio_capture_close(capture_handle))
+ {
+ LYINFLOG("qser_AudRecorder_Close sc_audio_capture_close fail.\n");
+ return;
+ }
+
+ capture_handle = SC_AUDIO_INVALID_HANDLE;
+}
+
+/********************************************************************
+* @brief: qser_Audio_Deinit, deinitialize the audio system, stop and close any active playback or capture,
+ and uninitialize the audio system
+* @return : void
+* @todo: NA
+* @see: NA
+* @warning: NA
+*********************************************************************/
+void qser_Audio_Deinit(void)
+{
+ if(SC_AUDIO_INVALID_HANDLE != playback_handle)
+ {
+ sc_audio_playback_stop(playback_handle);
+ sc_audio_playback_close(playback_handle);
+ playback_handle = SC_AUDIO_INVALID_HANDLE;
+ }
+
+ if(SC_AUDIO_INVALID_HANDLE != capture_handle)
+ {
+ sc_audio_capture_stop(capture_handle);
+ sc_audio_capture_close(capture_handle);
+ capture_handle = SC_AUDIO_INVALID_HANDLE;
+ }
+
+ sc_audio_uninit();
+}
+
+DEFINE_LYNQ_LIB_LOG(LYNQ_AUDIO)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/makefile
new file mode 100644
index 0000000..cef3517
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-audio/makefile
@@ -0,0 +1,48 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -std=gnu++14 \
+ -g -Os \
+ -flto \
+ -fPIC \
+ -fpermissive \
+
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I$(LOCAL_PATH)/include \
+ -I$(LOCAL_PATH)/ \
+ -I$(ROOT)$(includedir)/logger \
+ -I$(ROOT)$(includedir)/liblog \
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+ -lstdc++ \
+ -llynq-log \
+ -lmedia \
+
+SOURCES = lynq-qser-audio.cpp
+LIBRARY = liblynq-qser-audio.so
+
+OBJECTS=$(SOURCES:.cpp=.o)
+
+all: $(LIBRARY)
+
+$(LIBRARY): $(OBJECTS)
+ $(CXX) -shared -o $@ $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES)
+
+%.o : %.cpp
+ $(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -fPIC -c $<
+
+install:
+ mkdir -p $(ROOT)$(base_libdir)/
+ install $(LIBRARY) $(ROOT)$(base_libdir)/
+ mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk
+
+clean:
+ $(RM) $(OBJECTS) $(LIBRARY)
+
+