From c6b80c7b7e0cb3abf96411c1e5732946320b4d7c Mon Sep 17 00:00:00 2001 From: mamingshuai Date: Thu, 11 Mar 2021 18:43:15 +0800 Subject: [PATCH] update openharmony 1.0.1 --- .gitee/ISSUE_TEMPLATE.zh-CN.md | 13 - .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md | 15 - BUILD.gn | 50 --- LICENSE | 352 +++++++++--------- README.md | 52 +++ README_zh.md | 52 +++ figures/audio_lite.png | Bin 0 -> 54008 bytes figures/audio_lite_en.png | Bin 0 -> 41309 bytes frameworks/BUILD.gn | 49 +++ .../audio_capturer.cpp | 2 +- .../audio_capturer_impl.cpp | 42 +-- .../audio_capturer_impl.h | 9 +- .../audio_encoder}/audio_encoder.cpp | 52 +-- .../audio_encoder}/include/audio_encoder.h | 53 +-- .../audio_source}/audio_source.cpp | 34 +- .../audio_source}/include/audio_source.h | 50 +-- interfaces/kits/audio_capturer.h | 253 +++++++++++++ readme.md | 3 - 18 files changed, 681 insertions(+), 400 deletions(-) delete mode 100755 .gitee/ISSUE_TEMPLATE.zh-CN.md delete mode 100755 .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md delete mode 100755 BUILD.gn mode change 100755 => 100644 LICENSE create mode 100644 README.md create mode 100644 README_zh.md create mode 100644 figures/audio_lite.png create mode 100644 figures/audio_lite_en.png create mode 100755 frameworks/BUILD.gn rename audio_capturer.cpp => frameworks/audio_capturer.cpp (97%) rename audio_capturer_impl.cpp => frameworks/audio_capturer_impl.cpp (83%) rename audio_capturer_impl.h => frameworks/audio_capturer_impl.h (89%) rename {audio_encoder => frameworks/audio_encoder}/audio_encoder.cpp (80%) rename {audio_encoder => frameworks/audio_encoder}/include/audio_encoder.h (64%) rename {audio_source => frameworks/audio_source}/audio_source.cpp (86%) rename {audio_source => frameworks/audio_source}/include/audio_source.h (64%) create mode 100755 interfaces/kits/audio_capturer.h delete mode 100755 readme.md diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md deleted file mode 100755 index f09d98d..0000000 --- a/.gitee/ISSUE_TEMPLATE.zh-CN.md +++ /dev/null @@ -1,13 +0,0 @@ -### 该问题是怎么引起的? - - - -### 重现步骤 - - - -### 报错信息 - - - - diff --git a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md deleted file mode 100755 index 33948fd..0000000 --- a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md +++ /dev/null @@ -1,15 +0,0 @@ -### 相关的Issue - - -### 原因(目的、解决的问题等) - - -### 描述(做了什么,变更了什么) - - -### 测试用例(新增、改动、可能影响的功能) - - - - - diff --git a/BUILD.gn b/BUILD.gn deleted file mode 100755 index ec5468f..0000000 --- a/BUILD.gn +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2020 Huawei Device Co., Ltd. -# 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. -import("//build/lite/config/component/lite_component.gni") -import("//build/lite/ndk/ndk.gni") - -shared_library("audio_capturer") { - sources = [ - "audio_capturer.cpp", - "audio_capturer_impl.cpp", - "audio_encoder/audio_encoder.cpp", - "audio_source/audio_source.cpp", - ] - cflags = ["-fPIC"] - cflags += ["-Wall"] - cflags_cc = cflags - include_dirs = [ - "audio_encoder/include", - "audio_source/include", - "//foundation/multimedia/hals/camera_lite", - "//drivers/hdf/lite/hdi/audio/include", - "//drivers/hdf/lite/hdi/codec/include", - "//drivers/hdf/lite/hdi/format/include", - ] - outdir = rebase_path("$root_out_dir") - public_configs = [":audio_external_library_config"] - ldflags = [ - "-L$outdir", - "-laudio_hw" - ] - deps = [ - "//third_party/bounds_checking_function:libsec_shared", - "//foundation/graphic/lite/frameworks/surface:surface", - "//foundation/multimedia/utils/lite:media_common", - ] -} - -config("audio_external_library_config") { - include_dirs = ["//foundation/multimedia/interfaces/kits/audio_lite"] - include_dirs += ["//foundation/multimedia/utils/lite/include"] -} diff --git a/LICENSE b/LICENSE old mode 100755 new mode 100644 index 4a45986..4947287 --- a/LICENSE +++ b/LICENSE @@ -1,177 +1,177 @@ - - 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. - + + 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 \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..def93f2 --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# AUDIO\_LITE + +- [AUDIO\_LITE](#audio_lite) + - [Introduction](#introduction) + - [Directory Structure](#directory-structure) + - [Usage](#usage) + - [Constraints](#constraints) + - [Repositories Involved](#repositories-involved) + +## Introduction + +This repository provides the audio capability. + +**Figure 1** Position of this repository \(in the dotted blue box\) in the multimedia subsystem +![](figures/audio_lite_en.png "audio_lite_en") + +## Directory Structure + +``` +foundation/multimedia/audio_lite +├── frameworks # Framework code +└── interfaces # APIs + └── kits # External APIs +``` + +## Usage + +Build a single repository in the root directory. + +``` +# Select the development board. +hb set +# Build this repository. +hb build audio_manager_lite +``` + +## Constraints + +- C++ 11 or later + +## Repositories Involved + +/hmf/multimedia/camera\_lite + +/hmf/multimedia/audio\_lite + +/hmf/multimedia/media\_lite + +/hmf/multimedia/utils\_lite + +/hmf/multimedia/service\_lite + diff --git a/README_zh.md b/README_zh.md new file mode 100644 index 0000000..11773ad --- /dev/null +++ b/README_zh.md @@ -0,0 +1,52 @@ +# 媒体子系统AUDIO\_LITE组件 + +- [媒体子系统AUDIO\_LITE组件](#媒体子系统audio_lite组件) + - [简介](#简介) + - [目录](#目录) + - [使用说明](#使用说明) + - [约束](#约束) + - [相关仓](#相关仓) + +## 简介 + +AUDIO\_LITE组件提供音频能力的支持。 + +**图 1** 媒体子系统架构(蓝色虚线框是audio\_lite) +![](figures/audio_lite.png "媒体子系统架构(蓝色虚线框是audio_lite)") + +## 目录 + +``` +foundation/multimedia/audio_lite +├── frameworks # 框架代码 +└── interfaces # 接口 + └── kits # 对外接口 +``` + +## 使用说明 + +单仓的编译构建,在根目录下进行单仓的构建和编译 + +``` +# 开发板选择 +hb set +# 单仓构建和编译 +hb build audio_manager_lite +``` + +## 约束 + +- C++11版本或以上 + +## 相关仓 + +/hmf/multimedia/camera\_lite + +/hmf/multimedia/audio\_lite + +/hmf/multimedia/media\_lite + +/hmf/multimedia/utils\_lite + +/hmf/multimedia/service\_lite + diff --git a/figures/audio_lite.png b/figures/audio_lite.png new file mode 100644 index 0000000000000000000000000000000000000000..7646f664f639d17e1165155b58fa2b5d2fa53d92 GIT binary patch literal 54008 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

