• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 <dlfcn.h>
17 #include <limits.h>
18 #include <pthread.h>
19 #include <securec.h>
20 #include <signal.h>
21 #include <string.h>
22 #include <sys/mman.h>
23 #include <unistd.h>
24 #include "hdf_base.h"
25 #include "inttypes.h"
26 #include "audio_manager.h"
27 #include "framework_common.h"
28 
29 #define BUFFER_LEN 256
30 #define ID_RIFF 0x46464952
31 #define ID_WAVE 0x45564157
32 #define ID_FMT  0x20746d66
33 #define ID_DATA 0x61746164
34 #define AUDIO_SAMPLE_RATE_8K 8000
35 #define AUDIO_CHANNELCOUNT 2
36 #define AUDIO_SAMPLE_RATE_48K 48000
37 #define PATH_LEN 256
38 #define DEEP_BUFFER_RENDER_PERIOD_SIZE 1024
39 #define DEEP_BUFFER_RENDER_PERIOD_COUNT 8
40 #define INT_32_MAX 0x7fffffff
41 #define PERIOD_SIZE 1024
42 #define ATTR_PERIOD_MIN 2048
43 #define EXT_PARAMS_MAXLEN 107
44 #define BITS_TO_FROMAT 3
45 
46 enum RenderSoundCardMode {
47     PRIMARY = 1,
48     PRIMARY_EXT = 2,
49     AUDIO_USB = 3,
50     AUDIO_A2DP = 4,
51 };
52 
53 struct StrPara {
54     struct AudioRender *render;
55     FILE *file;
56     struct AudioSampleAttributes attrs;
57     uint64_t *replyBytes;
58     char *frame;
59     int32_t bufferSize;
60 };
61 
62 struct AudioRender *g_render = NULL;
63 struct AudioAdapter *g_adapter = NULL;
64 struct AudioManager *g_manager = NULL;
65 struct AudioDeviceDescriptor g_devDesc;
66 struct AudioSampleAttributes g_attrs;
67 struct AudioPort g_audioPort;
68 struct AudioHeadInfo g_wavHeadInfo;
69 static struct StrPara g_str;
70 static int32_t g_audioRouteHandle;
71 
72 pthread_t g_tids;
73 char *g_frame = NULL;
74 void *g_handle;
75 FILE *g_file;
76 
77 char g_path[256];
78 static int32_t g_closeEnd = 0;
79 pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
80 pthread_cond_t g_functionCond = PTHREAD_COND_INITIALIZER;
81 bool g_waitSleep = false;
82 enum RenderMenuId {
83     RENDER_START = 1,
84     RENDER_STOP,
85     RENDER_RESUME,
86     RENDER_PAUSE,
87     SET_RENDER_VOLUME,
88     SET_RENDER_GAIN,
89     SET_RENDER_MUTE,
90     SET_RENDER_ATTRIBUTES,
91     SET_RENDER_SLECET_SCENE,
92     GET_RENDER_EXT_PARAMS,
93     GET_RENDER_POSITION,
94 };
95 
96 enum RenderInputType {
97     INPUT_INT = 0,
98     INPUT_FLOAT,
99     INPUT_UINT32,
100 };
101 
102 typedef int32_t (*AudioRenderOperation)(struct AudioRender **);
103 
104 struct ProcessRenderMenuSwitchList {
105     enum RenderMenuId cmd;
106     AudioRenderOperation operation;
107 };
108 
CheckInputName(int type,void * val)109 static int32_t CheckInputName(int type, void *val)
110 {
111     int ret;
112     int renderInputInt = 0;
113     float renderInputFloat = 0.0;
114     uint32_t renderInputUint = 0;
115     if (val == NULL) {
116         return HDF_FAILURE;
117     }
118     printf("\n");
119     switch (type) {
120         case INPUT_INT:
121             ret = scanf_s("%d", &renderInputInt);
122             if (renderInputInt < 0 || renderInputInt > GET_RENDER_POSITION + 1) {
123                 AUDIO_FUNC_LOGE("Input failure");
124                 return HDF_FAILURE;
125             }
126             *(int *)val = renderInputInt;
127             break;
128         case INPUT_FLOAT:
129             ret = scanf_s("%f", &renderInputFloat);
130             *(float *)val = renderInputFloat;
131             break;
132         case INPUT_UINT32:
133             ret = scanf_s("%u", &renderInputUint);
134             if (renderInputUint > 0xFFFFFFFF) {
135                 return HDF_FAILURE;
136             }
137             *(uint32_t *)val = renderInputUint;
138             break;
139         default:
140             ret = EOF;
141             break;
142     }
143     if (ret == 0) {
144         CleanStdin();
145     } else if (ret == EOF) {
146         AUDIO_FUNC_LOGE("Input error occurs!");
147         return HDF_FAILURE;
148     }
149     return HDF_SUCCESS;
150 }
151 
InitAttrs(struct AudioSampleAttributes * renderAttrs)152 static int32_t InitAttrs(struct AudioSampleAttributes *renderAttrs)
153 {
154     if (renderAttrs == NULL) {
155         return HDF_FAILURE;
156     }
157     /* Initialization of audio parameters for playback */
158     renderAttrs->format = AUDIO_FORMAT_PCM_16_BIT;
159     renderAttrs->channelCount = AUDIO_CHANNELCOUNT;
160     renderAttrs->sampleRate = AUDIO_SAMPLE_RATE_48K;
161     renderAttrs->interleaved = 1;
162     renderAttrs->type = AUDIO_IN_MEDIA;
163     renderAttrs->period = ATTR_PERIOD_MIN;
164     renderAttrs->frameSize = PCM_16_BIT * renderAttrs->channelCount / PCM_8_BIT;
165     renderAttrs->isBigEndian = false;
166     renderAttrs->isSignedData = true;
167     renderAttrs->startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (renderAttrs->frameSize);
168     renderAttrs->stopThreshold = INT_32_MAX;
169     renderAttrs->silenceThreshold = 0;
170     renderAttrs->streamId = 0;
171     return HDF_SUCCESS;
172 }
173 
InitDevDesc(struct AudioDeviceDescriptor * devDesc,uint32_t portId)174 static int32_t InitDevDesc(struct AudioDeviceDescriptor *devDesc, uint32_t portId)
175 {
176     if (devDesc == NULL) {
177         return HDF_FAILURE;
178     }
179     /* Initialization of audio parameters for playback */
180     devDesc->portId = portId;
181     devDesc->pins = PIN_OUT_SPEAKER;
182     devDesc->desc = NULL;
183     return HDF_SUCCESS;
184 }
185 
WavHeadAnalysis(FILE * file,struct AudioSampleAttributes * attrs)186 static int32_t WavHeadAnalysis(FILE *file, struct AudioSampleAttributes *attrs)
187 {
188     if (file == NULL || attrs == NULL) {
189         printf("params is null\n");
190         return HDF_FAILURE;
191     }
192     size_t ret;
193     const char *audioRiffIdParam = "RIFF";
194     const char *audioFileFmtParam = "WAVE";
195     const char *aduioDataIdParam = "data";
196     ret = fread(&g_wavHeadInfo, sizeof(g_wavHeadInfo), 1, file);
197     if (ret != 1) {
198         return HDF_FAILURE;
199     }
200     uint32_t audioRiffId = StringToInt(audioRiffIdParam);
201     uint32_t audioFileFmt = StringToInt(audioFileFmtParam);
202     uint32_t aduioDataId = StringToInt(aduioDataIdParam);
203     if (g_wavHeadInfo.riffId != audioRiffId || g_wavHeadInfo.waveType != audioFileFmt ||
204         g_wavHeadInfo.dataId != aduioDataId) {
205         printf("audio format error \n");
206         return HDF_FAILURE;
207         }
208     attrs->channelCount = g_wavHeadInfo.audioChannelNum;
209     attrs->sampleRate = g_wavHeadInfo.audioSampleRate;
210     switch (g_wavHeadInfo.audioBitsPerSample) {
211         case PCM_8_BIT: {
212             attrs->format = AUDIO_FORMAT_PCM_8_BIT;
213             break;
214         }
215         case PCM_16_BIT: {
216             attrs->format = AUDIO_FORMAT_PCM_16_BIT;
217             break;
218         }
219         case PCM_24_BIT: {
220             attrs->format = AUDIO_FORMAT_PCM_24_BIT;
221             break;
222         }
223         case PCM_32_BIT: {
224             attrs->format = AUDIO_FORMAT_PCM_32_BIT;
225             break;
226         }
227         default:
228             printf("nonsupport audio format %d\n", g_wavHeadInfo.audioBitsPerSample);
229             return HDF_FAILURE;
230     }
231     return HDF_SUCCESS;
232 }
233 
SwitchAdapter(struct AudioAdapterDescriptor * descs,const char * adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort * renderPort,int32_t size)234 static int32_t SwitchAdapter(struct AudioAdapterDescriptor *descs,
235     const char *adapterNameCase, enum AudioPortDirection portFlag,
236     struct AudioPort *renderPort, int32_t size)
237 {
238     struct AudioAdapterDescriptor *desc = NULL;
239     if (descs == NULL || adapterNameCase == NULL || renderPort == NULL) {
240         return HDF_FAILURE;
241     }
242     uint32_t port;
243     for (int32_t index = 0; index < size; index++) {
244         desc = &descs[index];
245         if (desc == NULL) {
246             continue;
247         }
248         if (desc->adapterName == NULL) {
249             return HDF_FAILURE;
250         }
251         if (strcmp(desc->adapterName, adapterNameCase)) {
252             continue;
253         }
254         for (port = 0; port < desc->portNum; port++) {
255             // Only find out the port of out in the sound card
256             if (desc->ports[port].dir == portFlag) {
257                 *renderPort = desc->ports[port];
258                 return index;
259             }
260         }
261     }
262     return HDF_ERR_NOT_SUPPORT;
263 }
264 
PcmFramesToBytes(const struct AudioSampleAttributes attrs)265 static uint32_t PcmFramesToBytes(const struct AudioSampleAttributes attrs)
266 {
267     return DEEP_BUFFER_RENDER_PERIOD_SIZE * attrs.channelCount * (PcmFormatToBits(attrs.format) >> BITS_TO_FROMAT);
268 }
269 
StopAudioFiles(struct AudioRender ** renderS)270 static int32_t StopAudioFiles(struct AudioRender **renderS)
271 {
272     if (renderS == NULL) {
273         return HDF_FAILURE;
274     }
275     if (g_waitSleep) {
276         pthread_mutex_lock(&g_mutex);
277         g_waitSleep = false;
278         pthread_cond_signal(&g_functionCond);
279         pthread_mutex_unlock(&g_mutex);
280     }
281     if (!g_closeEnd) {
282         g_closeEnd = true;
283         usleep(100000); // sleep 100000us
284     }
285     struct AudioRender *render = *renderS;
286     if (render == NULL) {
287         AUDIO_FUNC_LOGE("render is null");
288         return HDF_FAILURE;
289     }
290     int32_t ret = render->control.Stop((AudioHandle)render);
291     if (ret < 0) {
292         AUDIO_FUNC_LOGE("Stop Render!");
293     }
294     if (g_adapter == NULL || g_adapter->DestroyRender == NULL) {
295         return HDF_FAILURE;
296     }
297     ret = g_adapter->DestroyRender(g_adapter, render);
298     if (ret < 0) {
299         AUDIO_FUNC_LOGE("Destroy Render!");
300     }
301     render = NULL;
302     g_render = NULL;
303     if (g_frame != NULL) {
304         free(g_frame);
305         g_frame = NULL;
306     }
307     FileClose(&g_file);
308     printf("Stop Successful\n");
309     return ret;
310 }
311 
PrepareStopAndUnloadAdapter(void)312 static bool PrepareStopAndUnloadAdapter(void)
313 {
314     bool soMode = false;
315 
316     if (g_render != NULL && g_adapter != NULL) {
317         StopAudioFiles(&g_render);
318     }
319 
320     if (g_manager != NULL) {
321         soMode = true;
322         if (g_manager->UnloadAdapter != NULL) {
323             g_manager->UnloadAdapter(g_manager, g_adapter);
324         }
325     }
326 
327     return soMode;
328 }
329 
StopRenderBySig(int32_t sig)330 static void StopRenderBySig(int32_t sig)
331 {
332     (void)PrepareStopAndUnloadAdapter();
333     dlclose(g_handle);
334     g_closeEnd = 1;
335 
336     (void)signal(sig, SIG_DFL);
337     return;
338 }
ProcessCommonSig(void)339 static inline void ProcessCommonSig(void)
340 {
341     (void)signal(SIGKILL, StopRenderBySig);
342     (void)signal(SIGINT, StopRenderBySig);
343     (void)signal(SIGTERM, StopRenderBySig);
344     return;
345 }
346 
MmapInitFile(FILE ** fp)347 static int32_t MmapInitFile(FILE **fp)
348 {
349     if (fp == NULL) {
350         return HDF_FAILURE;
351     }
352     char pathBuf[PATH_MAX] = {'\0'};
353     if (realpath(g_path, pathBuf) == NULL) {
354         return HDF_FAILURE;
355     }
356     *fp = fopen(pathBuf, "rb+");
357     if (*fp == NULL) {
358         printf("Open file failed!\n");
359         return HDF_FAILURE;
360     }
361     int32_t ret = fseek(*fp, 0, SEEK_END);
362     if (ret != 0) {
363         return HDF_FAILURE;
364     }
365     return HDF_SUCCESS;
366 }
367 
FrameStartMmap(const AudioHandle param)368 static int32_t FrameStartMmap(const AudioHandle param)
369 {
370     if (param == NULL) {
371         return HDF_FAILURE;
372     }
373     struct StrPara *strParam = (struct StrPara *)param;
374     struct AudioRender *render = strParam->render;
375     struct AudioMmapBufferDescripter desc;
376     ProcessCommonSig();
377     // get file length
378     FILE *fp = NULL;
379     if (MmapInitFile(&fp) < 0) {
380         if (fp != NULL) {
381             (void)fclose(fp);
382             return HDF_FAILURE;
383         }
384     }
385     int32_t reqSize = (int32_t)ftell(fp);
386     if (reqSize == -1) {
387         (void)fclose(fp);
388         return HDF_FAILURE;
389     }
390     // Converts a file pointer to a device descriptor
391     int fd = fileno(fp);
392     if (fd == -1) {
393         printf("fileno failed, fd is %d\n", fd);
394         (void)fclose(fp);
395         return HDF_FAILURE;
396     }
397     // Init param
398     desc.memoryFd = fd;
399     desc.isShareable = 1; // 1:Shareable ,0:Don't share
400     desc.transferFrameSize = DEEP_BUFFER_RENDER_PERIOD_SIZE / 4; // One frame size 4 bit
401     desc.offset = sizeof(g_wavHeadInfo);
402     // start
403     if (render == NULL || render->attr.ReqMmapBuffer == NULL) {
404         (void)fclose(fp);
405         return HDF_FAILURE;
406     }
407     int32_t ret = render->attr.ReqMmapBuffer(render, reqSize, &desc);
408     if (ret < 0 || reqSize <= 0) {
409         printf("Request map fail,please check.\n");
410         (void)fclose(fp);
411         return HDF_FAILURE;
412     }
413     munmap(desc.memoryAddress, reqSize);
414     (void)fclose(fp);
415     if (g_render != NULL) {
416         ret = StopAudioFiles(&render);
417         if (ret < 0) {
418             AUDIO_FUNC_LOGE("StopAudioFiles File!");
419         }
420     }
421     return HDF_SUCCESS;
422 }
423 
FrameStart(const AudioHandle param)424 static int32_t FrameStart(const AudioHandle param)
425 {
426     if (param == NULL) {
427         return HDF_FAILURE;
428     }
429     struct StrPara *strParam = (struct StrPara *)param;
430     struct AudioRender *render = strParam->render;
431     char *frame = strParam->frame;
432     int32_t bufferSize = strParam->bufferSize;
433     int32_t ret;
434     size_t readSize;
435     int32_t remainingDataSize = (int32_t)g_wavHeadInfo.riffSize;
436     size_t numRead;
437     ProcessCommonSig();
438     uint64_t replyBytes;
439     if (g_file == NULL) {
440         return HDF_FAILURE;
441     }
442     if (render == NULL || render->RenderFrame == NULL || frame == NULL) {
443         return HDF_FAILURE;
444     }
445     do {
446         readSize = (size_t)((remainingDataSize > bufferSize) ? bufferSize : remainingDataSize);
447         numRead = fread(frame, 1, readSize, g_file);
448         if (numRead > 0) {
449             ret = render->RenderFrame(render, frame, numRead, &replyBytes);
450             if (ret == HDF_ERR_INVALID_OBJECT) {
451                 AUDIO_FUNC_LOGE("Render already stop!");
452                 break;
453             }
454             remainingDataSize -= (int32_t)numRead;
455         }
456         while (g_waitSleep) {
457             printf("music pause now.\n");
458             pthread_cond_wait(&g_functionCond, &g_mutex);
459             printf("music resume now.\n");
460         }
461     } while (!g_closeEnd && numRead > 0 && remainingDataSize > 0);
462     if (!g_closeEnd) {
463         printf("\nPlay complete, please select input again\n");
464         (void)StopAudioFiles(&render);
465     }
466     return HDF_SUCCESS;
467 }
468 
InitPlayingAudioParam(struct AudioRender * render)469 static int32_t InitPlayingAudioParam(struct AudioRender *render)
470 {
471     if (render == NULL) {
472         return HDF_FAILURE;
473     }
474     uint32_t bufferSize = PcmFramesToBytes(g_attrs);
475     g_frame = (char *)calloc(1, bufferSize);
476     if (g_frame == NULL) {
477         return HDF_FAILURE;
478     }
479     (void)memset_s(&g_str, sizeof(struct StrPara), 0, sizeof(struct StrPara));
480     g_str.render = render;
481     g_str.bufferSize = (int32_t)bufferSize;
482     g_str.frame = g_frame;
483     return HDF_SUCCESS;
484 }
485 
PrintPlayMode(void)486 static void PrintPlayMode(void)
487 {
488     printf(" ============= Play Render Mode ==========\n");
489     printf("| 1. Render non-mmap                     |\n");
490     printf("| 2. Render mmap                         |\n");
491     printf(" ======================================== \n");
492 }
493 
SelectPlayMode(int32_t * palyModeFlag)494 static int32_t SelectPlayMode(int32_t *palyModeFlag)
495 {
496     if (palyModeFlag == NULL) {
497         AUDIO_FUNC_LOGE("palyModeFlag is null");
498         return HDF_FAILURE;
499     }
500     system("clear");
501     int choice = 0;
502     PrintPlayMode();
503     printf("Please enter your choice:");
504     int32_t ret = CheckInputName(INPUT_INT, (void *)&choice);
505     if (ret < 0) {
506         AUDIO_FUNC_LOGE("CheckInputName Fail");
507         return HDF_FAILURE;
508     } else {
509         *palyModeFlag = choice;
510     }
511     return HDF_SUCCESS;
512 }
513 
StartPlayThread(int32_t palyModeFlag)514 static int32_t StartPlayThread(int32_t palyModeFlag)
515 {
516     pthread_attr_t tidsAttr;
517     pthread_attr_init(&tidsAttr);
518     pthread_attr_setdetachstate(&tidsAttr, PTHREAD_CREATE_DETACHED);
519     switch (palyModeFlag) {
520         case 1: // 1. Stander Loading
521             if (pthread_create(&g_tids, &tidsAttr, (void *)(&FrameStart), &g_str) != 0) {
522                 AUDIO_FUNC_LOGE("Create Thread Fail");
523                 return HDF_FAILURE;
524             }
525             break;
526         case 2: // 2. Low latency Loading
527             if (pthread_create(&g_tids, &tidsAttr, (void *)(&FrameStartMmap), &g_str) != 0) {
528                 AUDIO_FUNC_LOGE("Create Thread Fail");
529                 return HDF_FAILURE;
530             }
531             break;
532         default:
533             printf("Input error,Switched to non-mmap Mode for you,");
534             SystemInputFail();
535             if (pthread_create(&g_tids, &tidsAttr, (void *)(&FrameStart), &g_str) != 0) {
536                 AUDIO_FUNC_LOGE("Create Thread Fail");
537                 return HDF_FAILURE;
538             }
539             break;
540     }
541     return HDF_SUCCESS;
542 }
PlayingAudioInitFile(void)543 static int32_t PlayingAudioInitFile(void)
544 {
545     if (g_file != NULL) {
546         AUDIO_FUNC_LOGE("the music is playing,please stop first");
547         return HDF_FAILURE;
548     }
549     g_closeEnd = false;
550     char pathBuf[PATH_MAX] = {'\0'};
551     if (realpath(g_path, pathBuf) == NULL) {
552         return HDF_FAILURE;
553     }
554     g_file = fopen(pathBuf, "rb");
555     if (g_file == NULL) {
556         printf("failed to open '%s'\n", g_path);
557         return HDF_FAILURE;
558     }
559     if (WavHeadAnalysis(g_file, &g_attrs) < 0) {
560         AUDIO_FUNC_LOGE("Frame test is Fail");
561         FileClose(&g_file);
562         return HDF_FAILURE;
563     }
564     return HDF_SUCCESS;
565 }
BindRouteToRender(int32_t streamid,enum AudioPortPin outputDevice)566 static int32_t BindRouteToRender(int32_t streamid, enum AudioPortPin outputDevice)
567 {
568     struct AudioRouteNode source = {
569         .portId = 0,
570         .role = AUDIO_PORT_SOURCE_ROLE,
571         .type = AUDIO_PORT_MIX_TYPE,
572         .ext.mix.moduleId = 0,
573         .ext.mix.streamId = streamid,
574     };
575 
576     struct AudioRouteNode sink = {
577         .portId = 0,
578         .role = AUDIO_PORT_SINK_ROLE,
579         .type = AUDIO_PORT_DEVICE_TYPE,
580         .ext.device.moduleId = 0,
581         .ext.device.type = outputDevice,
582         .ext.device.desc = "pin_out_speaker",
583     };
584 
585     struct AudioRoute route = {
586         .sourcesNum = 1,
587         .sources = &source,
588         .sinksNum = 1,
589         .sinks = &sink,
590     };
591 
592     return g_adapter->UpdateAudioRoute(g_adapter, &route, &g_audioRouteHandle);
593 }
PlayingAudioFiles(struct AudioRender ** renderS)594 static int32_t PlayingAudioFiles(struct AudioRender **renderS)
595 {
596     if (renderS == NULL || g_adapter == NULL || g_adapter->CreateRender == NULL) {
597         return HDF_FAILURE;
598     }
599     if (PlayingAudioInitFile() < 0) {
600         AUDIO_FUNC_LOGE("PlayingAudioInitFile Fail");
601         return HDF_FAILURE;
602     }
603     int32_t palyModeFlag = 0;
604     if (SelectPlayMode(&palyModeFlag) < 0) {
605         AUDIO_FUNC_LOGE("SelectPlayMode Fail");
606         FileClose(&g_file);
607         return HDF_FAILURE;
608     }
609     struct AudioRender *render = NULL;
610     int32_t ret = g_adapter->CreateRender(g_adapter, &g_devDesc, &g_attrs, &render);
611     if (render == NULL || ret < 0 || render->RenderFrame == NULL) {
612         AUDIO_FUNC_LOGE("AudioDeviceCreateRender failed or RenderFrame is null");
613         FileClose(&g_file);
614         return HDF_FAILURE;
615     }
616 
617     (void)BindRouteToRender(g_attrs.streamId, g_devDesc.pins);
618     // Playing audio files
619     if (render->control.Start((AudioHandle)render)) {
620         AUDIO_FUNC_LOGE("Start Bind Fail!");
621         FileClose(&g_file);
622         return HDF_FAILURE;
623     }
624     if (InitPlayingAudioParam(render) < 0) {
625         AUDIO_FUNC_LOGE("InitPlayingAudioParam Fail");
626         FileClose(&g_file);
627         return HDF_FAILURE;
628     }
629     if (StartPlayThread(palyModeFlag) < 0) {
630         AUDIO_FUNC_LOGE("Create Thread Fail");
631         FileClose(&g_file);
632         return HDF_FAILURE;
633     }
634     *renderS = render;
635     printf("Start Successful,Music is playing\n");
636     return HDF_SUCCESS;
637 }
638 
PrintMenu0(void)639 static void PrintMenu0(void)
640 {
641     printf(" ============= Play Render Sound Card Mode ==========\n");
642     printf("| 1. Render Primary                                 |\n");
643     printf("| 2. Render Primary_Ext                             |\n");
644     printf("| 3. Render Usb                                     |\n");
645     printf("| 4. Render A2dp                                    |\n");
646     printf(" =================================================== \n");
647 }
648 
PrintMenu1(void)649 static void PrintMenu1(void)
650 {
651     printf(" ============== Play Render Loading Mode ===========\n");
652     printf("| 1. Render Direct Loading                         |\n");
653     printf("| 2. Render Service Loading                        |\n");
654     printf("| Note: switching is not supported in the MPI's    |\n");
655     printf("|       version.                                   |\n");
656     printf(" ================================================== \n");
657 }
658 
SwitchInternalOrExternal(char * adapterNameCase,int32_t nameLen)659 static int32_t SwitchInternalOrExternal(char *adapterNameCase, int32_t nameLen)
660 {
661     system("clear");
662     int choice = 0;
663     PrintMenu0();
664     printf("Please enter your choice:");
665     int32_t ret = CheckInputName(INPUT_INT, (void *)&choice);
666     if (ret < 0) return HDF_FAILURE;
667     switch (choice) {
668         case PRIMARY:
669             snprintf_s(adapterNameCase, nameLen, nameLen - 1, "%s", "primary");
670             break;
671         case PRIMARY_EXT:
672             snprintf_s(adapterNameCase, nameLen, nameLen - 1, "%s", "primary_ext");
673             break;
674         case AUDIO_USB:
675             snprintf_s(adapterNameCase, nameLen, nameLen - 1, "%s", "usb");
676             break;
677         case AUDIO_A2DP:
678             snprintf_s(adapterNameCase, nameLen, nameLen - 1, "%s", "a2dp");
679             break;
680         default:
681             printf("Input error,Switched to Acodec in for you,");
682             SystemInputFail();
683             snprintf_s(adapterNameCase, nameLen, nameLen - 1, "%s", "primary");
684             break;
685     }
686     return HDF_SUCCESS;
687 }
688 
SelectLoadingMode(char * renderResolvedPath,int32_t pathLen)689 static int32_t SelectLoadingMode(char *renderResolvedPath, int32_t pathLen)
690 {
691     system("clear");
692     int choice = 0;
693     int32_t ret;
694     PrintMenu1();
695     printf("Please enter your choice:");
696     ret = CheckInputName(INPUT_INT, (void *)&choice);
697     if (ret < 0) {
698         AUDIO_FUNC_LOGE("render CheckInputName failed!");
699         return HDF_FAILURE;
700     }
701     ret = FormatLoadLibPath(renderResolvedPath, pathLen, choice);
702     if (ret < 0) {
703         AUDIO_FUNC_LOGE("render FormatLoadLibPath failed!");
704         return HDF_FAILURE;
705     }
706     return HDF_SUCCESS;
707 }
708 
GetAudioManagerInsForRender(const char * funcString)709 static struct AudioManager *GetAudioManagerInsForRender(const char *funcString)
710 {
711     struct AudioManager *(*getAudioManager)(void) = NULL;
712     if (funcString == NULL) {
713         AUDIO_FUNC_LOGE("funcString is null!");
714         return NULL;
715     }
716     if (g_handle == NULL) {
717         AUDIO_FUNC_LOGE("g_captureHandle is null!");
718         return NULL;
719     }
720     getAudioManager = (struct AudioManager *(*)())(dlsym(g_handle, funcString));
721     if (getAudioManager == NULL) {
722         AUDIO_FUNC_LOGE("Get Audio Manager Funcs Fail");
723         return NULL;
724     }
725     return getAudioManager();
726 }
727 
GetRenderManagerFunc(const char * adapterNameCase)728 static int32_t GetRenderManagerFunc(const char *adapterNameCase)
729 {
730     struct AudioAdapterDescriptor *descs = NULL;
731     enum AudioPortDirection port = PORT_OUT; // Set port information
732     struct AudioPort renderPort;
733     int32_t size = 0;
734     if (adapterNameCase == NULL) {
735         AUDIO_FUNC_LOGE("The Parameter is NULL");
736         return HDF_FAILURE;
737     }
738     struct AudioManager *manager = GetAudioManagerInsForRender("GetAudioManagerFuncs");
739     if (manager == NULL) {
740         AUDIO_FUNC_LOGE("GetAudioManagerInsForRender Fail");
741         return HDF_FAILURE;
742     }
743     int32_t ret = manager->GetAllAdapters(manager, &descs, &size);
744     if ((size == 0) || (descs == NULL) || (ret < 0)) {
745         AUDIO_FUNC_LOGE("Get All Adapters Fail");
746         return HDF_ERR_NOT_SUPPORT;
747     }
748     int32_t index = SwitchAdapter(descs, adapterNameCase, port, &renderPort, size);
749     if (index < 0) {
750         AUDIO_FUNC_LOGE("Not Switch Adapter Invalid");
751         return HDF_ERR_NOT_SUPPORT;
752     }
753     struct AudioAdapterDescriptor *desc = &descs[index];
754     if (manager->LoadAdapter(manager, desc, &g_adapter) != 0) {
755         AUDIO_FUNC_LOGE("Load Adapter Fail");
756         return HDF_ERR_NOT_SUPPORT;
757     }
758     g_manager = manager;
759     if (g_adapter == NULL) {
760         AUDIO_FUNC_LOGE("load audio device Invalid");
761         return HDF_FAILURE;
762     }
763     (void)g_adapter->InitAllPorts(g_adapter);
764     if (InitAttrs(&g_attrs) < 0) {
765         g_manager->UnloadAdapter(g_manager, g_adapter);
766         return HDF_FAILURE;
767     }
768     // Specify a hardware device
769     if (InitDevDesc(&g_devDesc, renderPort.portId) < 0) {
770         g_manager->UnloadAdapter(g_manager, g_adapter);
771         return HDF_FAILURE;
772     }
773     return HDF_SUCCESS;
774 }
775 
InitParam(void)776 static int32_t InitParam(void)
777 {
778     /* Internal and external switch,begin */
779     char adapterNameCase[PATH_LEN] = {0};
780     if (SwitchInternalOrExternal(adapterNameCase, PATH_LEN) < 0) {
781         return HDF_FAILURE;
782     }
783     char resolvedPath[PATH_LEN] = {0}; // Select loading mode,begin
784     if (SelectLoadingMode(resolvedPath, PATH_LEN) < 0) {
785         return HDF_FAILURE;
786     }
787     /* Select loading mode,end */
788     g_audioPort.dir = PORT_OUT;
789     g_audioPort.portId = 0;
790     g_audioPort.portName = "AOP";
791     g_handle = dlopen(resolvedPath, 1);
792     if (g_handle == NULL) {
793         AUDIO_FUNC_LOGE("Open so Fail, reason:%s", dlerror());
794         return HDF_FAILURE;
795     }
796     if (GetRenderManagerFunc(adapterNameCase) < 0) {
797         AUDIO_FUNC_LOGE("GetManagerFunc Failed.");
798         return HDF_FAILURE;
799     }
800     return HDF_SUCCESS;
801 }
802 
SetRenderMute(struct AudioRender ** render)803 static int32_t SetRenderMute(struct AudioRender **render)
804 {
805     (void)render;
806     int32_t val;
807     bool isMute = false;
808     int32_t ret;
809     if (g_render == NULL || g_render->volume.GetMute == NULL) {
810         return HDF_FAILURE;
811     }
812     ret = g_render->volume.GetMute((AudioHandle)g_render, &isMute);
813     if (ret < 0) {
814         AUDIO_FUNC_LOGE("The current mute state was not obtained!");
815     }
816     printf("Now %s ,Do you need to set mute status(1/0):", isMute ? "mute" : "not mute");
817     ret = CheckInputName(INPUT_INT, (void *)&val);
818     if (ret < 0) {
819         return HDF_FAILURE;
820     }
821     if (isMute != 0 && isMute != 1) {
822         AUDIO_FUNC_LOGE("Invalid value!");
823         SystemInputFail();
824         return HDF_FAILURE;
825     }
826     if (g_render == NULL || g_render->volume.SetMute == NULL) {
827         AUDIO_FUNC_LOGE("Music already stop!");
828         SystemInputFail();
829         return HDF_FAILURE;
830     }
831     if (val == 1) {
832         ret = g_render->volume.SetMute((AudioHandle)g_render, !isMute);
833     }
834     return ret;
835 }
836 
SetRenderVolume(struct AudioRender ** render)837 static int32_t SetRenderVolume(struct AudioRender **render)
838 {
839     (void)render;
840     int32_t ret;
841     float val = 0.0;
842     if (g_render == NULL || g_render->volume.GetVolume == NULL) {
843         return HDF_FAILURE;
844     }
845     ret = g_render->volume.GetVolume((AudioHandle)g_render, &val);
846     if (ret < 0) {
847         AUDIO_FUNC_LOGE("Get current volume failed!");
848         SystemInputFail();
849         return ret;
850     }
851     printf("Now the volume is %f ,Please enter the volume value you want to set (0.0-1.0):", val);
852     ret = CheckInputName(INPUT_FLOAT, (void *)&val);
853     if (ret < 0) return HDF_FAILURE;
854     if (val < 0.0 || val > 1.0) {
855         AUDIO_FUNC_LOGE("Invalid volume value!");
856         SystemInputFail();
857         return HDF_FAILURE;
858     }
859     if (g_render == NULL || g_render->volume.SetVolume == NULL) {
860         AUDIO_FUNC_LOGE("Music already stop!");
861         SystemInputFail();
862         return HDF_FAILURE;
863     }
864     ret = g_render->volume.SetVolume((AudioHandle)g_render, val);
865     if (ret < 0) {
866         AUDIO_FUNC_LOGE("set volume fail!");
867         SystemInputFail();
868     }
869     return ret;
870 }
871 
GetRenderGain(struct AudioRender ** render)872 static int32_t GetRenderGain(struct AudioRender **render)
873 {
874     (void)render;
875     int32_t ret;
876     float val = 1.0;
877     if (g_render == NULL || g_render->volume.GetGain == NULL) {
878         return HDF_FAILURE;
879     }
880     ret = g_render->volume.GetGain((AudioHandle)g_render, &val);
881     if (ret < 0) {
882         AUDIO_FUNC_LOGE("Get current gain failed!");
883         SystemInputFail();
884         return HDF_FAILURE;
885     }
886     printf("Now the gain is %f,", val);
887     SystemInputFail();
888     return HDF_SUCCESS;
889 }
890 
SetRenderPause(struct AudioRender ** render)891 static int32_t SetRenderPause(struct AudioRender **render)
892 {
893     (void)render;
894     if (g_waitSleep) {
895         AUDIO_FUNC_LOGE("Already pause,not need pause again!");
896         SystemInputFail();
897         return HDF_FAILURE;
898     }
899     int32_t ret;
900     if (g_render == NULL || g_render->control.Pause == NULL) {
901         return HDF_FAILURE;
902     }
903     ret = g_render->control.Pause((AudioHandle)g_render);
904     if (ret != 0) {
905         return HDF_FAILURE;
906     }
907     printf("Pause success!\n");
908     g_waitSleep = true;
909     return HDF_SUCCESS;
910 }
911 
SetRenderResume(struct AudioRender ** render)912 static int32_t SetRenderResume(struct AudioRender **render)
913 {
914     (void)render;
915     if (!g_waitSleep) {
916         AUDIO_FUNC_LOGE("Now is Playing,not need resume!");
917         SystemInputFail();
918         return HDF_FAILURE;
919     }
920     int32_t ret;
921     if (g_render == NULL || g_render->control.Resume == NULL) {
922         return HDF_FAILURE;
923     }
924     ret = g_render->control.Resume((AudioHandle)g_render);
925     if (ret != 0) {
926         return HDF_FAILURE;
927     }
928     printf("resume success!\n");
929     pthread_mutex_lock(&g_mutex);
930     g_waitSleep = false;
931     pthread_cond_signal(&g_functionCond);
932     pthread_mutex_unlock(&g_mutex);
933     return HDF_SUCCESS;
934 }
935 
PrintRenderAttributesFromat(void)936 static void PrintRenderAttributesFromat(void)
937 {
938     printf(" ============= Render Sample Attributes Format =============== \n");
939     printf("| 1. Render AUDIO_FORMAT_PCM_8_BIT                            |\n");
940     printf("| 2. Render AUDIO_FORMAT_PCM_16_BIT                           |\n");
941     printf("| 3. Render AUDIO_FORMAT_PCM_24_BIT                           |\n");
942     printf("| 4. Render AUDIO_FORMAT_PCM_32_BIT                           |\n");
943     printf(" ============================================================= \n");
944 }
945 
SelectAttributesFomat(uint32_t * renderPcmFomat)946 static int32_t SelectAttributesFomat(uint32_t *renderPcmFomat)
947 {
948     if (renderPcmFomat == NULL) {
949         AUDIO_FUNC_LOGE("fomat is null!");
950         return HDF_FAILURE;
951     }
952     PrintRenderAttributesFromat();
953     printf("Please select audio format,If not selected, the default is 16bit:");
954     int32_t ret;
955     int val = 0;
956     ret = CheckInputName(INPUT_INT, (void *)&val);
957     if (ret < 0) {
958         AUDIO_FUNC_LOGE("CheckInputName failed!");
959         return HDF_FAILURE;
960     }
961     ret = CheckPcmFormat(val, renderPcmFomat);
962     if (ret < 0) {
963         AUDIO_FUNC_LOGE("Render CheckPcmFormat failed!");
964         return HDF_FAILURE;
965     }
966     return HDF_SUCCESS;
967 }
968 
SetRenderAttributes(struct AudioRender ** render)969 static int32_t SetRenderAttributes(struct AudioRender **render)
970 {
971     (void)render;
972     int32_t ret;
973     struct AudioSampleAttributes renderAttrs;
974     if (g_render == NULL || g_render->attr.GetSampleAttributes == NULL) {
975         AUDIO_FUNC_LOGE("The pointer is null!");
976         return HDF_FAILURE;
977     }
978     ret = g_render->attr.GetSampleAttributes((AudioHandle)g_render, &renderAttrs);
979     if (ret < 0) {
980         AUDIO_FUNC_LOGE("GetRenderAttributes failed!");
981     } else {
982         printf("Current sample attributes:\n");
983         printf("audioType is %u\nfomat is %u\nsampleRate is %u\nchannalCount is"
984             "%u\nperiod is %u\nframesize is %u\nbigEndian is %u\nSignedData is %u\n",
985             renderAttrs.type, renderAttrs.format, renderAttrs.sampleRate,
986             renderAttrs.channelCount, renderAttrs.period, renderAttrs.frameSize,
987             renderAttrs.isBigEndian, renderAttrs.isSignedData);
988     }
989     printf("Set Sample Attributes,");
990     SystemInputFail();
991     system("clear");
992     printf("The sample attributes you want to set,Step by step, please.\n");
993     ret = SelectAttributesFomat((uint32_t *)(&renderAttrs.format));
994     if (ret < 0) {
995         AUDIO_FUNC_LOGE("SetRenderAttributes format failed!");
996         return HDF_FAILURE;
997     }
998     printf("\nPlease input sample rate(48000,44100,32000...):");
999     ret = CheckInputName(INPUT_UINT32, (void *)(&renderAttrs.sampleRate));
1000     if (ret < 0) {
1001         return HDF_FAILURE;
1002     }
1003     printf("\nPlease input bigEndian(false=0/true=1):");
1004     ret = CheckInputName(INPUT_UINT32, (void *)(&renderAttrs.isBigEndian));
1005     if (ret < 0) {
1006         return HDF_FAILURE;
1007     }
1008     if (g_render == NULL || g_render->attr.SetSampleAttributes == NULL) {
1009         AUDIO_FUNC_LOGE("Music already complete,Please replay and set the attrbutes!");
1010         SystemInputFail();
1011         return HDF_FAILURE;
1012     }
1013     ret = g_render->attr.SetSampleAttributes((AudioHandle)g_render, &renderAttrs);
1014     if (ret < 0) {
1015         AUDIO_FUNC_LOGE("Set render attributes failed!");
1016         SystemInputFail();
1017     }
1018     return ret;
1019 }
1020 
SelectRenderScene(struct AudioRender ** render)1021 static int32_t SelectRenderScene(struct AudioRender **render)
1022 {
1023     (void)render;
1024     system("clear");
1025     int32_t ret;
1026     int val = 0;
1027     struct AudioSceneDescriptor scene;
1028     printf(" =================== Select Scene ===================== \n");
1029     printf("0 is Speaker.                                          |\n");
1030     printf("1 is HeadPhones.                                       |\n");
1031     printf(" ====================================================== \n");
1032     printf("Please input your choice:\n");
1033     ret = CheckInputName(INPUT_INT, (void *)&val);
1034     if (ret < 0 || (val != 0 && val != 1)) {
1035         AUDIO_FUNC_LOGE("Invalid value!");
1036         SystemInputFail();
1037         return HDF_FAILURE;
1038     }
1039     if (val == 1) {
1040         scene.scene.id = 0;
1041         scene.desc.pins = PIN_OUT_HEADSET;
1042     } else {
1043         scene.scene.id = 0;
1044         scene.desc.pins = PIN_OUT_SPEAKER;
1045     }
1046     if (g_render == NULL) {
1047         AUDIO_FUNC_LOGE("Music already stop,");
1048         SystemInputFail();
1049         return HDF_FAILURE;
1050     }
1051     if (g_render->scene.SelectScene == NULL) {
1052         return HDF_FAILURE;
1053     }
1054     ret = g_render->scene.SelectScene((AudioHandle)g_render, &scene);
1055     if (ret < 0) {
1056         AUDIO_FUNC_LOGE("Select scene fail\n");
1057     }
1058     return ret;
1059 }
1060 
GetExtParams(struct AudioRender ** render)1061 static int32_t GetExtParams(struct AudioRender **render)
1062 {
1063     (void)render;
1064     char keyValueList[BUFFER_LEN] = {0};
1065     int32_t ret;
1066     if (g_render == NULL || g_render->attr.GetExtraParams == NULL) {
1067         return HDF_FAILURE;
1068     }
1069     ret = g_render->attr.GetExtraParams((AudioHandle)g_render, keyValueList, EXT_PARAMS_MAXLEN);
1070     if (ret < 0) {
1071         AUDIO_FUNC_LOGE("Get EXT params failed!");
1072         SystemInputFail();
1073         return HDF_FAILURE;
1074     }
1075     printf("keyValueList = %s\n", keyValueList);
1076     return HDF_SUCCESS;
1077 }
1078 
GetRenderMmapPosition(struct AudioRender ** render)1079 static int32_t GetRenderMmapPosition(struct AudioRender **render)
1080 {
1081     (void)render;
1082     int32_t ret;
1083     if (g_render == NULL || g_render->attr.GetMmapPosition == NULL) {
1084         return HDF_FAILURE;
1085     }
1086     uint64_t frames = 0;
1087     struct AudioTimeStamp time;
1088     time.tvNSec = 0;
1089     time.tvSec = 0;
1090     ret = g_render->attr.GetMmapPosition((AudioHandle)g_render, &frames, &time);
1091     if (ret < 0) {
1092         AUDIO_FUNC_LOGE("Get current Mmap frames Position failed!");
1093         SystemInputFail();
1094         return HDF_FAILURE;
1095     }
1096     printf("Now the Position is %"PRIu64"\n", frames);
1097     return HDF_SUCCESS;
1098 }
1099 
PrintMenu2(void)1100 static void PrintMenu2(void)
1101 {
1102     printf(" ================== Play Render Menu ================== \n");
1103     printf("| 1. Render Start                                      |\n");
1104     printf("| 2. Render Stop                                       |\n");
1105     printf("| 3. Render Resume                                     |\n");
1106     printf("| 4. Render Pause                                      |\n");
1107     printf("| 5. Render SetVolume                                  |\n");
1108     printf("| 6. Render GetGain                                    |\n");
1109     printf("| 7. Render SetMute                                    |\n");
1110     printf("| 8. Render SetAttributes                              |\n");
1111     printf("| 9. Render SelectScene                                |\n");
1112     printf("| 10. Render getEXtParams                              |\n");
1113     printf("| 11. Render getMmapPosition                           |\n");
1114     printf("| 12.Exit                                              |\n");
1115     printf(" ====================================================== \n");
1116 }
1117 
1118 static struct ProcessRenderMenuSwitchList g_processRenderMenuSwitchList[] = {
1119     {RENDER_START, PlayingAudioFiles},
1120     {RENDER_STOP, StopAudioFiles},
1121     {RENDER_RESUME, SetRenderResume},
1122     {RENDER_PAUSE, SetRenderPause},
1123     {SET_RENDER_VOLUME, SetRenderVolume},
1124     {SET_RENDER_GAIN, GetRenderGain},
1125     {SET_RENDER_MUTE, SetRenderMute},
1126     {SET_RENDER_ATTRIBUTES, SetRenderAttributes},
1127     {SET_RENDER_SLECET_SCENE, SelectRenderScene},
1128     {GET_RENDER_EXT_PARAMS, GetExtParams},
1129     {GET_RENDER_POSITION, GetRenderMmapPosition},
1130 };
1131 
ProcessMenu(int32_t choice)1132 static void ProcessMenu(int32_t choice)
1133 {
1134     int32_t i;
1135     if (choice == GET_RENDER_POSITION + 1) {
1136         return;
1137     }
1138     if (g_render == NULL && choice != 1) {
1139         AUDIO_FUNC_LOGE("This render already release!");
1140         SystemInputFail();
1141         return;
1142     }
1143     for (i = RENDER_START; i <= GET_RENDER_POSITION; ++i) {
1144         if ((choice == (int32_t)g_processRenderMenuSwitchList[i - 1].cmd) &&
1145             (g_processRenderMenuSwitchList[i - 1].operation != NULL)) {
1146             g_processRenderMenuSwitchList[i - 1].operation(&g_render);
1147         }
1148     }
1149 }
1150 
Choice(void)1151 static void Choice(void)
1152 {
1153     int32_t choice = 0;
1154     int ret;
1155     while (choice < GET_RENDER_POSITION + 1 && choice >= 0) {
1156         system("clear");
1157         PrintMenu2();
1158         printf("your choice is:\n");
1159         ret = CheckInputName(INPUT_INT, (void *)&choice);
1160         if (ret < 0) {
1161             continue;
1162         }
1163         if (choice < RENDER_START || choice > GET_RENDER_POSITION + 1) {
1164             AUDIO_FUNC_LOGE("You input is wrong!");
1165             choice = 0;
1166             SystemInputFail();
1167             continue;
1168         }
1169         ProcessMenu(choice);
1170     }
1171 }
1172 
main(int32_t argc,char const * argv[])1173 int32_t main(int32_t argc, char const *argv[])
1174 {
1175     int32_t ret = 0;
1176     if (argc < 2 || argv == NULL || argv[0] == NULL) { // The parameter number is not greater than 2
1177         printf("usage:[1]sample [2]/data/test.wav\n");
1178         return 0;
1179     }
1180     if (argv[1] == NULL || strlen(argv[1]) == 0) {
1181         return HDF_FAILURE;
1182     }
1183     ret = strncpy_s(g_path, PATH_LEN, argv[1], strlen(argv[1]) + 1);
1184     if (ret != 0) {
1185         AUDIO_FUNC_LOGE("strncpy_s failed!");
1186         return HDF_FAILURE;
1187     }
1188     char pathBuf[PATH_MAX] = {'\0'};
1189     if (realpath(g_path, pathBuf) == NULL) {
1190         return HDF_FAILURE;
1191     }
1192     FILE *file = fopen(pathBuf, "rb");
1193     if (file == NULL) {
1194         printf("Failed to open '%s',Please enter the correct file name \n", g_path);
1195         return HDF_FAILURE;
1196     }
1197     (void)fclose(file);
1198     if (InitParam() != HDF_SUCCESS) { // init
1199         AUDIO_FUNC_LOGE("InitParam Fail!");
1200         return HDF_FAILURE;
1201     }
1202 
1203     Choice();
1204     (void)PrepareStopAndUnloadAdapter();
1205     dlclose(g_handle);
1206     return 0;
1207 }
1208