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, &timestamp);
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