1 /*
2 * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
3 *
4 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
5 * the the people's Republic of China and other countries.
6 * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
7 *
8 * DISCLAIMER
9 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
10 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
11 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
12 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
13 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
14 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
15 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
19 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
21 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
22 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 #include <stdio.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 //#include <FreeRTOS.h>
37 #include <aw-alsa-lib/pcm.h>
38 #include "common.h"
39 #include <hal_timer.h>
40
41 unsigned int g_verbose = 0;
42
set_param(snd_pcm_t * handle,snd_pcm_format_t format,unsigned int rate,unsigned int channels,snd_pcm_uframes_t period_size,snd_pcm_uframes_t buffer_size)43 int set_param(snd_pcm_t *handle, snd_pcm_format_t format,
44 unsigned int rate, unsigned int channels,
45 snd_pcm_uframes_t period_size,
46 snd_pcm_uframes_t buffer_size)
47 {
48 int ret = 0;
49 snd_pcm_hw_params_t *params;
50 snd_pcm_sw_params_t *sw_params;
51 snd_pcm_uframes_t period_size_tmp = period_size;
52 snd_pcm_uframes_t buffer_size_tmp = buffer_size;
53
54 /* HW params */
55 snd_pcm_hw_params_alloca(¶ms);
56 ret = snd_pcm_hw_params_any(handle, params);
57 if (ret < 0) {
58 printf("no configurations available\n");
59 return ret;
60 }
61 ret = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
62 if (ret < 0) {
63 printf("failed to set access\n");
64 return ret;
65 }
66 ret = snd_pcm_hw_params_set_format(handle, params, format);
67 if (ret < 0) {
68 printf("failed to set format\n");
69 return ret;
70 }
71 ret = snd_pcm_hw_params_set_channels(handle, params, channels);
72 if (ret < 0) {
73 printf("failed to set channels\n");
74 return ret;
75 }
76 ret = snd_pcm_hw_params_set_rate(handle, params, rate, 0);
77 if (ret < 0) {
78 printf("failed to set rate\n");
79 return ret;
80 }
81
82 ret = snd_pcm_hw_params_set_period_size_near(handle, params, &period_size_tmp, NULL);
83 if (ret < 0) {
84 printf("failed to set period size\n");
85 return ret;
86 }
87 if (period_size_tmp != period_size) {
88 printf("period size changed (request: %lu, get: %lu)\n",
89 period_size, period_size_tmp);
90 period_size = period_size_tmp;
91 }
92 ret = snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_size_tmp);
93 if (ret < 0) {
94 printf("failed to set buffer size\n");
95 return ret;
96 }
97 if (buffer_size_tmp != buffer_size) {
98 printf("buffer size changed (request: %lu, get: %lu)\n",
99 buffer_size, buffer_size_tmp);
100 buffer_size = buffer_size_tmp;
101 }
102 ret = snd_pcm_hw_params(handle, params);
103 if (ret < 0) {
104 printf("Unable to install hw prams! (return: %d)\n", ret);
105 return ret;
106 }
107
108 /* SW params */
109 snd_pcm_sw_params_alloca(&sw_params);
110 snd_pcm_sw_params_current(handle, sw_params);
111 if (snd_pcm_stream(handle) == SND_PCM_STREAM_CAPTURE) {
112 snd_pcm_sw_params_set_start_threshold(handle, sw_params, 1);
113 } else {
114 snd_pcm_uframes_t boundary = 0;
115 snd_pcm_sw_params_get_boundary(sw_params, &boundary);
116 snd_pcm_sw_params_set_start_threshold(handle, sw_params, buffer_size);
117 /* set silence size, in order to fill silence data into ringbuffer */
118 snd_pcm_sw_params_set_silence_size(handle, sw_params, boundary);
119 }
120 snd_pcm_sw_params_set_stop_threshold(handle, sw_params, buffer_size);
121 snd_pcm_sw_params_set_avail_min(handle, sw_params, period_size);
122 ret = snd_pcm_sw_params(handle ,sw_params);
123 if (ret < 0) {
124 printf("Unable to install sw prams!\n");
125 return ret;
126 }
127
128 if (g_verbose)
129 snd_pcm_dump(handle);
130
131 return ret;
132 }
133
xrun(snd_pcm_t * handle)134 void xrun(snd_pcm_t *handle)
135 {
136 int ret;
137
138 printf("Xrun...\n");
139 ret = snd_pcm_prepare(handle);
140 if (ret < 0) {
141 printf("prepare failed in xrun. return %d\n", ret);
142 }
143 }
144
do_pause(snd_pcm_t * handle)145 void do_pause(snd_pcm_t *handle)
146 {
147 int ret = 0;
148 printf("[%s] line:%d pause start...\n", __func__, __LINE__);
149 ret = snd_pcm_pause(handle, 1);
150 if (ret < 0)
151 printf("pause failed!, return %d\n", ret);
152 hal_sleep(5);
153 ret = snd_pcm_pause(handle, 0);
154 if (ret < 0)
155 printf("pause release failed!, return %d\n", ret);
156 printf("[%s] line:%d pause end...\n", __func__, __LINE__);
157 }
158
do_other_test(snd_pcm_t * handle)159 void do_other_test(snd_pcm_t *handle)
160 {
161 do_pause(handle);
162 return;
163 }
164
audio_mgr_create(void)165 audio_mgr_t *audio_mgr_create(void)
166 {
167 audio_mgr_t *audio_mgr = NULL;
168
169 audio_mgr = malloc(sizeof(audio_mgr_t));
170 if (!audio_mgr) {
171 printf("no memory\n");
172 return NULL;
173 }
174 memset(audio_mgr, 0, sizeof(audio_mgr_t));
175 audio_mgr->format = SND_PCM_FORMAT_S16_LE;
176 audio_mgr->rate = 16000;
177 audio_mgr->channels = 2;
178 audio_mgr->period_size = 1024;
179 audio_mgr->buffer_size = 4096;
180 return audio_mgr;
181 }
182
audio_mgr_release(audio_mgr_t * mgr)183 void audio_mgr_release(audio_mgr_t *mgr)
184 {
185 if (!mgr) {
186 printf("%s: mgr null !\n", __func__);
187 return;
188 }
189 free(mgr);
190 }
191