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(&params);
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