From 5aba6f6753fa3debc992f3cc629bf6a5b5388bb3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=BC=A0=E5=B8=86?= <446962864@qq.com>
Date: Mon, 31 May 2021 14:48:24 +0800
Subject: [PATCH 01/11] update README.md.
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index d5e595f..57d34f5 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
#### 效果演示
-
+
#### 安装教程
--
Gitee
From d4a29951af1c0f6ab7febc0d39deb4c076501e10 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=BC=A0=E5=B8=86?= <446962864@qq.com>
Date: Mon, 31 May 2021 14:49:16 +0800
Subject: [PATCH 02/11] update README.md.
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 57d34f5..372801a 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,7 @@ allprojects {
```java
dependencies {
- implementation('com.gitee.chinasoft_ohos:audio-visualizer-ohos:0.0.1-SNAPSHOT')
+ implementation 'com.gitee.chinasoft_ohos:audio-visualizer-ohos:0.0.1-SNAPSHOT'
......
}
```
--
Gitee
From b75c852799fba8c3f9cc60e9c24acfd9cb1bf52f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=BC=A0=E5=B8=86?= <446962864@qq.com>
Date: Mon, 31 May 2021 14:49:43 +0800
Subject: [PATCH 03/11] update README.md.
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 372801a..99daf19 100644
--- a/README.md
+++ b/README.md
@@ -73,7 +73,7 @@ CloudTest代码测试无异常
#### 版权和许可信息
-```java
+```txt
Copyright 2018 Gaurav Kumar
Licensed under the Apache License, Version 2.0 (the "License");
--
Gitee
From 8804c4b3ccc9c5a4f4d89498e597514a02df5a87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=BC=A0=E5=B8=86?= <446962864@qq.com>
Date: Mon, 31 May 2021 14:50:55 +0800
Subject: [PATCH 04/11] update README.md.
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 99daf19..f272f21 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@
1.在项目根目录下的build.gradle文件中
-```java
+```txt
allprojects {
repositories {
maven {
@@ -30,9 +30,9 @@ allprojects {
2.在entry模块下的build.gradle文件中
-```java
+```text
dependencies {
- implementation 'com.gitee.chinasoft_ohos:audio-visualizer-ohos:0.0.1-SNAPSHOT'
+ implementation('com.gitee.chinasoft_ohos:audio-visualizer-ohos:0.0.1-SNAPSHOT')
......
}
```
--
Gitee
From 3de350b8d1d8a0770aa84acdea70f0e8d8dd382d Mon Sep 17 00:00:00 2001
From: ZYF949 <446962864@qq.com>
Date: Mon, 31 May 2021 15:46:14 +0800
Subject: [PATCH 05/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9README.OPENRESOURCE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
AudioVisualizerOhos/.gitignore | 14 ++
AudioVisualizerOhos/CHANGELOG.md | 6 +
AudioVisualizerOhos/LICENSE | 201 ++++++++++++++++
AudioVisualizerOhos/README.OPENRESOURCE.md | 10 +
AudioVisualizerOhos/README.md | 91 +++++++
.../audiovisualizer/.gitignore | 1 +
.../audiovisualizer/build.gradle | 14 ++
.../audiovisualizer/src/main/config.json | 26 ++
.../audiovisualizer/base/BaseVisualizer.java | 210 ++++++++++++++++
.../audiovisualizer/model/AnimSpeed.java | 32 +++
.../audiovisualizer/model/PaintStyle.java | 28 +++
.../model/PositionGravity.java | 28 +++
.../audiovisualizer/utils/AVConstants.java | 46 ++++
.../audiovisualizer/utils/BezierSpline.java | 153 ++++++++++++
.../visualizer/BarVisualizer.java | 182 ++++++++++++++
.../visualizer/BlastVisualizer.java | 117 +++++++++
.../visualizer/BlobVisualizer.java | 225 ++++++++++++++++++
.../visualizer/CircleLineVisualizer.java | 185 ++++++++++++++
.../visualizer/HiFiVisualizer.java | 155 ++++++++++++
.../visualizer/WaveVisualizer.java | 219 +++++++++++++++++
.../main/resources/base/element/string.json | 8 +
AudioVisualizerOhos/build.gradle | 46 ++++
AudioVisualizerOhos/entry/.gitignore | 1 +
AudioVisualizerOhos/entry/build.gradle | 13 +
.../entry/src/main/config.json | 209 ++++++++++++++++
.../audiovisualizersample/MainAbility.java | 18 ++
.../audiovisualizersample/MyApplication.java | 10 +
.../slice/MainAbilitySlice.java | 108 +++++++++
.../audiovisualizersample/ui/BarAbility.java | 69 ++++++
.../ui/BlastAbility.java | 70 ++++++
.../audiovisualizersample/ui/BlobAbility.java | 70 ++++++
.../ui/CircleLineAbility.java | 48 ++++
.../audiovisualizersample/ui/HiFiAbility.java | 48 ++++
.../ui/MusicStreamAbility.java | 118 +++++++++
.../audiovisualizersample/ui/WaveAbility.java | 70 ++++++
.../util/MusicFinish.java | 8 +
.../util/PermissionUtils.java | 50 ++++
.../util/PlaySoundUtil.java | 65 +++++
.../main/resources/base/element/color.json | 46 ++++
.../main/resources/base/element/string.json | 24 ++
.../base/graphic/background_ability_main.xml | 6 +
.../resources/base/graphic/main_bt_bg.xml | 12 +
.../resources/base/layout/ability_main.xml | 129 ++++++++++
.../resources/base/layout/activity_bar.xml | 29 +++
.../resources/base/layout/activity_blast.xml | 28 +++
.../resources/base/layout/activity_blob.xml | 28 +++
.../base/layout/activity_circle_line.xml | 28 +++
.../resources/base/layout/activity_hi_fi.xml | 28 +++
.../base/layout/activity_music_stream.xml | 40 ++++
.../resources/base/layout/activity_wave.xml | 28 +++
.../resources/base/layout/progress_layout.xml | 27 +++
.../src/main/resources/base/media/icon.png | Bin 0 -> 6790 bytes
.../src/main/resources/base/media/play.png | Bin 0 -> 583 bytes
.../src/main/resources/base/media/stop.png | Bin 0 -> 449 bytes
.../main/resources/base/profile/sample.aac | Bin 0 -> 481012 bytes
.../src/main/resources/rawfile/Ring10.wav | Bin 0 -> 701708 bytes
.../src/main/resources/rawfile/red_e.mp3 | Bin 0 -> 960648 bytes
.../src/main/resources/rawfile/sample.aac | Bin 0 -> 481012 bytes
.../github/gabrielbb/cutout/ExampleTest.java | 9 +
AudioVisualizerOhos/gradle.properties | 10 +
.../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 58694 bytes
.../gradle/wrapper/gradle-wrapper.properties | 5 +
AudioVisualizerOhos/gradlew | 183 ++++++++++++++
AudioVisualizerOhos/gradlew.bat | 103 ++++++++
AudioVisualizerOhos/img/audio.gif | Bin 0 -> 1276728 bytes
AudioVisualizerOhos/settings.gradle | 1 +
README.OPENRESOURCE.md | 4 +-
README.md | 10 +-
.../visualizer/BlastVisualizer.java | 2 +-
.../visualizer/BlobVisualizer.java | 17 +-
entry/build.gradle | 11 +
.../slice/MainAbilitySlice.java | 1 +
.../ui/MusicStreamAbility.java | 4 +-
.../util/PermissionUtils.java | 7 +-
74 files changed, 3777 insertions(+), 15 deletions(-)
create mode 100644 AudioVisualizerOhos/.gitignore
create mode 100644 AudioVisualizerOhos/CHANGELOG.md
create mode 100644 AudioVisualizerOhos/LICENSE
create mode 100644 AudioVisualizerOhos/README.OPENRESOURCE.md
create mode 100644 AudioVisualizerOhos/README.md
create mode 100644 AudioVisualizerOhos/audiovisualizer/.gitignore
create mode 100644 AudioVisualizerOhos/audiovisualizer/build.gradle
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/config.json
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/base/BaseVisualizer.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/AnimSpeed.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/PaintStyle.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/PositionGravity.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/utils/AVConstants.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/utils/BezierSpline.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BarVisualizer.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BlastVisualizer.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BlobVisualizer.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/CircleLineVisualizer.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/HiFiVisualizer.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/WaveVisualizer.java
create mode 100644 AudioVisualizerOhos/audiovisualizer/src/main/resources/base/element/string.json
create mode 100644 AudioVisualizerOhos/build.gradle
create mode 100644 AudioVisualizerOhos/entry/.gitignore
create mode 100644 AudioVisualizerOhos/entry/build.gradle
create mode 100644 AudioVisualizerOhos/entry/src/main/config.json
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/MainAbility.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/MyApplication.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/slice/MainAbilitySlice.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BarAbility.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BlastAbility.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BlobAbility.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/CircleLineAbility.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/HiFiAbility.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/MusicStreamAbility.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/WaveAbility.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/MusicFinish.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/PermissionUtils.java
create mode 100644 AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/PlaySoundUtil.java
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/element/color.json
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/element/string.json
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/graphic/background_ability_main.xml
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/graphic/main_bt_bg.xml
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/layout/ability_main.xml
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/layout/activity_bar.xml
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/layout/activity_blast.xml
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/layout/activity_blob.xml
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/layout/activity_circle_line.xml
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/layout/activity_hi_fi.xml
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/layout/activity_music_stream.xml
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/layout/activity_wave.xml
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/layout/progress_layout.xml
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/media/icon.png
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/media/play.png
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/media/stop.png
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/base/profile/sample.aac
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/rawfile/Ring10.wav
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/rawfile/red_e.mp3
create mode 100644 AudioVisualizerOhos/entry/src/main/resources/rawfile/sample.aac
create mode 100644 AudioVisualizerOhos/entry/src/test/java/com/github/gabrielbb/cutout/ExampleTest.java
create mode 100644 AudioVisualizerOhos/gradle.properties
create mode 100644 AudioVisualizerOhos/gradle/wrapper/gradle-wrapper.jar
create mode 100644 AudioVisualizerOhos/gradle/wrapper/gradle-wrapper.properties
create mode 100644 AudioVisualizerOhos/gradlew
create mode 100644 AudioVisualizerOhos/gradlew.bat
create mode 100644 AudioVisualizerOhos/img/audio.gif
create mode 100644 AudioVisualizerOhos/settings.gradle
diff --git a/AudioVisualizerOhos/.gitignore b/AudioVisualizerOhos/.gitignore
new file mode 100644
index 0000000..603b140
--- /dev/null
+++ b/AudioVisualizerOhos/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/AudioVisualizerOhos/CHANGELOG.md b/AudioVisualizerOhos/CHANGELOG.md
new file mode 100644
index 0000000..492e3b2
--- /dev/null
+++ b/AudioVisualizerOhos/CHANGELOG.md
@@ -0,0 +1,6 @@
+## 0.0.1-SNAPSHOT
+
+ohos第一个版本
+
+* 实现了原库大部分api
+* 因为缺少对应api,当前仅支持播放wav音频时背景联动,若播放mp3则背景不联动
\ No newline at end of file
diff --git a/AudioVisualizerOhos/LICENSE b/AudioVisualizerOhos/LICENSE
new file mode 100644
index 0000000..46699c7
--- /dev/null
+++ b/AudioVisualizerOhos/LICENSE
@@ -0,0 +1,201 @@
+ 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 2018 Gaurav Kumar
+
+ 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.
diff --git a/AudioVisualizerOhos/README.OPENRESOURCE.md b/AudioVisualizerOhos/README.OPENRESOURCE.md
new file mode 100644
index 0000000..f9e6356
--- /dev/null
+++ b/AudioVisualizerOhos/README.OPENRESOURCE.md
@@ -0,0 +1,10 @@
+[
+ {
+ "Name": "AudioVisualizerOhos",
+ "License": "Apache License",
+ "License File": "LICENSE",
+ "Version Number": "0.9.1",
+ "Upstream URL": "[](https://github.com/gauravk95/audio-visualizer-android)",
+ "Description": "A light-weight and easy-to-use Audio Visualizer for Android using the Android Canvas."
+ }
+]
\ No newline at end of file
diff --git a/AudioVisualizerOhos/README.md b/AudioVisualizerOhos/README.md
new file mode 100644
index 0000000..6718247
--- /dev/null
+++ b/AudioVisualizerOhos/README.md
@@ -0,0 +1,91 @@
+# audio-visualizer-ohos
+
+#### 项目介绍
+
+* 项目名称:audio-visualizer-ohos
+* 所属系列:openharmony的第三方组件适配移植
+* 功能:音频播放及背景联动
+* 项目移植状态:当前仅支持播放wav格式音频,若想播放mp3音频,背景无法联动
+* 调用差异:无
+* 开发版本:sdk5,DevEco Studio2.1 beta4
+* 基线版本:Relesase版本号0.9.1
+
+#### 效果演示
+
+
+
+#### 安装教程
+
+1.在项目根目录下的build.gradle文件中
+
+```java
+allprojects {
+ repositories {
+ maven {
+ url 'https://s01.oss.sonatype.org/content/repositories/snapshots/'
+ }
+ }
+}
+```
+
+2.在entry模块下的build.gradle文件中
+
+```java
+dependencies {
+ implementation('com.gitee.chinasoft_ohos:AudioVisualizerOhos:0.0.1-SNAPSHOT')
+ ......
+ }
+```
+
+在sdk5,DevEco Studio2.1 beta4下项目可直接运行 如无法运行,删除项目.gradle,.idea,build,gradle,build.gradle文件, 并依据自己的版本创建新项目,将新项目的对应文件复制到根目录下
+
+#### 使用说明
+
+在布局中引入对应的自定义控件用于绘制频率,例如:
+
+```xml
+
+ * Created by gk + */ + +public abstract class BaseVisualizer extends ComponentContainer { + protected byte[] mRawAudioBytes; + protected Paint mPaint; + protected Color mColor = AVConstants.DEFAULT_COLOR; + protected byte[] bytes; + + protected PaintStyle mPaintStyle = PaintStyle.FILL; + protected PositionGravity mPositionGravity = PositionGravity.BOTTOM; + + protected float mStrokeWidth = AVConstants.DEFAULT_STROKE_WIDTH; + protected float mDensity = AVConstants.DEFAULT_DENSITY; + + protected AnimSpeed mAnimSpeed = AnimSpeed.MEDIUM; + protected boolean isVisualizationEnabled = true; + + private AudioWaver audioWaver; + + /** + * 使用java代码实例化调用 + * + * @param context + */ + public BaseVisualizer(Context context) { + super(context); + init(context, null); + init(); + } + + /** + * 使用xml布局引用调用 + * + * @param context + * @param attrSet + */ + public BaseVisualizer(Context context, AttrSet attrSet) { + super(context, attrSet); + init(context, attrSet); + init(); + } + + /** + * 使用xml并设置style调用 + * + * @param context + * @param attrSet + * @param styleName + */ + public BaseVisualizer(Context context, AttrSet attrSet, String styleName) { + super(context, attrSet, styleName); + init(context, attrSet); + init(); + } + + /** + * 子类初始化操作 + */ + protected abstract void init(); + + private void init(Context context, AttrSet attrs) { + this.mDensity = attrs.getAttr("avDensity").get().getFloatValue(); + this.mColor = attrs.getAttr("avColor").get().getColorValue(); + this.mStrokeWidth = attrs.getAttr("avWidth").get().getDimensionValue(); + String avType = attrs.getAttr("avType").get().getStringValue(); + if (avType != null && !avType.equals("")) { + this.mPaintStyle = avType.toLowerCase().equals("outline") ? PaintStyle.OUTLINE : PaintStyle.FILL; + } + String avSpeed = attrs.getAttr("avSpeed").get().getStringValue(); + if (avSpeed != null && !avSpeed.equals("")) { + this.mAnimSpeed = AnimSpeed.MEDIUM; + if (avSpeed.toLowerCase().equals("slow")) { + this.mAnimSpeed = AnimSpeed.SLOW; + } + else if (avSpeed.toLowerCase().equals("fast")) { + this.mAnimSpeed = AnimSpeed.FAST; + } + } + + mPaint = new Paint(); + mPaint.setColor(mColor); + mPaint.setStrokeWidth(mStrokeWidth); + if (mPaintStyle == PaintStyle.FILL) { + mPaint.setStyle(Paint.Style.FILL_STYLE); + } + else { + mPaint.setStyle(Paint.Style.STROKE_STYLE); + } + } + + /** + * Set color to visualizer with color resource id. + * + * @param color color resource id. + */ + public void setColor(Color color) { + this.mColor = color; + this.mPaint.setColor(this.mColor); + } + + /** + * Set the density of the visualizer + * + * @param density density for visualization + */ + public void setDensity(float density) { + synchronized (this) { + this.mDensity = density; + init(); + } + } + + /** + * Sets the paint style of the visualizer + * + * @param paintStyle style of the visualizer. + */ + public void setPaintStyle(PaintStyle paintStyle) { + this.mPaintStyle = paintStyle; + this.mPaint.setStyle(paintStyle == PaintStyle.FILL ? Paint.Style.FILL_STYLE : Paint.Style.STROKE_STYLE); + } + + /** + * Sets the position of the Visualization{@link PositionGravity} + * + * @param positionGravity position of the Visualization + */ + public void setPositionGravity(PositionGravity positionGravity) { + this.mPositionGravity = positionGravity; + } + + /** + * Sets the Animation speed of the visualization{@link AnimSpeed} + * + * @param animSpeed speed of the animation + */ + public void setAnimationSpeed(AnimSpeed animSpeed) { + this.mAnimSpeed = animSpeed; + } + + /** + * Sets the width of the outline {@link PaintStyle} + * + * @param width style of the visualizer. + */ + public void setStrokeWidth(float width) { + this.mStrokeWidth = width; + this.mPaint.setStrokeWidth(width); + } + + /** + * Sets the audio session id for the currently playing audio + * + * @param audioSessionId of the media to be visualised + */ + public void setAudioSessionId(int audioSessionId) { + audioWaver = new AudioWaver(audioSessionId, this.getClass().getName()); + audioWaver.setActivated(false); + audioWaver.setDataSize(AudioWaver.getMaxDataSize()); + audioWaver.setWaveDataObserver(new AudioWaver.WaveDataObserver() { + @Override + public void onWaveData(byte[] mBytes, int i) { + BaseVisualizer.this.mRawAudioBytes = mBytes; + + // 刷新 + getContext().getUITaskDispatcher().syncDispatch(new Runnable() { + @Override + public void run() { + invalidate(); + } + }); + } + }, AudioWaver.getMinInterval()); + audioWaver.setActivated(true); + } +} \ No newline at end of file diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/AnimSpeed.java b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/AnimSpeed.java new file mode 100644 index 0000000..88856d5 --- /dev/null +++ b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/AnimSpeed.java @@ -0,0 +1,32 @@ +/* + Copyright 2018 Gaurav Kumar + + 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. +*/ + +package com.gauravk.audiovisualizer.model; + +public enum AnimSpeed { + /** + * SLOW + */ + SLOW, + /** + * MEDIUM + */ + MEDIUM, + /** + * FAST + */ + FAST +} diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/PaintStyle.java b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/PaintStyle.java new file mode 100644 index 0000000..41fab70 --- /dev/null +++ b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/PaintStyle.java @@ -0,0 +1,28 @@ +/* + Copyright 2018 Gaurav Kumar + + 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. +*/ + +package com.gauravk.audiovisualizer.model; + +public enum PaintStyle { + /** + * OUTLINE + */ + OUTLINE, + /** + * FILL + */ + FILL +} diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/PositionGravity.java b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/PositionGravity.java new file mode 100644 index 0000000..1f2d385 --- /dev/null +++ b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/model/PositionGravity.java @@ -0,0 +1,28 @@ +/* + Copyright 2018 Gaurav Kumar + + 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. +*/ + +package com.gauravk.audiovisualizer.model; + +public enum PositionGravity { + /** + * TOP + */ + TOP, + /** + * BOTTOM + */ + BOTTOM +} diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/utils/AVConstants.java b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/utils/AVConstants.java new file mode 100644 index 0000000..3af76f7 --- /dev/null +++ b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/utils/AVConstants.java @@ -0,0 +1,46 @@ +/* + Copyright 2018 Gaurav Kumar + + 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. +*/ + +package com.gauravk.audiovisualizer.utils; + +import ohos.agp.utils.Color; + +public class AVConstants { + /** + * 代替0.25 + */ + public static final float DEFAULT_DENSITY = 0.25f; + /** + * 白色 + */ + public static final Color DEFAULT_COLOR = Color.WHITE; + /** + * 代替0.6 + */ + public static final float DEFAULT_STROKE_WIDTH = 6.0f; + /** + * 代替4 + */ + public static final int MAX_ANIM_BATCH_COUNT = 4; + /** + * 代替2 + */ + public static final int NUM_2 = 2; + /** + * 代替3 + */ + public static final int NUM_3 = 3; +} \ No newline at end of file diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/utils/BezierSpline.java b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/utils/BezierSpline.java new file mode 100644 index 0000000..25c62e9 --- /dev/null +++ b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/utils/BezierSpline.java @@ -0,0 +1,153 @@ +/* + Copyright 2018 Gaurav Kumar + + 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. +*/ + +package com.gauravk.audiovisualizer.utils; + +import ohos.agp.utils.Point; + +public class BezierSpline { + private final int nSize; + private final Point[] firstControlPoints; + private final Point[] secondControlPoints; + + /** + * BezierSpline构造方法 + * + * @param size + */ + public BezierSpline(int size) { + this.nSize = size - 1; + firstControlPoints = new Point[nSize]; + secondControlPoints = new Point[nSize]; + for (int i = 0; i < nSize; i++) { + firstControlPoints[i] = new Point(); + secondControlPoints[i] = new Point(); + } + } + + /** + * Get open-ended bezier spline control points. + * + * @param knots bezier spline points + * @throws IllegalArgumentException if less than two knots are passed. + */ + public void updateCurveControlPoints(Point[] knots) { + if (knots == null || knots.length < AVConstants.NUM_2) { + throw new IllegalArgumentException("At least two knot points are required"); + } + final int n = knots.length - 1; + + // Special case: bezier curve should be a straight line + if (n == 1) { + // 3P1 = 2P0 + P3 + float x = (AVConstants.NUM_2 * knots[0].getPointX() + knots[1].getPointX()) / AVConstants.NUM_3; + float y = (AVConstants.NUM_2 * knots[0].getPointY() + knots[1].getPointY()) / AVConstants.NUM_3; + + firstControlPoints[0].modify(x, y); + + // P2 = 2P1 - P0 + x = AVConstants.NUM_2 * firstControlPoints[0].getPointX() - knots[0].getPointX(); + y = AVConstants.NUM_2 * firstControlPoints[0].getPointY() - knots[0].getPointY(); + + secondControlPoints[0].modify(x, y); + + } else { + + // Calculate first bezier control points + // Right hand side vector + float[] rhs = new float[n]; + + // Set right hand side X values + for (int i = 1; i < n - 1; i++) { + rhs[i] = 4 * knots[i].getPointX() + 2 * knots[i + 1].getPointX(); + } + rhs[0] = knots[0].getPointX() + 2 * knots[1].getPointX(); + rhs[n - 1] = (8 * knots[n - 1].getPointX() + knots[n].getPointX()) / 2f; + + // Get first control points X-values + float[] x = getFirstControlPoints(rhs); + + // Set right hand side Y values + for (int i = 1; i < n - 1; i++) { + rhs[i] = 4 * knots[i].getPointY() + 2 * knots[i + 1].getPointY(); + } + rhs[0] = knots[0].getPointY() + 2 * knots[1].getPointY(); + rhs[n - 1] = (8 * knots[n - 1].getPointY() + knots[n].getPointY()) / 2f; + + // Get first control points Y-values + float[] y = getFirstControlPoints(rhs); + + for (int i = 0; i < n; i++) { + // First control point + firstControlPoints[i].modify(x[i], y[i]); + + // Second control point + if (i < n - 1) { + float xx = 2 * knots[i + 1].getPointX() - x[i + 1]; + float yy = 2 * knots[i + 1].getPointY() - y[i + 1]; + secondControlPoints[i].modify(xx, yy); + } else { + float xx = (knots[n].getPointX() + x[n - 1]) / 2; + float yy = (knots[n].getPointY() + y[n - 1]) / 2; + secondControlPoints[i].modify(xx, yy); + } + } + } + } + + private Point pointSet(float x, float y) { + Point point = new Point(x, y); + return point; + } + + /** + * Solves a tridiagonal system for one of coordinates (x or y) of first + * bezier control points. + * + * @param rhs right hand side vector. + * @return Solution vector. + */ + private float[] getFirstControlPoints(float[] rhs) { + int n = rhs.length; + float[] x = new float[n]; // Solution vector + float[] tmp = new float[n]; // Temp workspace + + float b = 2.0f; + x[0] = rhs[0] / b; + + // Decomposition and forward substitution + for (int i = 1; i < n; i++) { + tmp[i] = 1 / b; + b = (i < n - 1 ? 4.0f : 3.5f) - tmp[i]; + x[i] = (rhs[i] - x[i - 1]) / b; + } + + // Backsubstitution + for (int i = 1; i < n; i++) { + x[n - i - 1] -= tmp[n - i] * x[n - i]; + } + + return x; + } + + public Point[] getFirstControlPoints() { + return firstControlPoints; + } + + public Point[] getSecondControlPoints() { + return secondControlPoints; + } +} \ No newline at end of file diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BarVisualizer.java b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BarVisualizer.java new file mode 100644 index 0000000..6703126 --- /dev/null +++ b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BarVisualizer.java @@ -0,0 +1,182 @@ +/* + Copyright 2018 Gaurav Kumar + + 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. +*/ + +package com.gauravk.audiovisualizer.visualizer; + +import com.gauravk.audiovisualizer.base.BaseVisualizer; +import com.gauravk.audiovisualizer.model.AnimSpeed; +import com.gauravk.audiovisualizer.model.PositionGravity; +import com.gauravk.audiovisualizer.utils.AVConstants; + +import ohos.agp.components.AttrSet; +import ohos.agp.components.Component; +import ohos.agp.render.Canvas; +import ohos.agp.utils.Rect; +import ohos.app.Context; + +import java.security.SecureRandom; +import java.util.Random; + +/** + * Custom view to create bar visualizer + *
+ * Created by gk + */ +public class BarVisualizer extends BaseVisualizer implements Component.DrawTask { + private static final int BAR_MAX_POINTS = 120; + private static final int BAR_MIN_POINTS = 3; + + private int mMaxBatchCount; + + private int nPoints; + + private float[] mSrcY; + private float[] mDestY; + + private float mBarWidth; + private Rect mClipBounds; + + private int nBatchCount; + + private SecureRandom mRandom = new SecureRandom(); + + /** + * 使用java代码实例化调用 + * + * @param context + */ + public BarVisualizer(Context context) { + super(context); + } + + /** + * 使用xml布局引用调用 + * + * @param context + * @param attrSet + */ + public BarVisualizer(Context context, AttrSet attrSet) { + super(context, attrSet); + } + + /** + * 使用xml并设置style调用 + * + * @param context + * @param attrSet + * @param styleName + */ + public BarVisualizer(Context context, AttrSet attrSet, String styleName) { + super(context, attrSet, styleName); + } + + @Override + protected void init() { + addDrawTask(this::onDraw); + nPoints = (int) (BAR_MAX_POINTS * mDensity); + if (nPoints < BAR_MIN_POINTS) { + nPoints = BAR_MIN_POINTS; + } + + mBarWidth = -1; + nBatchCount = 0; + + setAnimationSpeed(mAnimSpeed); + + mClipBounds = new Rect(); + + mSrcY = new float[nPoints]; + mDestY = new float[nPoints]; + } + + @Override + public void setAnimationSpeed(AnimSpeed animSpeed) { + super.setAnimationSpeed(animSpeed); + mMaxBatchCount = AVConstants.MAX_ANIM_BATCH_COUNT - mAnimSpeed.ordinal(); + } + + @Override + public void onDraw(Component component, Canvas canvas) { + if (mBarWidth == -1) { + canvas.getLocalClipBounds(mClipBounds); + mBarWidth = component.getWidth() / nPoints; + + // initialize points + for (int i = 0; i < mSrcY.length; i++) { + float posY; + if (mPositionGravity == PositionGravity.TOP) { + posY = mClipBounds.top; + } else { + posY = mClipBounds.bottom; + } + + mSrcY[i] = posY; + mDestY[i] = posY; + } + } + + // create the path and draw + if (isVisualizationEnabled && mRawAudioBytes != null) { + if (mRawAudioBytes.length == 0) { + return; + } + + // find the destination bezier point for a batch + if (nBatchCount == 0) { + float randPosY = mDestY[mRandom.nextInt(nPoints)]; + for (int i = 0; i < mSrcY.length; i++) { + + int x = (int) Math.ceil((i + 1) * (mRawAudioBytes.length / nPoints)); + int t = 0; + if (x < 1024) { + t = component.getHeight() + + ((byte) (Math.abs(mRawAudioBytes[x]) + 128)) * component.getHeight() / 128; + } + + float posY; + if (mPositionGravity == PositionGravity.TOP) { + posY = mClipBounds.bottom - t; + } else { + posY = mClipBounds.top + t; + } + + // change the source and destination y + mSrcY[i] = mDestY[i]; + mDestY[i] = posY; + } + + mDestY[mSrcY.length - 1] = randPosY; + } + + // increment batch count + nBatchCount++; + + // calculate bar position and draw + for (int i = 0; i < mSrcY.length; i++) { + float barY = mSrcY[i] + (((float) (nBatchCount) / mMaxBatchCount) * (mDestY[i] - mSrcY[i])); + float barX = (i * mBarWidth) + (mBarWidth / 2); + canvas.drawLine(barX, component.getHeight(), barX, barY, mPaint); + } + + // reset the batch count + if (nBatchCount == mMaxBatchCount) { + nBatchCount = 0; + } + } + + super.addDrawTask(this::onDraw); + } +} \ No newline at end of file diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BlastVisualizer.java b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BlastVisualizer.java new file mode 100644 index 0000000..8f26898 --- /dev/null +++ b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BlastVisualizer.java @@ -0,0 +1,117 @@ +/* + Copyright 2018 Gaurav Kumar + + 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. +*/ + +package com.gauravk.audiovisualizer.visualizer; + +import com.gauravk.audiovisualizer.base.BaseVisualizer; + +import ohos.agp.components.AttrSet; +import ohos.agp.components.Component; +import ohos.agp.render.Canvas; +import ohos.agp.render.Path; +import ohos.app.Context; + +import org.jetbrains.annotations.Nullable; + +/** + * Custom view to create blast visualizer + *
+ * Created by gk + */ +public class BlastVisualizer extends BaseVisualizer implements Component.DrawTask { + private static final int BLAST_MAX_POINTS = 1000; + private static final int BLAST_MIN_POINTS = 3; + + private Path mSpikePath; + private int mRadius; + private int nPoints; + + /** + * 使用java代码实例化调用 + * + * @param context + */ + public BlastVisualizer(Context context) { + super(context); + } + + /** + * 使用xml布局引用调用 + * + * @param context + * @param attrSet + */ + public BlastVisualizer(Context context, + @Nullable AttrSet attrSet) { + super(context, attrSet); + } + + @Override + protected void init() { + addDrawTask(this::onDraw); + mRadius = -1; + nPoints = (int) (BLAST_MAX_POINTS * mDensity); + if (nPoints < BLAST_MIN_POINTS) { + nPoints = BLAST_MIN_POINTS; + } + + mSpikePath = new Path(); + } + + @Override + public void onDraw(Component component,Canvas canvas) { + // first time initialization + if (mRadius == -1) { + mRadius = getHeight() < getWidth() ? getHeight() : getWidth(); + mRadius = (int) (mRadius * 0.65 / 2); + } + + // create the path and draw + if (isVisualizationEnabled && mRawAudioBytes != null) { + if (mRawAudioBytes.length == 0) { + return; + } + + mSpikePath.rewind(); + + double angle = 0; + for (int i = 0; i < nPoints; i++, angle += (360.0f / nPoints)) { + int x = (int) Math.ceil(i * (mRawAudioBytes.length / nPoints)); + int t = 0; + if (x < 1024) { + t = ((byte) (-Math.abs(mRawAudioBytes[x]) + 128)) * (component.getHeight() / 4) / 128; + } + + float posX = (float) (getWidth() / 2 + + (mRadius + t) + * Math.cos(Math.toRadians(angle))); + + float posY = (float) (getHeight() / 2 + + (mRadius + t) + * Math.sin(Math.toRadians(angle))); + + if (i == 0) { + mSpikePath.moveTo(posX, posY); + } else { + mSpikePath.lineTo(posX, posY); + } + } + mSpikePath.close(); + canvas.drawPath(mSpikePath, mPaint); + } + + } +} \ No newline at end of file diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BlobVisualizer.java b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BlobVisualizer.java new file mode 100644 index 0000000..444c79d --- /dev/null +++ b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/BlobVisualizer.java @@ -0,0 +1,225 @@ +/* + Copyright 2018 Gaurav Kumar + + 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. +*/ + +package com.gauravk.audiovisualizer.visualizer; + +import com.gauravk.audiovisualizer.base.BaseVisualizer; +import com.gauravk.audiovisualizer.model.AnimSpeed; +import com.gauravk.audiovisualizer.model.PaintStyle; +import com.gauravk.audiovisualizer.utils.BezierSpline; + +import ohos.agp.components.AttrSet; +import ohos.agp.components.Component; +import ohos.agp.components.element.ShapeElement; +import ohos.agp.render.Canvas; +import ohos.agp.render.Path; +import ohos.agp.utils.Point; +import ohos.app.Context; + +/** + * Custom view to create blob visualizer + *
+ * Created by gk + */ +public class BlobVisualizer extends BaseVisualizer implements Component.DrawTask { + private static final int BLOB_MAX_POINTS = 60; + private static final int BLOB_MIN_POINTS = 3; + + private Path mBlobPath; + private int mRadius; + + private int nPoints; + + private Point[] mBezierPoints; + private BezierSpline mBezierSpline; + + private float mAngleOffset; + private float mChangeFactor; + + /** + * 使用java代码实例化调用 + * + * @param context + */ + public BlobVisualizer(Context context) { + super(context); + } + + /** + * 使用xml布局引用调用 + * + * @param context + * @param attrSet + */ + public BlobVisualizer(Context context, AttrSet attrSet) { + super(context, attrSet); + } + + /** + * 使用xml并设置style调用 + * + * @param context + * @param attrSet + * @param styleName + */ + public BlobVisualizer(Context context, AttrSet attrSet, String styleName) { + super(context, attrSet, styleName); + } + + + + @Override + protected void init() { + addDrawTask(this::onDraw); + mRadius = -1; + nPoints = (int) (mDensity * BLOB_MAX_POINTS); + if (nPoints < BLOB_MIN_POINTS) { + nPoints = BLOB_MIN_POINTS; + } + + mAngleOffset = (360.0f / nPoints); + + updateChangeFactor(mAnimSpeed, false); + + mBlobPath = new Path(); + + // initialize mBezierPoints, 2 extra for the smoothing first and last point + mBezierPoints = new Point[nPoints + 2]; + for (int i = 0; i < mBezierPoints.length; i++) { + mBezierPoints[i] = new Point(); + } + + mBezierSpline = new BezierSpline(mBezierPoints.length); + } + + @Override + public void setAnimationSpeed(AnimSpeed animSpeed) { + super.setAnimationSpeed(animSpeed); + updateChangeFactor(animSpeed, true); + } + + private void updateChangeFactor(AnimSpeed animSpeed, boolean useHeight) { + int height = 1; + if (useHeight) { + height = getHeight() > 0 ? getHeight() : 1000; + } + + if (animSpeed == AnimSpeed.SLOW) { + mChangeFactor = height * 0.003f; + } else if (animSpeed == AnimSpeed.MEDIUM) { + mChangeFactor = height * 0.006f; + } else { + mChangeFactor = height * 0.01f; + } + } + + @Override + public void onDraw(Component component, Canvas canvas) { + + double angle = 0; + // first time initialization + if (mRadius == -1) { + mRadius = getHeight() < getWidth() ? getHeight() : getWidth(); + + // 382 + mRadius = (int) (mRadius * 0.65 / 2); + + // 10.8 + mChangeFactor = getHeight() * mChangeFactor; + + // initialize bezier points + for (int i = 0; i < nPoints; i++, angle += mAngleOffset) { + float posX = (float) (getWidth() / 2 + + (mRadius) + * Math.cos(Math.toRadians(angle))); + + float posY = (float) (getHeight() / 2 + + (mRadius) + * Math.sin(Math.toRadians(angle))); + + mBezierPoints[i].modify(posX, posY); + } + } + + // create the path and draw + if (isVisualizationEnabled && mRawAudioBytes != null) { + if (mRawAudioBytes.length == 0) { + return; + } + + mBlobPath.rewind(); + + // find the destination bezier point for a batch + for (int i = 0; i < nPoints; i++, angle += mAngleOffset) { + Point mBezierPoint = mBezierPoints[i]; + + // 1=1 X=34 i=2 X=68 + int x = (int) Math.ceil((i + 1) * (mRawAudioBytes.length / nPoints)); + int t = 0; + if (x < 1024) { + t = ((byte) (-Math.abs(mRawAudioBytes[x]) + 128)) * (component.getHeight() / 4) / 128; + } + + float posX = (float) (getWidth() / 2 + + (mRadius + t) + * Math.cos(Math.toRadians(angle))); + + float posY = (float) (getHeight() / 2 + + (mRadius + t) + * Math.sin(Math.toRadians(angle))); + + // calculate the new x based on change + if (posX - mBezierPoint.getPointXToInt() > 0) { + mBezierPoint.modify(mBezierPoint.getPointX() + mChangeFactor, mBezierPoint.getPointY()); + } else { + mBezierPoint.modify(mBezierPoint.getPointX() - mChangeFactor, mBezierPoint.getPointY()); + } + + // calculate the new y based on change + if (posY - mBezierPoint.getPointY() > 0) { + mBezierPoint.modify(mBezierPoint.getPointX(), mBezierPoint.getPointY() + mChangeFactor); + } else { + mBezierPoint.modify(mBezierPoint.getPointX(), mBezierPoint.getPointY() - mChangeFactor); + } + } + + // set the first and last point as first + + mBezierPoints[nPoints].modify(mBezierPoints[0].getPointX(), mBezierPoints[0].getPointY()); + mBezierPoints[nPoints + 1].modify(mBezierPoints[0].getPointX(), mBezierPoints[0].getPointY()); + + // update the control points + mBezierSpline.updateCurveControlPoints(mBezierPoints); + Point[] firstCP = mBezierSpline.getFirstControlPoints(); + Point[] secondCP = mBezierSpline.getSecondControlPoints(); + + // create the path + mBlobPath.moveTo(mBezierPoints[0].getPointX(), mBezierPoints[0].getPointY()); + for (int i = 0; i < firstCP.length; i++) { + mBlobPath.cubicTo(firstCP[i].getPointX(), firstCP[i].getPointY(), + secondCP[i].getPointX(), secondCP[i].getPointY(), + mBezierPoints[i + 1].getPointX(), mBezierPoints[i + 1].getPointY()); + } + + // add an extra line to center cover the gap generated by last cubicTo + if (mPaintStyle == PaintStyle.FILL) { + mBlobPath.lineTo(getWidth() / 2, getHeight() / 2); + } + canvas.drawPath(mBlobPath, mPaint); + } + super.addDrawTask(this::onDraw); + } +} \ No newline at end of file diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/CircleLineVisualizer.java b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/CircleLineVisualizer.java new file mode 100644 index 0000000..6fd2c2e --- /dev/null +++ b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/CircleLineVisualizer.java @@ -0,0 +1,185 @@ +package com.gauravk.audiovisualizer.visualizer; + +import com.gauravk.audiovisualizer.base.BaseVisualizer; + +import ohos.agp.components.AttrSet; +import ohos.agp.components.Component; +import ohos.agp.components.ComponentContainer; +import ohos.agp.render.*; +import ohos.agp.utils.Color; +import ohos.agp.utils.Point; +import ohos.agp.utils.Rect; +import ohos.app.Context; + +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; + +/** + * 圆形 + * + * @author maple on 2019/4/24 15:17. + * @version v1.0 + */ +public class CircleLineVisualizer extends BaseVisualizer implements Component.DrawTask, ComponentContainer.ArrangeListener { + private static final int BAR_MAX_POINTS = 240; + private static final int BAR_MIN_POINTS = 30; + private Rect mClipBounds; + private int mPoints; + private int mPointRadius; + private float[] mSrcY; + private int mRadius; + private Paint mGPaint; + private boolean drawLine; + + /** + * 使用java代码实例化调用 + * + * @param context + */ + public CircleLineVisualizer(Context context) { + super(context); + } + + /** + * 使用xml布局引用调用 + * + * @param context + * @param attrs + */ + public CircleLineVisualizer(Context context, @Nullable AttrSet attrs) { + super(context, attrs); + } + + public boolean isDrawLine() { + return drawLine; + } + + /** + * control the display of drawLine + * + * @param drawLine is show drawLine + */ + public void setDrawLine(boolean drawLine) { + this.drawLine = drawLine; + } + + @Override + protected void init() { + addDrawTask(this::onDraw); + setArrangeListener(this::onArrange); + mPoints = (int) (BAR_MAX_POINTS * mDensity); + if (mPoints < BAR_MIN_POINTS) { + mPoints = BAR_MIN_POINTS; + } + mSrcY = new float[mPoints]; + mClipBounds = new Rect(); + setAnimationSpeed(mAnimSpeed); + mPaint.setAntiAlias(true); + mGPaint = new Paint(); + mGPaint.setAntiAlias(true); + } + + @Override + public void onDraw(Component component, Canvas canvas) { + canvas.getLocalClipBounds(mClipBounds); + updateData(); + + // draw circle's points + for (int i = 0; i < 360; i = i + 360 / mPoints) { + float cx = (float) (getWidth() / 2 + Math.cos(i * Math.PI / 180) * mRadius); + float cy = (float) (getHeight() / 2 - Math.sin(i * Math.PI / 180) * mRadius); + canvas.drawCircle(cx, cy, mPointRadius, mPaint); + } + + // draw lines + if (drawLine) { + drawLines(canvas); + } + + // draw bar + for (int i = 0; i < 360; i = i + 360 / mPoints) { + if (mSrcY[i * mPoints / 360] == 0) { + continue; + } + canvas.save(); + canvas.rotate(-i, getWidth() / 2, getHeight() / 2); + float cx = (float) (getWidth() / 2 + mRadius); + float cy = (float) (getHeight() / 2); + canvas.drawRect(cx, cy - mPointRadius, cx + mSrcY[i * mPoints / 360], + cy + mPointRadius, mPaint); + canvas.drawCircle(cx + mSrcY[i * mPoints / 360], cy, mPointRadius, mPaint); + canvas.restore(); + } + super.addDrawTask(this::onDraw); + } + + /** + * Draw a translucent ray + * + * @param canvas target canvas + */ + private void drawLines(Canvas canvas) { + int lineLen = 14 * mPointRadius; + + // default len, + for (int i = 0; i < 360; i = i + 360 / mPoints) { + canvas.save(); + canvas.rotate(-i, getWidth() / 2, getHeight() / 2); + float cx = (float) (getWidth() / 2 + mRadius) + mSrcY[i * mPoints / 360]; + float cy = (float) (getHeight() / 2); + Path path = new Path(); + path.moveTo(cx, cy + mPointRadius); + path.lineTo(cx, cy - mPointRadius); + path.lineTo(cx + lineLen, cy); + canvas.drawPath(path, mGPaint); + canvas.restore(); + } + } + + private void updateData() { + if (isVisualizationEnabled && mRawAudioBytes != null) { + if (mRawAudioBytes.length == 0) { + return; + } + for (int i = 0; i < mSrcY.length; i++) { + int x = (int) Math.ceil((i + 1) * (mRawAudioBytes.length / mPoints)); + int t = 0; + if (x < 1024) { + t = ((byte) (Math.abs(mRawAudioBytes[x]) + 128)) * mRadius / 128; + } + mSrcY[i] = -t; + } + } + } + + /** + * 大小发生变化调用 + * + * @param w 0 + * @param h 0 + * @param oldw 1176 + * @param oldh 1800 + * @return + */ + @Override + public boolean onArrange(int w, int h, int oldw, int oldh) { + setArrangeListener(this::onArrange); + mRadius = Math.min(oldw, oldh) / 4; + mPointRadius = Math.abs((int) (2 * mRadius * Math.sin(Math.PI / mPoints / 3))); + Point[] newPoints = new Point[]{new Point(getWidth() / 2 + mRadius, getHeight() / 2)}; + float[] newStops = {getWidth() / 2 + mRadius + mPointRadius * 5, getHeight() / 2}; + Color[] newColors = new Color[]{new Color(Color.getIntColor("#77FF5722")), new Color(Color.getIntColor("#10FF5722"))}; + LinearShader lg = new LinearShader( + newPoints, + newStops, + newColors, + Shader.TileMode.CLAMP_TILEMODE); + mGPaint.setShader(lg, Paint.ShaderType.PIXELMAP_SHADER); + return false; + } + + public void setVisualizationEnabled(boolean b) { + isVisualizationEnabled = b; + } +} diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/HiFiVisualizer.java b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/HiFiVisualizer.java new file mode 100644 index 0000000..6406bbf --- /dev/null +++ b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/HiFiVisualizer.java @@ -0,0 +1,155 @@ +package com.gauravk.audiovisualizer.visualizer; + +import com.gauravk.audiovisualizer.base.BaseVisualizer; + +import com.gauravk.audiovisualizer.model.PaintStyle; +import ohos.agp.colors.ColorSpec; +import ohos.agp.colors.RgbColor; +import ohos.agp.components.AttrSet; +import ohos.agp.components.Component; +import ohos.agp.render.Canvas; +import ohos.agp.render.Paint; +import ohos.agp.render.Path; +import ohos.agp.utils.Color; +import ohos.app.Context; + +import org.jetbrains.annotations.Nullable; + +/** + * 折线图 + * + * @author maple on 2019/4/25 10:17. + * @version v1.0 + */ +public class HiFiVisualizer extends BaseVisualizer implements Component.DrawTask { + private static final int BAR_MAX_POINTS = 240; + private static final int BAR_MIN_POINTS = 30; + private static final float PER_RADIUS = .65f; + private int mRadius; + private int mPoints; + private int[] mHeights; + private Paint paint; + // outward path + private Path mPath; + + // inward path + private Path mPath1; + + /** + * This is the distance from center to bezier control point. + * We can calculate the bezier control points of each segment this distance and its angle; + */ + private int mBezierControlPointLen; + + /** + * 使用java代码实例化调用 + * + * @param context + */ + public HiFiVisualizer(Context context) { + super(context); + } + + /** + * 使用xml布局引用调用 + * + * @param context + * @param attrs + */ + public HiFiVisualizer(Context context, @Nullable AttrSet attrs) { + super(context, attrs); + } + + @Override + protected void init() { + addDrawTask(this::onDraw); + mRadius = -1; + mPath = new Path(); + mPath1 = new Path(); + mPaint.setStyle(Paint.Style.STROKE_STYLE); + mPaint.setAntiAlias(true); + mPaint.setStrokeWidth(1.0f); + mPoints = (int) (BAR_MAX_POINTS * mDensity); + if (mPoints < BAR_MIN_POINTS) { + mPoints = BAR_MIN_POINTS; + } + mHeights = new int[mPoints]; + + paint = new Paint(); + paint.setColor(new Color(Color.getIntColor("#FCB8A3"))); + paint.setStrokeWidth(mStrokeWidth); + if (mPaintStyle == PaintStyle.FILL) { + paint.setStyle(Paint.Style.FILL_STYLE); + } + else { + paint.setStyle(Paint.Style.STROKE_STYLE); + } + } + + @Override + public void onDraw(Component component, Canvas canvas) { + if (mRadius == -1) { + mRadius = (int) (Math.min(getWidth(), getHeight()) / 2 * PER_RADIUS); + mBezierControlPointLen = (int) (mRadius / Math.cos(Math.PI / mPoints)); + } + updateData(); + mPath.reset(); + mPath1.reset(); + + // start the outward path from the last point + float cxL = (float) (getWidth() / 2 + Math.cos((360 - 360 / mPoints) * Math.PI / 180) * (mRadius + mHeights[mPoints - 1])); + float cyL = (float) (getHeight() / 2 - Math.sin((360 - 360 / mPoints) * Math.PI / 180) * (mRadius + mHeights[mPoints - 1])); + mPath.moveTo(cxL, cyL); + + // start the inward path from the last point + float cxL1 = (float) (getWidth() / 2 + Math.cos((360 - 360 / mPoints) * Math.PI / 180) * (mRadius - mHeights[mPoints - 1])); + float cyL1 = (float) (getHeight() / 2 - Math.sin((360 - 360 / mPoints) * Math.PI / 180) * (mRadius - mHeights[mPoints - 1])); + mPath1.moveTo(cxL1, cyL1); + for (int i = 0; i < 360; i = i + 360 / mPoints) { + // outward + // the next point of path + float cx = (float) (getWidth() / 2 + Math.cos(i * Math.PI / 180) * (mRadius + mHeights[i * mPoints / 360])); + float cy = (float) (getHeight() / 2 - Math.sin(i * Math.PI / 180) * (mRadius + mHeights[i * mPoints / 360])); + + // second bezier control point + float bx = (float) (getWidth() / 2 + Math.cos((i - (180 / mPoints)) * Math.PI / 180) * (mBezierControlPointLen + mHeights[i * mPoints / 360])); + float by = (float) (getHeight() / 2 - Math.sin((i - (180 / mPoints)) * Math.PI / 180) * (mBezierControlPointLen + mHeights[i * mPoints / 360])); + int lastPoint = i == 0 ? mPoints - 1 : i * mPoints / 360 - 1; + + // fist bezier control point + float ax = (float) (getWidth() / 2 + Math.cos((i - (180 / mPoints)) * Math.PI / 180) * (mBezierControlPointLen + mHeights[lastPoint])); + float ay = (float) (getHeight() / 2 - Math.sin((i - (180 / mPoints)) * Math.PI / 180) * (mBezierControlPointLen + mHeights[lastPoint])); + mPath.cubicTo(ax, ay, bx, by, cx, cy); + + // inward + float cx1 = (float) (getWidth() / 2 + Math.cos(i * Math.PI / 180) * (mRadius - mHeights[i * mPoints / 360])); + float cy1 = (float) (getHeight() / 2 - Math.sin(i * Math.PI / 180) * (mRadius - mHeights[i * mPoints / 360])); + float bx1 = (float) (getWidth() / 2 + Math.cos((i - (180 / mPoints)) * Math.PI / 180) * (mBezierControlPointLen - mHeights[i * mPoints / 360])); + float by1 = (float) (getHeight() / 2 - Math.sin((i - (180 / mPoints)) * Math.PI / 180) * (mBezierControlPointLen - mHeights[i * mPoints / 360])); + float ax1 = (float) (getWidth() / 2 + Math.cos((i - (180 / mPoints)) * Math.PI / 180) * (mBezierControlPointLen - mHeights[lastPoint])); + float ay1 = (float) (getHeight() / 2 - Math.sin((i - (180 / mPoints)) * Math.PI / 180) * (mBezierControlPointLen - mHeights[lastPoint])); + mPath1.cubicTo(ax1, ay1, bx1, by1, cx1, cy1); + canvas.drawLine(cx, cy, cx1, cy1, mPaint); + } + canvas.drawPath(mPath, mPaint); + canvas.drawPath(mPath1, mPaint); + } + + private void updateData() { + if (isVisualizationEnabled && mRawAudioBytes != null) { + if (mRawAudioBytes.length == 0) return; + for (int i = 0; i < mHeights.length; i++) { + int x = (int) Math.ceil((i + 1) * (mRawAudioBytes.length / mPoints)); + int t = 0; + if (x < 1024) { + t = ((byte) (Math.abs(mRawAudioBytes[x]) + 128)) * mRadius / 128; + } + mHeights[i] = -t; + } + } + } + + public void setVisualizationEnabled(boolean b) { + isVisualizationEnabled = b; + } +} diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/WaveVisualizer.java b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/WaveVisualizer.java new file mode 100644 index 0000000..d9cbe3e --- /dev/null +++ b/AudioVisualizerOhos/audiovisualizer/src/main/java/com/gauravk/audiovisualizer/visualizer/WaveVisualizer.java @@ -0,0 +1,219 @@ +/* + Copyright 2018 Gaurav Kumar + + 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. +*/ + +package com.gauravk.audiovisualizer.visualizer; + +import com.gauravk.audiovisualizer.base.BaseVisualizer; +import com.gauravk.audiovisualizer.model.AnimSpeed; +import com.gauravk.audiovisualizer.model.PaintStyle; +import com.gauravk.audiovisualizer.model.PositionGravity; +import com.gauravk.audiovisualizer.utils.AVConstants; + +import ohos.agp.components.AttrSet; +import ohos.agp.components.Component; +import ohos.agp.render.Canvas; +import ohos.agp.render.Path; +import ohos.agp.utils.Point; +import ohos.agp.utils.Rect; +import ohos.app.Context; + +import org.jetbrains.annotations.Nullable; + +import java.security.SecureRandom; +import java.util.Random; + +/** + * Custom view to create wave visualizer + *
+ * Created by gk
+ */
+public class WaveVisualizer extends BaseVisualizer implements Component.DrawTask {
+ private static final int WAVE_MAX_POINTS = 54;
+ private static final int WAVE_MIN_POINTS = 3;
+
+ private int mMaxBatchCount;
+
+ private Path mWavePath;
+
+ private int nPoints;
+
+ private Point[] mBezierPoints;
+ private Point[] mBezierControlPoints1;
+ private Point[] mBezierControlPoints2;
+
+ private float[] mSrcY;
+ private float[] mDestY;
+
+ private float mWidthOffset;
+ private Rect mClipBounds;
+
+ private int nBatchCount;
+
+ private SecureRandom mRandom = new SecureRandom();
+
+ /**
+ * 使用java代码实例化调用
+ *
+ * @param context
+ */
+ public WaveVisualizer(Context context) {
+ super(context);
+ }
+
+ /**
+ * 使用xml布局引用调用
+ *
+ * @param context
+ * @param attrs
+ */
+ public WaveVisualizer(Context context,
+ @Nullable AttrSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void init() {
+ addDrawTask(this::onDraw);
+ nPoints = (int) (WAVE_MAX_POINTS * mDensity);
+ if (nPoints < WAVE_MIN_POINTS) {
+ nPoints = WAVE_MIN_POINTS;
+ }
+
+ mWidthOffset = -1;
+ nBatchCount = 0;
+
+ setAnimationSpeed(mAnimSpeed);
+
+ mClipBounds = new Rect();
+
+ mWavePath = new Path();
+
+ mSrcY = new float[nPoints + 1];
+ mDestY = new float[nPoints + 1];
+
+ // initialize mBezierPoints
+ mBezierPoints = new Point[nPoints + 1];
+ mBezierControlPoints1 = new Point[nPoints + 1];
+ mBezierControlPoints2 = new Point[nPoints + 1];
+ for (int i = 0; i < mBezierPoints.length; i++) {
+ mBezierPoints[i] = new Point();
+ mBezierControlPoints1[i] = new Point();
+ mBezierControlPoints2[i] = new Point();
+ }
+ }
+
+ @Override
+ public void setAnimationSpeed(AnimSpeed animSpeed) {
+ super.setAnimationSpeed(animSpeed);
+ this.mMaxBatchCount = AVConstants.MAX_ANIM_BATCH_COUNT - mAnimSpeed.ordinal();
+ }
+
+ @Override
+ public void onDraw(Component component, Canvas canvas) {
+ if (mWidthOffset == -1) {
+ canvas.getLocalClipBounds(mClipBounds);
+
+ mWidthOffset = component.getWidth() / nPoints;
+
+ //initialize bezier points
+ for (int i = 0; i < mBezierPoints.length; i++) {
+ float posX = mClipBounds.left + (i * mWidthOffset);
+
+ float posY;
+ if (mPositionGravity == PositionGravity.TOP) {
+ posY = mClipBounds.top;
+ } else {
+ posY = mClipBounds.bottom;
+ }
+
+ mSrcY[i] = posY;
+ mDestY[i] = posY;
+ mBezierPoints[i].modify(posX, posY);
+ }
+ }
+
+ // create the path and draw
+ if (isVisualizationEnabled && mRawAudioBytes != null) {
+ if (mRawAudioBytes.length == 0) {
+ return;
+ }
+
+ mWavePath.rewind();
+
+ // find the destination bezier point for a batch
+ if (nBatchCount == 0) {
+ float randPosY = mDestY[mRandom.nextInt(nPoints)];
+ for (int i = 0; i < mBezierPoints.length; i++) {
+ int x = (int) Math.ceil((i + 1) * (mRawAudioBytes.length / nPoints));
+
+ int t = 0;
+ if (x < 1024) {
+ t = component.getHeight()
+ + ((byte) (Math.abs(mRawAudioBytes[x]) + 128)) * component.getHeight() / 128;
+ }
+
+ float posY;
+ if (mPositionGravity == PositionGravity.TOP) {
+ posY = mClipBounds.bottom - t;
+ } else {
+ posY = mClipBounds.top + t;
+ }
+
+ //change the source and destination y
+ mSrcY[i] = mDestY[i];
+ mDestY[i] = posY;
+ }
+
+ mDestY[mBezierPoints.length - 1] = randPosY;
+ }
+
+ // increment batch count
+ nBatchCount++;
+
+ // for smoothing animation
+ for (int i = 0; i < mBezierPoints.length; i++) {
+ mBezierPoints[i].modify(mBezierPoints[i].getPointX(), mSrcY[i] + (((float) (nBatchCount) / mMaxBatchCount) * (mDestY[i] - mSrcY[i])));
+ }
+
+ // reset the batch count
+ if (nBatchCount == mMaxBatchCount) {
+ nBatchCount = 0;
+ }
+
+ // calculate the bezier curve control points
+ for (int i = 1; i < mBezierPoints.length; i++) {
+ mBezierControlPoints1[i].modify((mBezierPoints[i].getPointX() + mBezierPoints[i - 1].getPointX()) / 2, mBezierPoints[i - 1].getPointY());
+ mBezierControlPoints2[i].modify((mBezierPoints[i].getPointX() + mBezierPoints[i - 1].getPointX()) / 2, mBezierPoints[i].getPointY());
+ }
+
+ // create the path
+ mWavePath.moveTo(mBezierPoints[0].getPointX(), mBezierPoints[0].getPointY());
+ for (int i = 1; i < mBezierPoints.length; i++) {
+ mWavePath.cubicTo(mBezierControlPoints1[i].getPointX(), mBezierControlPoints1[i].getPointY(),
+ mBezierControlPoints2[i].getPointX(), mBezierControlPoints2[i].getPointY(),
+ mBezierPoints[i].getPointX(), mBezierPoints[i].getPointY());
+ }
+
+ if (mPaintStyle == PaintStyle.FILL) {
+ mWavePath.lineTo(mClipBounds.right, mClipBounds.bottom);
+ mWavePath.lineTo(mClipBounds.left, mClipBounds.bottom);
+ mWavePath.close();
+ }
+ canvas.drawPath(mWavePath, mPaint);
+ }
+ super.addDrawTask(this::onDraw);
+ }
+}
\ No newline at end of file
diff --git a/AudioVisualizerOhos/audiovisualizer/src/main/resources/base/element/string.json b/AudioVisualizerOhos/audiovisualizer/src/main/resources/base/element/string.json
new file mode 100644
index 0000000..87682f6
--- /dev/null
+++ b/AudioVisualizerOhos/audiovisualizer/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "audiovisualizer"
+ }
+ ]
+}
diff --git a/AudioVisualizerOhos/build.gradle b/AudioVisualizerOhos/build.gradle
new file mode 100644
index 0000000..da99825
--- /dev/null
+++ b/AudioVisualizerOhos/build.gradle
@@ -0,0 +1,46 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ maven {
+ url 'http://106.15.92.248:8081/repository/Releases/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.2.7'
+ classpath 'com.huawei.ohos:decctest:1.0.0.6'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://mirrors.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ maven {
+ url 'http://106.15.92.248:8081/repository/Releases/'
+ }
+ repositories{
+ mavenCentral()
+ }
+ jcenter()
+ }
+}
diff --git a/AudioVisualizerOhos/entry/.gitignore b/AudioVisualizerOhos/entry/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/AudioVisualizerOhos/entry/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/AudioVisualizerOhos/entry/build.gradle b/AudioVisualizerOhos/entry/build.gradle
new file mode 100644
index 0000000..6674e0f
--- /dev/null
+++ b/AudioVisualizerOhos/entry/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 5
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ implementation project(path: ':audiovisualizer')
+ testCompile 'junit:junit:4.12'
+}
diff --git a/AudioVisualizerOhos/entry/src/main/config.json b/AudioVisualizerOhos/entry/src/main/config.json
new file mode 100644
index 0000000..3e71dc4
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/config.json
@@ -0,0 +1,209 @@
+{
+ "app": {
+ "bundleName": "com.gauravk.audiovisualizersample",
+ "vendor": "github",
+ "version": {
+ "code": 1,
+ "name": "1.0"
+ },
+ "apiVersion": {
+ "compatible": 5,
+ "target": 5
+ }
+ },
+ "deviceConfig": {
+ "default": {
+ "network": {
+ "cleartextTraffic": true
+ }
+ }
+ },
+ "module": {
+ "package": "com.gauravk.audiovisualizersample",
+ "name": "com.gauravk.audiovisualizersample.MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "reqPermissions": [
+ {
+ "name": "ohos.permission.MICROPHONE"
+ },
+ {
+ "name": "ohos.permission.READ_MEDIA"
+ },
+ {
+ "name": "ohos.permission.WRITE_MEDIA"
+ },
+ {
+ "name": "ohos.permission.RECORD_AUDIO"
+ },
+ {
+ "name": "ohos.permission.INTERNET"
+ },
+ {
+ "name": "ohos.permission.GET_NETWORK_INFO"
+ }
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "com.gauravk.audiovisualizersample.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "AudioVisualizerAndroid",
+ "type": "page",
+ "launchType": "standard",
+ "metaData": {
+ "customizeData": [
+ {
+ "name": "hwc-theme",
+ "value": "androidhwext:style/Theme.Emui.NoTitleBar",
+ "extra": ""
+ }
+ ]
+ }
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.gauravk.audiovisualizersample.ui.BarAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "visualizer",
+ "type": "page",
+ "launchType": "standard",
+ "metaData": {
+ "customizeData": [
+ {
+ "name": "hwc-theme",
+ "value": "androidhwext:style/Theme.Emui.NoTitleBar",
+ "extra": ""
+ }
+ ]
+ }
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.gauravk.audiovisualizersample.ui.BlastAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "visualizer",
+ "type": "page",
+ "launchType": "standard",
+ "metaData": {
+ "customizeData": [
+ {
+ "name": "hwc-theme",
+ "value": "androidhwext:style/Theme.Emui.NoTitleBar",
+ "extra": ""
+ }
+ ]
+ }
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.gauravk.audiovisualizersample.ui.CircleLineAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "visualizer",
+ "type": "page",
+ "launchType": "standard",
+ "metaData": {
+ "customizeData": [
+ {
+ "name": "hwc-theme",
+ "value": "androidhwext:style/Theme.Emui.NoTitleBar",
+ "extra": ""
+ }
+ ]
+ }
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.gauravk.audiovisualizersample.ui.HiFiAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "visualizer",
+ "type": "page",
+ "launchType": "standard",
+ "metaData": {
+ "customizeData": [
+ {
+ "name": "hwc-theme",
+ "value": "androidhwext:style/Theme.Emui.NoTitleBar",
+ "extra": ""
+ }
+ ]
+ }
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.gauravk.audiovisualizersample.ui.MusicStreamAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "visualizer",
+ "type": "page",
+ "launchType": "standard",
+ "metaData": {
+ "customizeData": [
+ {
+ "name": "hwc-theme",
+ "value": "androidhwext:style/Theme.Emui.NoTitleBar",
+ "extra": ""
+ }
+ ]
+ }
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.gauravk.audiovisualizersample.ui.WaveAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "visualizer",
+ "type": "page",
+ "launchType": "standard",
+ "metaData": {
+ "customizeData": [
+ {
+ "name": "hwc-theme",
+ "value": "androidhwext:style/Theme.Emui.NoTitleBar",
+ "extra": ""
+ }
+ ]
+ }
+ },
+ {
+ "orientation": "unspecified",
+ "name": "com.gauravk.audiovisualizersample.ui.BlobAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "visualizer",
+ "type": "page",
+ "launchType": "standard",
+ "metaData": {
+ "customizeData": [
+ {
+ "name": "hwc-theme",
+ "value": "androidhwext:style/Theme.Emui.NoTitleBar",
+ "extra": ""
+ }
+ ]
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/MainAbility.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/MainAbility.java
new file mode 100644
index 0000000..b17955a
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/MainAbility.java
@@ -0,0 +1,18 @@
+package com.gauravk.audiovisualizersample;
+
+import com.gauravk.audiovisualizersample.slice.MainAbilitySlice;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.utils.Color;
+import ohos.agp.window.service.WindowManager;
+
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+
+ WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.rgb(66, 119, 208));
+ }
+}
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/MyApplication.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/MyApplication.java
new file mode 100644
index 0000000..e817211
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/MyApplication.java
@@ -0,0 +1,10 @@
+package com.gauravk.audiovisualizersample;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/slice/MainAbilitySlice.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/slice/MainAbilitySlice.java
new file mode 100644
index 0000000..5614152
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/slice/MainAbilitySlice.java
@@ -0,0 +1,108 @@
+package com.gauravk.audiovisualizersample.slice;
+
+import com.gauravk.audiovisualizersample.ResourceTable;
+import com.gauravk.audiovisualizersample.ui.*;
+import com.gauravk.audiovisualizersample.util.PermissionUtils;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.aafwk.content.Operation;
+import ohos.agp.components.Component;
+import ohos.bundle.IBundleManager;
+import ohos.global.resource.RawFileDescriptor;
+import ohos.media.common.Source;
+import ohos.media.player.Player;
+
+import java.io.IOException;
+
+public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ initReqPermissions();
+ initView();
+ }
+
+ private void initView() {
+ findComponentById(ResourceTable.Id_bt_main_blob).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_main_blast).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_main_wave).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_main_bar).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_main_stream).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_main_circle_line).setClickedListener(this);
+ findComponentById(ResourceTable.Id_bt_main_hifi).setClickedListener(this);
+ }
+
+ @Override
+ protected void onActive() {
+ super.onActive();
+ try {
+ RawFileDescriptor filDescriptor = getResourceManager().getRawFileEntry("resources/rawfile/sample.aac").openRawFileDescriptor();
+ Source source = new Source(filDescriptor.getFileDescriptor());
+ Player impl = new Player(this);
+ impl.setSource(source);
+ impl.prepare();
+ impl.play();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onClick(Component component) {
+ switch (component.getId()) {
+ case ResourceTable.Id_bt_main_blob:
+ nextPage(BlobAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_main_blast:
+ nextPage(BlastAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_main_wave:
+ nextPage(WaveAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_main_bar:
+ nextPage(BarAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_main_stream:
+ nextPage(MusicStreamAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_main_circle_line:
+ nextPage(CircleLineAbility.class.getName());
+ break;
+ case ResourceTable.Id_bt_main_hifi:
+ nextPage(HiFiAbility.class.getName());
+ break;
+ default:
+ break;
+ }
+ }
+
+ public void nextPage(String abilityName) {
+ Intent intent = new Intent();
+ Operation build = new Intent.OperationBuilder()
+ .withBundleName(getBundleName())
+ .withAbilityName(abilityName)
+ .build();
+ intent.setOperation(build);
+ startAbility(intent);
+ }
+
+ private void initReqPermissions() {
+ if (verifySelfPermission(PermissionUtils.MICROPHONE) != IBundleManager.PERMISSION_GRANTED
+ || verifySelfPermission(PermissionUtils.READ_MEDIA) != IBundleManager.PERMISSION_GRANTED
+ || verifySelfPermission(PermissionUtils.WRITE_MEDIA) != IBundleManager.PERMISSION_GRANTED
+ || verifySelfPermission(PermissionUtils.RECORD_AUDIO) != IBundleManager.PERMISSION_GRANTED
+ ) {
+ if (canRequestPermission(PermissionUtils.MICROPHONE)
+ || canRequestPermission(PermissionUtils.READ_MEDIA)
+ || canRequestPermission(PermissionUtils.WRITE_MEDIA)
+ || canRequestPermission(PermissionUtils.RECORD_AUDIO)) {
+ requestPermissionsFromUser(
+ PermissionUtils.permission, PermissionUtils.PERMISSION_CODE);
+ }
+ }
+ }
+
+}
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BarAbility.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BarAbility.java
new file mode 100644
index 0000000..292d6ef
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BarAbility.java
@@ -0,0 +1,69 @@
+/*
+ Copyright 2018 Gaurav Kumar
+
+ 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.
+*/
+
+package com.gauravk.audiovisualizersample.ui;
+
+import com.gauravk.audiovisualizer.visualizer.BarVisualizer;
+import com.gauravk.audiovisualizersample.ResourceTable;
+import com.gauravk.audiovisualizersample.util.MusicFinish;
+import com.gauravk.audiovisualizersample.util.PlaySoundUtil;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.utils.Color;
+import ohos.agp.window.service.WindowManager;
+import ohos.media.audio.*;
+
+public class BarAbility extends Ability {
+ private BarVisualizer mVisualizer;
+ private PlaySoundUtil playSoundUtil;
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_activity_bar);
+
+ WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.rgb(66, 119, 208));
+
+ playSoundUtil = new PlaySoundUtil();
+ mVisualizer = (BarVisualizer) findComponentById(ResourceTable.Id_bar);
+ mVisualizer.setAudioSessionId(playSoundUtil.getAudioRenderer().getRendererSessionId());
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ if (playSoundUtil.getAudioRenderer().getState() != AudioRenderer.State.STATE_PLAYING) {
+ playSoundUtil.loadSound("Ring10.wav", new MusicFinish() {
+ @Override
+ public void finish() {
+ getUITaskDispatcher().syncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ mVisualizer.setVisibility(Component.HIDE);
+ }
+ });
+ }
+ });
+ }
+ }
+ }).start();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ playSoundUtil.getAudioRenderer().stop();
+ }
+}
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BlastAbility.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BlastAbility.java
new file mode 100644
index 0000000..5e0c0ed
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BlastAbility.java
@@ -0,0 +1,70 @@
+/*
+ Copyright 2018 Gaurav Kumar
+
+ 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.
+*/
+
+package com.gauravk.audiovisualizersample.ui;
+
+import com.gauravk.audiovisualizer.visualizer.BlastVisualizer;
+import com.gauravk.audiovisualizersample.ResourceTable;
+import com.gauravk.audiovisualizersample.util.MusicFinish;
+import com.gauravk.audiovisualizersample.util.PlaySoundUtil;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.utils.Color;
+import ohos.agp.window.service.WindowManager;
+import ohos.media.audio.AudioRenderer;
+
+public class BlastAbility extends Ability {
+ private BlastVisualizer mVisualizer;
+ private PlaySoundUtil playSoundUtil;
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_activity_blast);
+
+ WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.rgb(66, 119, 208));
+
+ playSoundUtil = new PlaySoundUtil();
+ mVisualizer = (BlastVisualizer) findComponentById(ResourceTable.Id_blast);
+ mVisualizer.setAudioSessionId(playSoundUtil.getAudioRenderer().getRendererSessionId());
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ if (playSoundUtil.getAudioRenderer().getState() != AudioRenderer.State.STATE_PLAYING) {
+ playSoundUtil.loadSound("Ring10.wav", new MusicFinish() {
+ @Override
+ public void finish() {
+ getUITaskDispatcher().syncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ mVisualizer.setVisibility(Component.HIDE);
+ }
+ });
+ }
+ });
+ }
+ }
+ }).start();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ playSoundUtil.getAudioRenderer().stop();
+ }
+}
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BlobAbility.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BlobAbility.java
new file mode 100644
index 0000000..848e8e9
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/BlobAbility.java
@@ -0,0 +1,70 @@
+/*
+ Copyright 2018 Gaurav Kumar
+
+ 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.
+*/
+
+package com.gauravk.audiovisualizersample.ui;
+
+import com.gauravk.audiovisualizer.visualizer.BlobVisualizer;
+import com.gauravk.audiovisualizersample.ResourceTable;
+import com.gauravk.audiovisualizersample.util.MusicFinish;
+import com.gauravk.audiovisualizersample.util.PlaySoundUtil;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.utils.Color;
+import ohos.agp.window.service.WindowManager;
+import ohos.media.audio.AudioRenderer;
+
+public class BlobAbility extends Ability {
+ private BlobVisualizer mVisualizer;
+ private PlaySoundUtil playSoundUtil;
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_activity_blob);
+
+ WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.rgb(66, 119, 208));
+
+ playSoundUtil = new PlaySoundUtil();
+ mVisualizer = (BlobVisualizer) findComponentById(ResourceTable.Id_blob);
+ mVisualizer.setAudioSessionId(playSoundUtil.getAudioRenderer().getRendererSessionId());
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ if (playSoundUtil.getAudioRenderer().getState() != AudioRenderer.State.STATE_PLAYING) {
+ playSoundUtil.loadSound("Ring10.wav", new MusicFinish() {
+ @Override
+ public void finish() {
+ getUITaskDispatcher().syncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ mVisualizer.setVisibility(Component.HIDE);
+ }
+ });
+ }
+ });
+ }
+ }
+ }).start();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ playSoundUtil.getAudioRenderer().stop();
+ }
+}
\ No newline at end of file
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/CircleLineAbility.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/CircleLineAbility.java
new file mode 100644
index 0000000..1df6f82
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/CircleLineAbility.java
@@ -0,0 +1,48 @@
+package com.gauravk.audiovisualizersample.ui;
+
+import com.gauravk.audiovisualizer.visualizer.CircleLineVisualizer;
+import com.gauravk.audiovisualizersample.ResourceTable;
+import com.gauravk.audiovisualizersample.util.MusicFinish;
+import com.gauravk.audiovisualizersample.util.PlaySoundUtil;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.utils.Color;
+import ohos.agp.window.service.WindowManager;
+import ohos.media.audio.AudioRenderer;
+
+public class CircleLineAbility extends Ability {
+ private CircleLineVisualizer mVisualizer;
+ private PlaySoundUtil playSoundUtil;
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_activity_circle_line);
+
+ WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.rgb(66, 119, 208));
+
+ playSoundUtil = new PlaySoundUtil();
+ mVisualizer = (CircleLineVisualizer) findComponentById(ResourceTable.Id_circle);
+ mVisualizer.setAudioSessionId(playSoundUtil.getAudioRenderer().getRendererSessionId());
+ mVisualizer.setDrawLine(true);
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ if (playSoundUtil.getAudioRenderer().getState() != AudioRenderer.State.STATE_PLAYING) {
+ playSoundUtil.loadSound("Ring10.wav", new MusicFinish() {
+ @Override
+ public void finish() {
+ mVisualizer.setVisualizationEnabled(false);
+ }
+ });
+ }
+ }
+ }).start();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ playSoundUtil.getAudioRenderer().stop();
+ }
+}
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/HiFiAbility.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/HiFiAbility.java
new file mode 100644
index 0000000..9321524
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/HiFiAbility.java
@@ -0,0 +1,48 @@
+package com.gauravk.audiovisualizersample.ui;
+
+import com.gauravk.audiovisualizer.visualizer.HiFiVisualizer;
+import com.gauravk.audiovisualizersample.ResourceTable;
+import com.gauravk.audiovisualizersample.util.MusicFinish;
+import com.gauravk.audiovisualizersample.util.PlaySoundUtil;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.utils.Color;
+import ohos.agp.window.service.WindowManager;
+import ohos.media.audio.AudioRenderer;
+
+public class HiFiAbility extends Ability {
+ private HiFiVisualizer mVisualizer;
+ private PlaySoundUtil playSoundUtil;
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_activity_hi_fi);
+
+ WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.rgb(66, 119, 208));
+
+ playSoundUtil = new PlaySoundUtil();
+ mVisualizer = (HiFiVisualizer) findComponentById(ResourceTable.Id_hifi);
+ mVisualizer.setAudioSessionId(playSoundUtil.getAudioRenderer().getRendererSessionId());
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ if (playSoundUtil.getAudioRenderer().getState() != AudioRenderer.State.STATE_PLAYING) {
+ playSoundUtil.loadSound("Ring10.wav", new MusicFinish() {
+ @Override
+ public void finish() {
+ mVisualizer.setVisualizationEnabled(false);
+ }
+ });
+ }
+ }
+ }).start();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ playSoundUtil.getAudioRenderer().stop();
+ }
+}
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/MusicStreamAbility.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/MusicStreamAbility.java
new file mode 100644
index 0000000..292611d
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/MusicStreamAbility.java
@@ -0,0 +1,118 @@
+package com.gauravk.audiovisualizersample.ui;
+
+import com.gauravk.audiovisualizer.visualizer.BlastVisualizer;
+import com.gauravk.audiovisualizersample.ResourceTable;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.*;
+import ohos.agp.utils.Color;
+import ohos.agp.utils.LayoutAlignment;
+import ohos.agp.window.dialog.CommonDialog;
+import ohos.agp.window.service.DisplayManager;
+import ohos.agp.window.service.WindowManager;
+import ohos.media.audio.AudioManager;
+import ohos.media.common.Source;
+import ohos.media.player.Player;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class MusicStreamAbility extends Ability {
+ private Image imgButton;
+ private BlastVisualizer mVisualizer;
+ private Player player = new Player(MusicStreamAbility.this);
+ private String stream = "http://stream.radioreklama.bg/radio1rock128";
+ private int progress = 0;
+ private Timer timer;
+ private CommonDialog toastDialog;
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_activity_music_stream);
+
+ WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.rgb(66, 119, 208));
+
+ mVisualizer = (BlastVisualizer) findComponentById(ResourceTable.Id_blast);
+ imgButton = (Image) findComponentById(ResourceTable.Id_playbtn);
+ imgButton.setPixelMap(ResourceTable.Media_play);
+ mVisualizer.setAudioSessionId(AudioManager.makeSessionId());
+ imgButton.setClickedListener(new Component.ClickedListener() {
+ @Override
+ public void onClick(Component component) {
+ if (player.isNowPlaying()) {
+ player.pause();
+ imgButton.setPixelMap(ResourceTable.Media_play);
+ } else {
+ player.play();
+ imgButton.setPixelMap(ResourceTable.Media_stop);
+ }
+ }
+ });
+ openDialog();
+ openNet();
+ }
+
+ private void openDialog() {
+ Component component = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_progress_layout, null, false);
+ RoundProgressBar bar = (RoundProgressBar) component.findComponentById(ResourceTable.Id_bar);
+ timer = new Timer();
+ timer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ bar.setProgressValue(progress);
+ progress += 10;
+ if (progress == 100) {
+ progress = 0;
+ }
+ }
+ }, 0, 100);
+ toastDialog = new CommonDialog(this);
+ toastDialog.setContentCustomComponent(component);
+ toastDialog.setAutoClosable(true);
+ toastDialog.setSize(DisplayManager.getInstance().getDefaultDisplay(this).get().getAttributes().width / 7 * 6,
+ DirectionalLayout.LayoutConfig.MATCH_CONTENT);
+ toastDialog.setAlignment(LayoutAlignment.CENTER);
+ toastDialog.show();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ player.stop();
+ }
+
+ private void openNet() {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ InputStream inputStream = null;
+ try {
+ URL url = new URL(stream);
+ HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+ inputStream = urlConnection.getInputStream();
+ Source source = new Source(stream);
+ player.setSource(source);
+ player.prepare();
+ timer.cancel();
+ toastDialog.remove();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }).start();
+ }
+}
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/WaveAbility.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/WaveAbility.java
new file mode 100644
index 0000000..8cb542e
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/ui/WaveAbility.java
@@ -0,0 +1,70 @@
+/*
+ Copyright 2018 Gaurav Kumar
+
+ 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.
+*/
+
+package com.gauravk.audiovisualizersample.ui;
+
+import com.gauravk.audiovisualizer.visualizer.WaveVisualizer;
+import com.gauravk.audiovisualizersample.ResourceTable;
+import com.gauravk.audiovisualizersample.util.MusicFinish;
+import com.gauravk.audiovisualizersample.util.PlaySoundUtil;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.utils.Color;
+import ohos.agp.window.service.WindowManager;
+import ohos.media.audio.AudioRenderer;
+
+public class WaveAbility extends Ability {
+ private WaveVisualizer mVisualizer;
+ private PlaySoundUtil playSoundUtil;
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_activity_wave);
+
+ WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.rgb(66, 119, 208));
+
+ playSoundUtil = new PlaySoundUtil();
+ mVisualizer = (WaveVisualizer) findComponentById(ResourceTable.Id_wave);
+ mVisualizer.setAudioSessionId(playSoundUtil.getAudioRenderer().getRendererSessionId());
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ if (playSoundUtil.getAudioRenderer().getState() != AudioRenderer.State.STATE_PLAYING) {
+ playSoundUtil.loadSound("Ring10.wav", new MusicFinish() {
+ @Override
+ public void finish() {
+ getUITaskDispatcher().syncDispatch(new Runnable() {
+ @Override
+ public void run() {
+ mVisualizer.setVisibility(Component.HIDE);
+ }
+ });
+ }
+ });
+ }
+ }
+ }).start();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ playSoundUtil.getAudioRenderer().stop();
+ }
+}
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/MusicFinish.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/MusicFinish.java
new file mode 100644
index 0000000..73ec2e2
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/MusicFinish.java
@@ -0,0 +1,8 @@
+package com.gauravk.audiovisualizersample.util;
+
+public interface MusicFinish {
+ /**
+ * 播放音频结束回调
+ */
+ void finish();
+}
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/PermissionUtils.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/PermissionUtils.java
new file mode 100644
index 0000000..9c9c091
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/PermissionUtils.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 The Chinese Software International 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.
+ *
+ */
+
+package com.gauravk.audiovisualizersample.util;
+
+/**
+ * PermissionUtils
+ *
+ * @since 2021-03-27
+ */
+public class PermissionUtils {
+ /**
+ * 麦克风权限
+ */
+ public static final String MICROPHONE = "ohos.permission.MICROPHONE";
+ /**
+ * 读取媒体资源权限
+ */
+ public static final String READ_MEDIA = "ohos.permission.READ_MEDIA";
+ /**
+ * 写入媒体资源权限
+ */
+ public static final String WRITE_MEDIA = "ohos.permission.WRITE_MEDIA";
+ /**
+ * 重置权限
+ */
+ public static final String RECORD_AUDIO = "ohos.permission.RECORD_AUDIO";
+
+ /**
+ * 权限号
+ */
+ public static final int PERMISSION_CODE = 0X000000;
+ /**
+ * 权限数组
+ */
+ public static String[] permission = {MICROPHONE, READ_MEDIA, WRITE_MEDIA,RECORD_AUDIO};
+}
\ No newline at end of file
diff --git a/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/PlaySoundUtil.java b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/PlaySoundUtil.java
new file mode 100644
index 0000000..a3084ea
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/java/com/gauravk/audiovisualizersample/util/PlaySoundUtil.java
@@ -0,0 +1,65 @@
+package com.gauravk.audiovisualizersample.util;
+
+import ohos.media.audio.*;
+
+import java.io.InputStream;
+
+public class PlaySoundUtil {
+ private final int SAMPLE_RATE = 192000;
+ private AudioStreamInfo audioStreamInfo = null;
+ private AudioRendererInfo audioRendererInfo = null;
+ private AudioRenderer.PlayMode playMode = AudioRenderer.PlayMode.MODE_STREAM;
+ private AudioRenderer audioRenderer = null;
+ private InputStream soundInputStream = null;
+
+ /**
+ * PlaySoundUtil构造方法 初始化音频播放器
+ */
+ public PlaySoundUtil() {
+ audioStreamInfo = new AudioStreamInfo.Builder().sampleRate(44100) // 44.1kHz
+ .audioStreamFlag(AudioStreamInfo.AudioStreamFlag.AUDIO_STREAM_FLAG_MAY_DUCK) // 混音
+ .encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT) // 16-bit PCM
+ .channelMask(AudioStreamInfo.ChannelMask.CHANNEL_OUT_DEFAULT) // 双声道输出
+ .streamUsage(AudioStreamInfo.StreamUsage.STREAM_USAGE_MEDIA) // 媒体类音频
+ .build();
+
+ audioRendererInfo = new AudioRendererInfo.Builder().audioStreamInfo(audioStreamInfo)
+ .audioStreamOutputFlag(
+ AudioRendererInfo.AudioStreamOutputFlag.AUDIO_STREAM_OUTPUT_FLAG_DIRECT_PCM) // pcm格式的输出流
+ .bufferSizeInBytes(1024)
+ .isOffload(false) // false表示分段传输buffer并播放,true表示整个音频流一次性传输到HAL层播放
+ .build();
+ audioRenderer = new AudioRenderer(audioRendererInfo, playMode);
+ }
+
+ /**
+ * 加载本地音频资源
+ *
+ * @param fileName
+ * @param musicFinish
+ */
+ public void loadSound(String fileName, MusicFinish musicFinish) {
+ String filePath = String.format("assets/entry/resources/rawfile/%s", fileName);
+ soundInputStream = this.getClass().getClassLoader().getResourceAsStream(filePath);
+
+ byte[] buffer = new byte[1024];
+ int len;
+ try {
+ audioRenderer.start();
+ while ((len = soundInputStream.read(buffer, 0, buffer.length)) != -1) {
+ audioRenderer.write(buffer, 0, buffer.length);
+ }
+ soundInputStream.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (audioRenderer.getState() == AudioRenderer.State.STATE_PLAYING) {
+ audioRenderer.pause();
+ }
+ musicFinish.finish();
+ }
+
+ public AudioRenderer getAudioRenderer() {
+ return this.audioRenderer;
+ }
+}
diff --git a/AudioVisualizerOhos/entry/src/main/resources/base/element/color.json b/AudioVisualizerOhos/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000..edcde0c
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/resources/base/element/color.json
@@ -0,0 +1,46 @@
+{
+ "color": [
+ {
+ "name": "colorPrimary",
+ "value": "#E6000000"
+ },
+ {
+ "name": "colorMainBtBgEmty",
+ "value": "#D6D7D7"
+ },
+ {
+ "name": "colorListDividerPressed",
+ "value": "#C2C4C4"
+ },
+ {
+ "name": "colorListHeadBackground",
+ "value": "#77787b"
+ },
+ {
+ "name": "white",
+ "value": "#ffffff"
+ },
+ {
+ "name": "colorPrimaryDark",
+ "value": "#303F9F"
+ },
+ {
+ "name": "colorAccent",
+ "value": "#FF4081"
+ },
+ {
+ "name": "black",
+ "value": "#000000"
+ },
+ {
+ "name": "green",
+ "value": "#45b97c"
+ },
+ {
+ "name": "brown",
+ "value": "#843900"
+ }
+
+
+ ]
+}
\ No newline at end of file
diff --git a/AudioVisualizerOhos/entry/src/main/resources/base/element/string.json b/AudioVisualizerOhos/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000..4903083
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,24 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "AudioVisualizerAndroid"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "HelloWorld",
+ "value": "Hello World"
+ },
+ {
+ "name": "testability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "HelloWorld",
+ "value": "Hello World"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/AudioVisualizerOhos/entry/src/main/resources/base/graphic/background_ability_main.xml b/AudioVisualizerOhos/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000..c0c0a3d
--- /dev/null
+++ b/AudioVisualizerOhos/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,6 @@
+
+ +0mW+vVG4mxd(n$(eQf3-w>JPl2UJpafrPaL5@2j}%{VE-)
zBI%6Qpj*dsdH<;g!S!avA~bv^0E+
zfyJbSjPb+j;J52U)<|cIcntQBI2T#>2;tOxu{%D?kML476AErF(qN9hPva5Nkc@BF
zC-tLF@3ZFb%Kpj)M<{)x*l|*Ia@ECeXo2E4h2f!aV=cHAhi_E_mfUth(sM4^hJq7B
zQsGWqdZUm9 LA
zdF-7-^JkMCF6~>Yr)*bd+L#sY83Q?Xzp6j8XPy+xwr&PppXGl?%QWG{l*gXa;6TyR
zA2bDoPtox~liTR5TSJ6um#(VCzVn{VMrN{U_3V$^m!h;Wk7m4o+J0&YrrIphC`^0@
zAmuT>NB77uz7V!Y{5;i&@6+QrRXg&tozBkF9QH`xGboedah`{-fN^rayg}bOBZq(R
z2mOB^ hPwL`@1w8edq1ZURR{24=lNzA(dHcp#STJxlymF*vh@f~fDAkaz63s+
z9s0o(ID7eiJNE|v-TITm0a3UX=<|c)Mmzq@B(dV?tM*s!w;+i3eO8KSuXj$CIT)Yz
zghiWF)#jiq8OzZhZv`XOj4x|XgI_GNY_G;UuVFqi^OEMToIU*B4zke9r;zWmFlB#Y
zRM#jP@2mVPtzmR%4mjBKKC0`$GrybHtRWuEB@cevDy&*$))idUYBMELZKiv3M#d=;
zWQ<2*Hpv}|?78wV{XmtX;ne6DA$Ki7Omsha6?miCD@hfgNX43Fz@N?cG5z%Js)Wb&5u#NFEYJX34+?ooZ9QO-hxKdmXrjwMZMa#ir&VS-qxbx=C0cIy50eY<`I+o
zLq5Md^PPanzVc1cm{t3r`)uWx8
mO%@AJb4Ze>=R#1dRBeR*1tQaUG+5VhpTI$lTKq3c3s+_r@_aM{P7L#
zK^NMiH>F2Pj_NPwtnv>P@?|6e>Dck&kpN0}K-@n_xI3RAxxX=bfaMrJ>j*f&pyz1{
zo+HTOpH1QZ>GO|3m56lbd7X}S&k8|rj}zUU<+CI@tY&A;)`^R|hhIN`Lo24oP3~gZ
zgAOT$Uo1Ygzj(O6CDb5VXEG74T^zrKHGMP)5Gt{*oD$2%!LfV|phnTV9JM4>=ozjg
zSxE5eOlofg5+;Ve$}wYS%~9%PU_3{hxGK*@p*NN=+BeivQQ)1ICoik1eit@6H{>tP
z(dCEjKHPY0RNT6)op-ln?VBt3vCP!`lL9?nKa~j>D2Fj>jQyPw{Td?_ab2Y
oECvyfz`Ha*
z;-N
RMK+HgWMr3mQ@k%P`lbp#zxWVn0FnX<1NNh$a5VyrYK5Bz%z6Yf0|
zUzr)DrOuIWM_jaYC(!-eLIvg0F2~nT9Cb|1K