--- /dev/null
+CMakeCache.txt
+*/CMakeFiles/*
+*.cmake
+CMakeFiles*
+*.a
+*.so
+Testing
+cmake.depends
+cmake.check_depends
+cmake.check_cache
+core
+core.*
+gmon.out
+install_manifest.txt
+*~
+.kdev_include_paths
+src.kdev4
+.cproject
+.project
+tet_captured
+tet_lock
+*.pc
+Makefile
+*-test
+*-test_*
+*tester.c
+.gitattributes
Kangho Hur <kanho.hur@samsung.com>
Seungkeun Lee <sngn.lee@samsung.com>
Seungbae Shin <seungbae.shin at samsung.com>
+SeonYoung Jeong <sy7787.jeong@samsung.com>
+JeongYeon Kim <jeongyeon.kim@samsung.com>
-
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
SET(fw_name "capi-media-audio-io")
SET(INC_DIR include)
INCLUDE_DIRECTORIES(${INC_DIR})
-SET(dependents "dlog mm-sound capi-base-common capi-media-sound-manager")
+SET(dependents "dlog mm-sound capi-base-common capi-media-sound-manager mm-common mm-session libpulse vconf")
SET(pc_dependents "capi-base-common capi-media-sound-manager")
INCLUDE(FindPkgConfig)
pkg_check_modules(${fw_name} REQUIRED ${dependents})
FOREACH(flag ${${fw_name}_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
ENDFOREACH(flag)
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror")
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -fPIC -Wall -Werror -std=c++0x")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+
IF("${ARCH}" STREQUAL "arm")
ADD_DEFINITIONS("-DTARGET")
ENDIF("${ARCH}" STREQUAL "arm")
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}")
+aux_source_directory(src/cpp CPPSOURCES)
aux_source_directory(src SOURCES)
-ADD_LIBRARY(${fw_name} SHARED ${SOURCES})
+
+SET(ALL_SRC ${SOURCES} ${CPPSOURCES})
+
+ADD_LIBRARY(${fw_name} SHARED ${ALL_SRC})
SET_TARGET_PROPERTIES(${fw_name}
PROPERTIES
DIRECTORY ${INC_DIR}/ DESTINATION include/media
FILES_MATCHING
PATTERN "*_private.h" EXCLUDE
+ PATTERN "*cpp*.h" EXCLUDE
+ PATTERN "C*.h" EXCLUDE
+ PATTERN "I*.h" EXCLUDE
PATTERN "${INC_DIR}/*.h"
)
)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
-ADD_SUBDIRECTORY(test)
+#ADD_SUBDIRECTORY(test)
IF(UNIX)
ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution)
ADD_CUSTOM_COMMAND(
- DEPENDS clean
+ DEPENDS clean
COMMENT "distribution clean"
COMMAND find
- ARGS .
+ ARGS .
-not -name config.cmake -and \(
-name tester.c -or
-name Testing -or
)
ENDIF(UNIX)
-
--- /dev/null
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+ Apache License\r
+ Version 2.0, January 2004\r
+ http://www.apache.org/licenses/\r
+\r
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+ 1. Definitions.\r
+\r
+ "License" shall mean the terms and conditions for use, reproduction,\r
+ and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+ "Licensor" shall mean the copyright owner or entity authorized by\r
+ the copyright owner that is granting the License.\r
+\r
+ "Legal Entity" shall mean the union of the acting entity and all\r
+ other entities that control, are controlled by, or are under common\r
+ control with that entity. For the purposes of this definition,\r
+ "control" means (i) the power, direct or indirect, to cause the\r
+ direction or management of such entity, whether by contract or\r
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+ outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+ "You" (or "Your") shall mean an individual or Legal Entity\r
+ exercising permissions granted by this License.\r
+\r
+ "Source" form shall mean the preferred form for making modifications,\r
+ including but not limited to software source code, documentation\r
+ source, and configuration files.\r
+\r
+ "Object" form shall mean any form resulting from mechanical\r
+ transformation or translation of a Source form, including but\r
+ not limited to compiled object code, generated documentation,\r
+ and conversions to other media types.\r
+\r
+ "Work" shall mean the work of authorship, whether in Source or\r
+ Object form, made available under the License, as indicated by a\r
+ copyright notice that is included in or attached to the work\r
+ (an example is provided in the Appendix below).\r
+\r
+ "Derivative Works" shall mean any work, whether in Source or Object\r
+ form, that is based on (or derived from) the Work and for which the\r
+ editorial revisions, annotations, elaborations, or other modifications\r
+ represent, as a whole, an original work of authorship. For the purposes\r
+ of this License, Derivative Works shall not include works that remain\r
+ separable from, or merely link (or bind by name) to the interfaces of,\r
+ the Work and Derivative Works thereof.\r
+\r
+ "Contribution" shall mean any work of authorship, including\r
+ the original version of the Work and any modifications or additions\r
+ to that Work or Derivative Works thereof, that is intentionally\r
+ submitted to Licensor for inclusion in the Work by the copyright owner\r
+ or by an individual or Legal Entity authorized to submit on behalf of\r
+ the copyright owner. For the purposes of this definition, "submitted"\r
+ means any form of electronic, verbal, or written communication sent\r
+ to the Licensor or its representatives, including but not limited to\r
+ communication on electronic mailing lists, source code control systems,\r
+ and issue tracking systems that are managed by, or on behalf of, the\r
+ Licensor for the purpose of discussing and improving the Work, but\r
+ excluding communication that is conspicuously marked or otherwise\r
+ designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+ "Contributor" shall mean Licensor and any individual or Legal Entity\r
+ on behalf of whom a Contribution has been received by Licensor and\r
+ subsequently incorporated within the Work.\r
+\r
+ 2. Grant of Copyright License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ copyright license to reproduce, prepare Derivative Works of,\r
+ publicly display, publicly perform, sublicense, and distribute the\r
+ Work and such Derivative Works in Source or Object form.\r
+\r
+ 3. Grant of Patent License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ (except as stated in this section) patent license to make, have made,\r
+ use, offer to sell, sell, import, and otherwise transfer the Work,\r
+ where such license applies only to those patent claims licensable\r
+ by such Contributor that are necessarily infringed by their\r
+ Contribution(s) alone or by combination of their Contribution(s)\r
+ with the Work to which such Contribution(s) was submitted. If You\r
+ institute patent litigation against any entity (including a\r
+ cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+ or a Contribution incorporated within the Work constitutes direct\r
+ or contributory patent infringement, then any patent licenses\r
+ granted to You under this License for that Work shall terminate\r
+ as of the date such litigation is filed.\r
+\r
+ 4. Redistribution. You may reproduce and distribute copies of the\r
+ Work or Derivative Works thereof in any medium, with or without\r
+ modifications, and in Source or Object form, provided that You\r
+ meet the following conditions:\r
+\r
+ (a) You must give any other recipients of the Work or\r
+ Derivative Works a copy of this License; and\r
+\r
+ (b) You must cause any modified files to carry prominent notices\r
+ stating that You changed the files; and\r
+\r
+ (c) You must retain, in the Source form of any Derivative Works\r
+ that You distribute, all copyright, patent, trademark, and\r
+ attribution notices from the Source form of the Work,\r
+ excluding those notices that do not pertain to any part of\r
+ the Derivative Works; and\r
+\r
+ (d) If the Work includes a "NOTICE" text file as part of its\r
+ distribution, then any Derivative Works that You distribute must\r
+ include a readable copy of the attribution notices contained\r
+ within such NOTICE file, excluding those notices that do not\r
+ pertain to any part of the Derivative Works, in at least one\r
+ of the following places: within a NOTICE text file distributed\r
+ as part of the Derivative Works; within the Source form or\r
+ documentation, if provided along with the Derivative Works; or,\r
+ within a display generated by the Derivative Works, if and\r
+ wherever such third-party notices normally appear. The contents\r
+ of the NOTICE file are for informational purposes only and\r
+ do not modify the License. You may add Your own attribution\r
+ notices within Derivative Works that You distribute, alongside\r
+ or as an addendum to the NOTICE text from the Work, provided\r
+ that such additional attribution notices cannot be construed\r
+ as modifying the License.\r
+\r
+ You may add Your own copyright statement to Your modifications and\r
+ may provide additional or different license terms and conditions\r
+ for use, reproduction, or distribution of Your modifications, or\r
+ for any such Derivative Works as a whole, provided Your use,\r
+ reproduction, and distribution of the Work otherwise complies with\r
+ the conditions stated in this License.\r
+\r
+ 5. Submission of Contributions. Unless You explicitly state otherwise,\r
+ any Contribution intentionally submitted for inclusion in the Work\r
+ by You to the Licensor shall be under the terms and conditions of\r
+ this License, without any additional terms or conditions.\r
+ Notwithstanding the above, nothing herein shall supersede or modify\r
+ the terms of any separate license agreement you may have executed\r
+ with Licensor regarding such Contributions.\r
+\r
+ 6. Trademarks. This License does not grant permission to use the trade\r
+ names, trademarks, service marks, or product names of the Licensor,\r
+ except as required for reasonable and customary use in describing the\r
+ origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+ 7. Disclaimer of Warranty. Unless required by applicable law or\r
+ agreed to in writing, Licensor provides the Work (and each\r
+ Contributor provides its Contributions) on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+ implied, including, without limitation, any warranties or conditions\r
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+ PARTICULAR PURPOSE. You are solely responsible for determining the\r
+ appropriateness of using or redistributing the Work and assume any\r
+ risks associated with Your exercise of permissions under this License.\r
+\r
+ 8. Limitation of Liability. In no event and under no legal theory,\r
+ whether in tort (including negligence), contract, or otherwise,\r
+ unless required by applicable law (such as deliberate and grossly\r
+ negligent acts) or agreed to in writing, shall any Contributor be\r
+ liable to You for damages, including any direct, indirect, special,\r
+ incidental, or consequential damages of any character arising as a\r
+ result of this License or out of the use or inability to use the\r
+ Work (including but not limited to damages for loss of goodwill,\r
+ work stoppage, computer failure or malfunction, or any and all\r
+ other commercial damages or losses), even if such Contributor\r
+ has been advised of the possibility of such damages.\r
+\r
+ 9. Accepting Warranty or Additional Liability. While redistributing\r
+ the Work or Derivative Works thereof, You may choose to offer,\r
+ and charge a fee for, acceptance of support, warranty, indemnity,\r
+ or other liability obligations and/or rights consistent with this\r
+ License. However, in accepting such obligations, You may act only\r
+ on Your own behalf and on Your sole responsibility, not on behalf\r
+ of any other Contributor, and only if You agree to indemnify,\r
+ defend, and hold each Contributor harmless for any liability\r
+ incurred by, or claims asserted against, such Contributor by reason\r
+ of your accepting any such warranty or additional liability.\r
+\r
+ END OF TERMS AND CONDITIONS\r
+\r
+ APPENDIX: How to apply the Apache License to your work.\r
+\r
+ To apply the Apache License to your work, attach the following\r
+ boilerplate notice, with the fields enclosed by brackets "[]"\r
+ replaced with your own identifying information. (Don't include\r
+ the brackets!) The text should be enclosed in the appropriate\r
+ comment syntax for the file format. We also recommend that a\r
+ file or class name and description of purpose be included on the\r
+ same "printed page" as the copyright notice for easier\r
+ identification within third-party archives.\r
+\r
+ Copyright [yyyy] [name of copyright owner]\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+\r
+\r
+++ /dev/null
-Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- 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.
-
-
-
/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 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.
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_AUDIO_IO_CAUDIOERROR_H__
+#define __TIZEN_MEDIA_AUDIO_IO_CAUDIOERROR_H__
+
+
+#ifdef __cplusplus
+
+
+namespace tizen_media_audio {
+
+
+ /**
+ * Audio Error
+ */
+ class CAudioError {
+ public:
+ /* Constants Definition */
+ static const unsigned int MSG_LENGTH = 512;
+
+ enum EError {
+ ERROR_NONE,
+
+ ERROR_INVALID_ARGUMENT,
+ ERROR_INVALID_HANDLE,
+ ERROR_INVALID_SAMPLERATE,
+ ERROR_INVALID_CHANNEL,
+ ERROR_INVALID_FORMAT,
+ ERROR_INVALID_POINTER,
+ ERROR_INVALID_OPERATION,
+
+ ERROR_NOT_INITIALIZED,
+ ERROR_NOT_SUPPORTED,
+
+ ERROR_PERMISSION_DENIED,
+
+ ERROR_DEVICE_NOT_OPENED,
+ ERROR_DEVICE_NOT_CLOSED,
+
+ ERROR_OUT_OF_MEMORY,
+ ERROR_INTERNAL_OPERATION,
+ ERROR_FAILED_OPERATION,
+
+ ERROR_POLICY_BLOCKED,
+ ERROR_POLICY_INTERRUPTED,
+ ERROR_POLICY_DUPLICATED,
+
+ ERROR_MAX
+ };
+
+ private:
+ /* Members */
+ static EError mLastError;
+ static char mLastErrorMsg[MSG_LENGTH];
+
+ EError mError;
+ char mErrorMsg[MSG_LENGTH];
+
+ const char* _convertErrorToString(EError err);
+
+ public:
+ /* Constructor & Destructor */
+ CAudioError(EError err);
+ CAudioError(EError err, const char* fileName, const char* parentFunc, int lineNum);
+ CAudioError(EError err, const char* msg, const char* fileName, const char* parentFunc, int lineNum);
+ //CAudioError(CAudioError& err);
+ ~CAudioError();
+
+ /* Static Methods */
+ static EError getLastError();
+ static const char* getLastErrorMsg();
+
+ /* Setter & Getter */
+ EError getError();
+ const char* getErrorMsg();
+
+ /* Overrided Operation */
+ CAudioError& operator = (const EError err);
+ CAudioError& operator = (const CAudioError& err);
+ bool operator != (const EError err);
+ bool operator == (const EError err);
+// friend bool operator == (const CAudioError& src, const EError& err);
+ };
+
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_CPP_OBJECTS_IO_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_AUDIO_IO_CAUDIO_IO_H__
+#define __TIZEN_MEDIA_AUDIO_IO_CAUDIO_IO_H__
+
+
+#ifdef __cplusplus
+
+
+namespace tizen_media_audio {
+
+
+ /**
+ * Abstract Class
+ * You can't take this object directly.
+ */
+ class IPulseStreamListener;
+ class IAudioSessionEventListener;
+ class CAudioIO : public IPulseStreamListener, public IAudioSessionEventListener {
+ public:
+ struct SStreamCallback {
+ void* mUserData;
+ void (*onStream)(size_t nbytes, void* user_data);
+
+ SStreamCallback() : mUserData(NULL), onStream(NULL)
+ {/* Empty Body */}
+ };
+
+ struct SStateChangedCallback {
+ void* mUserData;
+ void (*onStateChanged)(CAudioInfo::EAudioIOState state, CAudioInfo::EAudioIOState statePrev, bool byPolicy, void* user_data);
+
+ SStateChangedCallback() : mUserData(NULL), onStateChanged(NULL)
+ {/* Empty Body */}
+ };
+
+ struct SInterruptCallback {
+ void* mUserData;
+ void (*onInterrupt)(IAudioSessionEventListener::EInterruptCode code, void* user_data);
+
+ SInterruptCallback() : mUserData(NULL), onInterrupt(NULL)
+ {/* Empty Body */}
+ };
+
+ private:
+ pthread_mutex_t mMutex;
+ pthread_cond_t mCond;
+ bool mIsInit;
+ bool mForceIgnore;
+
+ protected:
+ CAudioSessionHandler* mpAudioSessionHandler;
+ CPulseAudioClient* mpPulseAudioClient;
+ CAudioInfo mAudioInfo;
+
+ SStreamCallback mStreamCallback;
+ SStateChangedCallback mStateChangedCallback;
+ SInterruptCallback mInterruptCallback;
+
+ CAudioInfo::EAudioIOState mState;
+ CAudioInfo::EAudioIOState mStatePrev;
+ bool mByPolicy;
+
+ /* Protected Methods */
+ virtual void setInit(bool flag);
+ virtual bool isInit();
+ virtual bool IsReady();
+
+ void internalLock() throw (CAudioError);
+ void internalUnlock() throw (CAudioError);
+ void internalWait() throw (CAudioError);
+ void internalSignal() throw (CAudioError);
+
+ bool isForceIgnore();
+
+ public:
+ /* Constructor & Destructor */
+ CAudioIO();
+ CAudioIO(CAudioInfo& audioInfo);
+ virtual ~CAudioIO();
+
+ /* Pure Virtual Methods */
+ virtual void initialize() throw (CAudioError) = 0;
+ virtual void finalize() = 0;
+
+ virtual void prepare() throw (CAudioError) = 0;
+ virtual void unprepare() throw (CAudioError) = 0;
+
+ virtual void pause() throw (CAudioError) = 0;
+ virtual void resume() throw (CAudioError) = 0;
+
+ virtual void drain() throw (CAudioError) = 0;
+ virtual void flush() throw (CAudioError) = 0;
+
+ virtual int getBufferSize() throw (CAudioError) = 0;
+
+ /* Implemented Handlers */
+ virtual void onStream(CPulseAudioClient* pClient, size_t length);
+ virtual void onStateChanged(CAudioInfo::EAudioIOState state, bool byPolicy);
+ virtual void onStateChanged(CAudioInfo::EAudioIOState state);
+ virtual void onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info);
+ virtual void onSignal(CAudioSessionHandler* pHandler, mm_sound_signal_name_t signal, int value);
+
+ /* Methods */
+ CAudioInfo getAudioInfo() throw (CAudioError);
+
+ virtual void setStreamCallback(SStreamCallback callback) throw (CAudioError);
+ SStreamCallback getStreamCallback() throw (CAudioError);
+
+ virtual void setStateChangedCallback(SStateChangedCallback callback) throw (CAudioError);
+ SStateChangedCallback getStateChangedCallback() throw (CAudioError);
+
+ void setInterruptCallback(SInterruptCallback callback) throw (CAudioError);
+ SInterruptCallback getInterruptCallback() throw (CAudioError);
+
+ void ignoreSession() throw (CAudioError);
+ };
+
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_AUDIO_IO_CAUDIO_IO_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_AUDIO_IO_CAUDIO_DEF_H__
+#define __TIZEN_MEDIA_AUDIO_IO_CAUDIO_DEF_H__
+
+
+#ifdef __cplusplus
+
+
+#include <stdio.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include "CAudioError.h"
+#include "CAudioInfo.h"
+#include "IAudioSessionEventListener.h"
+#include "CAudioSessionHandler.h"
+#include "IPulseStreamListener.h"
+#include "CPulseAudioVolume.h"
+#include "CPulseAudioPolicy.h"
+#include "CPulseStreamSpec.h"
+#include "CPulseAudioClient.h"
+#include "CAudioIO.h"
+#include "CAudioInput.h"
+#include "CAudioOutput.h"
+
+//#define _AUDIO_IO_DEBUG_TIMING_
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "TIZEN_N_AUDIO_IO"
+
+#define AUDIO_IO_LOGD(_fmt_, arg...) { \
+ LOGD(_fmt_, ##arg); \
+}
+
+#define AUDIO_IO_LOGW(_fmt_, arg...) { \
+ LOGW(_fmt_, ##arg); \
+}
+
+#define AUDIO_IO_LOGE(_fmt_, arg...) { \
+ LOGE(_fmt_, ##arg); \
+}
+
+#define _AUDIO_IO_SHELL_COLOR_
+#ifdef _AUDIO_IO_SHELL_COLOR_
+#define COLOR_BLACK "\033[0;30m"
+#define COLOR_RED "\033[0;31m"
+#define COLOR_GREEN "\033[0;32m"
+#define COLOR_YELLOW "\033[0;33m"
+#define COLOR_BLUE "\033[0;34m"
+#define COLOR_MAGENTA "\033[0;35m"
+#define COLOR_CYAN "\033[0;36m"
+#define COLOR_GRAY "\033[0;37m"
+#define COLOR_WHITE "\033[1;37m"
+#define COLOR_END "\033[0m"
+#else
+#define COLOR_BLACK
+#define COLOR_RED
+#define COLOR_GREEN
+#define COLOR_BLUE
+#define COLOR_YELLOW
+#define COLOR_MAGENTA
+#define COLOR_CYAN
+#define COLOR_WHITE
+#define COLOR_END
+#endif
+
+
+#define RET_ERROR(_x_) {return CAudioError((_x_), __FILE__, __func__, __LINE__);};
+#define RET_ERROR_MSG(_x_, _msg_) {return CAudioError((_x_), (_msg_), __FILE__, __func__, __LINE__);};
+
+#define RET_ERROR_MSG_FORMAT(_x_, _format_, ...) { \
+ char _msg_[CAudioError::MSG_LENGTH] = {0, }; \
+ snprintf(_msg_, CAudioError::MSG_LENGTH, _format_, ##__VA_ARGS__); \
+ return CAudioError((_x_), (_msg_), __FILE__, __func__, __LINE__); \
+};
+
+
+#define THROW_ERROR(_x_) {throw CAudioError((_x_), __FILE__, __func__, __LINE__);};
+#define THROW_ERROR_MSG(_x_, _msg_) {throw CAudioError((_x_), (_msg_), __FILE__, __func__, __LINE__);};
+
+#define THROW_ERROR_MSG_FORMAT(_x_, _format_, ...) { \
+ char _msg_[CAudioError::MSG_LENGTH] = {0, }; \
+ snprintf(_msg_, CAudioError::MSG_LENGTH, _format_, ##__VA_ARGS__); \
+ throw CAudioError((_x_), (_msg_), __FILE__, __func__, __LINE__); \
+};
+
+#define VALID_POINTER_START(_x_) { \
+ if ((_x_) != NULL) {
+
+#define VALID_POINTER_END } \
+}
+
+#define SAFE_DELETE(_x_) {if ((_x_)) {delete (_x_); (_x_) = NULL;}};
+#define SAFE_FINALIZE(_x_) {if ((_x_)) {(_x_)->finalize();}};
+#define SAFE_REMOVE(_x_) {if ((_x_)) {(_x_)->finalize(); delete (_x_); (_x_) = NULL;}};
+
+
+#endif
+#endif /* __TIZEN_MEDIA_CPP_OBJECTS_IO_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_AUDIO__IO_CAUDIO_INFO_H__
+#define __TIZEN_MEDIA_AUDIO__IO_CAUDIO_INFO_H__
+
+
+#ifdef __cplusplus
+
+
+namespace tizen_media_audio {
+
+
+ /**
+ * Audio Information
+ */
+ class CAudioInfo {
+ public:
+ const static unsigned int MIN_SYSTEM_SAMPLERATE = 8000;
+ const static unsigned int MAX_SYSTEM_SAMPLERATE = 48000;
+
+ enum EChannel {
+ CHANNEL_MONO = 1, /**< 1 channel, mono */
+ CHANNEL_STEREO, /**< 2 channel, stereo */
+ CHANNEL_MAX
+ };
+
+ enum ESampleType {
+ SAMPLE_TYPE_U8 = 1, /**< Unsigned 8-bit audio samples */
+ SAMPLE_TYPE_S16_LE, /**< Signed 16-bit audio samples */
+ SAMPLE_TYPE_MAX
+ };
+
+ enum EAudioType {
+ /* Only Input */
+ AUDIO_IN_TYPE_MEDIA = 0,
+ AUDIO_IN_TYPE_SYSTEM,
+ AUDIO_IN_TYPE_ALARM,
+ AUDIO_IN_TYPE_NOTIFICATION,
+ AUDIO_IN_TYPE_EMERGENCY,
+ AUDIO_IN_TYPE_VOICE_INFORMATION,
+ AUDIO_IN_TYPE_VOICE_RECOGNITION,
+ AUDIO_IN_TYPE_RINGTONE_VOIP,
+ AUDIO_IN_TYPE_VOIP,
+ AUDIO_IN_TYPE_LOOPBACK, /**< only for loopback */
+
+ /* Only Output */
+ AUDIO_OUT_TYPE_MEDIA,
+ AUDIO_OUT_TYPE_SYSTEM,
+ AUDIO_OUT_TYPE_ALARM,
+ AUDIO_OUT_TYPE_NOTIFICATION,
+ AUDIO_OUT_TYPE_EMERGENCY,
+ AUDIO_OUT_TYPE_VOICE_INFORMATION,
+ AUDIO_OUT_TYPE_VOICE_RECOGNITION,
+ AUDIO_OUT_TYPE_RINGTONE_VOIP,
+ AUDIO_OUT_TYPE_VOIP,
+
+ AUDIO_TYPE_MAX
+ };
+
+ enum EAudioIOState {
+ AUDIO_IO_STATE_NONE, /**< Audio-io handle is not created */
+ AUDIO_IO_STATE_IDLE, /**< Audio-io handle is created, but not prepared */
+ AUDIO_IO_STATE_RUNNING, /**< Audio-io handle is ready and the stream is running */
+ AUDIO_IO_STATE_PAUSED, /**< Audio-io handle is ready and the stream is paused */
+ };
+
+ private:
+ unsigned int mSampleRate;
+ EChannel mChannel;
+ ESampleType mSampleType;
+ EAudioType mAudioType;
+ int mAudioIndex;
+
+ const char *StreamTypeTable[AUDIO_TYPE_MAX] = {
+ /* Only Input */
+ "media", /**< AUDIO_IN_TYPE_MEDIA */
+ "system", /**< AUDIO_IN_TYPE_SYSTEM */
+ "alarm", /**< AUDIO_IN_TYPE_ALARM */
+ "notification", /**< AUDIO_IN_TYPE_NOTIFICATION */
+ "emergency", /**< AUDIO_IN_TYPE_EMERGENCY */
+ "voice-information", /**< AUDIO_IN_TYPE_VOICE_INFORMATION */
+ "voice-recognition", /**< AUDIO_IN_TYPE_VOICE_RECOGNITION */
+ "ringtone-voip", /**< AUDIO_IN_TYPE_RINGTONE_VOIP */
+ "voip", /**< AUDIO_IN_TYPE_VOIP */
+ "loopback", /**< AUDIO_IN_TYPE_LOOPBACK */ /**< only for loopback */
+
+ /* Only Output */
+ "media", /**< AUDIO_OUT_TYPE_MEDIA */
+ "system", /**< AUDIO_OUT_TYPE_SYSTEM */
+ "alarm", /**< AUDIO_OUT_TYPE_ALARM */
+ "notification", /**< AUDIO_OUT_TYPE_NOTIFICATION */
+ "emergency", /**< AUDIO_OUT_TYPE_EMERGENCY */
+ "voice-information", /**< AUDIO_OUT_TYPE_VOICE_INFORMATION */
+ "voice-recognition", /**< AUDIO_OUT_TYPE_VOICE_RECOGNITION */
+ "ringtone-voip", /**< AUDIO_OUT_TYPE_RINGTONE_VOIP */
+ "voip", /**< AUDIO_OUT_TYPE_VOIP */
+ };
+
+ public:
+ /* Constructors */
+ CAudioInfo();
+ CAudioInfo(unsigned int sampleRate, EChannel channel, ESampleType sampleType, EAudioType audioType, int audioIndex) throw (CAudioError);
+
+ /* Setter & Getter */
+ unsigned int getSampleRate();
+ EChannel getChannel();
+ ESampleType getSampleType();
+ EAudioType getAudioType();
+ void setAudioType(EAudioType AudioType);
+ int getAudioIndex();
+ void setAudioIndex(int AudioIndex);
+ void convertAudioType2StreamType (CAudioInfo::EAudioType audioType, char **streamType);
+ void convertStreamType2AudioType (char *streamType, CAudioInfo::EAudioType *audioType);
+ };
+
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_AUDIO__IO_CAUDIO_INFO_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_AUDIO_IO_CAUDIO_INPUT_H__
+#define __TIZEN_MEDIA_AUDIO_IO_CAUDIO_INPUT_H__
+
+
+#ifdef __cplusplus
+
+
+namespace tizen_media_audio {
+
+
+ /**
+ * A class CAudioInput that inherited from CAudioIO
+ */
+ class CAudioInput : public CAudioIO {
+ private:
+
+ const void* mpSyncReadDataPtr;
+ size_t mSyncReadIndex;
+ size_t mSyncReadLength;
+
+ bool mIsUsedSyncRead;
+ bool mIsInit;
+
+ /* Private Methods */
+ void setInit(bool flag);
+ bool IsInit();
+ bool IsReady();
+
+ public:
+ /* Constructor & Destructor */
+ CAudioInput(CAudioInfo& info);
+ CAudioInput(
+ unsigned int sampleRate,
+ CAudioInfo::EChannel channel,
+ CAudioInfo::ESampleType sampleType,
+ CAudioInfo::EAudioType audioType);
+ ~CAudioInput();
+
+ /* Overridden Handler */
+ virtual void onStream(CPulseAudioClient* pClient, size_t length);
+ virtual void onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info);
+ virtual void onSignal(CAudioSessionHandler* pHandler, mm_sound_signal_name_t signal, int value);
+
+ /* Implemented Methods */
+ virtual void initialize() throw (CAudioError);
+ virtual void finalize();
+
+ virtual void prepare() throw (CAudioError);
+ virtual void unprepare() throw (CAudioError);
+
+ virtual void pause() throw (CAudioError);
+ virtual void resume() throw (CAudioError);
+
+ virtual void drain() throw (CAudioError);
+ virtual void flush() throw (CAudioError);
+
+ virtual int getBufferSize() throw (CAudioError);
+
+ /* Overridden Methods */
+ virtual void setStreamCallback(SStreamCallback callback) throw (CAudioError);
+
+ /* Methods */
+ int read(void* buffer, size_t length) throw (CAudioError);
+ int peek(const void** buffer, size_t* length) throw (CAudioError);
+ int drop() throw (CAudioError);
+ };
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_AUDIO_IO_CAUDIO_INPUT_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_AUDIO_IO_CAUDIO_OUTPUT_H__
+#define __TIZEN_MEDIA_AUDIO_IO_CAUDIO_OUTPUT_H__
+
+
+#ifdef __cplusplus
+
+#include "CAudioIODef.h"
+
+
+namespace tizen_media_audio {
+
+
+ /**
+ * A class CAudioOutput that inherited from CAudioIO
+ */
+ class CAudioOutput : public CAudioIO {
+ private:
+ bool mIsUsedSyncWrite;
+ bool mIsInit;
+
+ /* Private Methods */
+ void setInit(bool flag);
+ bool IsInit();
+ bool IsReady();
+
+ public:
+ /* Constructor & Destructor */
+ CAudioOutput(CAudioInfo& info);
+ CAudioOutput(
+ unsigned int smapleRate,
+ CAudioInfo::EChannel channel,
+ CAudioInfo::ESampleType sampleType,
+ CAudioInfo::EAudioType type);
+ ~CAudioOutput();
+
+ /* Overridden Handler */
+ virtual void onStream(CPulseAudioClient* pClient, size_t length);
+ virtual void onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info);
+ virtual void onSignal(CAudioSessionHandler* pHandler, mm_sound_signal_name_t signal, int value);
+
+ /* Implemented Methods */
+ virtual void initialize() throw (CAudioError);
+ virtual void finalize();
+
+ virtual void prepare() throw (CAudioError);
+ virtual void unprepare() throw (CAudioError);
+
+ virtual void pause() throw (CAudioError);
+ virtual void resume() throw (CAudioError);
+
+ virtual void drain() throw (CAudioError);
+ virtual void flush() throw (CAudioError);
+
+ virtual int getBufferSize() throw (CAudioError);
+
+ /* Methods */
+ int write(const void* buffer, unsigned int length) throw (CAudioError);
+ };
+
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_AUDIO_IO_CAUDIO_OUTPUT_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_AUDIOIO_IO_CAUDIO_SESSION_HANDLER_H__
+#define __TIZEN_MEDIA_AUDIOIO_IO_CAUDIO_SESSION_HANDLER_H__
+
+
+#ifdef __cplusplus
+
+
+#include <mm_session.h>
+#include <mm_session_private.h>
+#include <audio-session-manager.h>
+#include <mm_sound.h>
+#include <mm_sound_focus.h>
+
+namespace tizen_media_audio {
+
+
+ /**
+ * ASM Thread
+ */
+ class CAudioSessionHandler {
+ public:
+ enum EAudioSessionType {
+ AUDIO_SESSION_TYPE_CAPTURE,
+ AUDIO_SESSION_TYPE_PLAYBACK
+ };
+
+ private:
+ /* Static Member */
+ static int sCaptureRef;
+ static int sFocusRef;
+
+ /* Members */
+ int mId;
+ int mOptions;
+
+ EAudioSessionType mAudioSession;
+ MMSessionType mMultimediaSession;
+
+ mm_sound_focus_type_e mFocusType; /* For audio focus */
+ mm_sound_focus_state_e mState; /* For audio focus */
+ char* mReasonForChange; /* For audio focus */
+ char* mAdditionalInfo; /* For audio focus */
+
+ CAudioInfo mAudioInfo; /* Referenced from CAudioIO */
+
+ IAudioSessionEventListener* mpEventListener;
+
+ bool mIsInit;
+
+ bool mUseFocus;
+ int mSubscribeId;
+
+ struct stream_type_table_s {
+ const char* name;
+ MMSessionType type;
+ };
+ const struct stream_type_table_s stream_type_table_in[MM_SESSION_TYPE_NUM] = {
+ {"media", MM_SESSION_TYPE_MEDIA},
+ {"media", MM_SESSION_TYPE_MEDIA_RECORD},
+ {"media", MM_SESSION_TYPE_ALARM},
+ {"media", MM_SESSION_TYPE_NOTIFY},
+ {"media", MM_SESSION_TYPE_EMERGENCY},
+ {"media", MM_SESSION_TYPE_CALL},
+ {"media", MM_SESSION_TYPE_VIDEOCALL},
+ {"voip", MM_SESSION_TYPE_VOIP},
+ {"media", MM_SESSION_TYPE_VOICE_RECOGNITION},
+ {"media", MM_SESSION_TYPE_RECORD_AUDIO},
+ {"media", MM_SESSION_TYPE_RECORD_VIDEO}
+ };
+ const struct stream_type_table_s stream_type_table_out[MM_SESSION_TYPE_NUM] = {
+ {"media", MM_SESSION_TYPE_MEDIA},
+ {"media", MM_SESSION_TYPE_MEDIA_RECORD},
+ {"alarm", MM_SESSION_TYPE_ALARM},
+ {"notification", MM_SESSION_TYPE_NOTIFY},
+ {"emergency", MM_SESSION_TYPE_EMERGENCY},
+ {"media", MM_SESSION_TYPE_CALL},
+ {"media", MM_SESSION_TYPE_VIDEOCALL},
+ {"voip", MM_SESSION_TYPE_VOIP},
+ {"media", MM_SESSION_TYPE_VOICE_RECOGNITION},
+ {"media", MM_SESSION_TYPE_RECORD_AUDIO},
+ {"media", MM_SESSION_TYPE_RECORD_VIDEO}
+ };
+
+ /* Private Static Methods */
+ static int PCM_CAPTURE_COUNT_INC();
+ static int PCM_CAPTURE_COUNT_DEC();
+ static int PCM_CAPTURE_COUNT_GET();
+ static int FOCUS_ID_COUNT_INC();
+ static int FOCUS_ID_COUNT_DEC();
+ static int FOCUS_ID_COUNT_GET();
+
+ static void _sound_pcm_signal_cb(mm_sound_signal_name_t signal, int value, void *user_data);
+ static ASM_cb_result_t _sound_pcm_asm_cb(int handle, ASM_event_sources_t eventSrc, ASM_sound_commands_t command, unsigned int soundState, void *cbData);
+ static void _sound_pcm_focus_cb(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info, void *user_data);
+ static void _sound_pcm_focus_watch_cb(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info, void *user_data);
+
+ /* Private Method */
+ CAudioError _convertStreamType(EAudioSessionType type1, MMSessionType type2, int *index);
+ CAudioError _getAsmInformation(MMSessionType *type, int *options);
+ bool _isFocusRequired(MMSessionType type, int options);
+
+ public:
+ /* Constructor & Destructor */
+ CAudioSessionHandler(EAudioSessionType sessionType, CAudioInfo& audioInfo, IAudioSessionEventListener* listener);
+ virtual ~CAudioSessionHandler();
+
+ /* Methods */
+ virtual void initialize() throw (CAudioError);
+ virtual void finalize();
+
+ bool isSkipSessionEvent() throw (CAudioError);
+
+ void registerSound() throw (CAudioError);
+ void unregisterSound() throw (CAudioError);
+
+ void updatePlaying() throw (CAudioError);
+ void updateStop() throw (CAudioError);
+ void disableSessionHandler() throw (CAudioError);
+
+ /* Setter & Getter */
+ int getId();
+ int getOptions();
+
+ EAudioSessionType getAudioSession();
+ MMSessionType getMultimediaSession();
+
+ int getSubscribeId();
+
+ CAudioInfo getAudioInfo();
+ };
+
+
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_AUDIOIO_IO_CAUDIO_SESSION_HANDLER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_AUDIO_IO_CPULSEAUDIO_CLIENT_H__
+#define __TIZEN_MEDIA_AUDIO_IO_CPULSEAUDIO_CLIENT_H__
+
+
+#ifdef __cplusplus
+
+
+#include <pulse/pulseaudio.h>
+#include <pulse/ext-policy.h>
+
+
+namespace tizen_media_audio {
+
+
+ /**
+ * PULSE Thread
+ */
+ class CPulseAudioVolume;
+ class CPulseAudioPolicy;
+ class CPulseStreamSpec;
+ class CPulseAudioClient {
+ public:
+ /* Constants */
+ static const char* CLIENT_NAME;
+
+ enum EStreamDirection {
+ STREAM_DIRECTION_RECORD, /**< Record stream */
+ STREAM_DIRECTION_PLAYBACK /**< Playback stream */
+ };
+
+ private:
+ /* Members */
+ EStreamDirection mDirection;
+ CPulseStreamSpec mSpec;
+ IPulseStreamListener* mpListener;
+
+ pa_threaded_mainloop* mpMainloop;
+ pa_context* mpContext;
+ pa_stream* mpStream;
+ pa_proplist* mpPropList;
+
+ bool mIsInit;
+ bool mIsOperationSuccess;
+
+ /* Static Methods */
+
+ /* Private Method */
+
+ /* Private Calblack Method */
+ static void _contextStateChangeCb(pa_context* c, void* user_data);
+ static void _successContextCb(pa_context* c, int success, void* user_data);
+
+ static void _streamStateChangeCb(pa_stream* s, void* user_data);
+ static void _streamCaptureCb(pa_stream* s, size_t length, void* user_data);
+ static void _streamPlaybackCb(pa_stream* s, size_t length, void* user_data);
+ static void _streamLatencyUpdateCb(pa_stream* s, void* user_data);
+ static void _successStreamCb(pa_stream* s, int success, void* user_data);
+
+ public:
+ /* Constructor & Destructor */
+ CPulseAudioClient(EStreamDirection direction,
+ CPulseStreamSpec& spec,
+ IPulseStreamListener* listener);
+ ~CPulseAudioClient();
+
+ /* Implemented Methods */
+ void initialize() throw (CAudioError);
+ void finalize();
+
+ /* Methods */
+ int peek(const void** data, size_t* length) throw (CAudioError);
+ int drop() throw (CAudioError);
+ int write(const void* data, size_t length) throw (CAudioError);
+
+ void cork(bool cork) throw (CAudioError);
+ bool isCorked() throw (CAudioError);
+
+ bool drain() throw (CAudioError);
+ bool flush() throw (CAudioError);
+
+ void checkRunningState() throw (CAudioError);
+ bool isInThread() throw (CAudioError);
+
+ size_t getWritableSize() throw (CAudioError);
+ size_t getReadableSize() throw (CAudioError);
+
+ size_t getBufferSize() throw (CAudioError);
+
+ pa_usec_t getLatency() throw (CAudioError);
+ pa_usec_t getFinalLatency() throw (CAudioError);
+
+ /* Setter & Getter */
+ EStreamDirection getStreamDirection();
+ CPulseStreamSpec getStreamSpec();
+ };
+
+
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_AUDIO_IO_CPULSEAUDIO_CLIENT_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#if 0
+#ifndef __TIZEN_MEDIA_AUDIO_IO_CPULSEAUDIO_POLICY_H__
+#define __TIZEN_MEDIA_AUDIO_IO_CPULSEAUDIO_POLICY_H__
+
+
+#ifdef __cplusplus
+
+
+namespace tizen_media_audio {
+
+
+ /**
+ * class CPulseAudioPolicy
+ */
+ class CPulseAudioPolicy {
+ public:
+ /* Constants */
+ enum EPolicy {
+ POLICY_DEFAULT,
+ POLICY_OUT_AUTO,
+ POLICY_OUT_PHONE,
+ POLICY_OUT_VOIP,
+ POLICY_OUT_ALL,
+ POLICY_IN_VOIP,
+ POLICY_IN_LOOPBACK,
+ POLICY_IN_MIRRORING,
+ POLICY_HIGH_LATENCY,
+ POLICY_MAX
+ };
+
+ private:
+ /* Members */
+ EPolicy mPolicy;
+
+ public:
+ /* Constructors */
+ CPulseAudioPolicy();
+ CPulseAudioPolicy(EPolicy policy);
+ ~CPulseAudioPolicy();
+
+ /* getter & setter */
+ void setPolicy(EPolicy policy) throw (CAudioError);
+ EPolicy getPolicy();
+
+ /* Override */
+ bool operator != (const EPolicy policy);
+ bool operator == (const EPolicy policy);
+ };
+
+
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_AUDIO_IO_CPULSEAUDIO_POLICY_H__ */
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#if 0
+#ifndef __TIZEN_MEDIA_AUDIO_IO_CPULSEAUDIO_VOLUME_H__
+#define __TIZEN_MEDIA_AUDIO_IO_CPULSEAUDIO_VOLUME_H__
+
+
+#ifdef __cplusplus
+
+
+namespace tizen_media_audio {
+
+
+ /**
+ * Audio Volume
+ */
+ class CPulseAudioVolume {
+ public:
+ /* Constants */
+ enum EVolume {
+ VOLUME_SYSTEM, /**< System volume type */
+ VOLUME_NOTIFICATION, /**< Notification volume type */
+ VOLUME_ALARM, /**< Alarm volume type */
+ VOLUME_RINGTONE, /**< Ringtone volume type */
+ VOLUME_MEDIA, /**< Media volume type */
+ VOLUME_CALL, /**< Call volume type */
+ VOLUME_VOIP, /**< VOIP volume type */
+ VOLUME_VOICE, /**< VOICE volume type */
+ VOLUME_FIXED, /**< Volume type for fixed acoustic level */
+ VOLUME_EXT_ANDROID = VOLUME_FIXED, /**< External system volume for Android */
+ VOLUME_MAX /**< Volume type count */
+ };
+
+ enum EVolumeGain {
+ VOLUME_GAIN_DEFAULT,
+ VOLUME_GAIN_DIALER,
+ VOLUME_GAIN_TOUCH,
+ VOLUME_GAIN_AF,
+ VOLUME_GAIN_SHUTTER1,
+ VOLUME_GAIN_SHUTTER2,
+ VOLUME_GAIN_CAMCORDING,
+ VOLUME_GAIN_MIDI,
+ VOLUME_GAIN_BOOTING,
+ VOLUME_GAIN_VIDEO,
+ VOLUME_GAIN_TTS,
+ VOLUME_GAIN_MAX
+ };
+
+ private:
+ /* Members */
+ EVolume mVolume;
+ EVolumeGain mVolumeGain;
+
+ public:
+ /* Constructor & Destructor */
+ CPulseAudioVolume();
+ CPulseAudioVolume(EVolume volume, EVolumeGain gain);
+ ~CPulseAudioVolume();
+
+ /* Methods */
+
+ /* Setter & Getter */
+ void setVolume(EVolume volume);
+ EVolume getVolume();
+
+ void setVolumeGain(EVolumeGain volumeGain);
+ EVolumeGain getVolumeGain();
+ };
+
+
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_AUDIO_IO_CPULSEAUDIO_VOLUME_H__ */
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_AUDIO_IO_CPULSESTREAM_SPEC_H__
+#define __TIZEN_MEDIA_AUDIO_IO_CPULSESTREAM_SPEC_H__
+
+
+#ifdef __cplusplus
+
+
+#include <pulse/pulseaudio.h>
+
+
+namespace tizen_media_audio {
+
+
+ /**
+ * class CPulseStreamSpec
+ */
+ class CPulseStreamSpec {
+ public:
+ /* Constants */
+ enum EStreamLatency {
+ STREAM_LATENCY_INPUT_LOW,
+ STREAM_LATENCY_INPUT_MID,
+ STREAM_LATENCY_INPUT_HIGH,
+ STREAM_LATENCY_INPUT_VOIP,
+ STREAM_LATENCY_OUTPUT_LOW,
+ STREAM_LATENCY_OUTPUT_MID,
+ STREAM_LATENCY_OUTPUT_HIGH,
+ STREAM_LATENCY_OUTPUT_VOIP,
+ STREAM_LATENCY_MAX
+ };
+
+ private:
+ /* Members */
+ EStreamLatency mLatency;
+ CAudioInfo mAudioInfo;
+ pa_sample_spec mSampleSpec;
+ pa_channel_map mChannelMap;
+ const char* mStreamName;
+
+ /* private meethod */
+ void _adjustSpec() throw (CAudioError);
+
+ public:
+ /* Constructor & Destructor */
+ CPulseStreamSpec() throw (CAudioError);
+ CPulseStreamSpec(EStreamLatency latency, CAudioInfo& audioInfo) throw (CAudioError);
+ CPulseStreamSpec(EStreamLatency latency, CAudioInfo& audioInfo, int customLatency) throw (CAudioError);
+ ~CPulseStreamSpec();
+
+ /* Setter & Getter */
+ EStreamLatency getStreamLatency();
+ CAudioInfo getAudioInfo();
+ pa_sample_spec getSampleSpec();
+ pa_channel_map getChannelMap();
+ const char* getStreamName();
+ };
+
+
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_AUDIO_IO_CPULSESTREAM_SPEC_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_AUDIO_IO_IAUDIO_SESSION_EVENT_LISTENER_H__
+#define __TIZEN_MEDIA_AUDIO_IO_IAUDIO_SESSION_EVENT_LISTENER_H__
+
+
+#ifdef __cplusplus
+
+
+#include <mm_sound.h>
+#include <mm_sound_focus.h>
+
+
+namespace tizen_media_audio {
+
+
+ /**
+ * Called by ASM Thread
+ */
+ class CAudioSessionHandler;
+ class IAudioSessionEventListener {
+ public:
+ enum EInterruptCode {
+ INTERRUPT_COMPLETED = 0, /**< Interrupt completed */
+ INTERRUPT_BY_MEDIA, /**< Interrupted by a media application */
+ INTERRUPT_BY_CALL, /**< Interrupted by an incoming call */
+ INTERRUPT_BY_EARJACK_UNPLUG, /**< Interrupted by unplugging headphones */
+ INTERRUPT_BY_RESOURCE_CONFLICT, /**< Interrupted by a resource conflict */
+ INTERRUPT_BY_ALARM, /**< Interrupted by an alarm */
+ INTERRUPT_BY_EMERGENCY, /**< Interrupted by an emergency */
+ INTERRUPT_BY_NOTIFICATION, /**< Interrupted by a notification */
+ INTERRUPT_MAX
+ };
+
+ static EInterruptCode convertInterruptedCode(int code, const char *reason_for_change);
+ virtual void onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info) = 0;
+ virtual void onSignal(CAudioSessionHandler* pHandler, mm_sound_signal_name_t signal, int value) = 0;
+ };
+
+
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_AUDIO_IO_IAUDIO_SESSION_EVENT_LISTENER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_AUDIO_IO_IPULSESTREAM_LISTENER_H__
+#define __TIZEN_MEDIA_AUDIO_IO_IPULSESTREAM_LISTENER_H__
+
+
+#ifdef __cplusplus
+
+
+#include <stddef.h>
+
+
+namespace tizen_media_audio {
+
+
+ /**
+ * Called by PulseAudio Thread
+ */
+ class CPulseAudioClient;
+ class IPulseStreamListener {
+ public:
+ virtual void onStream(CPulseAudioClient* pClient, size_t length) = 0;
+ virtual void onStateChanged(CAudioInfo::EAudioIOState state) = 0;
+ };
+
+
+} /* namespace tizen_media_audio */
+
+#endif
+#endif /* __TIZEN_MEDIA_AUDIO_IO_IPULSESTREAM_LISTENER_H__ */
/*
-* Copyright (c) 2011 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.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* 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.
-*/
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
#ifndef __TIZEN_MEDIA_AUDIO_IO_H__
#define __TIZEN_MEDIA_AUDIO_IO_H__
/**
* @addtogroup CAPI_MEDIA_AUDIO_IN_MODULE
* @{
-*/
+ */
/**
* @brief The audio input handle.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*/
-typedef struct audio_in_s *audio_in_h;
+typedef struct audio_io_s *audio_in_h;
/**
* @}
-*/
+ */
/**
* @addtogroup CAPI_MEDIA_AUDIO_OUT_MODULE
* @brief The audio output handle.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*/
-typedef struct audio_out_s *audio_out_h;
+typedef struct audio_io_s *audio_out_h;
/**
* @}
AUDIO_CHANNEL_STEREO, /**< 2 channel, stereo */
} audio_channel_e;
+/**
+ * @brief Enumeration for audio input and output state.
+ * @since_tizen 3.0
+ */
+typedef enum
+{
+ AUDIO_IO_STATE_IDLE, /**< Audio-io handle is created, but not prepared */
+ AUDIO_IO_STATE_RUNNING, /**< Audio-io handle is ready and the stream is running */
+ AUDIO_IO_STATE_PAUSED, /**< Audio-io handle is ready and the stream is paused */
+} audio_io_state_e;
+
/**
* @brief Enumeration for audio input and output error.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
AUDIO_IO_ERROR_DEVICE_NOT_CLOSED = TIZEN_ERROR_AUDIO_IO | 0x02, /**< Device close error */
AUDIO_IO_ERROR_INVALID_BUFFER = TIZEN_ERROR_AUDIO_IO | 0x03, /**< Invalid buffer pointer */
AUDIO_IO_ERROR_SOUND_POLICY = TIZEN_ERROR_AUDIO_IO | 0x04, /**< Sound policy error */
+ AUDIO_IO_ERROR_INVALID_STATE = TIZEN_ERROR_AUDIO_IO | 0x05, /**< Invalid state (Since 3.0) */
} audio_io_error_e;
/**
+ * @deprecated Deprecated since 3.0
* @brief Enumeration for audio IO interrupted messages.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*/
} audio_io_interrupted_code_e;
/**
+ * @deprecated Deprecated since 3.0. Use sound_stream_focus_state_changed_cb instead.
* @brief Called when audio input or output is interrupted.
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
/**
* @}
-*/
+ */
/**
* @addtogroup CAPI_MEDIA_AUDIO_IN_MODULE
* @{
-*/
+ */
//
//AUDIO INPUT
*
* @param[in] handle The handle to the audio input
* @param[in] nbytes The amount of available audio in data which can be peeked.
- * @param[in] userdata The user data passed from the callback registration function
+ * @param[in] user_data The user data passed from the callback registration function
*
* @see audio_in_set_stream_cb()
*/
-typedef void (*audio_in_stream_cb)(audio_in_h handle, size_t nbytes, void *userdata);
+typedef void (*audio_in_stream_cb)(audio_in_h handle, size_t nbytes, void *user_data);
+
+/**
+ * @brief Called when the state of audio input is changed.
+ *
+ * @since_tizen 3.0
+ *
+ * @param[in] handle The handle of the audio input
+ * @param[in] previous The previous state of the audio input
+ * @param[in] current The current state of the audio input
+ * @param[in] by_policy @c true if the state is changed by policy, otherwise @c false if the state is not changed by policy
+ * @param[in] user_data The user data passed from the callback registration function
+ *
+ * @see audio_in_set_state_changed_cb()
+ * @see audio_in_unset_state_changed_cb()
+ */
+typedef void (*audio_in_state_changed_cb)(audio_in_h handle, audio_io_state_e previous, audio_io_state_e current, bool by_policy, void *user_data);
/**
* @brief Creates an audio device instance and returns an input handle to record PCM (pulse-code modulation) data.
*
+ * @details This function is used for audio input initialization.
+ *
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
* @privlevel public
* @privilege %http://tizen.org/privilege/recorder
*
- * @details This function is used for audio input initialization.
- *
* @remarks @a input must be released using audio_in_destroy().
*
* @param[in] sample_rate The audio sample rate in 8000[Hz] ~ 48000[Hz]
* @retval #AUDIO_IO_ERROR_DEVICE_NOT_OPENED Device not opened
* @retval #AUDIO_IO_ERROR_SOUND_POLICY Sound policy error
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @post The state will be #AUDIO_IO_STATE_IDLE.\n
+ * audio_in_set_stream_info() is recommended to be called after this API.
* @see audio_in_destroy()
*/
int audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h *input);
/**
+ * @deprecated Deprecated since 3.0. Use sound_manager_create_stream_information() instead.
* @brief Creates an audio loopback device instance and returns an input handle to record PCM (pulse-code modulation) data.
*
+ * @details This function is used for audio loopback input initialization.
+ *
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
* @privlevel public
* @privilege %http://tizen.org/privilege/recorder
*
- * @details This function is used for audio loopback input initialization.
- *
* @remarks @a input must be released using audio_in_destroy().
*
* @param[in] sample_rate The audio sample rate in 8000[Hz] ~ 48000[Hz]
* @retval #AUDIO_IO_ERROR_DEVICE_NOT_OPENED Device not opened
* @retval #AUDIO_IO_ERROR_SOUND_POLICY Sound policy error
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ *
* @see audio_in_destroy()
*/
int audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input);
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #AUDIO_IO_ERROR_DEVICE_NOT_CLOSED Device not closed
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ *
* @see audio_in_create()
*/
int audio_in_destroy(audio_in_h input);
/**
- * @brief Prepares reading audio input by starting buffering of audio data from the device.
+ * @brief Sets the sound stream information to the audio input.
+ *
+ * @since_tizen 3.0
+ *
+ * @remarks @a the sound stream information includes audio routing and volume type.
+ * For more details, you can refer to @ref CAPI_MEDIA_SOUND_MANAGER_MODULE
+ *
+ * @param[in] input The handle to the audio input
+ * @param[in] stream_info The handle of stream information
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
+ *
+ * @pre The state should be #AUDIO_IO_STATE_IDLE.\n
+ * Call audio_in_create() before calling this function.
+ * @post Call audio_in_prepare() after calling this function.
+ * @see sound_manager_create_stream_information()
+ * @see sound_manager_destroy_stream_information()
+ */
+int audio_in_set_stream_info(audio_in_h input, sound_stream_info_h stream_info);
+
+/**
+ * @brief Prepares the audio input for reading audio data by starting buffering of audio data from the device.
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
*
+ * @post The state will be #AUDIO_IO_STATE_RUNNING.
* @see audio_in_unprepare()
*/
int audio_in_prepare(audio_in_h input);
/**
- * @brief Unprepares reading audio input by stopping buffering the audio data from the device.
+ * @brief Unprepares the audio input.
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
+ *
+ * @post The state will be #AUDIO_IO_STATE_IDLE.
* @see audio_in_prepare()
*/
int audio_in_unprepare(audio_in_h input);
+/**
+ * @brief Pauses buffering of audio data from the device.
+ *
+ * @since_tizen 3.0
+ *
+ * @param[in] input The handle to the audio input
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
+ *
+ * @pre The state should be #AUDIO_IO_STATE_RUNNING.
+ * @post The state will be #AUDIO_IO_STATE_PAUSED.
+ * @see audio_in_resume()
+ */
+int audio_in_pause(audio_in_h input);
+
+/**
+ * @brief Resumes buffering audio data from the device.
+ *
+ * @since_tizen 3.0
+ *
+ * @param[in] input The handle to the audio input
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
+ *
+ * @pre The state should be #AUDIO_IO_STATE_PAUSED.
+ * @post The state will be #AUDIO_IO_STATE_RUNNING.
+ * @see audio_in_pause()
+ */
+int audio_in_resume(audio_in_h input);
+
/**
* @brief Flushes and discards buffered audio data from the input stream.
*
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
+ *
+ * @pre The state should be #AUDIO_IO_STATE_RUNNING or #AUDIO_IO_STATE_PAUSED.
*/
int audio_in_flush(audio_in_h input);
* @retval #AUDIO_IO_ERROR_SOUND_POLICY Sound policy error
* @retval #AUDIO_IO_ERROR_INVALID_OPERATION Invalid operation
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
- * @pre audio_in_start_recording().
-*/
+ *
+ * @pre The state should be #AUDIO_IO_STATE_RUNNING.
+ */
int audio_in_read(audio_in_h input, void *buffer, unsigned int length);
/**
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
* @see audio_in_read()
-*/
+ */
int audio_in_get_buffer_size(audio_in_h input, int *size);
/**
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
-*/
+ */
int audio_in_get_sample_rate(audio_in_h input, int *sample_rate);
/**
* @brief Gets the channel type of the audio input data stream.
*
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- *
* @details The audio channel type defines whether the audio is mono or stereo.
*
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ *
* @param[in] input The handle to the audio input
* @param[out] channel The audio channel type
* @return @c 0 on success,
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
-*/
+ */
int audio_in_get_channel(audio_in_h input, audio_channel_e *channel);
/**
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
-*/
+ */
int audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type);
/**
+ * @deprecated Deprecated since 3.0. Use sound_manager_create_stream_information() instead.
* @brief Registers a callback function to be invoked when the audio input handle is interrupted or the interrupt is completed.
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
int audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callback, void *user_data);
/**
+ * @deprecated Deprecated since 3.0
* @brief Unregisters the callback function.
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
int audio_in_unset_interrupted_cb(audio_in_h input);
/**
+ * @deprecated Deprecated since 3.0
* @brief Ignores session for input.
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
/**
* @brief Sets an asynchronous(event) callback function to handle recording PCM (pulse-code modulation) data.
*
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- *
* @details @a callback will be called when you can read a PCM data.
* It might cause dead lock if change the state of audio handle in callback.
* (ex: audio_in_destroy, audio_in_prepare, audio_in_unprepare)
* Recommend to use as a VOIP only.
* Recommend not to hold callback too long.(it affects latency)
*
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ *
* @remarks @a input must be created using audio_in_create().
*
* @param[in] input An audio input handle
* @param[in] callback notify stream callback when user can read data (#audio_in_stream_cb)
- * @param[in] userdata user data to be retrieved when callback is called
+ * @param[in] user_data user data to be retrieved when callback is called
* @return @c 0 on success,
* otherwise a negative error value
* @retval #AUDIO_IO_ERROR_NONE Successful
*
* @see audio_out_set_stream_cb()
*/
-int audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* userdata);
+int audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data);
/**
* @brief Unregisters the callback function.
/**
* @brief peek from audio in buffer
*
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- *
* @details This function works correctly only with read, write callback. Otherwise it won't operate as intended.
*
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ *
* @remarks @a Works only in asynchronous(event) mode. This will just retrieve buffer pointer from audio in buffer. Drop after use.
*
* @param[in] input The handle to the audio input
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #AUDIO_IO_ERROR_INVALID_OPERATION Invalid operation
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
*
+ * @pre The state should be #AUDIO_IO_STATE_RUNNING.
* @see audio_in_drop()
*/
int audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length);
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #AUDIO_IO_ERROR_INVALID_OPERATION Invalid operation
* @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
*
+ * @pre The state should be #AUDIO_IO_STATE_RUNNING.
* @see audio_in_peek()
*/
int audio_in_drop(audio_in_h input);
+/**
+ * @brief Sets the state changed callback function to the audio input handle.
+ *
+ * @since_tizen 3.0
+ *
+ * @remarks @a input must be created using audio_in_create().
+ *
+ * @param[in] input The audio input handle
+ * @param[in] callback the state changed callback called when the state of the handle is changed (#audio_in_state_changed_cb)
+ * @param[in] user_data user data to be retrieved when callback is called
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see audio_in_unset_state_changed_cb()
+ */
+int audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data);
+
+/**
+ * @brief Unregisters the state changed callback function of the audio input handle.
+ *
+ * @since_tizen 3.0
+ *
+ * @param[in] input The handle to the audio input
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see audio_in_set_state_changed_cb()
+ */
+int audio_in_unset_state_changed_cb(audio_in_h input);
+/**
+ * @}
+ */
//
// AUDIO OUTPUT
//
-/**
- * @}
-*/
-
/**
* @addtogroup CAPI_MEDIA_AUDIO_OUT_MODULE
* @{
* @remarks @a use audio_out_write() to write pcm data inside this callback.
* @param[in] handle The handle to the audio output
* @param[in] nbytes The amount of audio in data which can be written.
- * @param[in] userdata The user data passed from the callback registration function
+ * @param[in] user_data The user data passed from the callback registration function
*
* @see audio_out_set_stream_cb()
*/
-typedef void (*audio_out_stream_cb)(audio_out_h handle, size_t nbytes, void *userdata);
+typedef void (*audio_out_stream_cb)(audio_out_h handle, size_t nbytes, void *user_data);
/**
- * @brief Creates an audio device instance and returns an output handle to play PCM (pulse-code modulation) data.
+ * @brief Called when the state of audio output is changed.
+ *
+ * @since_tizen 3.0
+ *
+ * @param[in] handle The handle of the audio output
+ * @param[in] previous The previous state of the audio output
+ * @param[in] current The current state of the audio output
+ * @param[in] by_policy @c true if the state is changed by policy, otherwise @c false if the state is not changed by policy
+ * @param[in] user_data The user data passed from the callback registration function
+ *
+ * @see audio_out_set_state_changed_cb()
+ * @see audio_out_unset_state_changed_cb()
+ */
+typedef void (*audio_out_state_changed_cb)(audio_out_h handle, audio_io_state_e previous, audio_io_state_e current, bool by_policy, void *user_data);
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+/**
+ * @deprecated Deprecated since 3.0. Use audio_out_create_new() instead.
+ * @brief Creates an audio device instance and returns an output handle to play PCM (pulse-code modulation) data.
*
* @details This function is used for audio output initialization.
*
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ *
* @remarks @a output must be released by audio_out_destroy().
*
* @param[in] sample_rate The audio sample rate in 8000[Hz] ~ 48000[Hz]
* @param[in] channel The audio channel type (mono or stereo)
- * @param[in] type The type of audio sample (8- or 16-bit)
+ * @param[in] type The type of audio sample (8-bit or 16-bit)
* @param[in] sound_type The type of sound (#sound_type_e)
* @param[out] output An audio output handle is created on success
* @return @c 0 on success,
* @retval #AUDIO_IO_ERROR_SOUND_POLICY Sound policy error
*
* @see audio_out_destroy()
-*/
+ */
int audio_out_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h *output);
+/**
+ * @brief Creates an audio device instance and returns an output handle to play PCM (pulse-code modulation) data.
+ *
+ * @details This function is used for audio output initialization.
+ *
+ * @since_tizen 3.0
+ *
+ * @remarks @a output must be released by audio_out_destroy().
+ * It is recommended to call audio_out_set_stream_info() after this API.
+ *
+ * @param[in] sample_rate The audio sample rate in 8000[Hz] ~ 48000[Hz]
+ * @param[in] channel The audio channel type (mono or stereo)
+ * @param[in] type The type of audio sample (8-bit or 16-bit)
+ * @param[out] output An audio output handle is created on success
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #AUDIO_IO_ERROR_DEVICE_NOT_OPENED Device not opened
+ * @retval #AUDIO_IO_ERROR_SOUND_POLICY Sound policy error
+ *
+ * @post The state will be #AUDIO_IO_STATE_IDLE.\n
+ * audio_out_set_stream_info() is recommended to be called after this API.
+ * @see audio_out_destroy()
+ */
+int audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output);
+
/**
* @brief Releases the audio output handle, along with all its resources.
*
* @retval #AUDIO_IO_ERROR_DEVICE_NOT_CLOSED Device not closed
*
* @see audio_out_create()
-*/
+ */
int audio_out_destroy(audio_out_h output);
/**
- * @brief Prepares playing audio output, this must be called before audio_out_write().
+ * @brief Sets the sound stream information to the audio output.
+ *
+ * @since_tizen 3.0
+ *
+ * @remarks @a the sound stream information includes audio routing and volume type.
+ * For more details, you can refer to sound_manager.h
+ *
+ * @param[in] output The handle to the audio output
+ * @param[in] stream_info The handle of stream information
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
+ *
+ * @pre The state should be #AUDIO_IO_STATE_IDLE.\n
+ * Call audio_out_create_new() before calling this function.
+ * @post Call audio_out_prepare() after calling this function.
+ * @see sound_manager_create_stream_information()
+ * @see sound_manager_destroy_stream_information()
+ */
+int audio_out_set_stream_info(audio_out_h output, sound_stream_info_h stream_info);
+
+/**
+ * @brief Prepares the audio output for playback, this must be called before audio_out_write().
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*
* otherwise a negative error value
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
*
+ * @post The state will be #AUDIO_IO_STATE_RUNNING.
* @see audio_out_unprepare()
*/
int audio_out_prepare(audio_out_h output);
/**
- * @brief Unprepares playing audio output.
+ * @brief Unprepares the audio output.
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*
* otherwise a negative error value
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
*
+ * @post The state will be #AUDIO_IO_STATE_IDLE.
* @see audio_out_prepare()
*/
int audio_out_unprepare(audio_out_h output);
+/**
+ * @brief Pauses feeding of audio data to the device.
+ *
+ * @since_tizen 3.0
+ *
+ * @param[in] output The handle to the audio output
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
+ *
+ * @pre The state should be #AUDIO_IO_STATE_RUNNING.
+ * @post The state will be #AUDIO_IO_STATE_PAUSED.
+ * @see audio_out_resume()
+ */
+int audio_out_pause(audio_out_h output);
+
+/**
+ * @brief Resumes feeding of audio data to the device.
+ *
+ * @since_tizen 3.0
+ *
+ * @param[in] output The handle to the audio output
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
+ *
+ * @pre The state should be #AUDIO_IO_STATE_PAUSED.
+ * @post The state will be #AUDIO_IO_STATE_RUNNING.
+ * @see audio_out_pause()
+ */
+int audio_out_resume(audio_out_h output);
+
/**
* @brief Drains buffered audio data from the output stream.
*
* otherwise a negative error value
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
*
+ * @pre The state should be #AUDIO_IO_STATE_RUNNING or #AUDIO_IO_STATE_PAUSED.
* @see audio_out_flush()
*/
int audio_out_drain(audio_out_h output);
* otherwise a negative error value
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
*
+ * @pre The state should be #AUDIO_IO_STATE_RUNNING or #AUDIO_IO_STATE_PAUSED.
* @see audio_out_drain()
*/
int audio_out_flush(audio_out_h output);
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #AUDIO_IO_ERROR_INVALID_BUFFER Invalid buffer pointer
* @retval #AUDIO_IO_ERROR_SOUND_POLICY Sound policy error
-*/
+ * @retval #AUDIO_IO_ERROR_INVALID_STATE Invalid state
+ *
+ * @pre The state should be #AUDIO_IO_STATE_RUNNING.
+ */
int audio_out_write(audio_out_h output, void *buffer, unsigned int length);
/**
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
*
* @see audio_out_write()
-*/
+ */
int audio_out_get_buffer_size(audio_out_h output, int *size);
/**
* otherwise a negative error value
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
-*/
+ */
int audio_out_get_sample_rate(audio_out_h output, int *sample_rate);
/**
* @brief Gets the channel type of the audio output data stream.
+ *
* @details The audio channel type defines whether the audio is mono or stereo.
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
* otherwise a negative error value
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
-*/
+ */
int audio_out_get_channel(audio_out_h output, audio_channel_e *channel);
/**
* otherwise a negative error value
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
-*/
+ */
int audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type);
-
/**
* @brief Gets the sound type supported by the audio output device.
*
* otherwise a negative error value
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
-*/
+ */
int audio_out_get_sound_type(audio_out_h output, sound_type_e *type);
/**
+ * @deprecated Deprecated since 3.0. Use sound_manager_create_stream_information() instead.
* @brief Registers a callback function to be invoked when the audio output handle is interrupted or the interrupt is completed.
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
int audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data);
/**
+ * @deprecated Deprecated since 3.0
* @brief Unregisters the callback function.
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
int audio_out_unset_interrupted_cb(audio_out_h output);
/**
+ * @deprecated Deprecated since 3.0
* @brief Ignores session for output.
*
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
/**
* @brief Sets an asynchronous(event) callback function to handle playing PCM (pulse-code modulation) data.
*
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- *
* @details @a callback will be called when you can write a PCM data.
* It might cause dead lock if change the state of audio handle in callback.
* (ex: audio_in_destroy, audio_in_prepare, audio_in_unprepare)
* Recommend to use as a VOIP only.
* Recommend not to hold callback too long.(it affects latency)
*
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ *
* @remarks @a output must be created using audio_out_create().
*
* @param[in] output An audio output handle
* @param[in] callback notify stream callback when user can write data (#audio_out_stream_cb)
- * @param[in] userdata user data to be retrieved when callback is called
+ * @param[in] user_data user data to be retrieved when callback is called
* @return 0 on success, otherwise a negative error value
* @retval #AUDIO_IO_ERROR_NONE Successful
* @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
*
* @see audio_in_set_stream_cb()
*/
-int audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* userdata);
+int audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data);
/**
* @brief Unregisters the callback function.
* @see audio_out_set_stream_cb()
*/
int audio_out_unset_stream_cb(audio_out_h output);
+
+/**
+ * @brief Sets the state changed callback function to the audio output handle.
+ *
+ * @since_tizen 3.0
+ *
+ * @remarks @a input must be created using audio_out_create_new().
+ *
+ * @param[in] output The audio output handle
+ * @param[in] callback the state changed callback called when the state of the handle is changed (#audio_out_state_changed_cb)
+ * @param[in] user_data user data to be retrieved when callback is called
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see audio_out_unset_state_changed_cb()
+ */
+int audio_out_set_state_changed_cb(audio_out_h output, audio_out_state_changed_cb callback, void* user_data);
+
+/**
+ * @brief Unregisters the state changed callback function of the audio output handle.
+ *
+ * @since_tizen 3.0
+ *
+ * @param[in] output The handle to the audio output
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see audio_out_set_state_changed_cb()
+ */
+int audio_out_unset_state_changed_cb(audio_out_h output);
+
/**
* @}
-*/
+ */
#ifdef __cplusplus
}
+++ /dev/null
-/*
-* Copyright (c) 2011 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.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* 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.
-*/
-
-#ifndef __TIZEN_MEDIA_AUDIO_IO_PRIVATE_H__
-#define __TIZEN_MEDIA_AUDIO_IO_PRIVATE_H__
-#include <sound_manager.h>
-#include <mm_sound.h>
-#include "audio_io.h"
-
-/*
-* Internal Macros
-*/
-
-#define AUDIO_IO_INTERRUPTED_BY_RESUMABLE_MEDIA (AUDIO_IO_INTERRUPTED_BY_NOTIFICATION + 1)
-#define AUDIO_IO_INTERRUPTED_BY_RESUMABLE_CANCELED (AUDIO_IO_INTERRUPTED_BY_NOTIFICATION + 2)
-
-#define AUDIO_IO_CHECK_CONDITION(condition,error,msg) \
- if(condition) {} else \
- { LOGE("[%s] %s(0x%08x)",__FUNCTION__, msg,error); return error;}; \
-
-#define AUDIO_IO_NULL_ARG_CHECK(arg) \
- AUDIO_IO_CHECK_CONDITION(arg != NULL, AUDIO_IO_ERROR_INVALID_PARAMETER, "AUDIO_IO_ERROR_INVALID_PARAMETER" )
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct _audio_in_s{
- MMSoundPcmHandle_t mm_handle;
- int is_async;
- int is_loopback;
- int _buffer_size;
- int _sample_rate;
- audio_channel_e _channel;
- audio_sample_type_e _type;
- audio_io_interrupted_cb user_cb;
- void* user_data;
- audio_in_stream_cb stream_cb;
- void* stream_userdata;
-} audio_in_s;
-
-typedef struct _audio_out_s{
- MMSoundPcmHandle_t mm_handle;
- int is_async;
- int is_loopback;
- int _buffer_size;
- int _sample_rate;
- audio_channel_e _channel;
- audio_sample_type_e _type;
- sound_type_e _sound_type;
- audio_io_interrupted_cb user_cb;
- void* user_data;
- audio_out_stream_cb stream_cb;
- void* stream_userdata;
-} audio_out_s;
-
-int __convert_audio_io_error_code(int code, char *func_name);
-int __check_parameter(int sample_rate, audio_channel_e channel, audio_sample_type_e type);
-int __mm_sound_pcm_capture_msg_cb (int message, void *param, void *user_param);
-audio_io_interrupted_code_e __translate_interrupted_code (int code);
-
-int audio_in_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type , int source_type, audio_in_h* input);
-
-int audio_in_set_callback_private(audio_in_h input, audio_in_stream_cb callback, void* userdata);
-
-int audio_out_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h* output);
-
-int audio_out_set_callback_private(audio_out_h output, audio_out_stream_cb callback, void* userdata);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //__TIZEN_MEDIA_AUDIO_IO_PRIVATE_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#ifndef __TIZEN_MEDIA_CPP_AUDIO_IO_H__
+#define __TIZEN_MEDIA_CPP_AUDIO_IO_H__
+
+#include "audio_io.h"
+
+
+#ifdef __cplusplus
+
+
+extern "C"
+{
+#endif
+
+int cpp_audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h *input);
+int cpp_audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input);
+int cpp_audio_in_destroy(audio_in_h input);
+int cpp_audio_in_set_stream_info(audio_in_h input, sound_stream_info_h stream_info);
+int cpp_audio_in_prepare(audio_in_h input);
+int cpp_audio_in_unprepare(audio_in_h input);
+int cpp_audio_in_pause(audio_in_h input);
+int cpp_audio_in_resume(audio_in_h input);
+int cpp_audio_in_drain(audio_in_h input);
+int cpp_audio_in_flush(audio_in_h input);
+int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length);
+int cpp_audio_in_get_buffer_size(audio_in_h input, int *size);
+int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate);
+int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel);
+int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type);
+int cpp_audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callback, void *user_data);
+int cpp_audio_in_unset_interrupted_cb(audio_in_h input);
+int cpp_audio_in_ignore_session(audio_in_h input);
+int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data);
+int cpp_audio_in_unset_stream_cb(audio_in_h input);
+int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length);
+int cpp_audio_in_drop(audio_in_h input);
+int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data);
+int cpp_audio_in_unset_state_changed_cb(audio_in_h input);
+
+
+int cpp_audio_out_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h *output);
+int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output);
+int cpp_audio_out_destroy(audio_out_h output);
+int cpp_audio_out_set_stream_info(audio_out_h output, sound_stream_info_h stream_info);
+int cpp_audio_out_prepare(audio_out_h output);
+int cpp_audio_out_unprepare(audio_out_h output);
+int cpp_audio_out_pause(audio_out_h output);
+int cpp_audio_out_resume(audio_out_h output);
+int cpp_audio_out_drain(audio_out_h output);
+int cpp_audio_out_flush(audio_out_h output);
+int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length);
+int cpp_audio_out_get_buffer_size(audio_out_h output, int *size);
+int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate);
+int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel);
+int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type);
+int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type);
+int cpp_audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data);
+int cpp_audio_out_unset_interrupted_cb(audio_out_h output);
+int cpp_audio_out_ignore_session(audio_out_h output);
+int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data);
+int cpp_audio_out_unset_stream_cb(audio_out_h output);
+int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data);
+int cpp_audio_out_unset_state_changed_cb(audio_out_h output);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_MEDIA_CPP_AUDIO_IO_H__ */
<manifest>
- <request>
- <domain name="_"/>
- </request>
+ <request>
+ <domain name="_" />
+ </request>
</manifest>
Name: capi-media-audio-io
Summary: An Audio Input & Audio Output library in Tizen Native API
-Version: 0.2.3
+Version: 0.3.5
Release: 0
Group: Multimedia/API
License: Apache-2.0
Source1001: capi-media-audio-io.manifest
BuildRequires: cmake
BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(mm-common)
+BuildRequires: pkgconfig(mm-session)
BuildRequires: pkgconfig(mm-sound)
+BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(capi-media-sound-manager)
BuildRequires: pkgconfig(capi-base-common)
+BuildRequires: pkgconfig(libpulse)
+Requires(post): libprivilege-control
%description
An Audio Input & Audio Output library in Tizen Native API
%setup -q
cp %{SOURCE1001} .
-
%build
MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
%cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
%install
%make_install
+mkdir -p %{buildroot}/usr/share/privilege-control
-%post -p /sbin/ldconfig
+%post
+/sbin/ldconfig
+/usr/bin/api_feature_loader --verbose --dir=/usr/share/privilege-control
%postun -p /sbin/ldconfig
-
%files
%manifest %{name}.manifest
-%license LICENSE.APLv2
+%license LICENSE
%{_libdir}/libcapi-media-audio-io.so.*
%manifest capi-media-audio-io.manifest
%{_includedir}/media/audio_io.h
%{_libdir}/pkgconfig/*.pc
%{_libdir}/libcapi-media-audio-io.so
-
+#%{_prefix}/bin/audio_io_test
/*
-* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 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.
* limitations under the License.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <mm.h>
-#include "audio_io_private.h"
-#include <dlog.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "TIZEN_N_AUDIO_IO"
-#include <mm_sound_pcm_async.h>
-/*
-* Internal Implementation
-*/
+#include <mm.h>
+#include <cpp_audio_io.h>
-/*
-* Public 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, SUPPORT_SOURCE_TYPE_DEFAULT, input);
+ return cpp_audio_in_create(sample_rate, channel, type, 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, SUPPORT_SOURCE_TYPE_LOOPBACK, input);
+ return cpp_audio_in_create_loopback(sample_rate, channel, type, input);
}
int audio_in_destroy(audio_in_h input)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- audio_in_s *handle = (audio_in_s *) input;
- int ret = MM_ERROR_NONE;
-
- 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__);
- }
- free(handle);
+ return cpp_audio_in_destroy(input);
+}
- LOGI("[%s] mm_sound_pcm_capture_close() success",__FUNCTION__);
- return AUDIO_IO_ERROR_NONE;
+int audio_in_set_stream_info(audio_in_h input, sound_stream_info_h stream_info)
+{
+ return cpp_audio_in_set_stream_info(input, stream_info);
}
int audio_in_prepare(audio_in_h input)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- audio_in_s *handle = (audio_in_s *) input;
- int ret = MM_ERROR_NONE;
-
- 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__);
- }
-
- LOGI("[%s] mm_sound_pcm_capture_start() success",__FUNCTION__);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_in_prepare(input);
}
int audio_in_unprepare(audio_in_h input)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- audio_in_s *handle = (audio_in_s *) input;
- int ret = MM_ERROR_NONE;
+ return cpp_audio_in_unprepare(input);
+}
- 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__);
- }
+int audio_in_pause(audio_in_h input)
+{
+ return cpp_audio_in_pause(input);
+}
- LOGI("[%s] mm_sound_pcm_capture_stop() success",__FUNCTION__);
- return AUDIO_IO_ERROR_NONE;
+int audio_in_resume(audio_in_h input)
+{
+ return cpp_audio_in_resume(input);
}
int audio_in_flush(audio_in_h input)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- audio_in_s *handle = (audio_in_s *) input;
- int ret = MM_ERROR_NONE;
-
- 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__);
- }
-
- LOGI("[%s] mm_sound_pcm_capture_flush() success",__FUNCTION__);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_in_flush(input);
}
int audio_in_read(audio_in_h input, void *buffer, unsigned int length )
{
- 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;
-
- 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;
-
- 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;
+ return cpp_audio_in_read(input, buffer, length);
}
int audio_in_get_buffer_size(audio_in_h input, int *size)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- AUDIO_IO_NULL_ARG_CHECK(size);
- audio_in_s *handle = (audio_in_s *) input;
-
- *size = handle->_buffer_size;
-
- LOGI("[%s] buffer size = %d",__FUNCTION__, *size);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_in_get_buffer_size(input, size);
}
int audio_in_get_sample_rate(audio_in_h input, int *sample_rate)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- AUDIO_IO_NULL_ARG_CHECK(sample_rate);
- audio_in_s *handle = (audio_in_s *) input;
-
- *sample_rate = handle->_sample_rate;
-
- LOGI("[%s] sample rate = %d",__FUNCTION__, *sample_rate);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_in_get_sample_rate(input, sample_rate);
}
-
int audio_in_get_channel(audio_in_h input, audio_channel_e *channel)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- AUDIO_IO_NULL_ARG_CHECK(channel);
- audio_in_s *handle = (audio_in_s *) input;
-
- *channel = handle->_channel;
-
- LOGI("[%s] channel = %d",__FUNCTION__, *channel);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_in_get_channel(input, channel);
}
int audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- AUDIO_IO_NULL_ARG_CHECK(type);
- audio_in_s *handle = (audio_in_s *) input;
-
- *type = handle->_type;
-
- LOGI("[%s] sample type = %d",__FUNCTION__, *type);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_in_get_sample_type(input, type);
}
int audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callback, void *user_data)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- AUDIO_IO_NULL_ARG_CHECK(callback);
- audio_in_s *handle = (audio_in_s *) input;
-
- handle->user_cb = callback;
- handle->user_data = user_data;
-
- LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_in_set_interrupted_cb(input, callback, user_data);
}
int audio_in_unset_interrupted_cb(audio_in_h input)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- audio_in_s * handle = (audio_in_s *) input;
-
- handle->user_cb = NULL;
- handle->user_data = NULL;
-
- LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_in_unset_interrupted_cb(input);
}
int audio_in_ignore_session(audio_in_h input)
{
- AUDIO_IO_NULL_ARG_CHECK(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__);
- }
-
- LOGI("[%s] mm_sound_pcm_capture_ignore_session() success",__FUNCTION__);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_in_ignore_session(input);
}
-int audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* userdata)
+int audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- AUDIO_IO_NULL_ARG_CHECK(callback);
- return audio_in_set_callback_private(input, callback, userdata);
+ return cpp_audio_in_set_stream_cb(input, callback, user_data);
}
int audio_in_unset_stream_cb(audio_in_h input)
{
- AUDIO_IO_NULL_ARG_CHECK(input);
- return audio_in_set_callback_private(input, NULL, NULL);
+ return cpp_audio_in_unset_stream_cb(input);
}
int audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length)
{
- 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;
+ return cpp_audio_in_peek(input, buffer, length);
}
int audio_in_drop(audio_in_h input)
{
- 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;
- }
+ return cpp_audio_in_drop(input);
+}
- ret = mm_sound_pcm_capture_drop(handle->mm_handle);
- if (ret == MM_ERROR_NONE) {
- return ret;
- }
+int audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data)
+{
+ return cpp_audio_in_set_state_changed_cb(input, callback, user_data);
+}
- 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_unset_state_changed_cb(audio_in_h input)
+{
+ return cpp_audio_in_unset_state_changed_cb(input);
}
/* Audio Out */
int audio_out_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h* output)
{
- return audio_out_create_private(sample_rate, channel, type, sound_type, output);
+ return cpp_audio_out_create(sample_rate, channel, type, sound_type, output);
}
-int audio_out_destroy(audio_out_h output)
+int audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- audio_out_s *handle = (audio_out_s *) output;
- int ret = MM_ERROR_NONE;
+ return cpp_audio_out_create_new(sample_rate, channel, type, output);
+}
- 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__);
- }
- free(handle);
+int audio_out_destroy(audio_out_h output)
+{
+ return cpp_audio_out_destroy(output);
+}
- LOGI("[%s] mm_sound_pcm_play_close() success",__FUNCTION__);
- return AUDIO_IO_ERROR_NONE;
+int audio_out_set_stream_info(audio_out_h output, sound_stream_info_h stream_info)
+{
+ return cpp_audio_out_set_stream_info(output, stream_info);
}
int audio_out_prepare(audio_out_h output)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- audio_out_s *handle = (audio_out_s *) output;
- int ret = MM_ERROR_NONE;
-
- 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__);
- }
-
- LOGI("[%s] mm_sound_pcm_play_start() success",__FUNCTION__);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_out_prepare(output);
}
int audio_out_unprepare(audio_out_h output)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- audio_out_s *handle = (audio_out_s *) output;
- int ret = MM_ERROR_NONE;
-
- if (handle->is_async) {
- ret = mm_sound_pcm_play_stop_async(handle->mm_handle);
- } else {
- ret = mm_sound_pcm_play_stop(handle->mm_handle);
- }
+ return cpp_audio_out_unprepare(output);
+}
- if (ret != MM_ERROR_NONE) {
- return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
- }
+int audio_out_pause(audio_out_h output)
+{
+ return cpp_audio_out_pause(output);
+}
- LOGI("[%s] mm_sound_pcm_play_stop() success",__FUNCTION__);
- return AUDIO_IO_ERROR_NONE;
+int audio_out_resume(audio_out_h output)
+{
+ return cpp_audio_out_resume(output);
}
int audio_out_drain(audio_out_h output)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- audio_out_s *handle = (audio_out_s *) output;
- int ret = MM_ERROR_NONE;
-
- 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__);
- }
-
- LOGI("[%s] mm_sound_pcm_play_drain() success",__FUNCTION__);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_out_drain(output);
}
int audio_out_flush(audio_out_h output)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- audio_out_s *handle = (audio_out_s *) output;
- int ret = MM_ERROR_NONE;
-
- 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__);
- }
-
- LOGI("[%s] mm_sound_pcm_play_flush() success",__FUNCTION__);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_out_flush(output);
}
int audio_out_write(audio_out_h output, void* buffer, unsigned int length)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- AUDIO_IO_NULL_ARG_CHECK(buffer);
- audio_out_s *handle = (audio_out_s *) output;
- int ret = MM_ERROR_NONE;
-
- 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:
- ret = AUDIO_IO_ERROR_INVALID_OPERATION;
- LOGE("[%s] (0x%08x) : Not playing started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION);
- break;
- default:
- ret = __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
- break;
- }
- return ret;
+ return cpp_audio_out_write(output, buffer, length);
}
int audio_out_get_buffer_size(audio_out_h output, int *size)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- AUDIO_IO_NULL_ARG_CHECK(size);
- audio_out_s *handle = (audio_out_s *) output;
-
- *size = handle->_buffer_size;
-
- LOGI("[%s] buffer size = %d",__FUNCTION__, *size);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_out_get_buffer_size(output, size);
}
int audio_out_get_sample_rate(audio_out_h output, int *sample_rate)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- AUDIO_IO_NULL_ARG_CHECK(sample_rate);
- audio_out_s *handle = (audio_out_s *) output;
-
- *sample_rate = handle->_sample_rate;
-
- LOGI("[%s] sample rate = %d",__FUNCTION__, *sample_rate);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_out_get_sample_rate(output, sample_rate);
}
int audio_out_get_channel(audio_out_h output, audio_channel_e *channel)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- AUDIO_IO_NULL_ARG_CHECK(channel);
- audio_out_s *handle = (audio_out_s *) output;
-
- *channel = handle->_channel;
-
- LOGI("[%s] channel = %d",__FUNCTION__, *channel);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_out_get_channel(output, channel);
}
int audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- AUDIO_IO_NULL_ARG_CHECK(type);
- audio_out_s *handle = (audio_out_s *) output;
-
- *type = handle->_type;
-
- LOGI("[%s] sample type = %d",__FUNCTION__, *type);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_out_get_sample_type(output, type);
}
int audio_out_get_sound_type(audio_out_h output, sound_type_e *type)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- AUDIO_IO_NULL_ARG_CHECK(type);
- audio_out_s *handle = (audio_out_s *) output;
-
- *type = handle->_sound_type;
-
- LOGI("[%s] sound type = %d",__FUNCTION__, *type);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_out_get_sound_type(output, type);
}
int audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- AUDIO_IO_NULL_ARG_CHECK(callback);
- audio_out_s *handle = (audio_out_s *) output;
-
- handle->user_cb = callback;
- handle->user_data = user_data;
-
- LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_out_set_interrupted_cb(output, callback, user_data);
}
int audio_out_unset_interrupted_cb(audio_out_h output)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- audio_out_s *handle = (audio_out_s *) output;
-
- handle->user_cb = NULL;
- handle->user_data = NULL;
-
- LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
- return AUDIO_IO_ERROR_NONE;
+ return cpp_audio_out_unset_interrupted_cb(output);
}
int audio_out_ignore_session(audio_out_h output)
{
- AUDIO_IO_NULL_ARG_CHECK(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;
- }
+ return cpp_audio_out_ignore_session(output);
+}
- ret = mm_sound_pcm_play_ignore_session(handle->mm_handle);
- if (ret != MM_ERROR_NONE) {
- return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
- }
- LOGI("[%s] mm_sound_pcm_play_ignore_session() success",__FUNCTION__);
+int audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data)
+{
+ return cpp_audio_out_set_stream_cb(output, callback, user_data);
+}
- return AUDIO_IO_ERROR_NONE;
+int audio_out_unset_stream_cb(audio_out_h output)
+{
+ return cpp_audio_out_unset_stream_cb(output);
}
-int audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* userdata)
+int audio_out_set_state_changed_cb(audio_out_h output, audio_out_state_changed_cb callback, void* user_data)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- AUDIO_IO_NULL_ARG_CHECK(callback);
- return audio_out_set_callback_private(output, callback, userdata);
+ return cpp_audio_out_set_state_changed_cb(output, callback, user_data);
}
-int audio_out_unset_stream_cb(audio_out_h output)
+int audio_out_unset_state_changed_cb(audio_out_h output)
{
- AUDIO_IO_NULL_ARG_CHECK(output);
- return audio_out_set_callback_private(output, NULL, NULL);
+ return cpp_audio_out_unset_state_changed_cb(output);
}
+++ /dev/null
-/*
-* Copyright (c) 2011 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.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* 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.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <mm.h>
-#include "audio_io_private.h"
-#include <dlog.h>
-
-#include <mm_sound_pcm_async.h>
-
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "TIZEN_N_AUDIO_IO"
-/*
-* Internal Implementation
-*/
-int __convert_audio_io_error_code(int code, char *func_name)
-{
- int ret = AUDIO_IO_ERROR_INVALID_OPERATION;
- char* msg = "AUDIO_IO_ERROR_INVALID_OPERATION";
-
- switch(code)
- {
- case MM_ERROR_NONE:
- ret = AUDIO_IO_ERROR_NONE;
- msg = "AUDIO_IO_ERROR_NONE";
- break;
- case MM_ERROR_INVALID_ARGUMENT:
- case MM_ERROR_SOUND_DEVICE_INVALID_SAMPLERATE:
- case MM_ERROR_SOUND_DEVICE_INVALID_CHANNEL:
- case MM_ERROR_SOUND_DEVICE_INVALID_FORMAT:
- ret = AUDIO_IO_ERROR_INVALID_PARAMETER;
- msg = "AUDIO_IO_ERROR_INVALID_PARAMETER";
- break;
- case MM_ERROR_SOUND_DEVICE_NOT_OPENED:
- ret = AUDIO_IO_ERROR_DEVICE_NOT_OPENED;
- msg = "AUDIO_IO_ERROR_DEVICE_NOT_OPENED";
- break;
- case MM_ERROR_SOUND_PERMISSION_DENIED:
- ret = AUDIO_IO_ERROR_PERMISSION_DENIED;
- msg = "AUDIO_IO_ERROR_PERMISSION_DENIED";
- break;
- case MM_ERROR_SOUND_INTERNAL:
- ret = AUDIO_IO_ERROR_INVALID_OPERATION;
- msg = "AUDIO_IO_ERROR_INVALID_OPERATION";
- break;
- case MM_ERROR_SOUND_INVALID_POINTER:
- ret = AUDIO_IO_ERROR_INVALID_BUFFER;
- msg = "AUDIO_IO_ERROR_INVALID_BUFFER";
- break;
- case MM_ERROR_POLICY_BLOCKED:
- case MM_ERROR_POLICY_INTERRUPTED:
- case MM_ERROR_POLICY_INTERNAL:
- case MM_ERROR_POLICY_DUPLICATED:
- ret = AUDIO_IO_ERROR_SOUND_POLICY;
- msg = "AUDIO_IO_ERROR_SOUND_POLICY";
- break;
- }
- LOGE("[%s] %s(0x%08x) : core fw error(0x%x)",func_name,msg, ret, code);
- return ret;
-}
-
-int __check_parameter(int sample_rate, audio_channel_e channel, audio_sample_type_e type)
-{
- if(sample_rate<8000 || sample_rate > 48000) {
- LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample rate (8000~48000Hz) : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,sample_rate);
- return AUDIO_IO_ERROR_INVALID_PARAMETER;
- }
- if (channel < AUDIO_CHANNEL_MONO || channel > AUDIO_CHANNEL_STEREO) {
- LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid audio channel : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,channel);
- return AUDIO_IO_ERROR_INVALID_PARAMETER;
- }
- if (type < AUDIO_SAMPLE_TYPE_U8 || type > AUDIO_SAMPLE_TYPE_S16_LE) {
- LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample typel : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,type);
- return AUDIO_IO_ERROR_INVALID_PARAMETER;
- }
- return AUDIO_IO_ERROR_NONE;
-}
-
-//LCOV_EXCL_START
-audio_io_interrupted_code_e __translate_interrupted_code (int code)
-{
- audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED;
-
- switch(code)
- {
- case MM_MSG_CODE_INTERRUPTED_BY_CALL_END:
- case MM_MSG_CODE_INTERRUPTED_BY_ALARM_END:
- case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_END:
- case MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_END:
- e = AUDIO_IO_INTERRUPTED_COMPLETED;
- break;
-
- case MM_MSG_CODE_INTERRUPTED_BY_MEDIA:
- case MM_MSG_CODE_INTERRUPTED_BY_OTHER_PLAYER_APP:
- e = AUDIO_IO_INTERRUPTED_BY_MEDIA;
- break;
-
- case MM_MSG_CODE_INTERRUPTED_BY_CALL_START:
- e = AUDIO_IO_INTERRUPTED_BY_CALL;
- break;
-
- case MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG:
- e = AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG;
- break;
-
- case MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT:
- e = AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT;
- break;
-
- case MM_MSG_CODE_INTERRUPTED_BY_ALARM_START:
- e = AUDIO_IO_INTERRUPTED_BY_ALARM;
- break;
-
- case MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_START:
- e = AUDIO_IO_INTERRUPTED_BY_NOTIFICATION;
- break;
-
- case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_START:
- e = AUDIO_IO_INTERRUPTED_BY_EMERGENCY;
- break;
-
- case MM_MSG_CODE_INTERRUPTED_BY_RESUMABLE_MEDIA:
- e = AUDIO_IO_INTERRUPTED_BY_RESUMABLE_MEDIA;
- break;
-
- case MM_MSG_CODE_INTERRUPTED_BY_RESUMABLE_CANCELED:
- e = AUDIO_IO_INTERRUPTED_BY_RESUMABLE_CANCELED;
- break;
- }
-
- return e;
-}
-
-int __mm_sound_pcm_capture_msg_cb (int message, void *param, void *user_param)
-{
- audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED;
- audio_in_s *handle = (audio_in_s *) user_param;
- MMMessageParamType *msg = (MMMessageParamType*)param;
-
- LOGI("[%s] Got message type : 0x%x with code : %d" ,__FUNCTION__, message, msg->code);
-
- if (handle->user_cb == NULL) {
- LOGI("[%s] No interrupt callback is set. Skip this" ,__FUNCTION__);
- return 0;
- }
-
- if (message == MM_MESSAGE_SOUND_PCM_INTERRUPTED) {
- e = __translate_interrupted_code (msg->code);
- } else if (message == MM_MESSAGE_SOUND_PCM_CAPTURE_RESTRICTED) {
- /* TODO : handling restricted code is needed */
- /* e = _translate_restricted_code (msg->code); */
- }
-
- handle->user_cb (e, handle->user_data);
-
- return 0;
-}
-
-static int __mm_sound_pcm_playback_msg_cb (int message, void *param, void *user_param)
-{
- audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED;
- audio_out_s *handle = (audio_out_s *) user_param;
- MMMessageParamType *msg = (MMMessageParamType*)param;
-
- LOGI("[%s] Got message type : 0x%x with code : %d" ,__FUNCTION__, message, msg->code);
-
- if (handle->user_cb == NULL) {
- LOGI("[%s] No interrupt callback is set. Skip this" ,__FUNCTION__);
- return 0;
- }
-
- if (message == MM_MESSAGE_SOUND_PCM_INTERRUPTED) {
- e = __translate_interrupted_code (msg->code);
- }
-
- handle->user_cb (e, handle->user_data);
-
- return 0;
-}
-//LCOV_EXCL_STOP
-
-static int __audio_in_stream_cb (void* p, int nbytes, void* userdata)
-{
- audio_in_s *handle = (audio_in_s *) userdata;
-
- LOGI("<< p=%p, nbytes=%d, userdata=%p", p, nbytes, userdata);
-
- if (handle && handle->stream_cb) {
- handle->stream_cb ((audio_in_h)handle, nbytes, handle->stream_userdata);
- LOGI("<< handle->stream_cb(handle:%p, nbytes:%d, handle->stream_userdata:%p)", p, nbytes, userdata);
- } else {
- LOGI("No stream callback is set. Skip this");
- }
- return 0;
-}
-
-static int __audio_out_stream_cb (void* p, int nbytes, void* userdata)
-{
- audio_out_s *handle = (audio_out_s *) userdata;
- bool is_started = false;
- char * dummy = NULL;
-
- LOGI(">> p=%p, nbytes=%d, userdata=%p", p, nbytes, userdata);
-
- if (handle) {
- mm_sound_pcm_is_started_async(handle->mm_handle, &is_started);
- if (is_started) {
- if (handle->stream_cb) {
- handle->stream_cb ((audio_out_h)handle, nbytes, handle->stream_userdata);
- } else {
- LOGI("Started state but No stream callback is set. Skip this");
- }
- } else {
- LOGI("Not started....write dummy data");
- if ((dummy = (char*)malloc(nbytes)) != NULL) {
- memset (dummy, 0, nbytes);
- mm_sound_pcm_play_write_async(handle->mm_handle, (void*) dummy, nbytes);
- free (dummy);
- LOGI("write done!!!");
- } else {
- LOGE("ERROR : AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)", AUDIO_IO_ERROR_OUT_OF_MEMORY);
- }
- }
- } else {
- LOGE("Handle is invalid...");
- }
-
- return 0;
-}
-
-int audio_in_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type , int source_type, audio_in_h* input)
-{
- int ret = 0;
- audio_in_s *handle = NULL;
-
- /* input condition check */
- AUDIO_IO_NULL_ARG_CHECK(input);
- if(__check_parameter(sample_rate, channel, type) != AUDIO_IO_ERROR_NONE)
- return AUDIO_IO_ERROR_INVALID_PARAMETER;
-
- /* Create Handle & Fill information */
- if ((handle = (audio_in_s*)malloc( sizeof(audio_in_s))) == NULL) {
- LOGE("ERROR : AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)", AUDIO_IO_ERROR_OUT_OF_MEMORY);
- return AUDIO_IO_ERROR_OUT_OF_MEMORY;
- }
- memset(handle, 0, sizeof(audio_in_s));
-
-
- /* Capture open */
- if ((ret = mm_sound_pcm_capture_open_ex(&handle->mm_handle, sample_rate, channel, type, source_type)) < 0) {
- LOGE("mm_sound_pcm_capture_open_ex() failed [0x%x]", ret);
- goto ERROR;
- }
- LOGI("mm_sound_pcm_capture_open_ex() success");
-
-
- if (source_type == SUPPORT_SOURCE_TYPE_LOOPBACK)
- {
- handle->is_loopback = 1;
- }
-
- handle->_buffer_size = ret; /* return by pcm_open */
- handle->_sample_rate = sample_rate;
- handle->_channel = channel;
- handle->_type = type;
-
- /* Set message interrupt callback */
- if ((ret = mm_sound_pcm_set_message_callback(handle->mm_handle, __mm_sound_pcm_capture_msg_cb, handle)) < 0) {
- LOGE("mm_sound_pcm_set_message_callback() failed [0x%x]", ret);
- goto ERROR;
- }
- LOGI("mm_sound_pcm_set_message_callback() success");
-
- /* Handle assign */
- *input = (audio_in_h)handle;
-
- return AUDIO_IO_ERROR_NONE;
-
-ERROR:
- if (handle)
- free (handle);
- return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
-}
-
-int audio_in_set_callback_private(audio_in_h input, audio_in_stream_cb callback, void* userdata)
-{
- AUDIO_IO_NULL_ARG_CHECK(input);
-
- int ret = AUDIO_IO_ERROR_NONE;
- int source_type = SUPPORT_SOURCE_TYPE_DEFAULT;
- audio_in_s* handle = (audio_in_s*)input;
-
- // at first, release existing audio 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) {
- return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
- }
-
- // Initialize flags
- handle->stream_cb = NULL;
- handle->stream_userdata = NULL;
- handle->is_async = 0;
-
- // Checks loopback type
- if (handle->is_loopback == 1) {
- source_type = SUPPORT_SOURCE_TYPE_LOOPBACK;
- }
-
- /* Async (callback exists) or Sync (otherwise) */
- if (callback != NULL) {
- handle->stream_cb = callback;
- handle->stream_userdata = userdata;
- handle->is_async = 1;
-
- /* Capture open */
- if ((ret = mm_sound_pcm_capture_open_async(&handle->mm_handle, handle->_sample_rate, handle->_channel, handle->_type, source_type,
- (mm_sound_pcm_stream_cb_t)__audio_in_stream_cb, handle)) < 0) {
- LOGE("mm_sound_pcm_capture_open_async() failed [0x%x]", ret);
- return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
- }
- LOGI("mm_sound_pcm_capture_open_async() success");
- } else {
- /* Capture open */
- if ((ret = mm_sound_pcm_capture_open_ex(&handle->mm_handle, handle->_sample_rate, handle->_channel, handle->_type, source_type)) < 0) {
- LOGE("mm_sound_pcm_capture_open_ex() failed [0x%x]", ret);
- return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
- }
- LOGI("mm_sound_pcm_capture_open_ex() success");
- }
-
- handle->_buffer_size = ret; /* return by pcm_open */
-
- return AUDIO_IO_ERROR_NONE;
-}
-
-int audio_out_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h* output)
-{
- audio_out_s *handle = NULL;
- int ret = 0;
-
- /* input condition check */
- AUDIO_IO_NULL_ARG_CHECK(output);
- if(__check_parameter(sample_rate, channel, type)!=AUDIO_IO_ERROR_NONE)
- return AUDIO_IO_ERROR_INVALID_PARAMETER;
- if(sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_VOICE) {
- LOGE("ERROR : AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample sound type : %d",
- AUDIO_IO_ERROR_INVALID_PARAMETER,sound_type );
- return AUDIO_IO_ERROR_INVALID_PARAMETER;
- }
-
- /* Create Handle & Fill information */
- if ((handle = (audio_out_s*)malloc( sizeof(audio_out_s))) == NULL) {
- LOGE("ERROR : AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)", AUDIO_IO_ERROR_OUT_OF_MEMORY);
- return AUDIO_IO_ERROR_OUT_OF_MEMORY;
- }
- memset(handle, 0 , sizeof(audio_out_s));
-
-
- if ((ret = mm_sound_pcm_play_open(&handle->mm_handle,sample_rate, channel, type, sound_type)) < 0) {
- LOGE("mm_sound_pcm_play_open() failed [0x%x]", ret);
- goto ERROR;
- }
- LOGI("mm_sound_pcm_play_open() success");
-
-
- handle->_buffer_size = ret; /* return by pcm_open */
- handle->_sample_rate = sample_rate;
- handle->_channel = channel;
- handle->_type = type;
- handle->_sound_type = sound_type;
-
- /* Set message interrupt callback */
- if ((ret = mm_sound_pcm_set_message_callback(handle->mm_handle, __mm_sound_pcm_playback_msg_cb, handle)) < 0) {
- LOGE("mm_sound_pcm_set_message_callback() failed [0x%x]", ret);
- goto ERROR;
- }
- LOGI("mm_sound_pcm_set_message_callback() success");
-
- /* Handle assign */
- *output = (audio_out_h)handle;
-
- return AUDIO_IO_ERROR_NONE;
-
-ERROR:
- if (handle)
- free (handle);
- return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
-}
-
-int audio_out_set_callback_private(audio_out_h output, audio_out_stream_cb callback, void* userdata)
-{
- AUDIO_IO_NULL_ARG_CHECK(output);
-
- int ret = AUDIO_IO_ERROR_NONE;
- audio_out_s* handle = (audio_out_s*)output;
-
- // at first, release existing 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) {
- return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
- }
-
- // Initialize flags
- handle->stream_cb = NULL;
- handle->stream_userdata = NULL;
- handle->is_async = 0;
-
- /* Async (callback exists) or Sync (otherwise) */
- if (callback != NULL) {
- handle->stream_cb = callback;
- handle->stream_userdata = userdata;
- handle->is_async = 1;
-
- /* Playback open */
- if ((ret = mm_sound_pcm_play_open_async(&handle->mm_handle, handle->_sample_rate, handle->_channel, handle->_type, handle->_sound_type,
- (mm_sound_pcm_stream_cb_t)__audio_out_stream_cb, handle)) < 0) {
- LOGE("mm_sound_pcm_play_open_async() failed [0x%x]", ret);
- return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
- }
- LOGI("mm_sound_pcm_play_open_async() success");
- } else {
- if ((ret = mm_sound_pcm_play_open(&handle->mm_handle, handle->_sample_rate, handle->_channel, handle->_type, handle->_sound_type)) < 0) {
- LOGE("mm_sound_pcm_play_open() failed [0x%x]", ret);
- return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
- }
- LOGI("mm_sound_pcm_play_open() success");
- }
- handle->_buffer_size = ret; /* return by pcm_open */
-
- return AUDIO_IO_ERROR_NONE;
-}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <dlog.h>
+#include "CAudioIODef.h"
+
+
+using namespace std;
+using namespace tizen_media_audio;
+
+
+/**
+ * class CAudioError
+ */
+CAudioError::EError CAudioError::mLastError = CAudioError::ERROR_NONE;
+char CAudioError::mLastErrorMsg[CAudioError::MSG_LENGTH];
+
+CAudioError::CAudioError(EError err) : mError(err) {
+ mLastError = mError;
+}
+
+CAudioError::CAudioError(EError err, const char* fileName, const char* parentFunc, int lineNum) : mError(err) {
+ mLastError = mError;
+
+ const char* findFileName = strrchr(fileName, '/');
+ findFileName++;
+ const char* errStr = _convertErrorToString(mError);
+
+ snprintf(mErrorMsg, CAudioError::MSG_LENGTH, "["
+ COLOR_RED "THROW" COLOR_END ":%s|"
+ COLOR_YELLOW "ERR" COLOR_END ":%s|"
+ COLOR_YELLOW "FUNC" COLOR_END ":%s(%d)]", findFileName, errStr, parentFunc, lineNum);
+
+ snprintf(mLastErrorMsg, CAudioError::MSG_LENGTH, "LastError:%s", mErrorMsg);
+}
+
+CAudioError::CAudioError(EError err, const char* msg, const char* fileName, const char* parentFunc, int lineNum) : mError(err) {
+ mLastError = mError;
+
+ const char* findFileName = strrchr(fileName, '/');
+ findFileName++;
+ const char* errStr = _convertErrorToString(mError);
+
+ snprintf(mErrorMsg, CAudioError::MSG_LENGTH, "["
+ COLOR_RED "THROW" COLOR_END ":%s|"
+ COLOR_YELLOW "ERR" COLOR_END ":%s|"
+ COLOR_YELLOW "FUNC" COLOR_END ":%s(%d)]"
+ COLOR_YELLOW "MSG" COLOR_END ":"
+ COLOR_CYAN "%s" COLOR_END, findFileName, errStr, parentFunc, lineNum, msg);
+
+ snprintf(mLastErrorMsg, CAudioError::MSG_LENGTH, "LastError:%s", mErrorMsg);
+}
+
+//CAudioError::CAudioError(CAudioError& err) {
+// mError = err.mError;
+// strncpy(mErrorMsg, err.mErrorMsg, MSG_LENGTH);
+//}
+
+CAudioError::~CAudioError() {
+}
+
+const char* CAudioError::_convertErrorToString(EError err) {
+ switch (err) {
+
+ default:
+ case ERROR_NONE: return COLOR_GREEN "ERROR_NONE" COLOR_END;
+ case ERROR_INVALID_ARGUMENT: return COLOR_RED "ERROR_INVALID_ARGUMENT" COLOR_END;
+ case ERROR_INVALID_HANDLE: return COLOR_RED "ERROR_INVALID_HANDLE" COLOR_END;
+ case ERROR_INVALID_SAMPLERATE: return COLOR_RED "ERROR_INVALID_SAMPLERATE" COLOR_END;
+ case ERROR_INVALID_CHANNEL: return COLOR_RED "ERROR_INVALID_CHANNEL" COLOR_END;
+ case ERROR_INVALID_FORMAT: return COLOR_RED "ERROR_INVALID_FORMAT" COLOR_END;
+ case ERROR_INVALID_POINTER: return COLOR_RED "ERROR_INVALID_POINTER" COLOR_END;
+ case ERROR_INVALID_OPERATION: return COLOR_RED "ERROR_INVALID_OPERATION" COLOR_END;
+ case ERROR_NOT_INITIALIZED: return COLOR_RED "ERROR_NOT_INITIALIZED" COLOR_END;
+ case ERROR_NOT_SUPPORTED: return COLOR_RED "ERROR_NOT_SUPPORTED" COLOR_END;
+ case ERROR_PERMISSION_DENIED: return COLOR_RED "ERROR_PERMISSION_DENIED" COLOR_END;
+ case ERROR_DEVICE_NOT_OPENED: return COLOR_RED "ERROR_DEVICE_NOT_OPENED" COLOR_END;
+ case ERROR_DEVICE_NOT_CLOSED: return COLOR_RED "ERROR_DEVICE_NOT_CLOSED" COLOR_END;
+ case ERROR_OUT_OF_MEMORY: return COLOR_RED "ERROR_OUT_OF_MEMORY" COLOR_END;
+ case ERROR_INTERNAL_OPERATION: return COLOR_RED "ERROR_INTERNAL_OPERATION" COLOR_END;
+ case ERROR_FAILED_OPERATION: return COLOR_RED "ERROR_FAILED_OPERATION" COLOR_END;
+ case ERROR_POLICY_BLOCKED: return COLOR_RED "ERROR_POLICY_BLOCKED" COLOR_END;
+ case ERROR_POLICY_INTERRUPTED: return COLOR_RED "ERROR_POLICY_INTERRUPTED" COLOR_END;
+ case ERROR_POLICY_DUPLICATED: return COLOR_RED "ERROR_POLICY_DUPLICATED" COLOR_END;
+ }
+}
+
+CAudioError::EError CAudioError::getLastError() {
+ return mLastError;
+}
+
+const char* CAudioError::getLastErrorMsg() {
+ return mLastErrorMsg;
+}
+
+CAudioError::EError CAudioError::getError() {
+ return mError;
+}
+
+const char* CAudioError::getErrorMsg() {
+ return mErrorMsg;
+}
+
+CAudioError& CAudioError::operator = (const EError err) {
+ mError = err;
+ mLastError = mError;
+ return *this;
+}
+
+CAudioError& CAudioError::operator = (const CAudioError& err) {
+ mError = err.mError;
+ mLastError = mError;
+ memcpy(mErrorMsg, err.mErrorMsg, MSG_LENGTH);
+ memcpy(mLastErrorMsg, mErrorMsg, MSG_LENGTH);
+ return *this;
+}
+
+bool CAudioError::operator != (const EError err) {
+ return (mError != err);
+}
+
+bool CAudioError::operator == (const EError err) {
+ return (mError == err);
+}
+
+//bool operator == (const CAudioError& src, const CAudioError::EError& err) {
+// //return (src.mLastError == err);
+// return true;
+//}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#include <mm.h>
+#include <pthread.h>
+#include <assert.h>
+#include <audio-session-manager.h>
+#include "CAudioIODef.h"
+
+#define AUDIO_IO_DEBUG
+
+using namespace std;
+using namespace tizen_media_audio;
+
+
+/**
+ * class CAudioIO
+ */
+CAudioIO::CAudioIO() : mIsInit(false), mForceIgnore(false), mpAudioSessionHandler(NULL), mpPulseAudioClient(NULL) {
+ mState = CAudioInfo::AUDIO_IO_STATE_NONE;
+ mStatePrev = CAudioInfo::AUDIO_IO_STATE_NONE;
+ mByPolicy = false;
+}
+
+CAudioIO::CAudioIO(CAudioInfo& audioInfo) : mIsInit(false), mForceIgnore(false), mpAudioSessionHandler(NULL), mpPulseAudioClient(NULL) {
+ mAudioInfo = audioInfo;
+ mState = CAudioInfo::AUDIO_IO_STATE_NONE;
+ mStatePrev = CAudioInfo::AUDIO_IO_STATE_NONE;
+ mByPolicy = false;
+}
+
+CAudioIO::~CAudioIO() {
+}
+
+void CAudioIO::setInit(bool flag) {
+ mIsInit = flag;
+}
+
+bool CAudioIO::isInit() {
+ return mIsInit;
+}
+
+bool CAudioIO::IsReady() {
+ return ((mState == CAudioInfo::AUDIO_IO_STATE_RUNNING || mState == CAudioInfo::AUDIO_IO_STATE_PAUSED)? true : false);
+}
+
+void CAudioIO::internalLock() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ if (pthread_mutex_lock(&mMutex) != 0) {
+ THROW_ERROR_MSG(CAudioError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock()");
+ }
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD(COLOR_RED"LOCK"COLOR_END);
+#endif
+}
+
+void CAudioIO::internalUnlock() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ if (pthread_mutex_unlock(&mMutex) != 0) {
+ THROW_ERROR_MSG(CAudioError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock()");
+ }
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD(COLOR_GREEN"UNLOCK"COLOR_END);
+#endif
+}
+
+void CAudioIO::internalWait() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD(COLOR_RED"WAIT"COLOR_END);
+#endif
+
+ pthread_cond_wait(&mCond, &mMutex);
+}
+
+void CAudioIO::internalSignal() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD(COLOR_GREEN"SIGNAL"COLOR_END);
+#endif
+
+ pthread_cond_signal(&mCond);
+}
+
+bool CAudioIO::isForceIgnore() {
+ return mForceIgnore;
+}
+
+void CAudioIO::initialize() throw (CAudioError) {
+ if (mIsInit == true) {
+ return;
+ }
+
+ AUDIO_IO_LOGD("initialize");
+
+ int ret = pthread_mutex_init(&mMutex, NULL);
+ if (ret != 0) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pthread_mutex_init()");
+ }
+
+ ret = pthread_cond_init(&mCond, NULL);
+ if (ret != 0) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pthread_cond_init()");
+ }
+
+ mIsInit = true;
+}
+
+void CAudioIO::finalize() {
+ if (mIsInit == false) {
+ return;
+ }
+
+ AUDIO_IO_LOGD("finalize");
+
+ int ret = pthread_mutex_destroy(&mMutex);
+ if (ret != 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pthread_mutex_destroy() ret:%d", ret);
+ }
+
+ ret = pthread_cond_destroy(&mCond);
+ if (ret != 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pthread_cond_destroy() ret:%d", ret);
+ }
+
+ mIsInit = false;
+}
+
+void CAudioIO::onStream(CPulseAudioClient* pClient, size_t length) {
+ assert(mIsInit == true);
+ assert(pClient != NULL);
+ assert(length > 0);
+
+ if (mStreamCallback.onStream != NULL) {
+ mStreamCallback.onStream(length, mStreamCallback.mUserData);
+ }
+}
+
+void CAudioIO::onStateChanged(CAudioInfo::EAudioIOState state, bool byPolicy) {
+ assert(mIsInit == true);
+ assert(state > 0);
+
+ mStatePrev = mState;
+ mState = state;
+ mByPolicy = byPolicy;
+
+ AUDIO_IO_LOGD("current(%d), previous(%d), by_policy(%d)", mState, mStatePrev, mByPolicy);
+
+ if (mStateChangedCallback.onStateChanged != NULL) {
+ mStateChangedCallback.onStateChanged(mState, mStatePrev, mByPolicy, mStateChangedCallback.mUserData);
+ }
+}
+
+void CAudioIO::onStateChanged(CAudioInfo::EAudioIOState state) {
+ onStateChanged(state, false);
+}
+
+void CAudioIO::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info) {
+ assert(pHandler);
+
+ int session_option = pHandler->getOptions();
+
+ if (id == -1) {
+ ///////////////////////////////////////
+ // Triggered by 'focus watch callback'
+ ///////////////////////////////////////
+
+ if (session_option & (ASM_SESSION_OPTION_PAUSE_OTHERS | ASM_SESSION_OPTION_UNINTERRUPTIBLE)) {
+ AUDIO_IO_LOGD("Session option is pausing others or uninterruptible, skip...");
+ return;
+ }
+
+ if (state == FOCUS_IS_RELEASED) {
+ // Focus handle(id) of the other application was released, do resume if possible
+ internalLock();
+
+ mpPulseAudioClient->cork(false);
+ onStateChanged(CAudioInfo::AUDIO_IO_STATE_RUNNING);
+
+ internalUnlock();
+
+ // Focus watch callback doesn't have focus handle, but it need to convert & report to application for convenience
+ state = FOCUS_IS_ACQUIRED;
+ } else if (state == FOCUS_IS_ACQUIRED) {
+ // Focus handle(id) of the other application was acquired, do pause if possible
+ internalLock();
+ if (mpPulseAudioClient->getStreamDirection() == CPulseAudioClient::STREAM_DIRECTION_PLAYBACK) {
+ if (mpPulseAudioClient->drain() == false) {
+ AUDIO_IO_LOGE("Failed CPulseAudioClient::drain()");
+ }
+ }
+
+ mpPulseAudioClient->cork(true);
+ onStateChanged(CAudioInfo::AUDIO_IO_STATE_PAUSED);
+
+ internalUnlock();
+
+ // Focus watch callback doesn't have focus handle, but it need to convert & report to application for convenience
+ state = FOCUS_IS_RELEASED;
+ }
+ } else {
+ ///////////////////////////////////////
+ // Triggered by 'focus callback'
+ ///////////////////////////////////////
+
+ if (pHandler->getId() != id) {
+ AUDIO_IO_LOGW("Id is different, why? [mId : %d]", pHandler->getId());
+ }
+
+ if (session_option & ASM_SESSION_OPTION_UNINTERRUPTIBLE) {
+ AUDIO_IO_LOGD("Session option is uninterruptible, skip...");
+ return;
+ }
+
+ if (state == FOCUS_IS_RELEASED) {
+ // Focus handle(id) was released, do pause here
+ internalLock();
+ if (mpPulseAudioClient->getStreamDirection() == CPulseAudioClient::STREAM_DIRECTION_PLAYBACK) {
+ if (mpPulseAudioClient->drain() == false) {
+ AUDIO_IO_LOGE("Failed CPulseAudioClient::drain()");
+ }
+ }
+
+ mpPulseAudioClient->cork(true);
+ onStateChanged(CAudioInfo::AUDIO_IO_STATE_PAUSED);
+
+ internalUnlock();
+ } else if (state == FOCUS_IS_ACQUIRED) {
+ // Focus handle(id) was acquired again,
+ // check reason_for_change ("call-voice","call-video","voip","alarm","notification", ...)
+ // do resume here and call interrupt completed callback to application.
+ internalLock();
+
+ mpPulseAudioClient->cork(false);
+ onStateChanged(CAudioInfo::AUDIO_IO_STATE_RUNNING);
+
+ internalUnlock();
+ }
+ }
+
+ if (mInterruptCallback.onInterrupt != NULL) {
+ IAudioSessionEventListener::EInterruptCode e = IAudioSessionEventListener::INTERRUPT_COMPLETED;
+ e = IAudioSessionEventListener::convertInterruptedCode(state, reason_for_change);
+ mInterruptCallback.onInterrupt(e, mInterruptCallback.mUserData);
+ }
+}
+
+void CAudioIO::onSignal(CAudioSessionHandler* pHandler, mm_sound_signal_name_t signal, int value) {
+ assert(pHandler);
+
+ if (signal == MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS) {
+ if (value == 1 && pHandler->getSubscribeId() >= 0) {
+ // Unregister focus watch callback & disable session handler
+ pHandler->disableSessionHandler();
+ AUDIO_IO_LOGD("Session handler disabled by signal");
+ } else if (value == 0) {
+ // Currently do nothing...
+ }
+ }
+}
+
+void CAudioIO::prepare() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ try {
+ internalLock();
+ AUDIO_IO_LOGD("prepare");
+ /* Do nothing */
+ internalUnlock();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioIO::unprepare() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ try {
+ internalLock();
+ AUDIO_IO_LOGD("unprepare");
+ /* Do nothing */
+ internalUnlock();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioIO::pause() throw (CAudioError) {
+ if (mIsInit == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
+ }
+
+ try {
+ internalLock();
+ AUDIO_IO_LOGD("pause");
+ mpPulseAudioClient->cork(true);
+ internalUnlock();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioIO::resume() throw (CAudioError) {
+ if (mIsInit == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
+ }
+
+ try {
+ internalLock();
+ AUDIO_IO_LOGD("resume");
+ mpPulseAudioClient->cork(false);
+ internalUnlock();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioIO::drain() throw (CAudioError) {
+ if (mIsInit == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
+ }
+
+ try {
+ internalLock();
+ AUDIO_IO_LOGD("drain");
+ mpPulseAudioClient->drain();
+ internalUnlock();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioIO::flush() throw (CAudioError) {
+ if (mIsInit == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
+ }
+
+ try {
+ internalLock();
+ AUDIO_IO_LOGD("flush");
+ mpPulseAudioClient->flush();
+ internalUnlock();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+CAudioInfo CAudioIO::getAudioInfo() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ return mAudioInfo;
+}
+
+void CAudioIO::setStreamCallback(SStreamCallback callback) throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ internalLock();
+ mStreamCallback = callback;
+ internalUnlock();
+}
+
+CAudioIO::SStreamCallback CAudioIO::getStreamCallback() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ return mStreamCallback;
+}
+
+void CAudioIO::setStateChangedCallback(SStateChangedCallback callback) throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ internalLock();
+ mStateChangedCallback = callback;
+ internalUnlock();
+}
+
+CAudioIO::SStateChangedCallback CAudioIO::getStateChangedCallback() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ return mStateChangedCallback;
+}
+
+void CAudioIO::setInterruptCallback(SInterruptCallback callback) throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ mInterruptCallback = callback;
+}
+
+CAudioIO::SInterruptCallback CAudioIO::getInterruptCallback() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ return mInterruptCallback;
+}
+
+
+void CAudioIO::ignoreSession() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
+ }
+
+ internalLock();
+
+ try {
+ if (mpPulseAudioClient != NULL && mpPulseAudioClient->isCorked() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_INVALID_OPERATION, "An Operation is not permitted while started");
+ }
+
+ bool isSkip = mpAudioSessionHandler->isSkipSessionEvent();
+ if (isSkip == false && mpAudioSessionHandler->getId() >= 0) {
+ mpAudioSessionHandler->unregisterSound();
+ mForceIgnore = true;
+ }
+ } catch (CAudioError e) {
+ internalUnlock();
+
+ throw e;
+ }
+
+ internalUnlock();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#include <stdio.h>
+#include "CAudioIODef.h"
+
+
+using namespace std;
+using namespace tizen_media_audio;
+
+
+/**
+ * class CAudioInfo
+ */
+CAudioInfo::CAudioInfo()
+ : mSampleRate(MAX_SYSTEM_SAMPLERATE), mChannel(CHANNEL_MONO),
+ mSampleType(SAMPLE_TYPE_U8), mAudioType(AUDIO_IN_TYPE_MEDIA),
+ mAudioIndex(-1) {
+}
+
+CAudioInfo::CAudioInfo(unsigned int sampleRate, EChannel channel, ESampleType sampleType, EAudioType audioType, int audioIndex) throw (CAudioError)
+ : mSampleRate(sampleRate), mChannel(channel), mSampleType(sampleType), mAudioType(audioType), mAudioIndex(audioIndex) {
+ // Check to invalid AudioInfo
+ if (sampleRate < CAudioInfo::MIN_SYSTEM_SAMPLERATE || sampleRate > CAudioInfo::MAX_SYSTEM_SAMPLERATE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "The sampleRate is invalid [sampleRate:%d]", sampleRate);
+ }
+
+ if (channel < CAudioInfo::CHANNEL_MONO || channel >= CAudioInfo::CHANNEL_MAX) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "The channel is invalid [channel:%d]", channel);
+ }
+
+ if (sampleType < CAudioInfo::SAMPLE_TYPE_U8 || sampleType >= CAudioInfo::SAMPLE_TYPE_MAX) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "The sampleType is invalid [sampleType:%d]", sampleType);
+ }
+
+ if (audioType < CAudioInfo::AUDIO_IN_TYPE_MEDIA || audioType >= CAudioInfo::AUDIO_TYPE_MAX) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "The audioType is invalid [audioType:%d]", audioType);
+ }
+}
+
+unsigned int CAudioInfo::getSampleRate() {
+ return mSampleRate;
+}
+
+CAudioInfo::EChannel CAudioInfo::getChannel() {
+ return mChannel;
+}
+
+CAudioInfo::ESampleType CAudioInfo::getSampleType() {
+ return mSampleType;
+}
+
+CAudioInfo::EAudioType CAudioInfo::getAudioType() {
+ return mAudioType;
+}
+
+void CAudioInfo::setAudioType(CAudioInfo::EAudioType AudioType) {
+ mAudioType = AudioType;
+ return;
+}
+
+int CAudioInfo::getAudioIndex() {
+ return mAudioIndex;
+}
+
+void CAudioInfo::setAudioIndex(int AudioIndex) {
+ mAudioIndex = AudioIndex;
+ return;
+}
+
+void CAudioInfo::convertAudioType2StreamType (CAudioInfo::EAudioType audioType, char **streamType)
+{
+ if (audioType < CAudioInfo::AUDIO_IN_TYPE_MEDIA || audioType >= CAudioInfo::AUDIO_TYPE_MAX) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "The audioType is invalid [audioType:%d]", audioType);
+ }
+ *streamType = (char *)StreamTypeTable[audioType];
+ return;
+}
+
+void CAudioInfo::convertStreamType2AudioType (char *streamType, CAudioInfo::EAudioType *audioType)
+{
+ unsigned int i;
+ for (i = 0 ; i < CAudioInfo::AUDIO_TYPE_MAX ; i++) {
+ if (!strcmp((char *)StreamTypeTable[i], streamType)) {
+ break;
+ }
+ }
+ if (i < CAudioInfo::AUDIO_IN_TYPE_MEDIA || i >= CAudioInfo::AUDIO_TYPE_MAX) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "The streamType is invalid [streamType:%s]", streamType);
+ }
+ *audioType = (CAudioInfo::EAudioType)i;
+ return;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#include "CAudioIODef.h"
+
+
+using namespace std;
+using namespace tizen_media_audio;
+
+
+/**
+ * class CAudioInput inherited by CAudioIO
+ */
+CAudioInput::CAudioInput(CAudioInfo& info)
+ : CAudioIO(info),
+ mpSyncReadDataPtr(NULL),
+ mSyncReadIndex(0),
+ mSyncReadLength(0),
+ mIsUsedSyncRead(true) {
+}
+
+CAudioInput::CAudioInput(
+ unsigned int sampleRate,
+ CAudioInfo::EChannel channel,
+ CAudioInfo::ESampleType type,
+ CAudioInfo::EAudioType audioType)
+ : mpSyncReadDataPtr(NULL),
+ mSyncReadIndex(0),
+ mSyncReadLength(0),
+ mIsUsedSyncRead(true) {
+ mAudioInfo = CAudioInfo(sampleRate, channel, type, audioType, -1);
+}
+
+CAudioInput::~CAudioInput() {
+}
+
+void CAudioInput::onStream(CPulseAudioClient* pClient, size_t length) {
+ assert(pClient);
+
+ /*
+ * Does not call CAudioIO::onStream() for synchronization
+ * if a user is using read()
+ */
+ if (mIsUsedSyncRead == true) {
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("Sync Read Mode! - signal! - pClient:[%p], length:[%d]", pClient, length);
+#endif
+ internalSignal();
+ return;
+ }
+
+ /*
+ * Accrues callback function
+ */
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("pClient:[%p], length:[%d]", pClient, length);
+#endif
+ CAudioIO::onStream(pClient, length);
+}
+
+void CAudioInput::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info) {
+ assert(pHandler);
+ AUDIO_IO_LOGD("[pHandler:0x%x], [focus_type:%d], [state:%d], [reason_for_change:%s], [additional_info:%s]", pHandler, focus_type, state, reason_for_change, additional_info);
+ CAudioIO::onInterrupt(pHandler, id, focus_type, state, reason_for_change, additional_info);
+}
+
+void CAudioInput::onSignal(CAudioSessionHandler* pHandler, mm_sound_signal_name_t signal, int value) {
+ assert(pHandler);
+ AUDIO_IO_LOGD("[pHandler:0x%x], [signal:%d], [value:%d]", pHandler, signal, value);
+ CAudioIO::onSignal(pHandler, signal, value);
+}
+
+void CAudioInput::setInit(bool flag) {
+ mIsInit = flag;
+}
+
+bool CAudioInput::IsInit() {
+ return (CAudioIO::isInit() == true && mIsInit == true);
+}
+
+bool CAudioInput::IsReady() {
+ return CAudioIO::IsReady();
+}
+
+void CAudioInput::initialize() throw (CAudioError) {
+ if (IsInit() == true) {
+ return;
+ }
+
+ try {
+ CAudioIO::initialize();
+
+ // Create ASM Handler
+ mpAudioSessionHandler = new CAudioSessionHandler(CAudioSessionHandler::AUDIO_SESSION_TYPE_CAPTURE, mAudioInfo, this);
+ if (mpAudioSessionHandler == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed to allocate CAudioSessionHandler object");
+ }
+
+ // Initialize ASM Handler
+ mpAudioSessionHandler->initialize();
+
+ setInit(true);
+ CAudioIO::onStateChanged(CAudioInfo::AUDIO_IO_STATE_IDLE);
+ } catch (CAudioError err) {
+ finalize();
+ throw err;
+ }
+}
+
+void CAudioInput::finalize() {
+ if (IsInit() == false) {
+ AUDIO_IO_LOGD("Did not initialize");
+ return;
+ }
+
+ SAFE_FINALIZE(mpAudioSessionHandler);
+ SAFE_DELETE(mpAudioSessionHandler);
+
+ CAudioIO::finalize();
+
+ setInit(false);
+}
+
+void CAudioInput::prepare() throw (CAudioError) {
+ if (IsInit() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CAudioInput");
+ }
+
+ if (IsReady() == true) {
+ AUDIO_IO_LOGD("Already prepared CAudioInput");
+ return;
+ }
+
+ try {
+ internalLock();
+
+ // Check to invalid AudioType
+ CAudioInfo::EAudioType audioType = mAudioInfo.getAudioType();
+ if (audioType < CAudioInfo::AUDIO_IN_TYPE_MEDIA || audioType > CAudioInfo::AUDIO_IN_TYPE_LOOPBACK) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "The audioType is invalid [type:%d]", static_cast<int>(audioType));
+ }
+
+ if (mpAudioSessionHandler->getId() < 0) { //Did not registerSound()
+ // Check session to skip registration
+ if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSessionEvent() == false) {
+ // Register ASM Listener
+ AUDIO_IO_LOGD("Register ASM Listener");
+ mpAudioSessionHandler->registerSound();
+ }
+ }
+
+ // Init StreamSpec
+ AUDIO_IO_LOGD("Set Strem Spec : CPulseStreamSpec::STREAM_LATENCY_INPUT_MID");
+ CPulseStreamSpec::EStreamLatency streamSpec = CPulseStreamSpec::STREAM_LATENCY_INPUT_MID;
+ CPulseStreamSpec spec(streamSpec, mAudioInfo);
+
+ // Create PulseAudio Handler
+ mpPulseAudioClient = new CPulseAudioClient(CPulseAudioClient::STREAM_DIRECTION_RECORD, spec, this);
+ if (mpPulseAudioClient == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed to allocate CPulseAudioClient object");
+ }
+
+ // Initialize PulseAudio Handler
+ mpPulseAudioClient->initialize();
+
+ if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSessionEvent() == false) {
+ /* Updates ASM to PLAYING */
+ mpAudioSessionHandler->updatePlaying();
+ }
+
+ internalUnlock();
+
+ // Do Prepare
+ CAudioIO::prepare();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioInput::unprepare() throw (CAudioError) {
+ if (IsInit() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CAudioInput");
+ }
+
+ if (IsReady() == false) {
+ AUDIO_IO_LOGD("Already unprepared");
+ return;
+ }
+
+ try{
+ // Do unprepare
+ CAudioIO::unprepare();
+
+ internalLock();
+
+ SAFE_FINALIZE(mpPulseAudioClient);
+ SAFE_DELETE(mpPulseAudioClient);
+
+ if (mpAudioSessionHandler->getId() >= 0) {
+ /* Updates ASM to STOP */
+ if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSessionEvent() == false) {
+ mpAudioSessionHandler->updateStop();
+ }
+
+ bool isSkip = mpAudioSessionHandler->isSkipSessionEvent();
+ if (isSkip == false) {
+ mpAudioSessionHandler->unregisterSound();
+ }
+ }
+
+ internalUnlock();
+
+ CAudioIO::onStateChanged(CAudioInfo::AUDIO_IO_STATE_IDLE);
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioInput::pause() throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioInput");
+ }
+
+ try{
+ CAudioIO::pause();
+
+ internalLock();
+
+ /* Updates ASM to STOP */
+ if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSessionEvent() == false) {
+ mpAudioSessionHandler->updateStop();
+ }
+
+ internalUnlock();
+
+ CAudioIO::onStateChanged(CAudioInfo::AUDIO_IO_STATE_PAUSED);
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioInput::resume() throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioInput");
+ }
+
+ try {
+ internalLock();
+
+ if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSessionEvent() == false) {
+
+ /* Updates ASM to PLAYING */
+ mpAudioSessionHandler->updatePlaying();
+ }
+
+ internalUnlock();
+
+ CAudioIO::resume();
+
+ CAudioIO::onStateChanged(CAudioInfo::AUDIO_IO_STATE_RUNNING);
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioInput::drain() throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioInput");
+ }
+
+ try{
+ CAudioIO::drain();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioInput::flush() throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioInput");
+ }
+
+ try {
+ CAudioIO::flush();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+int CAudioInput::getBufferSize() throw (CAudioError) {
+ if (IsInit() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CAudioInput");
+ }
+
+ if (IsReady() == false) {
+ AUDIO_IO_LOGD("Warning: Did not prepare CAudioInput, then return zero");
+ return 0;
+ }
+
+ int size = 0;
+
+ try {
+ internalLock();
+ size = mpPulseAudioClient->getBufferSize();
+ internalUnlock();
+ } catch (CAudioError err) {
+ internalUnlock();
+ throw err;
+ }
+
+ return size;
+}
+
+void CAudioInput::setStreamCallback(SStreamCallback callback) throw (CAudioError) {
+ if (IsInit() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CAudioInput");
+ }
+
+ internalLock();
+ if (callback.onStream == NULL) {
+ AUDIO_IO_LOGD("mIsUsedSyncRead = true");
+ mIsUsedSyncRead = true;
+ } else {
+ AUDIO_IO_LOGD("mIsUsedSyncRead = false");
+ mIsUsedSyncRead = false;
+ }
+ internalUnlock();
+
+ CAudioIO::setStreamCallback(callback);
+}
+
+int CAudioInput::read(void* buffer, unsigned int length) throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioInput");
+ }
+
+ if (buffer == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are invalid - buffer:%p, length:%d", buffer, length);
+ }
+
+ /* Checks synchronous flag */
+ if (mIsUsedSyncRead == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_SUPPORTED, "Does not support read() if receive stream callback");
+ }
+
+ internalLock();
+
+ unsigned int lengthIter = length;
+ int ret = 0;
+
+ try {
+ while (lengthIter > 0) {
+ size_t l;
+
+ while (mpSyncReadDataPtr == NULL) {
+ ret = mpPulseAudioClient->peek(&mpSyncReadDataPtr, &mSyncReadLength);
+ if (ret != 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INTERNAL_OPERATION, "Failed CPulseAudioClient::peek() ret:[%d]", ret);
+ }
+
+ if (mSyncReadLength <= 0) {
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("readLength(%d byte) is not valid.. wait..", mSyncReadLength);
+#endif
+ internalWait();
+ } else if (mpSyncReadDataPtr == NULL) {
+ /* There's a hole in the stream, skip it. We could generate
+ * silence, but that wouldn't work for compressed streams.
+ */
+ ret = mpPulseAudioClient->drop();
+ if (ret != 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INTERNAL_OPERATION, "Failed CPulseAudioClient::drop() ret:[%d]", ret);
+ }
+ } else {
+ mSyncReadIndex = 0;
+ }
+ }//end of while (pReadData == NULL)
+
+ if (mSyncReadLength < lengthIter) {
+ l = mSyncReadLength;
+ } else {
+ l = lengthIter;
+ }
+
+ // Copy partial pcm data on out parameter
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("memcpy() that a peeked buffer(%p), index(%d), length(%d), on out buffer", (const uint8_t*)(mpSyncReadDataPtr) + mSyncReadIndex, mSyncReadIndex, l);
+#endif
+ memcpy(buffer, (const uint8_t*)mpSyncReadDataPtr + mSyncReadIndex, l);
+
+ // Move next position
+ buffer = (uint8_t*)buffer + l;
+ lengthIter -= l;
+
+ // Adjusts the rest length
+ mSyncReadIndex += l;
+ mSyncReadLength -= l;
+
+ if (mSyncReadLength == 0) {
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("mSyncReadLength is zero - Do drop()");
+#endif
+ ret = mpPulseAudioClient->drop();
+ if (ret != 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INTERNAL_OPERATION, "Failed CPulseAudioClient::drop() ret:[%d]", ret);
+ }
+
+ // Reset the internal pointer
+ mpSyncReadDataPtr = NULL;
+ mSyncReadLength = 0;
+ mSyncReadIndex = 0;
+ }
+ }//end of while (length > 0)
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+
+ internalUnlock();
+
+ return length;
+}
+
+int CAudioInput::peek(const void** buffer, unsigned int* length) throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioInput");
+ }
+
+ if (buffer == NULL || length == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL buffer:%p, length:%p", buffer, length);
+ }
+
+ /* Checks synchronous flag */
+ internalLock();
+ if (mIsUsedSyncRead == true) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_SUPPORTED, "Does not support peek() if does not receive a stream callback");
+ }
+ internalUnlock();
+
+ int ret = 0;
+
+ try {
+ internalLock();
+ ret = mpPulseAudioClient->peek(buffer, length);
+ internalUnlock();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+
+ return ret;
+}
+
+int CAudioInput::drop() throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioInput");
+ }
+
+ /* Checks synchronous flag */
+ internalLock();
+ if (mIsUsedSyncRead == true) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_SUPPORTED, "Does not support drop() if does not receive a stream callback");
+ }
+ internalUnlock();
+
+ int ret = 0;
+
+ try {
+ internalLock();
+ ret = mpPulseAudioClient->drop();
+ internalUnlock();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#include <vconf.h>
+#include "CAudioIODef.h"
+
+using namespace std;
+using namespace tizen_media_audio;
+
+
+/**
+ * class CAudioOutput
+ */
+CAudioOutput::CAudioOutput(CAudioInfo& info) : CAudioIO(info), mIsUsedSyncWrite(false) {
+}
+
+CAudioOutput::CAudioOutput(
+ unsigned int sampleRate,
+ CAudioInfo::EChannel channel,
+ CAudioInfo::ESampleType sampleType,
+ CAudioInfo::EAudioType audioType) : mIsUsedSyncWrite(false) {
+ mAudioInfo = CAudioInfo(sampleRate, channel, sampleType, audioType, -1);
+}
+
+CAudioOutput::~CAudioOutput() {
+
+}
+
+void CAudioOutput::onStream(CPulseAudioClient* pClient, size_t length) {
+ assert(pClient);
+
+ /*
+ * Does not call CAudioIO::onStream() for synchronization
+ * if a user is using write()
+ */
+ if (mIsUsedSyncWrite == true) {
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("Sync Write Mode! - signal! - pClient:[%p], length:[%d]", pClient, length);
+#endif
+ internalSignal();
+ return;
+ }
+
+ /*
+ * Accrues callback function
+ */
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("pClient:[%p], length:[%d]", pClient, length);
+#endif
+ CAudioIO::onStream(pClient, length);
+}
+
+void CAudioOutput::onInterrupt(CAudioSessionHandler* pHandler, int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info) {
+ assert(pHandler);
+ AUDIO_IO_LOGD("[pHandler:0x%x], [focus_type:%d], [state:%d], [reason_for_change:%s], [additional_info:%s]", pHandler, focus_type, state, reason_for_change, additional_info);
+ CAudioIO::onInterrupt(pHandler, id, focus_type, state, reason_for_change, additional_info);
+}
+
+void CAudioOutput::onSignal(CAudioSessionHandler* pHandler, mm_sound_signal_name_t signal, int value) {
+ assert(pHandler);
+ AUDIO_IO_LOGD("[pHandler:0x%x], [signal:%d], [value:%d]", pHandler, signal, value);
+ CAudioIO::onSignal(pHandler, signal, value);
+}
+
+void CAudioOutput::setInit(bool flag) {
+ mIsInit = flag;
+}
+
+bool CAudioOutput::IsInit() {
+ return (CAudioIO::isInit() == true && mIsInit == true);
+}
+
+bool CAudioOutput::IsReady() {
+ return CAudioIO::IsReady();
+}
+
+void CAudioOutput::initialize() throw (CAudioError) {
+ if (IsInit() == true) {
+ return;
+ }
+
+ try {
+ CAudioIO::initialize();
+
+ // Create ASM Handler
+ mpAudioSessionHandler = new CAudioSessionHandler(CAudioSessionHandler::AUDIO_SESSION_TYPE_PLAYBACK, mAudioInfo, this);
+ if (mpAudioSessionHandler == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed to allocate CAudioSessionHandler object");
+ }
+
+ // Initialize ASM Handler
+ mpAudioSessionHandler->initialize();
+
+ setInit(true);
+ CAudioIO::onStateChanged(CAudioInfo::AUDIO_IO_STATE_IDLE);
+ } catch (CAudioError err) {
+ finalize();
+ throw err;
+ }
+}
+
+void CAudioOutput::finalize() {
+ if (IsInit() == false) {
+ AUDIO_IO_LOGD("Did not initialize");
+ return;
+ }
+
+ SAFE_FINALIZE(mpAudioSessionHandler);
+ SAFE_DELETE(mpAudioSessionHandler);
+
+ CAudioIO::finalize();
+
+ setInit(false);
+}
+
+void CAudioOutput::prepare() throw (CAudioError) {
+ if (IsInit() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CAudioOutput");
+ }
+
+ if (IsReady() == true) {
+ AUDIO_IO_LOGD("Already prepared CAudioOutput");
+ return;
+ }
+
+ try {
+ internalLock();
+
+ // Check to invalid AudioType
+ CAudioInfo::EAudioType audioType = mAudioInfo.getAudioType();
+ if (audioType < CAudioInfo::AUDIO_OUT_TYPE_MEDIA || audioType >= CAudioInfo::AUDIO_TYPE_MAX) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "The audioType is invalid [type:%d]", static_cast<int>(audioType));
+ }
+
+ if (mpAudioSessionHandler->getId() < 0) { //Did not registerSound()
+ if (isForceIgnore() == false) {
+ // Register ASM Listener
+ AUDIO_IO_LOGD("Register ASM Listener");
+ mpAudioSessionHandler->registerSound();
+ }
+ }
+
+ // Init StreamSpec
+ AUDIO_IO_LOGD("Set Stream Spec : CPulseStreamSpec::STREAM_LATENCY_OUTPUT_MID");
+ CPulseStreamSpec::EStreamLatency streamSpec = CPulseStreamSpec::STREAM_LATENCY_OUTPUT_MID;
+ CPulseStreamSpec spec(streamSpec, mAudioInfo);
+
+ // Create PulseAudio Handler
+ mpPulseAudioClient = new CPulseAudioClient(CPulseAudioClient::STREAM_DIRECTION_PLAYBACK, spec, this);
+ if (mpPulseAudioClient == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed to allocate CPulseAudioClient object");
+ }
+
+ // Initialize PulseAudio Handler
+ mpPulseAudioClient->initialize();
+
+ if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSessionEvent() == false) {
+ /* Updates ASM to PLAYING */
+ mpAudioSessionHandler->updatePlaying();
+ }
+
+ internalUnlock();
+
+ CAudioIO::prepare();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioOutput::unprepare() throw (CAudioError) {
+ if (IsInit() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CAudioOutput");
+ }
+
+ if (IsReady() == false) {
+ AUDIO_IO_LOGD("Already unprepared");
+ return;
+ }
+
+ try {
+ CAudioIO::unprepare();
+
+ internalLock();
+
+ SAFE_FINALIZE(mpPulseAudioClient);
+ SAFE_DELETE(mpPulseAudioClient);
+
+ if (mpAudioSessionHandler->getId() >= 0) {
+ /* Updates ASM to STOP */
+ if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSessionEvent() == false) {
+ mpAudioSessionHandler->updateStop();
+ }
+
+ bool isSkip = mpAudioSessionHandler->isSkipSessionEvent();
+ if (isSkip == false) {
+ mpAudioSessionHandler->unregisterSound();
+ }
+ }
+
+ internalUnlock();
+
+ CAudioIO::onStateChanged(CAudioInfo::AUDIO_IO_STATE_IDLE);
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioOutput::pause() throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioOutput");
+ }
+
+ try {
+ CAudioIO::pause();
+
+ internalLock();
+
+ /* Updates ASM to STOP */
+ if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSessionEvent() == false) {
+ mpAudioSessionHandler->updateStop();
+ }
+
+ internalUnlock();
+
+ CAudioIO::onStateChanged(CAudioInfo::AUDIO_IO_STATE_PAUSED);
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioOutput::resume() throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioOutput");
+ }
+
+ try {
+ internalLock();
+
+ if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSessionEvent() == false) {
+
+ /* Updates ASM to PLAYING */
+ mpAudioSessionHandler->updatePlaying();
+ }
+
+ internalUnlock();
+
+ CAudioIO::resume();
+ CAudioIO::onStateChanged(CAudioInfo::AUDIO_IO_STATE_RUNNING);
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioOutput::drain() throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioOutput");
+ }
+
+ try {
+ CAudioIO::drain();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+void CAudioOutput::flush() throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioOutput");
+ }
+
+ try {
+ CAudioIO::flush();
+ } catch (CAudioError e) {
+ internalUnlock();
+ throw e;
+ }
+}
+
+int CAudioOutput::getBufferSize() throw (CAudioError) {
+ if (IsInit() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CAudioOutput");
+ }
+
+ if (IsReady() == false) {
+ AUDIO_IO_LOGD("Warning: Did not prepare CAudioOutput, then return zero");
+ return 0;
+ }
+
+ int size = 0;
+
+ try {
+ internalLock();
+ size = mpPulseAudioClient->getBufferSize();
+ internalUnlock();
+ } catch (CAudioError err) {
+ internalUnlock();
+ throw err;
+ }
+
+ return size;
+}
+
+int CAudioOutput::write(const void* buffer, unsigned int length) throw (CAudioError) {
+ if (IsInit() == false || IsReady() == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioOutput");
+ }
+
+ if (buffer == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are invalid - buffer:%p, length:%d", buffer, length);
+ }
+
+ /*
+ * Check skip condition.
+ * If accessibility screen reader (VOICE type with NoSession), no need to check, always do write.
+ */
+ if (mpAudioSessionHandler->isSkipSessionEvent() == false) {
+ /* Check whether voicerecorder is running */
+ int vrState = 0;
+
+ vconf_get_int(VCONFKEY_RECORDER_STATE, &vrState);
+ if (vrState == VCONFKEY_RECORDER_STATE_RECORDING) {
+ THROW_ERROR_MSG(CAudioError::ERROR_POLICY_BLOCKED, "During Voicerecording --> MUTE");
+ }
+ }
+
+ /* When write() is called in PulseAudio callback, bypass a pcm data to PulseAudioClient (For Asynchronous) */
+ if (mpPulseAudioClient->isInThread() == true) {
+ int ret = mpPulseAudioClient->write(buffer, length);
+ if (ret == 0) {
+ return length;
+ }
+ }
+
+ /* For synchronization */
+ internalLock();
+
+ // Sets synchronous flag
+ mIsUsedSyncWrite = true;
+
+ unsigned int lengthIter = length;
+ try {
+ while (lengthIter > 0) {
+ int l, r;
+
+ while ((l = mpPulseAudioClient->getWritableSize()) == 0) {
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("writableSize is [%d].. wait", l);
+#endif
+ internalWait();
+ }
+
+ if (l == -1) {
+ THROW_ERROR_MSG(CAudioError::ERROR_INTERNAL_OPERATION, "The Writable size is invalid");
+ }
+
+ if (static_cast<unsigned int>(l) > lengthIter) {
+ l = lengthIter;
+ }
+
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("PulseAudioClient->write(buffer:%p, length:%d)", buffer, l);
+#endif
+
+ r = mpPulseAudioClient->write(buffer, l);
+ if (r < 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INTERNAL_OPERATION, "The written result is invalid ret:%d", r);
+ }
+
+ buffer = static_cast<const uint8_t*>(buffer) + l;
+ lengthIter -= l;
+ }//end of while (length > 0)
+ } catch (CAudioError e) {
+ // Unsets synchronous flag
+ mIsUsedSyncWrite = false;
+ internalUnlock();
+ throw e;
+ }
+
+ // Unsets synchronous flag
+ mIsUsedSyncWrite = false;
+ internalUnlock();
+
+ return length;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#include <mm_error.h>
+#include "CAudioIODef.h"
+
+
+using namespace std;
+using namespace tizen_media_audio;
+
+
+/**
+ * class CAudioSessionHandler
+ */
+int CAudioSessionHandler::sCaptureRef = 0;
+
+int CAudioSessionHandler::PCM_CAPTURE_COUNT_INC() {
+ int actual;
+ do {
+ actual = sCaptureRef;
+ } while (!__sync_bool_compare_and_swap(&sCaptureRef, actual, actual + 1));
+ AUDIO_IO_LOGD("CaptureRefCount+1 > [%d]", sCaptureRef);
+ return sCaptureRef;
+}
+
+int CAudioSessionHandler::PCM_CAPTURE_COUNT_DEC() {
+ int actual;
+ do {
+ actual = sCaptureRef;
+ } while (!__sync_bool_compare_and_swap(&sCaptureRef, actual, actual - 1));
+ AUDIO_IO_LOGD("CaptureRefCount-1 > [%d]", sCaptureRef);
+ if (sCaptureRef < 0) {
+ AUDIO_IO_LOGE("A CaptureRef[%d] is not valid! Something is wrong!", sCaptureRef);
+ sCaptureRef = 0;
+ }
+ return sCaptureRef;
+}
+
+int CAudioSessionHandler::PCM_CAPTURE_COUNT_GET() {
+ AUDIO_IO_LOGD("CaptureRefCount > [%d]", sCaptureRef);
+ return sCaptureRef;
+}
+
+int CAudioSessionHandler::sFocusRef = 0;
+
+int CAudioSessionHandler::FOCUS_ID_COUNT_INC() {
+ int actual;
+ do {
+ actual = sFocusRef;
+ } while (!__sync_bool_compare_and_swap(&sFocusRef, actual, actual + 1));
+ AUDIO_IO_LOGD("FocusRefCount+1 > [%d]", sFocusRef);
+ return sFocusRef;
+}
+
+int CAudioSessionHandler::FOCUS_ID_COUNT_DEC() {
+ int actual;
+ do {
+ actual = sFocusRef;
+ } while (!__sync_bool_compare_and_swap(&sFocusRef, actual, actual - 1));
+ AUDIO_IO_LOGD("FocusRefCount-1 > [%d]", sFocusRef);
+ return sFocusRef;
+}
+
+int CAudioSessionHandler::FOCUS_ID_COUNT_GET() {
+ /* AUDIO_IO_LOGD("FocusRefCount > [%d]", sFocusRef); */
+ return sFocusRef;
+}
+
+CAudioSessionHandler::CAudioSessionHandler(EAudioSessionType sessionType, CAudioInfo& audioInfo, IAudioSessionEventListener* listener)
+: mId(-1),
+ mOptions(0),
+ mAudioSession(sessionType),
+ mMultimediaSession(MM_SESSION_TYPE_MEDIA),
+ mpEventListener(listener),
+ mIsInit(false),
+ mUseFocus(false),
+ mSubscribeId(-1) {
+ mAudioInfo = audioInfo;
+}
+
+CAudioSessionHandler::~CAudioSessionHandler() {
+}
+
+CAudioError CAudioSessionHandler::_convertStreamType(EAudioSessionType type1, MMSessionType type2, int *index) {
+ unsigned int i;
+ int idx = -1;
+
+ assert(index != NULL);
+
+ if (type1 == AUDIO_SESSION_TYPE_CAPTURE) {
+ for (i = 0 ; i < sizeof(stream_type_table_in) / sizeof(stream_type_table_in[0]) ; i++) {
+ if (stream_type_table_in[i].type == type2) {
+ idx = i;
+ break;
+ }
+ }
+ } else {
+ for (i = 0 ; i < sizeof(stream_type_table_out) / sizeof(stream_type_table_out[0]) ; i++) {
+ if (stream_type_table_out[i].type == type2) {
+ idx = i;
+ break;
+ }
+ }
+ }
+
+ if (idx < 0) {
+ RET_ERROR_MSG(CAudioError::ERROR_NOT_SUPPORTED, "Does not support session type.");
+ }
+ *index = idx;
+ RET_ERROR(CAudioError::ERROR_NONE);
+}
+
+CAudioError CAudioSessionHandler::_getAsmInformation(MMSessionType *type, int *options) {
+ assert(type != NULL);
+ assert(options != NULL);
+
+ MMSessionType currentSession = MM_SESSION_TYPE_MEDIA;
+ int sessionOptions = 0;
+
+ /* Read session information */
+ int ret = 0;
+ if ((ret = _mm_session_util_read_information(-1, (int*)¤tSession, &sessionOptions)) < 0) {
+ if(ret == (int) MM_ERROR_INVALID_HANDLE) {
+ RET_ERROR_MSG(CAudioError::ERROR_INVALID_HANDLE, "Failed _mm_session_util_read_information(). Invalid handle");
+ } else {
+ RET_ERROR_MSG(CAudioError::ERROR_FAILED_OPERATION, "Failed _mm_session_util_read_information(). Not exist");
+ }
+ }
+
+ *type = currentSession;
+ *options = sessionOptions;
+
+ RET_ERROR(CAudioError::ERROR_NONE);
+}
+
+bool CAudioSessionHandler::_isFocusRequired(MMSessionType type, int options) {
+ if((options & ASM_SESSION_OPTION_PAUSE_OTHERS)
+ || ((type != MM_SESSION_TYPE_MEDIA) && (type != MM_SESSION_TYPE_MEDIA_RECORD)))
+ return true;
+ else
+ return false;
+}
+
+int CAudioSessionHandler::getId() {
+ return mId;
+}
+
+int CAudioSessionHandler::getOptions() {
+ return mOptions;
+}
+
+CAudioSessionHandler::EAudioSessionType CAudioSessionHandler::getAudioSession() {
+ return mAudioSession;
+}
+
+MMSessionType CAudioSessionHandler::getMultimediaSession() {
+ return mMultimediaSession;
+}
+
+int CAudioSessionHandler::getSubscribeId() {
+ return mSubscribeId;
+}
+
+CAudioInfo CAudioSessionHandler::getAudioInfo() {
+ return mAudioInfo;
+}
+
+void CAudioSessionHandler::_sound_pcm_signal_cb(mm_sound_signal_name_t signal, int value, void *user_data) {
+ assert(user_data);
+
+ AUDIO_IO_LOGD("[signal:%d], [value:%d], [user_data:0x%x]", signal, value, user_data);
+
+ CAudioSessionHandler* pHandler = static_cast<CAudioSessionHandler*>(user_data);
+ if (pHandler->mpEventListener != NULL) {
+ pHandler->mpEventListener->onSignal(pHandler, signal, value);
+ }
+}
+
+void CAudioSessionHandler::initialize() throw (CAudioError) {
+ AUDIO_IO_LOGD("");
+ if (mIsInit == true) {
+ return;
+ }
+
+ MMSessionType currentSession = MM_SESSION_TYPE_MEDIA;
+ int sessionOptions = 0; // Mix with others by default
+
+ CAudioError err = _getAsmInformation(¤tSession, &sessionOptions);
+ if (err == CAudioError::ERROR_NONE) {
+ // Session was configured before, use focus callback
+ mUseFocus = true;
+ AUDIO_IO_LOGD("Use audio focus concept internally!");
+ } else {
+ if (err == CAudioError::ERROR_INVALID_HANDLE) {
+ int value = 0;
+ unsigned int subscribe_id;
+
+ int errorCode = mm_sound_get_signal_value(MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS, &value);
+ if (errorCode != MM_ERROR_NONE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_POLICY_BLOCKED, "Failed mm_sound_get_signal_value() err:0x%x", errorCode);
+ }
+
+ if (value == 1) {
+ // stream_info was created or focus watch callback was configured before
+ mUseFocus = false;
+ AUDIO_IO_LOGD("Skip audio focus concept!");
+ } else if (value == 0) {
+ // No session, No stream_info, No focus watch callback before
+ // Use focus watch callback with signal subscribe
+ errorCode = mm_sound_subscribe_signal(MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS, &subscribe_id, _sound_pcm_signal_cb, static_cast<void*>(this));
+ if (errorCode != MM_ERROR_NONE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_POLICY_BLOCKED, "Failed mm_sound_get_signal_value() err:0x%x", errorCode);
+ }
+
+ mSubscribeId = (int)subscribe_id;
+ AUDIO_IO_LOGD("Subscribed mm_sound signal");
+
+ sessionOptions = 0; // Mix with others by default
+ mUseFocus = true;
+ AUDIO_IO_LOGD("Use audio focus(watch) concept internally!");
+ }
+ } else {
+ mUseFocus = false;
+ AUDIO_IO_LOGD("Skip audio focus concept!");
+ }
+
+ if (mAudioSession == AUDIO_SESSION_TYPE_CAPTURE) {
+ AUDIO_IO_LOGD("Set default \"Media_Record\" type");
+ currentSession = MM_SESSION_TYPE_MEDIA_RECORD;
+ } else {
+ AUDIO_IO_LOGD("Set default \"Media\" type");
+ currentSession = MM_SESSION_TYPE_MEDIA;
+ }
+ }
+
+ // Updates session information
+ mMultimediaSession = currentSession;
+ mOptions = sessionOptions;
+
+ if (this->mAudioSession == AUDIO_SESSION_TYPE_CAPTURE) {
+ PCM_CAPTURE_COUNT_INC();
+ }
+
+ mIsInit = true;
+}
+
+void CAudioSessionHandler::finalize() {
+ AUDIO_IO_LOGD("");
+ if (mIsInit == false) {
+ return;
+ }
+
+ if (mAudioSession == AUDIO_SESSION_TYPE_CAPTURE) {
+ PCM_CAPTURE_COUNT_DEC();
+ }
+
+ if (mSubscribeId >= 0) {
+ mm_sound_unsubscribe_signal(mSubscribeId);
+ }
+
+ mIsInit = false;
+}
+
+bool CAudioSessionHandler::isSkipSessionEvent() throw (CAudioError) {
+ bool ret = false;
+
+ // To be regarded...
+#if 0
+ /* Only Support below Event */
+ if (mEvent != ASM_EVENT_CALL && mEvent != ASM_EVENT_VOIP &&
+ mEvent != ASM_EVENT_VIDEOCALL && mEvent != ASM_EVENT_VOICE_RECOGNITION &&
+ mEvent != ASM_EVENT_MMCAMCORDER_AUDIO && mEvent != ASM_EVENT_MMCAMCORDER_VIDEO) {
+
+ // Check AudioType
+ switch (mAudioInfo.getAudioType()) {
+ case CAudioInfo::AUDIO_IN_TYPE_MEDIA:
+ case CAudioInfo::AUDIO_IN_TYPE_VOICECONTROL:
+ ret = false;
+ break;
+
+ case CAudioInfo::AUDIO_IN_TYPE_MIRRORING:
+ case CAudioInfo::AUDIO_IN_TYPE_LOOPBACK:
+ ret = true;
+ break;
+
+ default:
+ return false;
+ }
+
+ if (ret == true) {
+ int captureCount = CAudioSessionHandler::PCM_CAPTURE_COUNT_GET();
+ if (captureCount == 1) {/* If this is last one */
+ /* Recover session information to MEDIA */
+ int sessionResult = _mm_session_util_write_information(-1, MM_SESSION_TYPE_MEDIA, mOptions);
+ if (sessionResult != 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INTERNAL_OPERATION, "Failed _mm_session_util_write_information() ret:%d", sessionResult);
+ }
+ }
+ }
+ }
+#endif
+
+ return ret;
+}
+
+void CAudioSessionHandler::_sound_pcm_focus_cb(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info, void *user_data) {
+ assert(user_data);
+
+ AUDIO_IO_LOGD("[id:%d], [focus_type:%d], [state:%d], [reason_for_change:%s], [additional_info:%s], [user_data:0x%x]", id, focus_type, state, reason_for_change, additional_info, user_data);
+
+ CAudioSessionHandler* pHandler = static_cast<CAudioSessionHandler*>(user_data);
+ pHandler->mFocusType = focus_type;
+ pHandler->mState = state;
+ pHandler->mReasonForChange = (char *)reason_for_change;
+ pHandler->mAdditionalInfo = (char *)additional_info;
+
+ if (pHandler->mpEventListener != NULL) {
+ pHandler->mpEventListener->onInterrupt(pHandler, id, focus_type, state, reason_for_change, additional_info);
+ }
+
+ return;
+}
+
+void CAudioSessionHandler::_sound_pcm_focus_watch_cb(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info, void *user_data) {
+ AUDIO_IO_LOGD("[id:%d], [focus_type:%d], [state:%d], [reason_for_change:%s], [additional_info:%s], [user_data:0x%x]", id, focus_type, state, reason_for_change, additional_info, user_data);
+
+ CAudioSessionHandler::_sound_pcm_focus_cb(-1, focus_type, state, reason_for_change, additional_info, user_data);
+
+ return;
+}
+
+void CAudioSessionHandler::registerSound() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioSessionHandler");
+ }
+
+ if (mUseFocus == true) {
+ if (mId >= 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_POLICY_BLOCKED, "Already registered [id:%d]", mId);
+ }
+
+ int errorCode = 0;
+
+ if (_isFocusRequired(mMultimediaSession, mOptions)) {
+ int index = 0;
+ CAudioError err = _convertStreamType(mAudioSession, mMultimediaSession, &index);
+ if (err != CAudioError::ERROR_NONE) {
+ throw err;
+ }
+
+ errorCode = mm_sound_focus_get_id(&mId);
+ if (errorCode != MM_ERROR_NONE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_POLICY_BLOCKED, "Failed mm_sound_focus_get_id() err:0x%x", errorCode);
+ }
+
+ // Register focus callback
+ errorCode = mm_sound_register_focus(mId,
+ mAudioSession == AUDIO_SESSION_TYPE_CAPTURE ? stream_type_table_in[index].name : stream_type_table_out[index].name,
+ _sound_pcm_focus_cb,
+ static_cast<void*>(this));
+ if (errorCode != MM_ERROR_NONE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_POLICY_BLOCKED, "Failed mm_sound_register_focus() err:0x%x", errorCode);
+ }
+
+ FOCUS_ID_COUNT_INC();
+
+ AUDIO_IO_LOGD("Focus callback registered successfully [id:%d]", mId);
+ } else if (!(mOptions & ASM_SESSION_OPTION_UNINTERRUPTIBLE)) {
+ // Register focus watch callback
+ errorCode = mm_sound_set_focus_watch_callback(FOCUS_FOR_BOTH, _sound_pcm_focus_watch_cb, static_cast<void*>(this), &mId);
+ if (errorCode < 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_POLICY_BLOCKED, "Failed mm_sound_set_focus_watch_callback() err:0x%x", errorCode);
+ }
+
+ FOCUS_ID_COUNT_INC();
+
+ AUDIO_IO_LOGD("Focus watch callback registered successfully [id:%d]", mId);
+ }
+ }
+}
+
+void CAudioSessionHandler::unregisterSound() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioSessionHandler");
+ }
+
+ if (mUseFocus == true) {
+ if (mId < 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_POLICY_BLOCKED, "Did not register [id:%d]", mId);
+ }
+
+ int errorCode = 0;
+
+ if (_isFocusRequired(mMultimediaSession, mOptions)) {
+ // Unregister focus callback
+ errorCode = mm_sound_unregister_focus(mId);
+ if (errorCode != MM_ERROR_NONE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_POLICY_BLOCKED, "Failed mm_sound_unregister_focus() err:0x%x", errorCode);
+ }
+
+ FOCUS_ID_COUNT_DEC();
+
+ AUDIO_IO_LOGD("Focus callback unregistered successfully [id:%d]", mId);
+ mId = -1;
+ } else if (!(mOptions & ASM_SESSION_OPTION_UNINTERRUPTIBLE)) {
+ // Unregister focus watch callback.
+ errorCode = mm_sound_unset_focus_watch_callback(mId);
+ if (errorCode < 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_POLICY_BLOCKED, "Failed mm_sound_unset_focus_watch_callback() err:0x%x", errorCode);
+ }
+
+ FOCUS_ID_COUNT_DEC();
+
+ AUDIO_IO_LOGD("Focus watch callback unregistered successfully [id:%d]", mId);
+ mId = -1;
+ }
+ }
+}
+
+void CAudioSessionHandler::updatePlaying() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioSessionHandler");
+ }
+
+ if (mUseFocus && _isFocusRequired(mMultimediaSession, mOptions)) {
+ if (mId >= 0) {
+ int ret = mm_sound_acquire_focus(mId, FOCUS_FOR_BOTH, "audio-io acquire focus");
+ if (ret != MM_ERROR_NONE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_POLICY_BLOCKED, "Failed mm_sound_acquire_focus() err:0x%x", ret);
+ }
+ AUDIO_IO_LOGD("Focus acquired successfully [id:%d]", mId);
+ }
+ }
+}
+
+void CAudioSessionHandler::updateStop() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioSessionHandler");
+ }
+
+ if (mUseFocus && _isFocusRequired(mMultimediaSession, mOptions)) {
+ if (mId >= 0) {
+ int ret = mm_sound_release_focus(mId, FOCUS_FOR_BOTH, "audio-io release focus");
+ if (ret != MM_ERROR_NONE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_POLICY_BLOCKED, "Failed mm_sound_release_focus() err:0x%x", ret);
+ }
+ AUDIO_IO_LOGD("Focus released successfully [id:%d]", mId);
+ }
+ }
+}
+
+void CAudioSessionHandler::disableSessionHandler() throw (CAudioError) {
+ CAudioSessionHandler::updateStop();
+ CAudioSessionHandler::unregisterSound();
+
+ CAudioSessionHandler::mUseFocus = false;
+}
+
+/**
+ * class IAudioSessionEventListener
+ */
+IAudioSessionEventListener::EInterruptCode IAudioSessionEventListener::convertInterruptedCode(int code, const char *reason_for_change) {
+ EInterruptCode e = INTERRUPT_COMPLETED;
+
+ switch (code)
+ {
+ case FOCUS_IS_ACQUIRED:
+ e = INTERRUPT_COMPLETED;
+ break;
+
+ case FOCUS_IS_RELEASED:
+ if (!strcmp(reason_for_change, "media")) e = INTERRUPT_BY_MEDIA;
+ if (!strcmp(reason_for_change, "radio")) e = INTERRUPT_BY_MEDIA;
+ if (!strcmp(reason_for_change, "loopback")) e = INTERRUPT_BY_MEDIA;
+ if (!strcmp(reason_for_change, "system")) e = INTERRUPT_BY_MEDIA;
+ if (!strcmp(reason_for_change, "alarm")) e = INTERRUPT_BY_ALARM;
+ if (!strcmp(reason_for_change, "notification")) e = INTERRUPT_BY_NOTIFICATION;
+ if (!strcmp(reason_for_change, "emergency")) e = INTERRUPT_BY_EMERGENCY;
+ if (!strcmp(reason_for_change, "voice-information")) e = INTERRUPT_BY_MEDIA; //for what?
+ if (!strcmp(reason_for_change, "voice-recognition")) e = INTERRUPT_BY_MEDIA; //for what?
+ if (!strcmp(reason_for_change, "ringtone-voip")) e = INTERRUPT_BY_MEDIA; //for what?
+ if (!strcmp(reason_for_change, "ringtone-call")) e = INTERRUPT_BY_MEDIA; //for what?
+ if (!strcmp(reason_for_change, "voip")) e = INTERRUPT_BY_MEDIA; //for what?
+ if (!strcmp(reason_for_change, "call-voice")) e = INTERRUPT_BY_MEDIA; //for what?
+ if (!strcmp(reason_for_change, "call-video")) e = INTERRUPT_BY_MEDIA; //for what?
+ break;
+ }
+
+ return e;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#include <mm.h>
+#include "CAudioIODef.h"
+
+
+using namespace std;
+using namespace tizen_media_audio;
+
+
+/**
+ * class CPulseAudioClient
+ */
+const char* CPulseAudioClient::CLIENT_NAME = "AUDIO_IO_PA_CLIENT";
+
+CPulseAudioClient::CPulseAudioClient(EStreamDirection direction,
+ CPulseStreamSpec& spec,
+ IPulseStreamListener* listener)
+ : mDirection(direction), mSpec(spec), mpListener(listener),
+ mpMainloop(NULL), mpContext(NULL), mpStream(NULL),
+ mpPropList(NULL), mIsInit(false), mIsOperationSuccess(false) {
+}
+
+CPulseAudioClient::~CPulseAudioClient() {
+ finalize();
+}
+
+void CPulseAudioClient::_contextStateChangeCb(pa_context* c, void* user_data) {
+ CPulseAudioClient* pClient = static_cast<CPulseAudioClient*>(user_data);
+ assert(pClient);
+ assert(c);
+
+ switch (pa_context_get_state(c)) {
+ case PA_CONTEXT_READY:
+ AUDIO_IO_LOGD("The context is ready!");
+ case PA_CONTEXT_FAILED:
+ case PA_CONTEXT_TERMINATED:
+ pa_threaded_mainloop_signal(pClient->mpMainloop, 0);
+ break;
+
+ case PA_CONTEXT_UNCONNECTED:
+ case PA_CONTEXT_CONNECTING:
+ case PA_CONTEXT_AUTHORIZING:
+ case PA_CONTEXT_SETTING_NAME:
+ break;
+ }
+}
+
+void CPulseAudioClient::_successContextCb(pa_context* c, int success, void* user_data) {
+ AUDIO_IO_LOGD("pa_context[%p], success[%d], user_data[%p]", c, success, user_data);
+ assert(c);
+ assert(user_data);
+
+ CPulseAudioClient* pClient = static_cast<CPulseAudioClient*>(user_data);
+ pClient->mIsOperationSuccess = static_cast<bool>(success);
+
+ pa_threaded_mainloop_signal(pClient->mpMainloop, 0);
+}
+
+void CPulseAudioClient::_streamStateChangeCb(pa_stream* s, void* user_data) {
+ assert(s);
+ assert(user_data);
+
+ CPulseAudioClient* pClient = static_cast<CPulseAudioClient*>(user_data);
+
+ switch (pa_stream_get_state(s)) {
+ case PA_STREAM_READY:
+ AUDIO_IO_LOGD("The stream is ready!");
+ pClient->mpListener->onStateChanged(CAudioInfo::AUDIO_IO_STATE_RUNNING);
+ case PA_STREAM_FAILED:
+ case PA_STREAM_TERMINATED:
+ pa_threaded_mainloop_signal(pClient->mpMainloop, 0);
+ break;
+
+ case PA_STREAM_UNCONNECTED:
+ break;
+ case PA_STREAM_CREATING:
+ break;
+ }
+}
+
+void CPulseAudioClient::_streamCaptureCb(pa_stream* s, size_t length, void* user_data) {
+ assert(s);
+ assert(user_data);
+
+ CPulseAudioClient* pClient = static_cast<CPulseAudioClient*>(user_data);
+ assert(pClient->mpListener);
+
+ pClient->mpListener->onStream(pClient, length);
+}
+
+void CPulseAudioClient::_streamPlaybackCb(pa_stream* s, size_t length, void* user_data) {
+ //AUDIO_IO_LOGD("_streamPlaybackCb()");
+ assert(s);
+ assert(user_data);
+
+ CPulseAudioClient* pClient = static_cast<CPulseAudioClient*>(user_data);
+ assert(pClient->mpListener);
+
+ if (pClient->mIsInit == false) {
+ AUDIO_IO_LOGD("Occurred this listener when an out stream is on the way to create - Dummy write[length:%d]", length);
+
+ char* dummy = new char[length];
+ memset(dummy, 0, length);
+ pa_stream_write(s, dummy, length, NULL, 0LL, PA_SEEK_RELATIVE);
+ delete [] dummy;
+
+ return;
+ }
+
+ pClient->mpListener->onStream(pClient, length);
+}
+
+void CPulseAudioClient::_streamLatencyUpdateCb(pa_stream* s, void* user_data) {
+ assert(s);
+ assert(user_data);
+
+ CPulseAudioClient* pClient = static_cast<CPulseAudioClient*>(user_data);
+
+ pa_threaded_mainloop_signal(pClient->mpMainloop, 0);
+}
+
+void CPulseAudioClient::_successStreamCb(pa_stream* s, int success, void* user_data) {
+ AUDIO_IO_LOGD("pa_stream[%p], success[%d], user_data[%p]", s, success, user_data);
+ assert(s);
+ assert(user_data);
+
+ CPulseAudioClient* pClient = static_cast<CPulseAudioClient*>(user_data);
+ pClient->mIsOperationSuccess = static_cast<bool>(success);
+
+ pa_threaded_mainloop_signal(pClient->mpMainloop, 0);
+}
+
+void CPulseAudioClient::initialize() throw (CAudioError) {
+ AUDIO_IO_LOGD("");
+ if (mIsInit == true) {
+ return;
+ }
+
+ int ret = 0;
+ int err = 0;
+
+ try {
+ // Allocates PA proplist
+ mpPropList = pa_proplist_new();
+ if (mpPropList == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pa_proplist_new()");
+ }
+
+ // Adds values on proplist for delivery to PULSEAUDIO
+ char *streamType = NULL;
+ CAudioInfo::EAudioType audioType = mSpec.getAudioInfo().getAudioType();
+ mSpec.getAudioInfo().convertAudioType2StreamType(audioType, &streamType);
+ pa_proplist_sets(mpPropList, PA_PROP_MEDIA_ROLE, streamType);
+
+ int index = mSpec.getAudioInfo().getAudioIndex();
+ if (index >= 0) {
+ pa_proplist_setf(mpPropList, PA_PROP_MEDIA_PARENT_ID, "%u", (unsigned int) index);
+ }
+
+ // Adds latency on proplist for delivery to PULSEAUDIO
+ CPulseStreamSpec::EStreamLatency latency = mSpec.getStreamLatency();
+ AUDIO_IO_LOGD("LATENCY : %d", latency);
+
+ pa_proplist_setf(mpPropList, PA_PROP_MEDIA_TIZEN_AUDIO_LATENCY, "%d", latency);
+
+ // Allocates PA mainloop
+ mpMainloop = pa_threaded_mainloop_new();
+ if (mpMainloop == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pa_threaded_mainloop_new()");
+ }
+
+ // Allocates PA context
+ mpContext = pa_context_new(pa_threaded_mainloop_get_api(mpMainloop), CLIENT_NAME);
+ if (mpContext == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pa_context_new()");
+ }
+
+ // Sets context state changed callback
+ pa_context_set_state_callback(mpContext, _contextStateChangeCb, this);
+
+ // Connects this client with PA server
+ if (pa_context_connect(mpContext, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed pa_context_connect()");
+ }
+
+ // LOCK for synchronous connection
+ pa_threaded_mainloop_lock(mpMainloop);
+
+ // Start mainloop
+ if (pa_threaded_mainloop_start(mpMainloop) < 0) {
+ pa_threaded_mainloop_unlock(mpMainloop);
+ THROW_ERROR_MSG(CAudioError::ERROR_FAILED_OPERATION, "Failed pa_threaded_mainloop_start()");
+ }
+
+ // Connection process is asynchronously
+ // So, this function will be waited when occurred context state change event
+ // If I got a signal, do next processing
+ while (true) {
+ pa_context_state_t state;
+ state = pa_context_get_state(mpContext);
+
+ if (state == PA_CONTEXT_READY) {
+ break;
+ }
+
+ if (!PA_CONTEXT_IS_GOOD(state)) {
+ err = pa_context_errno(mpContext);
+ pa_threaded_mainloop_unlock(mpMainloop);
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INTERNAL_OPERATION, "pa_context's state is not good err:[%d]", err);
+ }
+
+ /* Wait until the context is ready */
+ pa_threaded_mainloop_wait(mpMainloop);
+ }
+
+ // Allocates PA stream
+ pa_sample_spec ss = mSpec.getSampleSpec();
+ pa_channel_map map = mSpec.getChannelMap();
+
+ mpStream = pa_stream_new_with_proplist(mpContext, mSpec.getStreamName(), &ss, &map, mpPropList);
+ if (mpStream == NULL) {
+ pa_threaded_mainloop_unlock(mpMainloop);
+ THROW_ERROR_MSG(CAudioError::ERROR_FAILED_OPERATION, "Failed pa_stream_new_with_proplist()()");
+ }
+
+ // Sets stream callbacks
+ pa_stream_set_state_callback(mpStream, _streamStateChangeCb, this);
+ pa_stream_set_read_callback(mpStream, _streamCaptureCb, this);
+ pa_stream_set_write_callback(mpStream, _streamPlaybackCb, this);
+ pa_stream_set_latency_update_callback(mpStream, _streamLatencyUpdateCb, this);
+
+ // Connect stream with PA Server
+
+ if (mDirection == STREAM_DIRECTION_PLAYBACK) {
+ pa_stream_flags_t flags = static_cast<pa_stream_flags_t>(
+ PA_STREAM_INTERPOLATE_TIMING |
+ PA_STREAM_ADJUST_LATENCY |
+ PA_STREAM_AUTO_TIMING_UPDATE);
+
+ ret = pa_stream_connect_playback(mpStream, NULL, NULL, flags, NULL, NULL);
+ } else {
+ pa_stream_flags_t flags = static_cast<pa_stream_flags_t>(
+ PA_STREAM_INTERPOLATE_TIMING |
+ PA_STREAM_ADJUST_LATENCY |
+ PA_STREAM_AUTO_TIMING_UPDATE);
+
+ ret = pa_stream_connect_record(mpStream, NULL, NULL, flags);
+ }
+
+ if (ret != 0) {
+ err = pa_context_errno(mpContext);
+ pa_threaded_mainloop_unlock(mpMainloop);
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_FAILED_OPERATION, "Failed pa_stream_connect() err:[%d]", err);
+ }
+
+ while (true) {
+ pa_stream_state_t state;
+ state = pa_stream_get_state(mpStream);
+
+ if (state == PA_STREAM_READY) {
+ AUDIO_IO_LOGD("STREAM READY");
+ break;
+ }
+
+ if (!PA_STREAM_IS_GOOD(state)) {
+ err = pa_context_errno(mpContext);
+ pa_threaded_mainloop_unlock(mpMainloop);
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INTERNAL_OPERATION, "pa_stream's state is not good err:[%d]", err);
+ }
+
+ /* Wait until the stream is ready */
+ pa_threaded_mainloop_wait(mpMainloop);
+ }
+
+ // End of synchronous
+ pa_threaded_mainloop_unlock(mpMainloop);
+
+ mIsInit = true;
+ } catch (CAudioError e) {
+ finalize();
+ throw e;
+ }
+}
+
+void CPulseAudioClient::finalize() {
+ AUDIO_IO_LOGD("");
+ if (mIsInit == false) {
+ return;
+ }
+
+ if (mpMainloop != NULL) {
+ pa_threaded_mainloop_stop(mpMainloop);
+ }
+ if (mpStream != NULL) {
+ pa_stream_disconnect(mpStream);
+ mpStream = NULL;
+ }
+
+ if (mpContext != NULL) {
+ pa_context_disconnect(mpContext);
+ pa_context_unref(mpContext);
+ mpContext = NULL;
+ }
+
+ if (mpMainloop != NULL) {
+ pa_threaded_mainloop_free(mpMainloop);
+ mpMainloop = NULL;
+ }
+
+ if (mpPropList != NULL) {
+ pa_proplist_free(mpPropList);
+ mpPropList = NULL;
+ }
+
+ mIsInit = false;
+}
+
+int CPulseAudioClient::peek(const void** data, size_t* length) throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("data:[%p], length:[%p]", data, length);
+#endif
+
+ checkRunningState();
+
+ if (data == NULL || length == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "The parameter is invalid - data:%p, length:%p", data, length);
+ }
+
+ if (mDirection == STREAM_DIRECTION_PLAYBACK) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_SUPPORTED, "The Playback client couldn't use this function");
+ }
+
+ int ret = 0;
+
+ if (isInThread() == false) {
+ pa_threaded_mainloop_lock(mpMainloop);
+ ret = pa_stream_peek(mpStream, data, length);
+ pa_threaded_mainloop_unlock(mpMainloop);
+ } else {
+ ret = pa_stream_peek(mpStream, data, length);
+ }
+
+ if (ret < 0) {
+ THROW_ERROR_MSG(CAudioError::ERROR_FAILED_OPERATION, "Failed pa_stream_peek()");
+ }
+
+ return ret;
+}
+
+int CPulseAudioClient::drop() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("");
+#endif
+
+ checkRunningState();
+
+ if (mDirection == STREAM_DIRECTION_PLAYBACK) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_SUPPORTED, "The Playback client couldn't use this function");
+ }
+
+ int ret = 0;
+
+ if (isInThread() == false) {
+ pa_threaded_mainloop_lock(mpMainloop);
+ ret = pa_stream_drop(mpStream);
+ pa_threaded_mainloop_unlock(mpMainloop);
+ } else {
+ ret = pa_stream_drop(mpStream);
+ }
+
+ if (ret < 0) {
+ THROW_ERROR_MSG(CAudioError::ERROR_FAILED_OPERATION, "Failed pa_stream_drop()");
+ }
+
+ return ret;
+}
+
+int CPulseAudioClient::write(const void* data, size_t length) throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("data[%p], length:[%d]", data, length);
+#endif
+
+ checkRunningState();
+
+ if (data == NULL || length < 0) {
+ THROW_ERROR_MSG(CAudioError::ERROR_INVALID_ARGUMENT, "The parameter is invalid");
+ }
+
+ if (mDirection == STREAM_DIRECTION_RECORD) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_SUPPORTED, "The Playback client couldn't use this function");
+ }
+
+ int ret = 0;
+
+ if (isInThread() == false) {
+ pa_threaded_mainloop_lock(mpMainloop);
+ ret = pa_stream_write(mpStream, data, length, NULL, 0LL, PA_SEEK_RELATIVE);
+ pa_threaded_mainloop_unlock(mpMainloop);
+ } else {
+ ret = pa_stream_write(mpStream, data, length, NULL, 0LL, PA_SEEK_RELATIVE);
+ }
+
+ if (ret < 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_FAILED_OPERATION, "Failed pa_stream_write() err:%d", ret);
+ }
+
+ return ret;
+}
+
+void CPulseAudioClient::cork(bool cork) throw (CAudioError) {
+ AUDIO_IO_LOGD("bool cork:%d", cork);
+
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+ if (isInThread() == true) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_SUPPORTED, "This operation is not supported in callback");
+ }
+
+ checkRunningState();
+
+ if (isInThread() == false) {
+ pa_threaded_mainloop_lock(mpMainloop);
+ pa_operation_unref(pa_stream_cork(mpStream, static_cast<int>(cork), _successStreamCb, this));
+ pa_threaded_mainloop_unlock(mpMainloop);
+ } else {
+ pa_operation_unref(pa_stream_cork(mpStream, static_cast<int>(cork), _successStreamCb, this));
+ }
+
+ return;
+}
+
+bool CPulseAudioClient::isCorked() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+ checkRunningState();
+
+ int isCork = 0;
+
+ if (isInThread() == false) {
+ pa_threaded_mainloop_lock(mpMainloop);
+ isCork = pa_stream_is_corked(mpStream);
+ pa_threaded_mainloop_unlock(mpMainloop);
+ } else {
+ isCork = pa_stream_is_corked(mpStream);
+ }
+
+ AUDIO_IO_LOGD("isCork:%d", isCork);
+ return static_cast<bool>(isCork);
+}
+
+bool CPulseAudioClient::drain() throw (CAudioError) {
+ AUDIO_IO_LOGD("drain");
+
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+ checkRunningState();
+
+ if (isInThread() == false) {
+ pa_threaded_mainloop_lock(mpMainloop);
+ pa_operation_unref(pa_stream_drain(mpStream, _successStreamCb, this));
+ pa_threaded_mainloop_unlock(mpMainloop);
+ } else {
+ pa_operation_unref(pa_stream_drain(mpStream, _successStreamCb, this));
+ }
+
+ return true;
+}
+
+bool CPulseAudioClient::flush() throw (CAudioError) {
+ AUDIO_IO_LOGD("flush");
+
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+ checkRunningState();
+
+ if (isInThread() == false) {
+ pa_threaded_mainloop_lock(mpMainloop);
+ pa_operation_unref(pa_stream_flush(mpStream, _successStreamCb, this));
+ pa_threaded_mainloop_unlock(mpMainloop);
+ } else {
+ pa_operation_unref(pa_stream_flush(mpStream, _successStreamCb, this));
+ }
+
+ return true;
+}
+
+size_t CPulseAudioClient::getWritableSize() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+ checkRunningState();
+
+ if (mDirection != STREAM_DIRECTION_PLAYBACK) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_SUPPORTED, "This client is used for Playback");
+ }
+
+ size_t ret = 0;
+
+ if (isInThread() == false) {
+ pa_threaded_mainloop_lock(mpMainloop);
+ ret = pa_stream_writable_size(mpStream);
+ pa_threaded_mainloop_unlock(mpMainloop);
+ } else {
+ ret = pa_stream_writable_size(mpStream);
+ }
+
+ return ret;
+}
+
+void CPulseAudioClient::checkRunningState() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+ if (mpContext == NULL || PA_CONTEXT_IS_GOOD(pa_context_get_state(mpContext)) == 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_NOT_INITIALIZED, "The context[%p] is not created or not good state", mpContext);
+ }
+ if (mpStream == NULL || PA_STREAM_IS_GOOD(pa_stream_get_state(mpStream)) == 0) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_NOT_INITIALIZED, "The stream[%p] is not created or not good state", mpStream);
+ }
+ if (pa_context_get_state(mpContext) != PA_CONTEXT_READY || pa_stream_get_state(mpStream) != PA_STREAM_READY) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_NOT_INITIALIZED, "The context[%p] or stream[%p] state is not ready", mpContext, mpStream);
+ }
+
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("This client is running");
+#endif
+}
+
+bool CPulseAudioClient::isInThread() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+ int ret = pa_threaded_mainloop_in_thread(mpMainloop);
+
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("isInThread : [%d][TRUE:1][FALSE:0]", ret);
+#endif
+ return static_cast<bool>(ret);
+}
+
+size_t CPulseAudioClient::getReadableSize() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+ checkRunningState();
+
+ if (mDirection != STREAM_DIRECTION_RECORD) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_SUPPORTED, "This client is used for Capture");
+ }
+
+ size_t ret = 0;
+
+ if (isInThread() == false) {
+ pa_threaded_mainloop_lock(mpMainloop);
+ ret = pa_stream_writable_size(mpStream);
+ pa_threaded_mainloop_unlock(mpMainloop);
+ } else {
+ ret = pa_stream_writable_size(mpStream);
+ }
+
+ return ret;
+}
+
+size_t CPulseAudioClient::getBufferSize() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+ checkRunningState();
+
+ size_t ret = 0;
+
+ try {
+ if (isInThread() == false) {
+ pa_threaded_mainloop_lock(mpMainloop);
+ }
+
+ const pa_buffer_attr* attr = pa_stream_get_buffer_attr(mpStream);
+ if (attr == NULL) {
+ int _err = pa_context_errno(mpContext);
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_FAILED_OPERATION, "Failed pa_stream_get_buffer_attr() err:%d", _err);
+ }
+
+ if (mDirection == STREAM_DIRECTION_PLAYBACK) {
+ ret = attr->tlength;
+ AUDIO_IO_LOGD("PLAYBACK buffer size : %d", ret);
+ } else {
+ ret = attr->fragsize;
+ AUDIO_IO_LOGD("RECORD buffer size : %d", ret);
+ }
+ } catch (CAudioError err) {
+ if (isInThread() == false) {
+ pa_threaded_mainloop_unlock(mpMainloop);
+ }
+ throw err;
+ }
+
+ if (isInThread() == false) {
+ pa_threaded_mainloop_unlock(mpMainloop);
+ }
+
+ return ret;
+}
+
+pa_usec_t CPulseAudioClient::getLatency() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+ checkRunningState();
+
+ pa_usec_t ret = 0;
+ int negative = 0;
+
+ if (isInThread() == false) {
+ if (pa_stream_get_latency(mpStream, &ret, &negative) < 0) {
+ int _err = pa_context_errno(mpContext);
+ if (_err != PA_ERR_NODATA) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_FAILED_OPERATION, "Failed pa_stream_get_latency() err:%d", _err);
+ }
+ }
+ return negative ? 0 : ret;
+ }
+
+ pa_threaded_mainloop_lock(mpMainloop);
+
+ try {
+ while (true) {
+ if (pa_stream_get_latency(mpStream, &ret, &negative) >= 0) {
+ break;
+ }
+
+ int _err = pa_context_errno(mpContext);
+ if (_err != PA_ERR_NODATA) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_FAILED_OPERATION, "Failed pa_stream_get_latency() err:%d", _err);
+ }
+
+ /* Wait until latency data is available again */
+ pa_threaded_mainloop_wait(mpMainloop);
+ }
+ } catch (CAudioError e) {
+ pa_threaded_mainloop_unlock(mpMainloop);
+ throw e;
+ }
+
+ pa_threaded_mainloop_unlock(mpMainloop);
+
+ return negative ? 0 : ret;
+}
+
+pa_usec_t CPulseAudioClient::getFinalLatency() throw (CAudioError) {
+ if (mIsInit == false) {
+ THROW_ERROR_MSG(CAudioError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+ }
+
+ checkRunningState();
+
+ pa_usec_t ret = 0;
+ uint32_t ver = 0;
+
+ try {
+ if (isInThread() == false) {
+ pa_threaded_mainloop_lock(mpMainloop);
+ }
+
+ ver = pa_context_get_server_protocol_version(mpContext);
+ if (ver >= 13) {
+ const pa_buffer_attr* buffer_attr = pa_stream_get_buffer_attr(mpStream);
+ const pa_sample_spec* sample_spec = pa_stream_get_sample_spec(mpStream);
+ const pa_timing_info* timing_info = pa_stream_get_timing_info(mpStream);
+
+ if (buffer_attr == NULL || sample_spec == NULL || timing_info == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_OUT_OF_MEMORY, "Failed to get buffer_attr[%p] or sample_spec[%p] or timing_info[%p] from a pa_stream",
+ buffer_attr, sample_spec, timing_info);
+ }
+
+ if (mDirection == STREAM_DIRECTION_PLAYBACK) {
+ ret = (pa_bytes_to_usec(buffer_attr->tlength, sample_spec) + timing_info->configured_sink_usec);
+ AUDIO_IO_LOGD("FINAL PLAYBACK LATENCY : %d", ret);
+ } else {
+ ret = (pa_bytes_to_usec(buffer_attr->fragsize, sample_spec) + timing_info->configured_source_usec);
+ AUDIO_IO_LOGD("FINAL RECORD LATENCY : %d", ret);
+ }
+ } else {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_NOT_SUPPORTED, "This version(ver.%d) is not supported", ver);
+ }
+
+ if (isInThread() == false) {
+ pa_threaded_mainloop_unlock(mpMainloop);
+ }
+ } catch (CAudioError e) {
+ if (isInThread() == false) {
+ pa_threaded_mainloop_unlock(mpMainloop);
+ }
+ throw e;
+ }
+
+ return ret;
+}
+
+CPulseAudioClient::EStreamDirection CPulseAudioClient::getStreamDirection() {
+ return mDirection;
+}
+
+CPulseStreamSpec CPulseAudioClient::getStreamSpec() {
+ return mSpec;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#if 0
+#include "CAudioIODef.h"
+
+
+using namespace std;
+using namespace tizen_media_audio;
+
+
+/**
+ * class CPulseAudioPolicy
+ */
+CPulseAudioPolicy::CPulseAudioPolicy() : mPolicy(POLICY_DEFAULT) {
+}
+
+CPulseAudioPolicy::CPulseAudioPolicy(EPolicy policy) : mPolicy(policy) {
+}
+
+CPulseAudioPolicy::~CPulseAudioPolicy() {
+}
+
+void CPulseAudioPolicy::setPolicy(EPolicy policy) throw (CAudioError) {
+ if (policy < POLICY_DEFAULT || policy >= POLICY_MAX) {
+ THROW_ERROR_MSG(CAudioError::ERROR_INVALID_ARGUMENT, "The argument is out of range");
+ }
+
+ mPolicy = policy;
+}
+
+CPulseAudioPolicy::EPolicy CPulseAudioPolicy::getPolicy() {
+ return mPolicy;
+}
+
+bool CPulseAudioPolicy::operator != (const EPolicy policy) {
+ return (mPolicy != policy);
+}
+
+bool CPulseAudioPolicy::operator == (const EPolicy policy) {
+ return (mPolicy == policy);
+}
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#if 0
+#include "CAudioIODef.h"
+
+
+using namespace std;
+using namespace tizen_media_audio;
+
+
+/**
+ * class CPulseAudioVolume
+ */
+CPulseAudioVolume::CPulseAudioVolume() : mVolume(VOLUME_MEDIA), mVolumeGain(VOLUME_GAIN_DEFAULT) {
+}
+
+CPulseAudioVolume::CPulseAudioVolume(EVolume volume, EVolumeGain gain) : mVolume(volume), mVolumeGain(gain) {
+}
+
+CPulseAudioVolume::~CPulseAudioVolume() {
+}
+
+void CPulseAudioVolume::setVolume(EVolume volume) {
+ mVolume = volume;
+}
+
+CPulseAudioVolume::EVolume CPulseAudioVolume::getVolume() {
+ return mVolume;
+}
+
+void CPulseAudioVolume::setVolumeGain(EVolumeGain volumeGain) {
+ mVolumeGain = volumeGain;
+}
+
+CPulseAudioVolume::EVolumeGain CPulseAudioVolume::getVolumeGain() {
+ return mVolumeGain;
+}
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#include "CAudioIODef.h"
+
+
+using namespace std;
+using namespace tizen_media_audio;
+
+
+static const char* STREAM_NAME_INPUT = "CAPTURE";
+static const char* STREAM_NAME_INPUT_LOW_LATENCY = "LOW LATENCY CAPTURE";
+static const char* STREAM_NAME_INPUT_HIGH_LATENCY = "HIGH LATENCY CAPTURE";
+static const char* STREAM_NAME_INPUT_VOIP = "VOIP CAPTURE";
+
+static const char* STREAM_NAME_OUTPUT = "PLAYBACK";
+static const char* STREAM_NAME_OUTPUT_LOW_LATENCY = "LOW LATENCY PLAYBACK";
+static const char* STREAM_NAME_OUTPUT_HIGH_LATENCY = "HIGH LATENCY PLAYBACK";
+static const char* STREAM_NAME_OUTPUT_VOIP = "VOIP PLAYBACK";
+
+
+CPulseStreamSpec::CPulseStreamSpec() throw (CAudioError)
+ : mLatency(STREAM_LATENCY_INPUT_MID), mStreamName(NULL) {
+ _adjustSpec();
+}
+
+CPulseStreamSpec::CPulseStreamSpec(EStreamLatency latency, CAudioInfo& audioInfo) throw (CAudioError)
+ : mLatency(latency), mAudioInfo(audioInfo), mStreamName(NULL) {
+ _adjustSpec();
+}
+
+CPulseStreamSpec::CPulseStreamSpec(EStreamLatency latency, CAudioInfo& audioInfo, int customLatency) throw (CAudioError)
+ : mLatency(latency), mAudioInfo(audioInfo), mStreamName(NULL) {
+ _adjustSpec();
+}
+
+CPulseStreamSpec::~CPulseStreamSpec() {
+}
+
+void CPulseStreamSpec::_adjustSpec() throw (CAudioError) {
+ // Sets a sampleRate
+ mSampleSpec.rate = mAudioInfo.getSampleRate();
+
+ // Convert channels for PA
+ switch (mAudioInfo.getChannel()) {
+ case CAudioInfo::CHANNEL_MONO:
+ mSampleSpec.channels = 1;
+ break;
+
+ case CAudioInfo::CHANNEL_STEREO:
+ default:
+ mSampleSpec.channels = 2;
+ break;
+ }
+
+ // Convert format for PA
+ switch (mAudioInfo.getSampleType()) {
+ case CAudioInfo::SAMPLE_TYPE_U8:
+ mSampleSpec.format = PA_SAMPLE_U8;
+ break;
+
+ case CAudioInfo::SAMPLE_TYPE_S16_LE:
+ default:
+ mSampleSpec.format = PA_SAMPLE_S16LE;
+ break;
+ }
+
+ // Sets channelmap
+ pa_channel_map_init_auto(&mChannelMap, mSampleSpec.channels, PA_CHANNEL_MAP_ALSA);
+
+ // Sets stream name
+ switch (mLatency) {
+ case STREAM_LATENCY_OUTPUT_MID:
+ mStreamName = STREAM_NAME_OUTPUT;
+ break;
+
+ case STREAM_LATENCY_OUTPUT_HIGH:
+ mStreamName = STREAM_NAME_OUTPUT_HIGH_LATENCY;
+ break;
+
+ case STREAM_LATENCY_OUTPUT_LOW:
+ mStreamName = STREAM_NAME_OUTPUT_LOW_LATENCY;
+ break;
+
+ case STREAM_LATENCY_OUTPUT_VOIP:
+ mStreamName = STREAM_NAME_OUTPUT_VOIP;
+ break;
+
+ case STREAM_LATENCY_INPUT_HIGH:
+ mStreamName = STREAM_NAME_INPUT_HIGH_LATENCY;
+ break;
+
+ case STREAM_LATENCY_INPUT_LOW:
+ mStreamName = STREAM_NAME_INPUT_LOW_LATENCY;
+ break;
+
+ case STREAM_LATENCY_INPUT_VOIP:
+ mStreamName = STREAM_NAME_INPUT_VOIP;
+ break;
+
+ case STREAM_LATENCY_INPUT_MID:
+ default:
+ mStreamName = STREAM_NAME_INPUT;
+ break;
+ }
+}
+
+CPulseStreamSpec::EStreamLatency CPulseStreamSpec::getStreamLatency() {
+ return mLatency;
+}
+
+CAudioInfo CPulseStreamSpec::getAudioInfo() {
+ return mAudioInfo;
+}
+
+pa_sample_spec CPulseStreamSpec::getSampleSpec() {
+ return mSampleSpec;
+}
+
+pa_channel_map CPulseStreamSpec::getChannelMap() {
+ return mChannelMap;
+}
+
+const char* CPulseStreamSpec::getStreamName() {
+ return mStreamName;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+
+#include "audio_io.h"
+#include "cpp_audio_io.h"
+#include "CAudioIODef.h"
+#include <sound_manager_internal.h>
+
+
+using namespace std;
+using namespace tizen_media_audio;
+
+
+/**
+ * Defines Structures
+ * type : struct
+ * Name : audio_io_interrupted_cb_s
+ * Declaration : Keeps user callback pointer and user data for delivering an interrupt event
+ */
+typedef struct audio_io_interrupted_cb_s {
+ void* user_data;
+ audio_io_interrupted_cb onInterrupt;
+
+ audio_io_interrupted_cb_s() : user_data(NULL), onInterrupt(NULL)
+ {/* Empty Body */}
+} audio_io_interrupted_cb_s;
+
+/**
+ * Defines Structures
+ * type : struct
+ * Name : audio_io_stream_cb_s
+ * Declaration : Keeps user callback pointer and user data for delivering an stream event
+ */
+typedef struct audio_io_stream_cb_s {
+ void* user_data;
+ audio_in_stream_cb onStream;
+
+ audio_io_stream_cb_s() : user_data(NULL), onStream(NULL)
+ {/* Empty Body */}
+} audio_io_stream_cb_s;
+
+/**
+ * Defines Structures
+ * type : struct
+ * Name : audio_io_state_changed_cb_s
+ * Declaration : Keeps user callback pointer and user data for delivering an state changed event
+ */
+typedef struct audio_io_state_changed_cb_s {
+ void* user_data;
+ audio_in_state_changed_cb onStateChanged;
+
+ audio_io_state_changed_cb_s() : user_data(NULL), onStateChanged(NULL)
+ {/* Empty Body */}
+} audio_io_state_changed_cb_s;
+
+/**
+ * Defines Structures
+ * type : struct
+ * Name : audio_io_s
+ * Declaration : An handle of AudioIO
+ * The handle has two struct for user callback
+ * And the handle has a pointer of private audioIO object
+ * The CAudioIO is a abstract class object about Input and Output
+ */
+typedef struct audio_io_s {
+ CAudioIO* audioIoHandle;
+ audio_io_interrupted_cb_s interrupt_callback;
+ audio_io_stream_cb_s stream_callback;
+ audio_io_state_changed_cb_s state_changed_callback;
+
+ audio_io_s() : audioIoHandle(NULL)
+ {/* Empty Body */}
+} audio_io_s;
+
+
+/**
+ * Internal functions
+ */
+static audio_io_error_e _convert_CAudioError(CAudioError& error) {
+ audio_io_error_e ret = AUDIO_IO_ERROR_NONE;
+ CAudioError::EError err = error.getError();
+
+ switch(err)
+ {
+ case CAudioError::ERROR_NONE:
+ ret = AUDIO_IO_ERROR_NONE;
+ break;
+
+ case CAudioError::ERROR_INVALID_ARGUMENT:
+ case CAudioError::ERROR_INVALID_HANDLE:
+ case CAudioError::ERROR_INVALID_SAMPLERATE:
+ case CAudioError::ERROR_INVALID_CHANNEL:
+ case CAudioError::ERROR_INVALID_FORMAT:
+ ret = AUDIO_IO_ERROR_INVALID_PARAMETER;
+ break;
+
+ case CAudioError::ERROR_DEVICE_NOT_OPENED:
+ ret = AUDIO_IO_ERROR_DEVICE_NOT_OPENED;
+ break;
+
+ case CAudioError::ERROR_DEVICE_NOT_CLOSED:
+ ret = AUDIO_IO_ERROR_DEVICE_NOT_CLOSED;
+ break;
+
+ case CAudioError::ERROR_PERMISSION_DENIED:
+ ret = AUDIO_IO_ERROR_PERMISSION_DENIED;
+ break;
+
+ case CAudioError::ERROR_NOT_SUPPORTED:
+ ret = AUDIO_IO_ERROR_NOT_SUPPORTED;
+ break;
+
+ case CAudioError::ERROR_MAX:
+ case CAudioError::ERROR_INTERNAL_OPERATION:
+ case CAudioError::ERROR_NOT_INITIALIZED:
+ case CAudioError::ERROR_FAILED_OPERATION:
+ case CAudioError::ERROR_INVALID_OPERATION:
+ ret = AUDIO_IO_ERROR_INVALID_OPERATION;
+ break;
+
+ case CAudioError::ERROR_OUT_OF_MEMORY:
+ case CAudioError::ERROR_INVALID_POINTER:
+ ret = AUDIO_IO_ERROR_INVALID_BUFFER;
+ break;
+
+ case CAudioError::ERROR_POLICY_BLOCKED:
+ case CAudioError::ERROR_POLICY_INTERRUPTED:
+ case CAudioError::ERROR_POLICY_DUPLICATED:
+ ret = AUDIO_IO_ERROR_SOUND_POLICY;
+ break;
+ }
+ return ret;
+
+}
+
+static void _convert_channel_2_audio_info_channel(const audio_channel_e& src_channel, CAudioInfo::EChannel& dst_channel) {
+ switch (src_channel) {
+ case AUDIO_CHANNEL_MONO:
+ dst_channel = CAudioInfo::CHANNEL_MONO;
+ break;
+ case AUDIO_CHANNEL_STEREO:
+ dst_channel = CAudioInfo::CHANNEL_STEREO;
+ break;
+ default:
+ dst_channel = CAudioInfo::CHANNEL_MONO;
+ }
+}
+
+static void _convert_audio_info_channel_2_channel(const CAudioInfo::EChannel& src_channel, audio_channel_e& dst_channel) {
+ switch (src_channel) {
+ case CAudioInfo::CHANNEL_MONO:
+ dst_channel = AUDIO_CHANNEL_MONO;
+ break;
+ case CAudioInfo::CHANNEL_STEREO:
+ dst_channel = AUDIO_CHANNEL_STEREO;
+ break;
+ default:
+ dst_channel = AUDIO_CHANNEL_MONO;
+ }
+}
+
+static void _convert_sample_type_2_audio_info_sample_type(const audio_sample_type_e& src_type, CAudioInfo::ESampleType& dst_type) {
+ switch (src_type) {
+ case AUDIO_SAMPLE_TYPE_U8:
+ dst_type = CAudioInfo::SAMPLE_TYPE_U8;
+ break;
+ case AUDIO_SAMPLE_TYPE_S16_LE:
+ dst_type = CAudioInfo::SAMPLE_TYPE_S16_LE;
+ break;
+ default:
+ dst_type = CAudioInfo::SAMPLE_TYPE_U8;
+ }
+}
+
+static void _convert_audio_info_sample_type_2_sample_type(const CAudioInfo::ESampleType& src_type, audio_sample_type_e& dst_type) {
+ switch (src_type) {
+ case CAudioInfo::SAMPLE_TYPE_U8:
+ dst_type = AUDIO_SAMPLE_TYPE_U8;
+ break;
+ case CAudioInfo::SAMPLE_TYPE_S16_LE:
+ dst_type = AUDIO_SAMPLE_TYPE_S16_LE;
+ break;
+ default:
+ dst_type = AUDIO_SAMPLE_TYPE_U8;
+ }
+}
+
+static void _convert_sound_type_2_audio_info_audio_type(const sound_type_e& src_type, CAudioInfo::EAudioType& dst_type) {
+ switch (src_type) {
+ case SOUND_TYPE_SYSTEM:
+ dst_type = CAudioInfo::AUDIO_OUT_TYPE_SYSTEM;
+ break;
+ case SOUND_TYPE_NOTIFICATION:
+ dst_type = CAudioInfo::AUDIO_OUT_TYPE_NOTIFICATION;
+ break;
+ case SOUND_TYPE_ALARM:
+ dst_type = CAudioInfo::AUDIO_OUT_TYPE_ALARM;
+ break;
+ case SOUND_TYPE_RINGTONE:
+ dst_type = CAudioInfo::AUDIO_OUT_TYPE_RINGTONE_VOIP;
+ break;
+ case SOUND_TYPE_MEDIA:
+ dst_type = CAudioInfo::AUDIO_OUT_TYPE_MEDIA;
+ break;
+ case SOUND_TYPE_CALL:
+ dst_type = CAudioInfo::AUDIO_OUT_TYPE_SYSTEM;
+ break;
+ case SOUND_TYPE_VOIP:
+ dst_type = CAudioInfo::AUDIO_OUT_TYPE_VOIP;
+ break;
+ case SOUND_TYPE_VOICE:
+ dst_type = CAudioInfo::AUDIO_OUT_TYPE_VOICE_INFORMATION;
+ break;
+ default:
+ dst_type = CAudioInfo::AUDIO_OUT_TYPE_MEDIA;
+ break;
+ }
+}
+
+static void _convert_audio_info_audio_type_2_sound_type(const CAudioInfo::EAudioType& src_type, sound_type_e& dst_type) {
+ switch (src_type) {
+ case CAudioInfo::AUDIO_OUT_TYPE_MEDIA:
+ dst_type = SOUND_TYPE_MEDIA;
+ break;
+ case CAudioInfo::AUDIO_OUT_TYPE_SYSTEM:
+ dst_type = SOUND_TYPE_SYSTEM;
+ break;
+ case CAudioInfo::AUDIO_OUT_TYPE_ALARM:
+ dst_type = SOUND_TYPE_ALARM;
+ break;
+ case CAudioInfo::AUDIO_OUT_TYPE_NOTIFICATION:
+ case CAudioInfo::AUDIO_OUT_TYPE_EMERGENCY:
+ dst_type = SOUND_TYPE_NOTIFICATION;
+ break;
+ case CAudioInfo::AUDIO_OUT_TYPE_VOICE_INFORMATION:
+ case CAudioInfo::AUDIO_OUT_TYPE_VOICE_RECOGNITION:
+ dst_type = SOUND_TYPE_VOICE;
+ break;
+ case CAudioInfo::AUDIO_OUT_TYPE_RINGTONE_VOIP:
+ dst_type = SOUND_TYPE_RINGTONE;
+ break;
+ case CAudioInfo::AUDIO_OUT_TYPE_VOIP:
+ dst_type = SOUND_TYPE_VOIP;
+ break;
+ default:
+ dst_type = SOUND_TYPE_MEDIA;
+ break;
+ }
+}
+
+static audio_io_state_e _convert_state_type(const CAudioInfo::EAudioIOState src_state) {
+ audio_io_state_e dst_state;
+ switch (src_state) {
+ case CAudioInfo::AUDIO_IO_STATE_NONE:
+ dst_state = AUDIO_IO_STATE_IDLE;
+ break;
+ case CAudioInfo::AUDIO_IO_STATE_IDLE:
+ dst_state = AUDIO_IO_STATE_IDLE;
+ break;
+ case CAudioInfo::AUDIO_IO_STATE_RUNNING:
+ dst_state = AUDIO_IO_STATE_RUNNING;
+ break;
+ case CAudioInfo::AUDIO_IO_STATE_PAUSED:
+ dst_state = AUDIO_IO_STATE_PAUSED;
+ break;
+ default:
+ dst_state = AUDIO_IO_STATE_IDLE;
+ }
+ return dst_state;
+}
+
+static CAudioInfo _generate_audio_input_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) throw (CAudioError) {
+ CAudioInfo::EChannel dstChannel;
+ CAudioInfo::ESampleType dstSampleType;
+ CAudioInfo::EAudioType dstAudioType = CAudioInfo::AUDIO_IN_TYPE_MEDIA;
+
+ _convert_channel_2_audio_info_channel(channel, dstChannel);
+ _convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
+
+ return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
+}
+
+static CAudioInfo _generate_audio_input_loopback_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) throw (CAudioError) {
+ CAudioInfo::EChannel dstChannel;
+ CAudioInfo::ESampleType dstSampleType;
+ CAudioInfo::EAudioType dstAudioType = CAudioInfo::AUDIO_IN_TYPE_LOOPBACK;
+
+ _convert_channel_2_audio_info_channel(channel, dstChannel);
+ _convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
+
+ return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
+}
+
+static CAudioInfo _generate_audio_output_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type, sound_type_e sound_type) throw (CAudioError) {
+ CAudioInfo::EChannel dstChannel;
+ CAudioInfo::ESampleType dstSampleType;
+ CAudioInfo::EAudioType dstAudioType;
+
+ _convert_channel_2_audio_info_channel(channel, dstChannel);
+ _convert_sample_type_2_audio_info_sample_type(sample_type, dstSampleType);
+ _convert_sound_type_2_audio_info_audio_type(sound_type, dstAudioType);
+
+ return CAudioInfo(sampleRate, dstChannel, dstSampleType, dstAudioType, -1);
+}
+
+static audio_io_interrupted_code_e _convert_interrupted_code(IAudioSessionEventListener::EInterruptCode code) {
+ switch (code) {
+ case IAudioSessionEventListener::INTERRUPT_COMPLETED:
+ return AUDIO_IO_INTERRUPTED_COMPLETED;
+ case IAudioSessionEventListener::INTERRUPT_BY_CALL:
+ return AUDIO_IO_INTERRUPTED_BY_CALL;
+ case IAudioSessionEventListener::INTERRUPT_BY_EARJACK_UNPLUG:
+ return AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG;
+ case IAudioSessionEventListener::INTERRUPT_BY_RESOURCE_CONFLICT:
+ return AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT;
+ case IAudioSessionEventListener::INTERRUPT_BY_ALARM:
+ return AUDIO_IO_INTERRUPTED_BY_ALARM;
+ case IAudioSessionEventListener::INTERRUPT_BY_EMERGENCY:
+ return AUDIO_IO_INTERRUPTED_BY_EMERGENCY;
+ case IAudioSessionEventListener::INTERRUPT_BY_NOTIFICATION:
+ return AUDIO_IO_INTERRUPTED_BY_NOTIFICATION;
+ case IAudioSessionEventListener::INTERRUPT_BY_MEDIA:
+ case IAudioSessionEventListener::INTERRUPT_MAX:
+ default:
+ return AUDIO_IO_INTERRUPTED_BY_MEDIA;
+ }
+}
+
+/**
+ * Implements CAPI functions
+ */
+int cpp_audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h *input) {
+ audio_io_s* handle = NULL;
+ try {
+ if (input == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ handle = new audio_io_s;
+ if (handle == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
+ }
+
+ CAudioInfo audioInfo = _generate_audio_input_info(sample_rate, channel, type);
+
+ handle->audioIoHandle = new CAudioInput(audioInfo);
+ if (handle == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
+ }
+
+ handle->audioIoHandle->initialize();
+
+ *input = handle;
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+
+ VALID_POINTER_START(handle)
+ SAFE_FINALIZE(handle->audioIoHandle);
+ SAFE_DELETE(handle->audioIoHandle);
+ SAFE_DELETE(handle);
+ VALID_POINTER_END
+
+ VALID_POINTER_START(input)
+ *input = NULL;
+ VALID_POINTER_END
+
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+
+}
+
+int cpp_audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input) {
+ audio_io_s* handle = NULL;
+ try {
+ if (input == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ handle = new audio_io_s;
+ if (handle == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
+ }
+
+ CAudioInfo audioInfo = _generate_audio_input_loopback_info(sample_rate, channel, type);
+
+ handle->audioIoHandle = new CAudioInput(audioInfo);
+ if (handle == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
+ }
+
+ handle->audioIoHandle->initialize();
+
+ *input = handle;
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+
+ VALID_POINTER_START(handle)
+ SAFE_FINALIZE(handle->audioIoHandle);
+ SAFE_DELETE(handle->audioIoHandle);
+ SAFE_DELETE(handle);
+ VALID_POINTER_END
+
+ VALID_POINTER_START(input)
+ *input = NULL;
+ VALID_POINTER_END
+
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_destroy(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ SAFE_FINALIZE(handle->audioIoHandle);
+ SAFE_DELETE(handle->audioIoHandle);
+ SAFE_DELETE(handle);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_set_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL || stream_info == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
+ }
+
+ assert(handle->audioIoHandle);
+
+ int errorCode = SOUND_MANAGER_ERROR_NONE;
+ CAudioInfo::EAudioType AudioType = CAudioInfo::AUDIO_IN_TYPE_MEDIA;
+ char *type = NULL;
+ int index = -1;
+
+ if ((errorCode = sound_manager_get_type_from_stream_information (stream_info, &type)) != SOUND_MANAGER_ERROR_NONE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode);
+ }
+ handle->audioIoHandle->getAudioInfo().convertStreamType2AudioType(type, &AudioType);
+ handle->audioIoHandle->getAudioInfo().setAudioType(AudioType);
+
+ if ((errorCode = sound_manager_get_index_from_stream_information (stream_info, &index)) != SOUND_MANAGER_ERROR_NONE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode);
+ }
+ handle->audioIoHandle->getAudioInfo().setAudioIndex(index);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_prepare(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->prepare();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_unprepare(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->unprepare();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_pause(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->pause();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_resume(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->resume();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_drain(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->drain();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_flush(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->flush();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+ int ret = 0;
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
+ ret = inputHandle->read(buffer, length);
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("ret:%d", ret);
+#endif
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return ret;
+}
+
+int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL || size == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, size:%p", input, size);
+ }
+
+ assert(handle->audioIoHandle);
+
+ CAudioIO* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
+ *size = inputHandle->getBufferSize();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL || sample_rate == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
+ }
+
+ assert(handle->audioIoHandle);
+ *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL || channel == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, channel:%p", input, channel);
+ }
+
+ assert(handle->audioIoHandle);
+
+ const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
+ audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
+ _convert_audio_info_channel_2_channel(srcChannel, dstChannel);
+
+ *channel = dstChannel;
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL || type == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, type:%p", input, type);
+ }
+
+ assert(handle->audioIoHandle);
+
+ const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
+ audio_sample_type_e dstSampleType = AUDIO_SAMPLE_TYPE_U8;
+ _convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
+
+ *type = dstSampleType;
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+static void _interrupt_cb_internal(IAudioSessionEventListener::EInterruptCode _code, void* user_data) {
+ audio_io_s* handle = static_cast<audio_io_s*>(user_data);
+ audio_io_interrupted_code_e code = _convert_interrupted_code(_code);
+
+ assert(handle);
+
+ if (handle->interrupt_callback.onInterrupt != NULL) {
+ handle->interrupt_callback.onInterrupt(code, handle->interrupt_callback.user_data);
+ }
+}
+
+int cpp_audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callback, void *user_data) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL || callback == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, callback:%p", input, callback);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->interrupt_callback.onInterrupt = callback;
+ handle->interrupt_callback.user_data = user_data;
+
+ CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
+ cb.mUserData = static_cast<void*>(handle);
+ cb.onInterrupt = _interrupt_cb_internal;
+
+ handle->audioIoHandle->setInterruptCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_unset_interrupted_cb(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->interrupt_callback.onInterrupt = NULL;
+ handle->interrupt_callback.user_data = NULL;
+
+ CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
+ cb.mUserData = NULL;
+ cb.onInterrupt = NULL;
+
+ handle->audioIoHandle->setInterruptCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_ignore_session(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->ignoreSession();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+static void _stream_cb_internal(size_t nbytes, void *user_data) {
+ audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
+ assert(audioIo);
+
+ if (audioIo->stream_callback.onStream != NULL) {
+ audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
+ }
+}
+
+static void _state_changed_cb_internal(CAudioInfo::EAudioIOState state, CAudioInfo::EAudioIOState state_prev, bool by_policy, void *user_data) {
+ audio_io_s* audioIo = static_cast<audio_io_s*>(user_data);
+ assert(audioIo);
+
+ if (audioIo->state_changed_callback.onStateChanged != NULL) {
+ audioIo->state_changed_callback.onStateChanged(audioIo, _convert_state_type(state_prev), _convert_state_type(state), by_policy, audioIo->state_changed_callback.user_data);
+ }
+}
+
+int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL || callback == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p, callback:%p", input, callback);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->stream_callback.onStream = callback;
+ handle->stream_callback.user_data = user_data;
+
+ CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
+ cb.mUserData = static_cast<void*>(handle);
+ cb.onStream = _stream_cb_internal;
+
+ handle->audioIoHandle->setStreamCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_unset_stream_cb(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->stream_callback.onStream = NULL;
+ handle->stream_callback.user_data = NULL;
+
+ CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
+ cb.mUserData = NULL;
+ cb.onStream = NULL;
+
+ handle->audioIoHandle->setStreamCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
+ assert(inputHandle);
+
+ inputHandle->peek(buffer, length);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_drop(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL input:%p", input);
+ }
+
+ CAudioInput* inputHandle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
+ assert(inputHandle);
+
+ inputHandle->drop();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", input, callback);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->state_changed_callback.onStateChanged = callback;
+ handle->state_changed_callback.user_data = user_data;
+
+ CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
+ cb.mUserData = static_cast<void*>(handle);
+ cb.onStateChanged = _state_changed_cb_internal;
+
+ handle->audioIoHandle->setStateChangedCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
+ audio_io_s* handle = static_cast<audio_io_s*>(input);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", input);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->state_changed_callback.onStateChanged = NULL;
+ handle->state_changed_callback.user_data = NULL;
+
+ CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
+ cb.mUserData = NULL;
+ cb.onStateChanged = NULL;
+
+ handle->audioIoHandle->setStateChangedCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+
+/**
+ * Audio Out
+ */
+int cpp_audio_out_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h *output) {
+ audio_io_s* handle = NULL;
+ try {
+ handle = new audio_io_s;
+ if (handle == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
+ }
+
+ CAudioInfo audioInfo = _generate_audio_output_info(sample_rate, channel, type, sound_type);
+
+ handle->audioIoHandle = new CAudioOutput(audioInfo);
+ if (handle == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
+ }
+
+ handle->audioIoHandle->initialize();
+
+ *output = handle;
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+
+ VALID_POINTER_START(handle)
+ SAFE_FINALIZE(handle->audioIoHandle);
+ SAFE_DELETE(handle->audioIoHandle);
+ SAFE_DELETE(handle);
+ VALID_POINTER_END
+
+ VALID_POINTER_START(output)
+ *output = NULL;
+ VALID_POINTER_END
+
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
+ audio_io_s* handle = NULL;
+ try {
+ handle = new audio_io_s;
+ if (handle == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation handle");
+ }
+
+ CAudioInfo audioInfo = _generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA /* default sound_tyoe */);
+
+ handle->audioIoHandle = new CAudioOutput(audioInfo);
+ if (handle == NULL) {
+ THROW_ERROR_MSG(CAudioError::ERROR_OUT_OF_MEMORY, "Failed allocation internal handle");
+ }
+
+ handle->audioIoHandle->initialize();
+
+ *output = handle;
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+
+ VALID_POINTER_START(handle)
+ SAFE_FINALIZE(handle->audioIoHandle);
+ SAFE_DELETE(handle->audioIoHandle);
+ SAFE_DELETE(handle);
+ VALID_POINTER_END
+
+ VALID_POINTER_START(output)
+ *output = NULL;
+ VALID_POINTER_END
+
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_destroy(audio_out_h output) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ SAFE_FINALIZE(handle->audioIoHandle);
+ SAFE_DELETE(handle->audioIoHandle);
+ SAFE_DELETE(handle);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_set_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL || stream_info == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
+ }
+
+ assert(handle->audioIoHandle);
+
+ int errorCode = SOUND_MANAGER_ERROR_NONE;
+ CAudioInfo::EAudioType AudioType = CAudioInfo::AUDIO_OUT_TYPE_MEDIA;
+ char *type = NULL;
+ int index = -1;
+
+ if ((errorCode = sound_manager_get_type_from_stream_information (stream_info, &type)) != SOUND_MANAGER_ERROR_NONE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode);
+ }
+ handle->audioIoHandle->getAudioInfo().convertStreamType2AudioType(type, &AudioType);
+ handle->audioIoHandle->getAudioInfo().setAudioType(AudioType);
+
+ if ((errorCode = sound_manager_get_index_from_stream_information (stream_info, &index)) != SOUND_MANAGER_ERROR_NONE) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode);
+ }
+ handle->audioIoHandle->getAudioInfo().setAudioIndex(index);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_prepare(audio_out_h output) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->prepare();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_unprepare(audio_out_h output) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->unprepare();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_pause(audio_out_h output) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->pause();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_resume(audio_out_h output) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->resume();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_drain(audio_out_h output) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->drain();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_flush(audio_out_h output) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->flush();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+ int ret = 0;
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameter is NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ CAudioOutput* outputHandle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
+ ret = outputHandle->write(buffer, length);
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD("ret:%d", ret);
+#endif
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return ret;
+}
+
+int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL || size == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, size:%p", output, size);
+ }
+
+ assert(handle->audioIoHandle);
+
+ CAudioOutput* outputHandle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
+ *size = outputHandle->getBufferSize();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL || sample_rate == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
+ }
+
+ assert(handle->audioIoHandle);
+ *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL || channel == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, channel:%p", output, channel);
+ }
+
+ assert(handle->audioIoHandle);
+
+ const CAudioInfo::EChannel srcChannel = handle->audioIoHandle->getAudioInfo().getChannel();
+ audio_channel_e dstChannel = AUDIO_CHANNEL_MONO;
+ _convert_audio_info_channel_2_channel(srcChannel, dstChannel);
+
+ *channel = dstChannel;
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL || type == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, type:%p", output, type);
+ }
+
+ assert(handle->audioIoHandle);
+
+ const CAudioInfo::ESampleType srcSampleType = handle->audioIoHandle->getAudioInfo().getSampleType();
+ audio_sample_type_e dstSampleType = AUDIO_SAMPLE_TYPE_U8;
+ _convert_audio_info_sample_type_2_sample_type(srcSampleType, dstSampleType);
+
+ *type = dstSampleType;
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL || type == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, type:%p", output, type);
+ }
+
+ assert(handle->audioIoHandle);
+
+ const CAudioInfo::EAudioType srcAudioType = handle->audioIoHandle->getAudioInfo().getAudioType();
+ sound_type_e dstSoundType = SOUND_TYPE_MEDIA;
+ _convert_audio_info_audio_type_2_sound_type(srcAudioType, dstSoundType);
+
+ *type = dstSoundType;
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL || callback == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->interrupt_callback.onInterrupt = callback;
+ handle->interrupt_callback.user_data = user_data;
+
+ CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
+ cb.mUserData = static_cast<void*>(handle);
+ cb.onInterrupt = _interrupt_cb_internal;
+
+ handle->audioIoHandle->setInterruptCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_unset_interrupted_cb(audio_out_h output) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->interrupt_callback.onInterrupt = NULL;
+ handle->interrupt_callback.user_data = NULL;
+
+ CAudioIO::SInterruptCallback cb = handle->audioIoHandle->getInterruptCallback();
+ cb.mUserData = NULL;
+ cb.onInterrupt = NULL;
+
+ handle->audioIoHandle->setInterruptCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_ignore_session(audio_out_h output) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->audioIoHandle->ignoreSession();
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->stream_callback.onStream = callback;
+ handle->stream_callback.user_data = user_data;
+
+ CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
+ cb.mUserData = static_cast<void*>(handle);
+ cb.onStream = _stream_cb_internal;
+
+ handle->audioIoHandle->setStreamCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_unset_stream_cb(audio_out_h output) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->stream_callback.onStream = NULL;
+ handle->stream_callback.user_data = NULL;
+
+ CAudioIO::SStreamCallback cb = handle->audioIoHandle->getStreamCallback();
+ cb.mUserData = NULL;
+ cb.onStream = NULL;
+
+ handle->audioIoHandle->setStreamCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p, callback:%p", output, callback);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->state_changed_callback.onStateChanged = callback;
+ handle->state_changed_callback.user_data = user_data;
+
+ CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
+ cb.mUserData = static_cast<void*>(handle);
+ cb.onStateChanged = _state_changed_cb_internal;
+
+ handle->audioIoHandle->setStateChangedCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
+ audio_io_s* handle = static_cast<audio_io_s*>(output);
+
+ try {
+ if (handle == NULL) {
+ THROW_ERROR_MSG_FORMAT(CAudioError::ERROR_INVALID_ARGUMENT, "Parameters are NULL output:%p", output);
+ }
+
+ assert(handle->audioIoHandle);
+
+ handle->state_changed_callback.onStateChanged = NULL;
+ handle->state_changed_callback.user_data = NULL;
+
+ CAudioIO::SStateChangedCallback cb = handle->audioIoHandle->getStateChangedCallback();
+ cb.mUserData = NULL;
+ cb.onStateChanged = NULL;
+
+ handle->audioIoHandle->setStateChangedCallback(cb);
+ } catch (CAudioError e) {
+ AUDIO_IO_LOGE("%s", e.getErrorMsg());
+ return _convert_CAudioError(e);
+ }
+
+ return AUDIO_IO_ERROR_NONE;
+}
-
SET(fw_test "${fw_name}-test")
INCLUDE(FindPkgConfig)
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
ENDFOREACH(flag)
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror -pie")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -fPIC -Wall -Werror -std=c++0x -pie")
aux_source_directory(. sources)
FOREACH(src ${sources})
GET_FILENAME_COMPONENT(src_name ${src} NAME_WE)
MESSAGE("${src_name}")
ADD_EXECUTABLE(${src_name} ${src})
- TARGET_LINK_LIBRARIES(${src_name} ${fw_name} ${${fw_test}_LDFLAGS})
+ TARGET_LINK_LIBRARIES(${src_name} ${fw_name} ${${fw_test}_LDFLAGS} -lm)
ENDFOREACH()
+INSTALL(TARGETS audio_io_test DESTINATION bin)
/*
-* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2015 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.
* 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 <audio_io.h>
-
-int audio_io_test()
-{
- int ret, size;
- audio_in_h input;
- if ((ret = audio_in_create(44100, AUDIO_CHANNEL_STEREO ,AUDIO_SAMPLE_TYPE_S16_LE, &input)) == AUDIO_IO_ERROR_NONE) {
- ret = audio_in_ignore_session(input);
- if (ret != 0) {
- printf ("ERROR, set session mix\n");
- audio_in_destroy(input);
- return 0;
- }
-
- audio_in_prepare(input);
- if ((ret = audio_in_get_buffer_size(input, &size)) == AUDIO_IO_ERROR_NONE) {
- size = 500000;
- char *buffer = alloca(size);
- if ((ret = audio_in_read(input, (void*)buffer, size)) > AUDIO_IO_ERROR_NONE) {
- FILE* fp = fopen ("/root/test.raw", "wb+");
- fwrite (buffer, size, sizeof(char), fp);
- fclose (fp);
- printf ("PASS, size=%d, ret=%d\n", size, ret);
- }
- else {
- printf ("FAIL, size=%d, ret=%d\n", size, ret);
- }
- }
- audio_in_destroy(input);
- }
-
- return 1;
+#include <unistd.h>
+#include <math.h>
+#include <audio_io.h>
+#include <sound_manager.h>
+
+//#define _NEW_SOUND_MANAGER_API_
+#define _SESSION_SOUND_MANAGER_API_
+
+#ifndef M_PI
+#define M_PI (3.14159265)
+#endif
+
+#define TABLE_SIZE (200)
+typedef struct
+{
+ float sine[TABLE_SIZE];
+ int left_channel;
+ int right_channel;
+} test_wav_t;
+test_wav_t test_wav;
+
+static int ch_table[3] = { 0, AUDIO_CHANNEL_MONO, AUDIO_CHANNEL_STEREO };
+
+void play_file(char *file, int length, int ch)
+{
+ audio_out_h output;
+ FILE* fp = fopen (file, "r");
+ if (fp == NULL) {
+ printf ("fopen failed\n");
+ return;
+ }
+
+ char * buf = malloc (length);
+ if (buf == NULL) {
+ printf ("malloc failed\n");
+ fclose (fp);
+ return;
+ }
+
+ printf ("start to play [%s][%d][%d]\n", file, length, ch);
+ //audio_out_create(44100, ch_table[ch] ,AUDIO_SAMPLE_TYPE_S16_LE, SOUND_TYPE_MEDIA, &output);
+ audio_out_create_new(44100, ch_table[ch] ,AUDIO_SAMPLE_TYPE_S16_LE, &output);
+ if (fread (buf, 1, length, fp) != length) {
+ printf ("error!!!!\n");
+ }
+
+ audio_out_prepare(output);
+ audio_out_write(output, buf, length);
+ audio_out_unprepare(output);
+
+ audio_out_destroy (output);
+
+ fclose (fp);
+
+ printf ("play done\n");
+}
+
+#define DUMP_FILE "/root/test.raw"
+
+
+void play_file_sample(char *file, int frequency, int ch, int type)
+{
+ audio_out_h output;
+ int file_size = 0;
+ int read_bytes = 0;
+ int buffer_size = 0;
+ char * buf = NULL;
+
+ if(ch < 0 || ch > 2) {
+ ch = 0;
+ }
+
+ FILE* fp = fopen (file, "r");
+ if (fp == NULL) {
+ printf("open failed\n");
+ return;
+ }
+ /*Get the size*/
+ fseek(fp, 0, SEEK_END);
+ file_size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ printf ("start to play [%s] of size [%d] with [%d][%d][%d]\n", file, file_size, frequency, ch, type);
+ if (type) {
+ //audio_out_create(frequency, ch_table[ch] ,AUDIO_SAMPLE_TYPE_S16_LE, SOUND_TYPE_MEDIA, &output);
+ audio_out_create_new(frequency, ch_table[ch] ,AUDIO_SAMPLE_TYPE_S16_LE, &output);
+ } else {
+ //audio_out_create(frequency, ch_table[ch] ,AUDIO_SAMPLE_TYPE_U8, SOUND_TYPE_MEDIA, &output);
+ audio_out_create_new(frequency, ch_table[ch] ,AUDIO_SAMPLE_TYPE_U8, &output);
+ }
+ audio_out_prepare(output);
+ audio_out_get_buffer_size(output, &buffer_size);
+
+ buf = (char *) malloc(buffer_size);
+ if (buf == NULL) {
+ printf ("malloc failed\n");
+ audio_out_unprepare(output);
+ audio_out_destroy(output);
+ fclose (fp);
+ return;
+ }
+ //audio_out_prepare(output);
+
+ while (file_size > 0) {
+ read_bytes = fread (buf, 1, buffer_size, fp);
+ printf ("Read %d Requested - %d\n", read_bytes, buffer_size);
+ audio_out_write(output, buf, read_bytes);
+ file_size = file_size - read_bytes;
+ }
+
+ audio_out_unprepare(output);
+ audio_out_destroy (output);
+
+ free(buf);
+ fclose (fp);
+ printf ("play done\n");
+}
+
+int audio_io_test(int length, int num, int ch)
+{
+ int ret, size, i;
+ audio_in_h input;
+ if ((ret = audio_in_create(44100, ch_table[ch] ,AUDIO_SAMPLE_TYPE_S16_LE, &input)) == AUDIO_IO_ERROR_NONE) {
+ ret = audio_in_ignore_session(input);
+ if (ret != 0) {
+ printf ("ERROR, set session mix\n");
+ audio_in_destroy(input);
+ return 0;
+ }
+
+ ret = audio_in_prepare(input);
+ if (ret != 0) {
+ printf ("ERROR, prepare\n");
+ audio_in_destroy(input);
+ return 0;
+ }
+
+ FILE* fp = fopen (DUMP_FILE, "wb+");
+
+ if (fp == NULL) {
+ printf ("ERROR, file open failed\n");
+ audio_in_destroy(input);
+ return 0;
+ }
+
+ if ((ret = audio_in_get_buffer_size(input, &size)) == AUDIO_IO_ERROR_NONE) {
+ size = length;
+ char *buffer = alloca(size);
+
+ for (i=0; i<num; i++) {
+ printf ("### loop = %d ============== \n", i);
+ if ((ret = audio_in_read(input, (void*)buffer, size)) > AUDIO_IO_ERROR_NONE) {
+ fwrite (buffer, size, sizeof(char), fp);
+ printf ("PASS, size=%d, ret=%d\n", size, ret);
+ } else {
+ printf ("FAIL, size=%d, ret=%d\n", size, ret);
+ }
+ }
+ }
+
+ fclose (fp);
+
+ audio_in_destroy(input);
+ }
+
+ play_file (DUMP_FILE, length*num, ch);
+
+ return 1;
+}
+
+int audio_io_loopback_in_test()
+{
+ int ret, size;
+ audio_in_h input;
+ FILE* fp = fopen ("/tmp/dump_test.raw", "wb+");
+
+ if(fp == NULL) {
+ printf("open failed \n");
+ return 0;
+ }
+
+ if ((ret = audio_in_create(16000, AUDIO_CHANNEL_MONO , AUDIO_SAMPLE_TYPE_S16_LE, &input)) == AUDIO_IO_ERROR_NONE) {
+ ret = audio_in_ignore_session(input);
+ if (ret != 0) {
+ printf ("ERROR, set session mix\n");
+ goto exit;
+ }
+
+ ret = audio_in_prepare(input);
+ if (ret != 0) {
+ printf ("ERROR, prepare\n");
+ goto exit;
+ }
+
+ ret = audio_in_get_buffer_size(input, &size);
+ if(ret != AUDIO_IO_ERROR_NONE) {
+ printf ("audio_in_get_buffer_size failed.\n");
+ goto exit;
+ }
+
+ while(1) {
+ char *buffer = alloca(size);
+ if ((ret = audio_in_read(input, (void*)buffer, size)) > AUDIO_IO_ERROR_NONE) {
+ fwrite (buffer, size, sizeof(char), fp);
+ printf ("PASS, size=%d, ret=%d\n", size, ret);
+ } else {
+ printf ("FAIL, size=%d, ret=%d\n", size, ret);
+ }
+ }
+ }
+
+exit:
+ audio_in_destroy(input);
+
+ fclose (fp);
+
+ return ret;
+
+}
+
+int audio_io_loopback_test()
+{
+ int ret, size;
+ audio_in_h input;
+ audio_out_h output;
+ char *buffer = NULL;
+
+ ret = audio_in_create(16000, AUDIO_CHANNEL_MONO , AUDIO_SAMPLE_TYPE_S16_LE, &input);
+ if(ret != AUDIO_IO_ERROR_NONE) {
+ printf ("audio_in_create_ex failed. \n");
+ return 0;
+ }
+
+ //ret = audio_out_create(16000, AUDIO_CHANNEL_MONO , AUDIO_SAMPLE_TYPE_S16_LE, SOUND_TYPE_CALL, &output);
+ ret = audio_out_create_new(16000, AUDIO_CHANNEL_MONO , AUDIO_SAMPLE_TYPE_S16_LE, &output);
+ if(ret != AUDIO_IO_ERROR_NONE) {
+ printf ("audio_out_create failed. \n");
+ return 0;
+ }
+
+ ret = audio_in_prepare(input);
+ if (ret != 0) {
+ printf ("audio_in_prepare failed.\n");
+ audio_in_destroy(input);
+ return 0;
+ } else {
+ ret = audio_in_get_buffer_size(input, &size);
+ if(ret != AUDIO_IO_ERROR_NONE) {
+ printf ("audio_in_get_buffer_size failed.\n");
+ return 0;
+ } else {
+ printf("size(%d)\n", size);
+ buffer = alloca(size);
+ }
+ }
+
+ ret = audio_out_prepare(output);
+ if (ret != 0) {
+ printf ("audio_out_prepare failed.\n");
+ audio_out_destroy(output);
+ return 0;
+ }
+
+ if(buffer == NULL) {
+ printf("buffer is null\n");
+ return 0;
+ }
+
+ while(1) {
+ ret = audio_in_read(input, (void*)buffer, size);
+ if(ret > AUDIO_IO_ERROR_NONE) {
+ ret = audio_out_write(output, buffer, size);
+ if(ret > AUDIO_IO_ERROR_NONE) {
+ printf("audio read/write success. buffer(%p), size(%d)\n", buffer, size);
+ } else {
+ printf("audio read success, write failed. buffer(%p), size(%d)\n", buffer, size);
+ }
+ } else
+ printf("audio read/write failed. buffer(%p), size(%d)\n", buffer, size);
+ }
+
+}
+
+audio_in_h input;
+audio_out_h output;
+
+FILE* fp_w = NULL;
+
+#ifdef _NEW_SOUND_MANAGER_API_
+sound_stream_info_h g_stream_info_read_h = NULL;
+sound_stream_info_h g_stream_info_write_h = NULL;
+
+static void focus_callback_read (sound_stream_info_h stream_info, sound_stream_focus_change_reason_e reason_for_change, const char *additional_info, void *user_data) {
+ int ret = 0;
+ sound_stream_focus_state_e playback_focus_state;
+ sound_stream_focus_state_e recording_focus_state;
+ printf ("*** focus_callback_read is called, stream_info(%p) ***\n", stream_info);
+ printf (" - reason_for_change(%d), additional_info(%s), user_data(%p)\n", reason_for_change, additional_info, user_data);
+ ret = sound_manager_get_focus_state (stream_info, &playback_focus_state, &recording_focus_state);
+ if (!ret)
+ printf (" - focus_state(playback_focus:%d, recording_focus:%d)\n", playback_focus_state, recording_focus_state);
+ if (playback_focus_state == SOUND_STREAM_FOCUS_STATE_ACQUIRED) {
+ printf (" -- PLAYBACK_FOCUS acquired\n");
+ }
+ if (recording_focus_state == SOUND_STREAM_FOCUS_STATE_ACQUIRED) {
+ printf (" -- FOCUS_RECORDING acquired\n");
+ }
+ printf ("*** focus_callback_read is ended, stream_info(%p) ****\n", stream_info);
+ return;
+}
+
+static void focus_callback_write (sound_stream_info_h stream_info, sound_stream_focus_change_reason_e reason_for_change, const char *additional_info, void *user_data) {
+ int ret = 0;
+ sound_stream_focus_state_e playback_focus_state;
+ sound_stream_focus_state_e recording_focus_state;
+ printf ("*** focus_callback_write is called, stream_info(%p) ***\n", stream_info);
+ printf (" - reason_for_change(%d), additional_info(%s), user_data(%p)\n", reason_for_change, additional_info, user_data);
+ ret = sound_manager_get_focus_state (stream_info, &playback_focus_state, &recording_focus_state);
+ if (!ret)
+ printf (" - focus_state(playback_focus:%d, recording_focus:%d)\n", playback_focus_state, recording_focus_state);
+ if (playback_focus_state == SOUND_STREAM_FOCUS_STATE_ACQUIRED) {
+ printf (" -- PLAYBACK_FOCUS acquired\n");
+ }
+ if (recording_focus_state == SOUND_STREAM_FOCUS_STATE_ACQUIRED) {
+ printf (" -- FOCUS_RECORDING acquired\n");
+ }
+ printf ("*** focus_callback_write is ended, stream_info(%p) ****\n", stream_info);
+ return;
+}
+#endif
+
+static void interrupted_callback_read(audio_io_interrupted_code_e code, void *user_data) {
+ printf ("*** interrupted_callback_read is called, code(%d), user_data(%p) ***\n", code, user_data);
+}
+
+static void interrupted_callback_write(audio_io_interrupted_code_e code, void *user_data) {
+ printf ("*** interrupted_callback_write is called, code(%d), user_data(%p) ***\n", code, user_data);
+}
+
+static void _audio_io_stream_read_cb (audio_in_h handle, size_t nbytes, void *user_data)
+{
+ const void * buffer = NULL;
+
+// printf("_audio_io_stream_read_cb : handle=%p, nbytes=%d, user_data=%p\n", handle, nbytes, user_data);
+
+ if (nbytes > 0) {
+ audio_in_peek (handle, &buffer, &nbytes);
+ if (fp_w) {
+ fwrite(buffer, sizeof(char), nbytes, fp_w);
+ }
+ audio_in_drop (handle);
+ }
+}
+
+static void _audio_io_stream_write_cb (audio_out_h handle, size_t nbytes, void *user_data)
+{
+ short* buffer = NULL;
+ int ret = 0;
+ int i = 0;
+
+// printf("_audio_io_stream_write_cb : handle=%p, nbytes=%d, user_data=%p\n", handle, nbytes, user_data);
+
+ if (nbytes > 0) {
+ buffer = (short *) malloc(nbytes);
+ if (buffer == NULL) {
+ printf ("malloc failed\n");
+ return;
+ }
+ memset (buffer, 0, nbytes);
+
+ for(i=0; i<nbytes/2; i+=2)
+ {
+ buffer[i] = (short) 32768 * test_wav.sine[test_wav.left_channel]; /* left */
+ buffer[i+1] = (short) 32768 * test_wav.sine[test_wav.right_channel]; /* right */
+ test_wav.left_channel += 1;
+ if( test_wav.left_channel >= TABLE_SIZE ) test_wav.left_channel -= TABLE_SIZE;
+ test_wav.right_channel += 3;
+ if( test_wav.right_channel >= TABLE_SIZE ) test_wav.right_channel -= TABLE_SIZE;
+ }
+
+ ret = audio_out_write(handle, buffer, nbytes);
+ if(ret > AUDIO_IO_ERROR_NONE) {
+// printf("audio write success. buffer(%p), nbytes(%d)\n", buffer, nbytes);
+ }
+
+ free (buffer);
+ }
+}
+
+static void _audio_in_state_cb (audio_in_h handle, audio_io_state_e previous, audio_io_state_e current, bool by_policy, void *user_data)
+{
+ printf(">>> _audio_in_state_cb() : handle(%p), current(%d), previous(%d), by_policy(%d), user_data(%p)\n", handle, current, previous, by_policy, user_data);
+}
+
+static void _audio_out_state_cb (audio_in_h handle, audio_io_state_e previous, audio_io_state_e current, bool by_policy, void *user_data)
+{
+ printf(">>> _audio_out_state_cb() : handle(%p), current(%d), previous(%d), by_policy(%d), user_data(%p)\n", handle, current, previous, by_policy, user_data);
+}
+
+int _convert_cmd_and_run(char cmd, int mode) {
+ int ret = 0;
+ switch (cmd) {
+ case 'P':
+ if(mode & 0x01) ret = audio_out_prepare(output);
+ if(mode & 0x02) ret = audio_in_prepare(input);
+ break;
+ case 'u':
+ if(mode & 0x01) ret = audio_out_unprepare(output);
+ if(mode & 0x02) ret = audio_in_unprepare(input);
+ break;
+ case 'p':
+ if(mode & 0x01) ret = audio_out_pause(output);
+ if(mode & 0x02) ret = audio_in_pause(input);
+ break;
+ case 'r':
+ if(mode & 0x01) ret = audio_out_resume(output);
+ if(mode & 0x02) ret = audio_in_resume(input);
+ break;
+ case 'd':
+ if(mode & 0x01) ret = audio_out_drain(output);
+ //if(mode & 0x02) ret = audio_in_drain(input);
+ break;
+ case 'f':
+ if(mode & 0x01) ret = audio_out_flush(output);
+ if(mode & 0x02) ret = audio_in_flush(input);
+ break;
+ case 'i':
+#ifdef _NEW_SOUND_MANAGER_API_
+ ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, focus_callback_write, NULL, &g_stream_info_write_h);
+ if (ret) {
+ printf ("fail to sound_manager_create_stream_information(), ret(0x%x)\n", ret);
+ }
+#endif
+#ifdef _SESSION_SOUND_MANAGER_API_
+ ret = sound_manager_set_session_type(SOUND_SESSION_TYPE_MEDIA);
+ if (ret) {
+ printf ("fail to sound_manager_set_session_type(), ret(0x%x)\n", ret);
+ }
+ ret = sound_manager_set_media_session_option (SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START, SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY);
+ if (ret) {
+ printf ("fail to sound_manager_set_media_session_option(), ret(0x%x)\n", ret);
+ }
+#endif
+ break;
+ case 'q': /* quit */
+ ret = 1;
+ break;
+ default:
+ ret = 1;
+ break;
+ }
+ return ret;
+}
+
+int audio_io_async_test(int mode)
+{
+ int ret, size;
+ char *buffer = NULL;
+ int i=0;
+
+ char cmd = 0;
+ int cmd_ret;
+
+ int write_mode = (mode & 0x01);
+ int read_mode = (mode & 0x02);
+
+ if((write_mode == 0) && (read_mode == 0)) {
+ printf ("not vaild mode.\n");
+ return 0;
+ }
+
+ if (read_mode) {
+
+#ifdef _SESSION_SOUND_MANAGER_API_
+ printf ("set session for capture.\n");
+
+ ret = sound_manager_set_session_type(SOUND_SESSION_TYPE_MEDIA);
+ if (ret) {
+ printf ("fail to sound_manager_set_session_type(), ret(0x%x)\n", ret);
+ }
+
+ ret = sound_manager_set_media_session_option (SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START, SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY);
+ if (ret) {
+ printf ("fail to sound_manager_set_media_session_option(), ret(0x%x)\n", ret);
+ }
+#endif
+
+ printf ("audio_in_create\n");
+ ret = audio_in_create(44100, AUDIO_CHANNEL_STEREO , AUDIO_SAMPLE_TYPE_S16_LE, &input);
+ if(ret != AUDIO_IO_ERROR_NONE) {
+ printf ("audio_in_create_ex failed. \n");
+ return 0;
+ }
+ printf ("audio_in_create success!!! [%p]\n", input);
+
+ ret = audio_in_set_stream_cb(input, _audio_io_stream_read_cb, NULL);
+ if(ret != AUDIO_IO_ERROR_NONE) {
+ printf ("audio_in_set_stream_cb failed. \n");
+ return 0;
+ }
+ printf ("audio_in_set_stream_cb success!!! [%p]\n", input);
+
+ ret = audio_in_set_state_changed_cb(input, _audio_in_state_cb, NULL);
+ if(ret != AUDIO_IO_ERROR_NONE) {
+ printf ("audio_out_set_state_changed_cb failed. \n");
+ return 0;
+ }
+ printf ("audio_out_set_state_changed_cb success!!! [%p]\n", input);
+
+ fp_w = fopen( "/tmp/pcm_w.raw", "w");
+
+#ifdef _NEW_SOUND_MANAGER_API_
+ //set stream type as SOUND_STREAM_TYPE_MEDIA
+ ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, focus_callback_read, NULL, &g_stream_info_read_h);
+ if (ret) {
+ printf ("fail to sound_manager_create_stream_information(), ret(0x%x)\n", ret);
+ }
+ ret = audio_in_set_stream_info(input, g_stream_info_read_h);
+#endif
+
+ ret = audio_in_set_interrupted_cb(input, interrupted_callback_read, NULL);
+ }
+
+ if (write_mode) {
+ printf ("before audio_out_create\n");
+ getchar();
+
+#ifdef _SESSION_SOUND_MANAGER_API_
+ printf ("set session for playback.\n");
+
+ ret = sound_manager_set_session_type(SOUND_SESSION_TYPE_MEDIA);
+ if (ret) {
+ printf ("fail to sound_manager_set_session_type(), ret(0x%x)\n", ret);
+ }
+
+ ret = sound_manager_set_media_session_option (SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START, SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY);
+ if (ret) {
+ printf ("fail to sound_manager_set_media_session_option(), ret(0x%x)\n", ret);
+ }
+#endif
+
+ printf ("audio_out_create\n");
+ //ret = audio_out_create(44100, AUDIO_CHANNEL_STEREO , AUDIO_SAMPLE_TYPE_S16_LE, SOUND_TYPE_MEDIA, &output);
+ ret = audio_out_create_new(44100, AUDIO_CHANNEL_STEREO , AUDIO_SAMPLE_TYPE_S16_LE, &output);
+ if(ret != AUDIO_IO_ERROR_NONE) {
+ printf ("audio_out_create failed. \n");
+ return 0;
+ }
+ printf ("audio_out_create success!!! [%p]\n", output);
+
+ ret = audio_out_set_stream_cb(output, _audio_io_stream_write_cb, NULL);
+ if(ret != AUDIO_IO_ERROR_NONE) {
+ printf ("audio_out_set_stream_cb failed. \n");
+ return 0;
+ }
+ printf ("audio_out_set_stream_cb success!!! [%p]\n", output);
+
+ ret = audio_out_set_state_changed_cb(output, _audio_out_state_cb, NULL);
+ if(ret != AUDIO_IO_ERROR_NONE) {
+ printf ("audio_out_set_state_changed_cb failed. \n");
+ return 0;
+ }
+ printf ("audio_out_set_state_changed_cb success!!! [%p]\n", output);
+
+#ifdef _NEW_SOUND_MANAGER_API_
+ //set stream type as SOUND_STREAM_TYPE_MEDIA
+ ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, focus_callback_write, NULL, &g_stream_info_write_h);
+ if (ret) {
+ printf ("fail to sound_manager_create_stream_information(), ret(0x%x)\n", ret);
+ }
+ ret = audio_out_set_stream_info(output, g_stream_info_write_h);
+#endif
+
+ ret = audio_out_set_interrupted_cb(output, interrupted_callback_write, NULL);
+
+ //generate wave data
+ for(i=0; i<TABLE_SIZE; i++) {
+ test_wav.sine[i] = 0.9 * (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+ }
+ test_wav.left_channel = test_wav.right_channel = 0;
+ }
+
+ if (read_mode) {
+ printf ("before audio_in_prepare\n");
+ getchar();
+ printf ("audio_in_prepare\n");
+ ret = audio_in_prepare(input);
+ if (ret != 0) {
+ printf ("audio_in_prepare failed.\n");
+ audio_in_destroy(input);
+ return 0;
+ } else {
+ ret = audio_in_get_buffer_size(input, &size);
+ if(ret != AUDIO_IO_ERROR_NONE) {
+ printf ("audio_in_get_buffer_size failed.\n");
+ return 0;
+ } else {
+ printf("size(%d)\n", size);
+ buffer = alloca(size);
+ }
+ }
+
+ if(buffer == NULL) {
+ printf("buffer is null\n");
+ return 0;
+ }
+ }
+
+ if (write_mode) {
+ printf ("before audio_out_prepare\n");
+ getchar();
+ printf ("audio_out_prepare\n");
+ ret = audio_out_prepare(output);
+ if (ret != 0) {
+ printf ("audio_out_prepare failed.\n");
+ audio_out_destroy(output);
+ return 0;
+ }
+ }
+
+ do {
+ printf ("command(q:quit) : ");
+ cmd = (char) getchar();
+ if(cmd != '\n') getchar();
+ cmd_ret = _convert_cmd_and_run(cmd, mode);
+ printf (" - result code : %d\n", cmd_ret);
+ } while (cmd != 'q');
+
+ //printf ("loop start\n");
+ //for (i=0; i<10; i++) {
+ // printf ("-------- %d -------\n",i);
+ // usleep (1000000);
+ //}
+
+ //getchar();
+
+ if (read_mode) {
+ printf ("audio_in_unprepare\n");
+ audio_in_unprepare(input);
+ printf ("audio_in_destroy\n");
+ audio_in_destroy(input);
+
+ fclose(fp_w);
+ fp_w = NULL;
+
+#ifdef _NEW_SOUND_MANAGER_API_
+ ret = sound_manager_destroy_stream_information(g_stream_info_read_h);
+ if (ret) {
+ printf ("fail to sound_manager_destroy_stream_information(), ret(0x%x)\n", ret);
+ } else {
+ g_stream_info_read_h = NULL;
+ }
+#endif
+ }
+
+ //getchar();
+
+ if (write_mode) {
+ printf ("audio_out_unprepare\n");
+ audio_out_unprepare(output);
+ printf ("audio_out_destroy\n");
+ audio_out_destroy(output);
+
+#ifdef _NEW_SOUND_MANAGER_API_
+ ret = sound_manager_destroy_stream_information(g_stream_info_write_h);
+ if (ret) {
+ printf ("fail to sound_manager_destroy_stream_information(), ret(0x%x)\n", ret);
+ } else {
+ g_stream_info_write_h = NULL;
+ }
+#endif
+ }
+
+ return 0;
}
int main(int argc, char ** argv)
{
- audio_io_test();
- return 0;
+ if ( argc == 2 && !strcmp(argv[1],"call-forwarding-loop")) {
+ audio_io_loopback_test();
+ } else if ( argc == 2 && !strcmp(argv[1],"call-forwarding-in")) {
+ audio_io_loopback_in_test();
+ } else if ( argc == 3 && !strcmp(argv[1],"async")) {
+ audio_io_async_test(atoi(argv[2]));
+ } else if (argc == 4) {
+ printf ("run with [%s][%s][%s]\n", argv[1],argv[2],argv[3]);
+ audio_io_test(atoi (argv[1]), atoi (argv[2]), atoi(argv[3]));
+ } else if (argc == 6) {
+ play_file_sample(argv[2], atoi(argv[3]), atoi(argv[4]), atoi(argv[5]));
+ } else {
+ printf ("1. usage : audio_io_test call-forwarding-loop\n");
+ printf ("2. usage : audio_io_test call-forwarding-in\n");
+ printf ("3. usage : audio_io_test [length to read] [number of iteration] [channels]\n");
+ printf ("4. usage : audio_io_test async [write(1) | read(2)]\n");
+ printf ("5. Uasge : audio_io_test play [filename] [sample rate] [channels] [type(0:U8)]\n");
+ }
+ return 0;
}