1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <iostream>
17 #include <cstdint>
18 #include <cstdio>
19 #include <cstring>
20 #include <thread>
21 #include <chrono>
22 #include <ctime>
23 #include <cinttypes>
24 #include "common/native_audiostreambuilder.h"
25 #include "native_audiorenderer.h"
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 namespace AudioTestConstants {
31 constexpr int32_t FIRST_ARG_IDX = 1;
32 constexpr int32_t SECOND_ARG_IDX = 2;
33 constexpr int32_t THIRD_ARG_IDX = 3;
34 constexpr int32_t FOUR_ARG_IDX = 4;
35 constexpr int32_t FIFTH_ARG_IDX = 5;
36 constexpr int32_t SIXTH_ARG_IDX = 6;
37 constexpr int32_t SEVEN_ARG_IDX = 7;
38 constexpr int32_t WAIT_INTERVAL = 1000;
39 }
40
41 std::string g_filePath = "/data/data/oh_test_audio.pcm";
42 FILE* g_file = nullptr;
43 bool g_readEnd = false;
44 int32_t g_samplingRate = 48000;
45 int32_t g_channelCount = 2;
46 int32_t g_latencyMode = 0;
47 int32_t g_sampleFormat = 1;
48 int32_t g_frameSize = 240;
49 float g_speed = 1.0f;
50
AudioRendererOnWriteData(OH_AudioRenderer * capturer,void * userData,void * buffer,int32_t bufferLen)51 static int32_t AudioRendererOnWriteData(OH_AudioRenderer* capturer,
52 void* userData,
53 void* buffer,
54 int32_t bufferLen)
55 {
56 size_t readCount = fread(buffer, bufferLen, 1, g_file);
57 if (!readCount) {
58 if (ferror(g_file)) {
59 printf("Error reading myfile");
60 } else if (feof(g_file)) {
61 printf("EOF found");
62 g_readEnd = true;
63 }
64 }
65
66 return 0;
67 }
68
AudioErrCallback(OH_AudioRenderer * renderer,void * userData,OH_AudioStream_Result error)69 static int32_t AudioErrCallback(OH_AudioRenderer* renderer,
70 void* userData,
71 OH_AudioStream_Result error)
72 {
73 printf("recv err : code %d \n", error);
74 return 0;
75 }
76
AudioInterruptCallback(OH_AudioRenderer * renderer,void * userData,OH_AudioInterrupt_ForceType type,OH_AudioInterrupt_Hint hint)77 static int32_t AudioInterruptCallback(OH_AudioRenderer* renderer,
78 void* userData,
79 OH_AudioInterrupt_ForceType type,
80 OH_AudioInterrupt_Hint hint)
81 {
82 printf("recv interrupt event : type: %d hint: %d \n", type, hint);
83 return 0;
84 }
85
AudioEventCallback(OH_AudioRenderer * renderer,void * userData,OH_AudioStream_Event event)86 static int32_t AudioEventCallback(OH_AudioRenderer* renderer,
87 void* userData,
88 OH_AudioStream_Event event)
89 {
90 printf("recv event : event: %d \n", event);
91 return 0;
92 }
93
AudioRendererDeviceChangeCb(OH_AudioRenderer * renderer,void * userData,OH_AudioStream_DeviceChangeReason reason)94 static void AudioRendererDeviceChangeCb(OH_AudioRenderer* renderer, void* userData,
95 OH_AudioStream_DeviceChangeReason reason)
96 {
97 printf("AudioRendererDeviceChangeCb reason: %d \n", reason);
98 }
99
PlayerTest(char * argv[])100 void PlayerTest(char *argv[])
101 {
102 OH_AudioStream_Result ret;
103
104 // 1. create builder
105 OH_AudioStreamBuilder* builder;
106 OH_AudioStream_Type type = AUDIOSTREAM_TYPE_RENDERER;
107 ret = OH_AudioStreamBuilder_Create(&builder, type);
108 printf("createcallback ret: %d \n", ret);
109
110 // 2. set params and callbacks
111 OH_AudioStreamBuilder_SetSamplingRate(builder, g_samplingRate);
112 OH_AudioStreamBuilder_SetChannelCount(builder, g_channelCount);
113 OH_AudioStreamBuilder_SetLatencyMode(builder, (OH_AudioStream_LatencyMode)g_latencyMode);
114 OH_AudioStreamBuilder_SetSampleFormat(builder, (OH_AudioStream_SampleFormat)g_sampleFormat);
115
116 OH_AudioRenderer_Callbacks callbacks;
117 callbacks.OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData;
118 callbacks.OH_AudioRenderer_OnError = AudioErrCallback;
119 callbacks.OH_AudioRenderer_OnInterruptEvent = AudioInterruptCallback;
120 callbacks.OH_AudioRenderer_OnStreamEvent = AudioEventCallback;
121 ret = OH_AudioStreamBuilder_SetRendererCallback(builder, callbacks, nullptr);
122 printf("setcallback ret: %d \n", ret);
123
124 OH_AudioRenderer_OutputDeviceChangeCallback deviceChangeCb = AudioRendererDeviceChangeCb;
125 ret = OH_AudioStreamBuilder_SetRendererOutputDeviceChangeCallback(builder, deviceChangeCb, nullptr);
126 printf("set device change callback ret: %d \n", ret);
127
128 // set buffer size to g_frameSize
129 ret = OH_AudioStreamBuilder_SetFrameSizeInCallback(builder, g_frameSize);
130 printf("set buffer size, ret: %d \n", ret);
131
132 // 3. create OH_AudioRenderer
133 OH_AudioRenderer* audioRenderer;
134 ret = OH_AudioStreamBuilder_GenerateRenderer(builder, &audioRenderer);
135 printf("create renderer client, ret: %d \n", ret);
136
137 // 4. setspeed
138 ret = OH_AudioRenderer_SetSpeed(audioRenderer, g_speed);
139 printf("speed ret: %d \n", ret);
140 // 5. start
141 ret = OH_AudioRenderer_Start(audioRenderer);
142 printf("start ret: %d \n", ret);
143 int32_t frameSize;
144 OH_AudioRenderer_GetFrameSizeInCallback(audioRenderer, &frameSize);
145 printf("framesize: %d \n", frameSize);
146
147 int timer = 0;
148 while (!g_readEnd) {
149 std::this_thread::sleep_for(std::chrono::milliseconds(AudioTestConstants::WAIT_INTERVAL));
150 int64_t frames;
151 OH_AudioRenderer_GetFramesWritten(audioRenderer, &frames);
152 printf("Wait for the audio to finish playing.(..%d s) frames:%" PRId64 "\n", ++timer, frames);
153 int64_t framePosition;
154 int64_t timestamp;
155 OH_AudioRenderer_GetTimestamp(audioRenderer, CLOCK_MONOTONIC, &framePosition, ×tamp);
156 printf("framePosition %" PRId64 " timestamp:%" PRId64 "\n", framePosition, timestamp);
157 }
158 // 6. stop and release client
159 ret = OH_AudioRenderer_Stop(audioRenderer);
160 printf("stop ret: %d \n", ret);
161 ret = OH_AudioRenderer_Release(audioRenderer);
162 printf("release ret: %d \n", ret);
163
164 // 7. destroy the builder
165 ret = OH_AudioStreamBuilder_Destroy(builder);
166 printf("destroy builder ret: %d \n", ret);
167 }
168
main(int argc,char * argv[])169 int main(int argc, char *argv[])
170 {
171 printf("start \n");
172 if ((argv == nullptr) || (argc < AudioTestConstants::SIXTH_ARG_IDX)) {
173 printf("input parms wrong. input format: filePath samplingRate channelCount latencyMode\n");
174 printf("input demo: ./oh_audio_renderer_test ./oh_test_audio.pcm 48000 2 1 1 800 1\n");
175 return 0;
176 }
177 printf("argc=%d ", argc);
178 printf("file path =%s ", argv[AudioTestConstants::FIRST_ARG_IDX]);
179 printf("sample rate =%s ", argv[AudioTestConstants::SECOND_ARG_IDX]);
180 printf("channel count =%s \n", argv[AudioTestConstants::THIRD_ARG_IDX]);
181 printf("latency mode =%s \n", argv[AudioTestConstants::FOUR_ARG_IDX]);
182 printf("sample Format = %s \n", argv[AudioTestConstants::FIFTH_ARG_IDX]);
183 printf("buffer size = %s \n", argv[AudioTestConstants::SIXTH_ARG_IDX]);
184 printf("speed = %s \n", argv[AudioTestConstants::SEVEN_ARG_IDX]);
185
186 g_filePath = argv[AudioTestConstants::FIRST_ARG_IDX];
187 g_samplingRate = atoi(argv[AudioTestConstants::SECOND_ARG_IDX]);
188 g_channelCount = atoi(argv[AudioTestConstants::THIRD_ARG_IDX]);
189 g_latencyMode = atoi(argv[AudioTestConstants::FOUR_ARG_IDX]);
190 g_sampleFormat = atoi(argv[AudioTestConstants::FIFTH_ARG_IDX]);
191 g_frameSize = atoi(argv[AudioTestConstants::SIXTH_ARG_IDX]);
192 g_speed = atof(argv[AudioTestConstants::SEVEN_ARG_IDX]);
193
194 printf("filePATH: %s \n", g_filePath.c_str());
195
196 g_file = fopen(g_filePath.c_str(), "rb");
197 if (g_file == nullptr) {
198 printf("OHAudioRendererTest: Unable to open file \n");
199 return 0;
200 }
201
202 PlayerTest(argv);
203
204 fclose(g_file);
205 g_file = nullptr;
206 return 0;
207 }
208
209 #ifdef __cplusplus
210 }
211 #endif
212