qQura#ln{$GRCPA^ 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 KN&NAvxBm%NjJXN` literal 0 HcmV?d00001 diff --git a/figures/audio_lite_en.png b/figures/audio_lite_en.png new file mode 100644 index 0000000000000000000000000000000000000000..3a362a61f37d70f6d2618abedf41927aa9225cd0 GIT binary patch literal 41309 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 - +/* include */ #include "audio_source.h" #include "audio_encoder.h" #include "media_log.h" @@ -26,8 +24,8 @@ namespace Audio { using namespace OHOS::Media; -const unsigned long long TIME_CONVERSION_US_S = 1000000ULL; /* us to s */ -const unsigned long long TIME_CONVERSION_NS_US = 1000ULL; /* ns to us */ +const unsigned long long TIME_CONVERSION_US_S = 1000000ULL; /* s to s */ +const unsigned long long TIME_CONVERSION_NS_US = 1000ULL; /* ns to s */ AudioCapturer::AudioCapturerImpl::AudioCapturerImpl() @@ -52,7 +50,7 @@ uint64_t AudioCapturer::AudioCapturerImpl::GetFrameCount() return audioSource_->GetFrameCount(); } -State AudioCapturer::AudioCapturerImpl::GetStatus() +State AudioCapturer::AudioCapturer::AudioCapturerImpl::GetStatus() { return status; } @@ -69,10 +67,10 @@ int32_t AudioCapturer::AudioCapturerImpl::SetCapturerInfo(const AudioCapturerInf std::vector devices; ret = audioSource_->EnumDeviceBySourceType(info.inputSource, devices); if (ret != SUCCESS || devices.empty()) { - MEDIA_ERR_LOG("EnumDeviceBySourceType failed inputSource:%d", info.inputSource); + MEDIA_ERR_LOG("EnumDeviceBySourceType failed inputSource:%d", info.inputSource); return ret; } - MEDIA_INFO_LOG("info.sampleRate:%d", info.sampleRate); + MEDIA_INFO_LOG("info.sampleRate %d", info.sampleRate); AudioSourceConfig sourceConfig; sourceConfig.deviceId = devices[0].deviceId; sourceConfig.audioFormat = info.audioFormat; @@ -83,7 +81,7 @@ int32_t AudioCapturer::AudioCapturerImpl::SetCapturerInfo(const AudioCapturerInf sourceConfig.streamUsage = TYPE_DEFAULT; ret = audioSource_->Initialize(sourceConfig); if (ret != SUCCESS) { - MEDIA_ERR_LOG("Initialize failed inputSource:%d", info.inputSource); + MEDIA_ERR_LOG("Initialize failed inputSource:%d", info.inputSource); return ret; } AudioEncodeConfig encodeConfig; @@ -92,14 +90,14 @@ int32_t AudioCapturer::AudioCapturerImpl::SetCapturerInfo(const AudioCapturerInf encodeConfig.sampleRate = info.sampleRate; encodeConfig.channelCount = info.channelCount; encodeConfig.bitWidth = info.bitWidth; - MEDIA_INFO_LOG("audioEncoder_ info.bitRate:%d", info.bitRate); + MEDIA_INFO_LOG("audioEncoder_ info.bitRate %d ", info.bitRate); ret = audioEncoder_->Initialize(encodeConfig); if (ret != SUCCESS) { - MEDIA_ERR_LOG("Initialize failed inputSource:%d", info.inputSource); + MEDIA_ERR_LOG("Initialize failed inputSource:%d", info.inputSource); return ret; } info_ = info; - status = PREPARED; + status = PREPPARED; MEDIA_INFO_LOG("Set Capturer Info SUCCESS"); return SUCCESS; } @@ -113,9 +111,9 @@ int32_t AudioCapturer::AudioCapturerImpl::GetCapturerInfo(AudioCapturerInfo &inf bool AudioCapturer::AudioCapturerImpl::Record() { - if (status != PREPARED && + if (status != PREPPARED && status != STOPPED) { - MEDIA_ERR_LOG("Record ILLEGAL_STATE status:%u", status); + MEDIA_ERR_LOG("Record ILLEGAL_STATE status:%u", status); return ERR_ILLEGAL_STATE; } int32_t ret = audioSource_->Start(); @@ -148,11 +146,11 @@ bool AudioCapturer::AudioCapturerImpl::Record() int32_t AudioCapturer::AudioCapturerImpl::Read(uint8_t *buffer, size_t userSize, bool isBlockingRead) { if (buffer == NULL || userSize == 0) { - MEDIA_ERR_LOG("Invalid buffer:%p userSize:%u", buffer, userSize); + MEDIA_ERR_LOG("Invalid buffer %p userSize:%u", buffer, userSize); return ERR_INVALID_READ; } if (status != RECORDING) { - MEDIA_ERR_LOG("ILLEGAL_STATE status:%u", status); + MEDIA_ERR_LOG("ILLEGAL_STATE status:%u", status); return ERR_INVALID_READ; } AudioStream stream; @@ -160,7 +158,7 @@ int32_t AudioCapturer::AudioCapturerImpl::Read(uint8_t *buffer, size_t userSize, stream.bufferLen = userSize; int32_t readLen = audioEncoder_->ReadStream(stream, isBlockingRead); if (readLen == ERR_INVALID_READ) { - MEDIA_ERR_LOG("audioEncoder_ ReadStream failed:0x%x", readLen); + MEDIA_ERR_LOG("audioEncoder_ ReadStream fail,ret:0x%x", readLen); return ERR_INVALID_READ; } timestamp_.time.tv_sec = static_cast(stream.timeStamp / TIME_CONVERSION_US_S); // us - s @@ -172,19 +170,19 @@ int32_t AudioCapturer::AudioCapturerImpl::Read(uint8_t *buffer, size_t userSize, bool AudioCapturer::AudioCapturerImpl::Stop() { if (status != RECORDING) { - MEDIA_ERR_LOG("ILLEGAL_STATE status:%u", status); + MEDIA_ERR_LOG("ILLEGAL_STATE status:%u", status); return ERR_ILLEGAL_STATE; } MEDIA_INFO_LOG("audioEncoder Stop"); int32_t ret = audioEncoder_->Stop(); if (ret != SUCCESS) { - MEDIA_DEBUG_LOG("audioEncoder_ stop failed:0x%x", ret); + MEDIA_DEBUG_LOG("audioEncoder_ stop fail,ret:0x%x", ret); return false; } MEDIA_INFO_LOG("audioSource Stop"); ret = audioSource_->Stop(); if (ret != SUCCESS) { - MEDIA_ERR_LOG("audioSource_ stop failed:0x%x", ret); + MEDIA_ERR_LOG("audioSource_ stop fail,ret:0x%x", ret); return false; } MEDIA_INFO_LOG("Stop Audio Capturer SUCCESS"); @@ -199,7 +197,7 @@ bool AudioCapturer::AudioCapturerImpl::Release() return false; } if (status == RECORDING && Stop()) { - MEDIA_ERR_LOG("Stop failed:%u", status); + MEDIA_ERR_LOG("Stop failed: %u", status); return false; } status = RELEASED; diff --git a/audio_capturer_impl.h b/frameworks/audio_capturer_impl.h similarity index 89% rename from audio_capturer_impl.h rename to frameworks/audio_capturer_impl.h index 818fa4c..850814e 100755 --- a/audio_capturer_impl.h +++ b/frameworks/audio_capturer_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * 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 @@ -17,20 +17,18 @@ #define AUDIO_CAPTURER_IMPL_H #include - #include "audio_capturer.h" namespace OHOS { namespace Audio { enum AudioChannel { - AUDIO_CHANNEL_IN_MONO = 1, - AUDIO_CHANNEL_IN_STEREO = 2, + AUDIO_CHANNEL_IN_MONO = 1, /* mono */ + AUDIO_CHANNEL_IN_STEREO = 2, /* stereo */ AUDIO_CHANNEL_BUTT }; class AudioSource; class AudioEncoder; - class AudioCapturer::AudioCapturerImpl { public: AudioCapturerImpl(); @@ -46,7 +44,6 @@ public: uint64_t GetFrameCount(); State GetStatus(); bool GetTimestamp(Timestamp ×tamp, Timestamp::Timebase base); - private: std::unique_ptr audioSource_; std::unique_ptr audioEncoder_; diff --git a/audio_encoder/audio_encoder.cpp b/frameworks/audio_encoder/audio_encoder.cpp similarity index 80% rename from audio_encoder/audio_encoder.cpp rename to frameworks/audio_encoder/audio_encoder.cpp index 9b991eb..1fcfaee 100755 --- a/audio_encoder/audio_encoder.cpp +++ b/frameworks/audio_encoder/audio_encoder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * 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 @@ -21,7 +21,7 @@ namespace OHOS { namespace Audio { using namespace OHOS::Media; -constexpr uint32_t AUDIO_READ_STREAM_TIME_OUT_MS = 1000; +constexpr uint32_t AUDIO_READ_STREAM_TIME_OUT_MS = 1000; /* 1S */ constexpr uint32_t AUDIO_CHANNEL_MONO = 1; constexpr uint32_t AUDIO_CHANNEL_STEREO = 2; @@ -50,7 +50,7 @@ AudioEncoder::~AudioEncoder() static bool IsAudioCodecFormatSupported(AudioCodecFormat format) { if ((format < AAC_LC) || (format > AAC_ELD)) { - MEDIA_ERR_LOG("Invalid format:%d", format); + MEDIA_ERR_LOG("Invalid format: %d", format); return false; } return true; @@ -70,7 +70,7 @@ static Profile GetProfileFromAudioCodecFormat(AudioCodecFormat format) case AAC_ELD: return AAC_ELD_PROFILE; default: - MEDIA_ERR_LOG("Invalid format:0x%x", format); + MEDIA_ERR_LOG("Invalid format: 0x%x", format); return AAC_LC_PROFILE; } } @@ -79,19 +79,29 @@ static AudioSampleRate ConvertSampleRate(uint32_t sampleRate) { switch (sampleRate) { case AUD_SAMPLE_RATE_8000: + return AUD_SAMPLE_RATE_8000; case AUD_SAMPLE_RATE_11025: + return AUD_SAMPLE_RATE_11025; case AUD_SAMPLE_RATE_12000: + return AUD_SAMPLE_RATE_12000; case AUD_SAMPLE_RATE_16000: + return AUD_SAMPLE_RATE_16000; case AUD_SAMPLE_RATE_22050: + return AUD_SAMPLE_RATE_22050; case AUD_SAMPLE_RATE_24000: + return AUD_SAMPLE_RATE_24000; case AUD_SAMPLE_RATE_32000: + return AUD_SAMPLE_RATE_32000; case AUD_SAMPLE_RATE_44100: + return AUD_SAMPLE_RATE_44100; case AUD_SAMPLE_RATE_48000: + return AUD_SAMPLE_RATE_48000; case AUD_SAMPLE_RATE_64000: + return AUD_SAMPLE_RATE_64000; case AUD_SAMPLE_RATE_96000: - return static_cast(sampleRate); + return AUD_SAMPLE_RATE_96000; default: - MEDIA_ERR_LOG("Invalid sample_rate:%u", sampleRate); + MEDIA_ERR_LOG("Invalid sample_rate: %d", sampleRate); return AUD_SAMPLE_RATE_48000; } } @@ -104,15 +114,15 @@ static AudioSoundMode ConvertSoundMode(uint32_t channelCount) case AUDIO_CHANNEL_STEREO: return AUD_SOUND_MODE_STEREO; default: - MEDIA_ERR_LOG("Invalid soundMode:%u", channelCount); + MEDIA_ERR_LOG("Invalid soundMode: %d", channelCount); return AUD_SOUND_MODE_MONO; } } -int32_t AudioEncoder::InitAudioEncoderAttr(const AudioEncodeConfig &config) +int32_t AudioEncoder::InitAencAttr(const AudioEncodeConfig &input) { - if (!IsAudioCodecFormatSupported(config.audioFormat)) { - MEDIA_ERR_LOG("config.audioFormat:0x%x is not support", config.audioFormat); + if (!IsAudioCodecFormatSupported(input.audioFormat)) { + MEDIA_ERR_LOG("input.audioFormat :0x%x is not support", input.audioFormat); return ERR_INVALID_PARAM; } uint32_t paramIndex = 0; @@ -126,22 +136,22 @@ int32_t AudioEncoder::InitAudioEncoderAttr(const AudioEncodeConfig &config) encAttr_[paramIndex].val = &codecMime_; encAttr_[paramIndex].size = sizeof(AvCodecMime); paramIndex++; - profile_ = GetProfileFromAudioCodecFormat(config.audioFormat); + profile_ = GetProfileFromAudioCodecFormat(input.audioFormat); encAttr_[paramIndex].key = KEY_AUDIO_PROFILE; encAttr_[paramIndex].val = &profile_; encAttr_[paramIndex].size = sizeof(Profile); paramIndex++; - sampleRate_ = ConvertSampleRate(config.sampleRate); + sampleRate_ = ConvertSampleRate(input.sampleRate); encAttr_[paramIndex].key = KEY_SAMPLE_RATE; encAttr_[paramIndex].val = &sampleRate_; encAttr_[paramIndex].size = sizeof(AudioSampleRate); paramIndex++; - bitRate_ = config.bitRate; + bitRate_ = input.bitRate; encAttr_[paramIndex].key = KEY_BITRATE; encAttr_[paramIndex].val = &bitRate_; encAttr_[paramIndex].size = sizeof(uint32_t); paramIndex++; - soundMode_ = ConvertSoundMode(config.channelCount); + soundMode_ = ConvertSoundMode(input.channelCount); encAttr_[paramIndex].key = KEY_SOUND_MODE; encAttr_[paramIndex].val = &soundMode_; encAttr_[paramIndex].size = sizeof(AudioSoundMode); @@ -158,17 +168,17 @@ int32_t AudioEncoder::InitAudioEncoderAttr(const AudioEncodeConfig &config) return SUCCESS; } -int32_t AudioEncoder::Initialize(const AudioEncodeConfig &config) +int32_t AudioEncoder::Initialize(const AudioEncodeConfig &input) { - int32_t ret = InitAudioEncoderAttr(config); + int32_t ret = InitAencAttr(input); if (ret != SUCCESS) { - MEDIA_ERR_LOG("InitAudioEncoderAttr failed:%d", ret); + MEDIA_ERR_LOG("InitAencAttr failed:%d", ret); return ret; } const char *audioEncName = "codec.aac.hardware.encoder"; ret = CodecCreate(audioEncName, encAttr_, AUDIO_ENC_PARAM_NUM, &encHandle_); if (ret != SUCCESS) { - MEDIA_ERR_LOG("CodecCreate failed:0x%x", ret); + MEDIA_ERR_LOG("CodecCreate failed :0x%x", ret); return ret; } return SUCCESS; @@ -184,7 +194,7 @@ int32_t AudioEncoder::BindSource(uint32_t deviceId) params[0].size = sizeof(uint32_t); ret = CodecSetParameter(encHandle_, params, sizeof(params) / sizeof(params[0])); if (ret != SUCCESS) { - MEDIA_ERR_LOG("CodecSetDevice failed:0x%x", ret); + MEDIA_ERR_LOG("CodecSetDevice :0x%x", ret); return ret; } return SUCCESS; @@ -219,7 +229,7 @@ int32_t AudioEncoder::ReadStream(AudioStream &stream, bool isBlockingRead) return ERR_INVALID_READ; } if (stream.buffer == nullptr || stream.bufferLen == 0) { - MEDIA_ERR_LOG("stream.buffer is nullptr"); + MEDIA_ERR_LOG("stream.buffer is nullptr"); return ERR_INVALID_READ; } uint32_t timeoutMs; @@ -241,7 +251,7 @@ int32_t AudioEncoder::ReadStream(AudioStream &stream, bool isBlockingRead) errno_t retCopy = memcpy_s(stream.buffer, stream.bufferLen, outInfo.buffers[0].addr, outInfo.buffers[0].length); if (retCopy != EOK) { - MEDIA_ERR_LOG("memcpy_s encData.encodedData:%p timeStamp:%lld failed:0x%x", + MEDIA_ERR_LOG("memcpy_s encData.encodedData %p timeStamp:%lld failed :0x%x", outInfo.buffers[0].addr, outInfo.timeStamp, retCopy); return ERR_INVALID_OPERATION; } else { diff --git a/audio_encoder/include/audio_encoder.h b/frameworks/audio_encoder/include/audio_encoder.h similarity index 64% rename from audio_encoder/include/audio_encoder.h rename to frameworks/audio_encoder/include/audio_encoder.h index 20c1631..af3599e 100755 --- a/audio_encoder/include/audio_encoder.h +++ b/frameworks/audio_encoder/include/audio_encoder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * 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 @@ -18,21 +18,19 @@ #include #include -#include #include +#include #include - -#include "codec_interface.h" -#include "format.h" #include "media_errors.h" #include "media_info.h" - +#include "format.h" +#include "codec_interface.h" namespace OHOS { namespace Audio { - constexpr int32_t AUDIO_ENC_PARAM_NUM = 8; /* count of audio frame in Buffer */ constexpr uint32_t AUDIO_FRAME_NUM_IN_BUF = 30; + /* sample per frame for all encoder(aacplus:2048) */ constexpr uint32_t AUDIO_AUDIO_POINT_NUM = 1024; @@ -56,63 +54,42 @@ public: ~AudioEncoder(); /** - * Initailizes the audio source according to a specific configuration. - * - * @param config a configuration of audio source. - * @return Returns SUCCESS if success, other values otherwise. + * AudioSourceConfig ʼǰsource. */ - int32_t Initialize(const AudioEncodeConfig &config); + int32_t Initialize(const AudioEncodeConfig &input); /** - * Binds audio source to a specific device. - * - * @param deviceId specifies the identity of device to bind. - * @return Returns SUCCESS if success, other values otherwise. + * ȡǰ豸ID. */ int32_t BindSource(uint32_t deviceId); /** - * Gets mute status of current encoder, dummy implemented currently. - * - * @param muted holds mute status if success. - * @return Returns SUCCESS if success, other values otherwise. + * ȡǰǷmute */ int32_t GetMute(bool &muted); /** - * Sets mute status of current encoder, dummy implemented currently. - * - * @param muted mute status to set. - * @return Returns SUCCESS if success, other values otherwise. + * ȡǰǷmute */ int32_t SetMute(bool muted); /** - * Starts audio source. - * - * @return Returns SUCCESS if success, other values otherwise. + * Դ. */ int32_t Start(); - + /** - * - * Reads stream from a audio source. - * - * @param stream source stream to read from. - * @param isBlockingRead reading mode. - * @return Returns size of data actually read. + * ȡԴݣʵʶȡС. */ int32_t ReadStream(AudioStream &stream, bool isBlockingRead); /** - * Stops audio source. - * - * @return Returns SUCCESS if success, other values otherwise. + * ֹͣԴ. */ int32_t Stop(); private: - int32_t InitAudioEncoderAttr(const AudioEncodeConfig &config); + int32_t InitAencAttr(const AudioEncodeConfig &input); private: CODEC_HANDLETYPE encHandle_; diff --git a/audio_source/audio_source.cpp b/frameworks/audio_source/audio_source.cpp similarity index 86% rename from audio_source/audio_source.cpp rename to frameworks/audio_source/audio_source.cpp index cb298a3..61a9f1c 100755 --- a/audio_source/audio_source.cpp +++ b/frameworks/audio_source/audio_source.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * 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 @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "audio_source.h" #include "media_log.h" #include "securec.h" @@ -29,7 +28,6 @@ namespace Audio { using namespace OHOS::Media; static AudioManager *g_audioManager = nullptr; - AudioSource::AudioSource() : initialized_(false), started_(false), @@ -38,12 +36,12 @@ AudioSource::AudioSource() { if (g_audioManager == nullptr) { g_audioManager = GetAudioManagerFuncs(); - MEDIA_DEBUG_LOG("g_audioManager:%p", g_audioManager); + MEDIA_DEBUG_LOG("g_audioManager: %p", g_audioManager); } int size = 0; struct AudioAdapterDescriptor *descs = nullptr; g_audioManager->GetAllAdapters(g_audioManager, &descs, &size); - MEDIA_DEBUG_LOG("GetAllAdapters size:%d", size); + MEDIA_DEBUG_LOG("GetAllAdapters: %d ", size); for (int index = 0; index < size; index++) { struct AudioAdapterDescriptor *desc = &descs[index]; @@ -64,9 +62,9 @@ AudioSource::AudioSource() AudioSource::~AudioSource() { - MEDIA_DEBUG_LOG("audioAdapter_:%p", audioAdapter_); + MEDIA_DEBUG_LOG("audioAdapter_ :%p", audioAdapter_); if (audioAdapter_ != nullptr) { - MEDIA_INFO_LOG("UnloadModule audioAdapter_:%p", audioAdapter_); + MEDIA_INFO_LOG("audioAdapter_ UnloadModule: %p", audioAdapter_); g_audioManager->UnloadAdapter(g_audioManager, audioAdapter_); audioAdapter_ = nullptr; } @@ -98,7 +96,7 @@ uint64_t AudioSource::GetFrameCount() uint64_t frameCount = 0; ret = audioCapture_->attr.GetFrameCount(reinterpret_cast(audioCapture_), &frameCount); if (ret != SUCCESS) { - MEDIA_ERR_LOG("attr GetFrameCount failed:0x%x", ret); + MEDIA_ERR_LOG("attr GetFrameCount failed 0x%x ", ret); return ret; } return frameCount; @@ -121,22 +119,22 @@ int32_t AudioSource::EnumDeviceBySourceType(AudioSourceType inputSource, std::ve return SUCCESS; } -int32_t AudioSource::Initialize(const AudioSourceConfig &config) +int32_t AudioSource::Initialize(const AudioSourceConfig &input) { AUDIO_RETURN_VAL_IF_NULL(audioAdapter_); - MEDIA_INFO_LOG("config.deviceId:0x%x config.sampleRate:%d", config.deviceId, config.sampleRate); + MEDIA_INFO_LOG("deviceId:0x%x input.sampleRate:%d", input.deviceId, input.sampleRate); int32_t ret = SUCCESS; struct AudioDeviceDescriptor desc; struct AudioSampleAttributes attrs; attrs.type = AUDIO_IN_MEDIA; - attrs.sampleRate = config.sampleRate; + attrs.sampleRate = input.sampleRate; attrs.format = AUDIO_FORMAT_PCM_16_BIT; - attrs.channelCount = config.channelCount; - attrs.interleaved = config.interleaved; + attrs.channelCount = input.channelCount; + attrs.interleaved = input.interleaved; ret = audioAdapter_->CreateCapture(audioAdapter_, &desc, &attrs, &audioCapture_); if (ret != SUCCESS || audioCapture_ == nullptr) { - MEDIA_ERR_LOG("CreateCapture failed:0x%x", ret); + MEDIA_ERR_LOG("CreateCapture failed 0x%x", ret); return ret; } initialized_ = true; @@ -153,7 +151,7 @@ int32_t AudioSource::GetCurrentDeviceId(uint32_t &deviceId) AUDIO_RETURN_VAL_IF_NULL(audioCapture_); int32_t ret = audioCapture_->attr.GetCurrentChannelId(reinterpret_cast(audioCapture_), &deviceId); if (ret != SUCCESS) { - MEDIA_ERR_LOG("GetCurrentChannelId failed:0x%x", ret); + MEDIA_ERR_LOG("GetCurrentChannelId failed 0x%x", ret); return ret; } MEDIA_INFO_LOG("deviceId:0x%x", deviceId); @@ -170,7 +168,7 @@ int32_t AudioSource::Start() AUDIO_RETURN_VAL_IF_NULL(audioCapture_); ret = audioCapture_->control.Start(reinterpret_cast(audioCapture_)); if (ret != SUCCESS) { - MEDIA_ERR_LOG("audioCapture_ Start failed:0x%x", ret); + MEDIA_ERR_LOG("audioCapture_ Start failed 0x%x", ret); return ret; } started_ = true; @@ -197,14 +195,14 @@ int32_t AudioSource::Stop() AUDIO_RETURN_VAL_IF_NULL(audioCapture_); ret = audioCapture_->control.Stop(reinterpret_cast(audioCapture_)); if (ret != SUCCESS) { - MEDIA_ERR_LOG("Stop failed:0x%x", ret); + MEDIA_ERR_LOG("Stop failed 0x%x", ret); return ret; } ret = audioAdapter_->DestroyCapture(audioAdapter_, audioCapture_); audioCapture_ = nullptr; started_ = false; if (ret != SUCCESS) { - MEDIA_ERR_LOG("Close failed:0x%x", ret); + MEDIA_ERR_LOG("Close failed 0x%x", ret); return ret; } return SUCCESS; diff --git a/audio_source/include/audio_source.h b/frameworks/audio_source/include/audio_source.h similarity index 64% rename from audio_source/include/audio_source.h rename to frameworks/audio_source/include/audio_source.h index 06231dc..c442310 100755 --- a/audio_source/include/audio_source.h +++ b/frameworks/audio_source/include/audio_source.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * 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 @@ -18,21 +18,20 @@ #include #include -#include #include +#include #include -#include "audio_manager.h" -#include "format.h" #include "media_errors.h" #include "media_info.h" +#include "format.h" +#include "audio_manager.h" namespace OHOS { namespace Audio { struct AudioSourceConfig { /** - * Enumerates currently supported devices by audio source type, - * and binds current audio source a specified device. + * EnumDeviceBySourceType öٵ豸ѡõǰaudio source Ҫʹõ豸. */ uint32_t deviceId; AudioCodecFormat audioFormat; @@ -49,11 +48,7 @@ public: ~AudioSource(); /** - * Enumerates currently supported devices by audio source type. - * - * @param inputSource the type of source audio. - * @param devices holds an array of statisfied audio device description, including name and identity. - * @return Returns SUCCESS if success, other values otherwise. + * Դöٵǰֵ֧豸豸豸ID. */ int32_t EnumDeviceBySourceType(AudioSourceType inputSource, std::vector &devices); @@ -77,51 +72,32 @@ public: uint64_t GetFrameCount(); /** - * Initailizes the audio source according to a specific configuration. - * - * @param config a configuration of audio source. - * @return Returns SUCCESS if success, other values otherwise. + * AudioSourceConfig ʼǰsource. */ - int32_t Initialize(const AudioSourceConfig &config); + int32_t Initialize(const AudioSourceConfig &input); /** - * Sets input device's identity when switching device. - * - * @param deviceId indentity to set. - * @return Returns SUCCESS if set successfully, other values otherwise. + * 豸IDҪл豸ʱ. */ int32_t SetInputDevice(uint32_t deviceId); /** - * Gets current device's identity. - * - * @param deviceId holds the identity of current device, if success. - * @return Returns SUCCESS if success, other values otherwise. + * ȡǰ豸ID. */ int32_t GetCurrentDeviceId(uint32_t &deviceId); /** - * Starts audio source. - * - * @return Returns SUCCESS if success, other values otherwise. + * Դ. */ int32_t Start(); /** - * - * Reads frame from source. - * - * @param buffer source to read from. - * @param bufferBytes size of buffer. - * @param isBlockingRead reading mode. - * @return Returns size of data actually read. + * ȡԴݣʵʶȡС. */ int32_t ReadFrame(uint8_t *buffer, size_t bufferBytes, bool isBlockingRead); /** - * Stops audio source. - * - * @return Returns SUCCESS if success, other values otherwise. + * ֹͣԴ. */ int32_t Stop(); diff --git a/interfaces/kits/audio_capturer.h b/interfaces/kits/audio_capturer.h new file mode 100755 index 0000000..c53ebea --- /dev/null +++ b/interfaces/kits/audio_capturer.h @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup MultiMedia_AudioCapturer + * @{ + * + * @brief Declares APIs in the AudioCapturer class for audio capture. + * + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file audio_capturer.h + * + * @brief Provides the AudioCapturer class to implement operations related to audio capture. + * + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef AUDIO_CAPTURER_H +#define AUDIO_CAPTURER_H + +#include +#include +#include +#include + +#include "media_errors.h" +#include "media_info.h" + +namespace OHOS { +namespace Audio { +/** + * @brief Defines information about audio capture parameters, including the input source, audio codec format,sampling + * rate (Hz), number of audio channels, bit rate, and bit width. + * + * @since 1.0 + * @version 1.0 + */ +struct AudioCapturerInfo { + /** Audio source type */ + AudioSourceType inputSource = AUDIO_MIC; + /** Audio codec format */ + AudioCodecFormat audioFormat = AUDIO_DEFAULT; + /** Sampling rate */ + int32_t sampleRate = 0; + /** Number of audio channels */ + int32_t channelCount = 0; + /** Bit rate */ + int32_t bitRate = 0; + /** Audio stream type */ + AudioStreamType streamType = TYPE_MEDIA; + /** Bit width */ + AudioBitWidth bitWidth = BIT_WIDTH_16; +}; + +/** + * @brief Represents timestamp information, including the frame position information and high-resolution time source. + * + * @since 1.0 + * @version 1.0 + */ +class Timestamp { +public: + Timestamp() : framePosition(0) + { + time.tv_sec = 0; + time.tv_nsec = 0; + } + ~Timestamp() = default; + uint32_t framePosition; + struct timespec time; + + /** + * @brief Enumerates the time base of this Timestamp. Different timing methods are supported. + * + */ + enum class Timebase : int32_t { + /** Monotonically increasing time, excluding the system sleep time */ + MONOTONIC = 0, + /** Monotonically increasing time, including the system sleep time */ + BOOTTIME = 1 + }; +}; + +/** + * @brief Enumerates the recording states of the current device. + * + * @since 1.0 + * @version 1.0 + */ +enum State : uint32_t { + /** Prepared */ + PREPPARED, + /** Recording */ + RECORDING, + /** Stopped */ + STOPPED, + /** Released */ + RELEASED +}; + +/** + * @brief Provides functions for applications to implement audio capturing. + * + * @since 1.0 + * @version 1.0 + */ +class AudioCapturer { +public: + AudioCapturer(); + virtual ~AudioCapturer(); + + /** + * @brief Obtains the minimum number of frames required in a specified condition, in bytes per sample. + * + * @param sampleRate Indicates the audio sampling rate, in Hz. + * @param channelCount Indicates the number of audio recording channels. + * @param audioFormat Indicates the audio data format. + * @param frameCount Indicates the minimum number of frames, in bytes per sample. + * @return Returns true if the minimum number of frames is successfully obtained; returns false + * otherwise. + * @since 1.0 + * @version 1.0 + */ + static bool GetMinFrameCount(int32_t sampleRate, int32_t channelCount, AudioCodecFormat audioFormat, + size_t &frameCount); + + /** + * @brief Obtains the number of frames required in the current condition, in bytes per sample. + * + * @return Returns the number of frames (in bytes per sample) if the operation is successful; returns -1 + * if an exception occurs. + * @since 1.0 + * @version 1.0 + */ + uint64_t GetFrameCount(); + + /** + * @brief Sets audio capture parameters. + * + * @param info Indicates information about audio capture parameters to set. For details, see + * {@link AudioCapturerInfo}. + * @return Returns {@link SUCCESS} if the setting is successful; returns an error code defined + * in {@link media_errors.h} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t SetCapturerInfo(const AudioCapturerInfo info); + + /** + * @brief Obtains audio capture parameters. + * + * This function can be called after {@link SetCapturerInfo} is successful. + * + * @param info Indicates information about audio capture parameters. For details, see {@link AudioCapturerInfo}. + * @return Returns {@link SUCCESS} if the parameter information is successfully obtained; returns an error code + * defined in {@link media_errors.h} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t GetCapturerInfo(AudioCapturerInfo &info); + + /** + * @brief Starts audio recording. + * + * @return Returns true if the recording is successfully started; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool Start(); + + /** + * @brief Reads audio data. + * + * @param buffer Indicates the pointer to the buffer into which the audio data is to be written. + * @param userSize Indicates the size of the buffer into which the audio data is to be written, in bytes. + * userSize >= frameCount * channelCount * BytesPerSample must evaluate to true. You can call + * {@link GetFrameCount} to obtain the frameCount value. + * @param isBlockingRead Specifies whether data reading will be blocked. + * @return Returns the size of the audio data read from the device. The value ranges from 0 to + * userSize. If the reading fails, one of the following error codes is returned: + * ERR_INVALID_PARAM: The input parameter is incorrect. + * ERR_ILLEGAL_STATE: The AudioCapturer instance is not initialized. + * ERR_SOURCE_NOT_SET: The state of hardware device instance is abnormal. + * @since 1.0 + * @version 1.0 + */ + int32_t Read(uint8_t *buffer, size_t userSize, bool isBlockingRead); + + /** + * @brief Obtains the audio capture state. + * + * @return Returns the audio capture state defined in {@link State}. + * @since 1.0 + * @version 1.0 + */ + State GetStatus(); + + /** + * @brief Obtains the timestamp. + * + * @param timestamp Indicates a {@link Timestamp} instance reference provided by the caller. + * @param base Indicates the time base, which can be {@link Timestamp.Timebase#BOOTTIME Timestamp.Timebase.BOOTTIME} + * or {@link Timestamp.Timebase#MONOTONIC Timestamp.Timebase.MONOTONIC}. + * @return Returns true if the timestamp is successfully obtained; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool GetAudioTime(Timestamp ×tamp, Timestamp::Timebase base); + + /** + * @brief Stops audio recording. + * + * @return Returns true if the recording is successfully stopped; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool Stop(); + + /** + * @brief Releases a local AudioCapturer object. + * + * @return Returns true if the object is successfully released; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool Release(); + +private: + class AudioCapturerImpl; + std::unique_ptr impl_; +}; +} // namespace Audio +} // namespace OHOS +#endif // AUDIO_CAPTURER_H diff --git a/readme.md b/readme.md deleted file mode 100755 index ec3c557..0000000 --- a/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -详见:https://gitee.com/openharmony/docs/blob/master/readme/媒体子系统README.md - -see: https://gitee.com/openharmony/docs/blob/master/docs-en/readme/media-subsystem.md