1/*
2 * Copyright (c) 2022 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 "framework_common.h"
17#include <string.h>
18#include "securec.h"
19#include "hdf_base.h"
20
21#define MOVE_LEFT_NUM        8
22#define WAV_HEAD_RIFF_OFFSET 8
23
24int32_t SwitchAudioPort(
25    struct AudioAdapterDescriptor *descs, enum AudioPortDirection portFlag, struct AudioPort *renderPort)
26{
27    uint32_t port;
28    uint32_t portNum;
29
30    if (descs == NULL || renderPort == NULL) {
31        return HDF_FAILURE;
32    }
33#ifdef IDL_SAMPLE
34    portNum = descs->portsLen;
35#else
36    portNum = descs->portNum;
37#endif
38    for (port = 0; port < portNum; port++) {
39        if (descs->ports[port].dir == portFlag) {
40            *renderPort = descs->ports[port];
41            return HDF_SUCCESS;
42        }
43    }
44
45    AUDIO_FUNC_LOGE("AudioPort Switch fail");
46    return HDF_ERR_NOT_SUPPORT;
47}
48
49int32_t SelectAudioCard(struct AudioAdapterDescriptor *descs, int32_t size, int32_t *adapterIndex)
50{
51    int32_t i;
52    errno_t ret;
53
54    if (descs == NULL || adapterIndex == NULL || size <= 0) {
55        return HDF_ERR_INVALID_PARAM;
56    }
57
58    printf(" ================= Select Audio Card ==================\n");
59    for (i = 0; i < size; i++) {
60        printf(" %d. %s\n", i + 1, descs[i].adapterName);
61    }
62    printf(" ======================================================\n");
63    printf("Please enter your choice:\n");
64    ret = scanf_s("%d", adapterIndex);
65    if (ret < 0) {
66        AUDIO_FUNC_LOGE("Input error occurs!");
67        return HDF_FAILURE;
68    }
69    if (*adapterIndex <= 0 || *adapterIndex > size) {
70        *adapterIndex = 1; // 1 for default audio card
71        printf("Input error, Default audio card selected: %s\n", descs[*adapterIndex - 1].adapterName);
72    }
73
74    return HDF_SUCCESS;
75}
76
77void PrintLoadModeMenu(void)
78{
79    printf(" ==================== Loading Mode =================== \n");
80    printf("| 1. Passthrough Loading                               |\n");
81    printf("| 2. IPC Loading                                       |\n");
82    printf(" ====================================================== \n");
83}
84
85int32_t CheckWavFileHeader(FILE *file, struct AudioHeadInfo *wavHeadInfo, struct AudioSampleAttributes *attrs)
86{
87    if (file == NULL || wavHeadInfo == NULL || attrs == NULL) {
88        AUDIO_FUNC_LOGE("params is null\n");
89        return HDF_FAILURE;
90    }
91
92    if (fread(wavHeadInfo, sizeof(struct AudioHeadInfo), 1, file) != 1) {
93        AUDIO_FUNC_LOGE("fread fail\n");
94        return HDF_FAILURE;
95    }
96
97    uint32_t audioRiffId = StringToInt("RIFF");
98    uint32_t audioFileFmt = StringToInt("WAVE");
99    if (wavHeadInfo->riffId != audioRiffId || wavHeadInfo->waveType != audioFileFmt) {
100        AUDIO_FUNC_LOGE("wav file head check fail\n");
101        return HDF_FAILURE;
102    }
103    printf("Music channels = %u\n", wavHeadInfo->audioChannelNum);
104    printf("Music Rate     = %u Hz\n", wavHeadInfo->audioSampleRate);
105    printf("Music Bit      = %u bit\n", wavHeadInfo->audioBitsPerSample);
106
107    attrs->channelCount = wavHeadInfo->audioChannelNum;
108    attrs->sampleRate = wavHeadInfo->audioSampleRate;
109    switch (wavHeadInfo->audioBitsPerSample) {
110        case PCM_8_BIT: {
111            attrs->format = AUDIO_FORMAT_TYPE_PCM_8_BIT;
112            break;
113        }
114        case PCM_16_BIT: {
115            attrs->format = AUDIO_FORMAT_TYPE_PCM_16_BIT;
116            break;
117        }
118        case PCM_24_BIT: {
119            attrs->format = AUDIO_FORMAT_TYPE_PCM_24_BIT;
120            break;
121        }
122        case PCM_32_BIT: {
123            attrs->format = AUDIO_FORMAT_TYPE_PCM_32_BIT;
124            break;
125        }
126        default:
127            AUDIO_FUNC_LOGE("wav format not in (8-bit|16-bit|24-bit|32-bit)\n");
128            return HDF_FAILURE;
129    }
130    return HDF_SUCCESS;
131}
132
133int32_t AddWavFileHeader(FILE *file, const struct StrParaCapture *strParam)
134{
135    struct AudioHeadInfo headInfo;
136
137    if (strParam == NULL) {
138        AUDIO_FUNC_LOGE("params is NULL");
139        return HDF_FAILURE;
140    }
141
142    (void)fseek(file, 0, SEEK_END);
143    headInfo.riffId = StringToInt("RIFF");
144    headInfo.riffSize = (uint32_t)ftell(file) - WAV_HEAD_RIFF_OFFSET;
145    headInfo.waveType = StringToInt("WAVE");
146    headInfo.audioFileFmtId = StringToInt("fmt ");
147    headInfo.audioFileFmtSize = PcmFormatToBits(strParam->attrs.format);
148    headInfo.audioFileFormat = 1;
149    headInfo.audioChannelNum = strParam->attrs.channelCount;
150    headInfo.audioSampleRate = strParam->attrs.sampleRate;
151    headInfo.audioByteRate =
152        headInfo.audioSampleRate * headInfo.audioChannelNum * headInfo.audioFileFmtSize / PCM_8_BIT;
153    headInfo.audioBlockAlign = (uint16_t)(headInfo.audioChannelNum * headInfo.audioFileFmtSize / PCM_8_BIT);
154    headInfo.audioBitsPerSample = (uint16_t)headInfo.audioFileFmtSize;
155    headInfo.dataId = StringToInt("data");
156    headInfo.dataSize = (uint32_t)ftell(file) - WAV_HEAD_OFFSET;
157    rewind(file);
158
159    if (fwrite(&headInfo, sizeof(struct AudioHeadInfo), 1, file) != 1) {
160        AUDIO_FUNC_LOGE("write wav file head error");
161        return HDF_FAILURE;
162    }
163
164    return HDF_SUCCESS;
165}
166
167void SystemInputFail(void)
168{
169    printf("please ENTER to go on...\n");
170    while (getchar() != '\n') {
171    }
172}
173
174uint32_t StringToInt(const char *flag)
175{
176    if (flag == NULL) {
177        return 0;
178    }
179    uint32_t temp = flag[0];
180    for (int32_t i = (int32_t)strlen(flag) - 1; i >= 0; i--) {
181        temp <<= MOVE_LEFT_NUM;
182        temp += flag[i];
183    }
184    return temp;
185}
186
187int32_t CheckPcmFormat(int32_t val, uint32_t *audioPcmFormat)
188{
189    if (audioPcmFormat == NULL) {
190        AUDIO_FUNC_LOGE("fomat is null!");
191        return HDF_FAILURE;
192    }
193    switch (val) {
194        case AUDIO_FORMAT_TYPE_PCM_8_BIT:
195            *audioPcmFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
196            break;
197        case AUDIO_FORMAT_TYPE_PCM_16_BIT:
198            *audioPcmFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
199            break;
200        case AUDIO_FORMAT_TYPE_PCM_24_BIT:
201            *audioPcmFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
202            break;
203        case AUDIO_FORMAT_TYPE_PCM_32_BIT:
204            *audioPcmFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
205            break;
206        default:
207            *audioPcmFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
208            break;
209    }
210
211    return HDF_SUCCESS;
212}
213
214uint32_t PcmFormatToBits(enum AudioFormat formatBit)
215{
216    switch (formatBit) {
217        case AUDIO_FORMAT_TYPE_PCM_16_BIT:
218            return PCM_16_BIT;
219        case AUDIO_FORMAT_TYPE_PCM_8_BIT:
220            return PCM_8_BIT;
221        default:
222            return PCM_16_BIT;
223    }
224}
225
226void CleanStdin(void)
227{
228    int c;
229    do {
230        c = getchar();
231    } while (c != '\n' && c != EOF);
232}
233
234void FileClose(FILE **file)
235{
236    if ((file != NULL) && ((*file) != NULL)) {
237        (void)fclose(*file);
238        *file = NULL;
239    }
240    return;
241}
242
243void PrintAudioInputTypeMenu(void)
244{
245    printf(" ================= Audio Input Type =============== \n");
246    printf("| 0. mic input type                                |\n");
247    printf("| 1. speech wakeup input type                      |\n");
248    printf("| 2. voice communication input typ                 |\n");
249    printf("| 3. voice recognition input type                  |\n");
250    printf("| 4. voice uplink input type                       |\n");
251    printf("| 5. voice downlink input type                     |\n");
252    printf("| 6. voice call input type                         |\n");
253    printf("| 7. camcorder input type                          |\n");
254    printf("| other. default input type                        |\n");
255    printf(" ================================================== \n");
256}