Added K70f120 project, set default playback to DAC
[pcm-lib.git] / example / pc_speaker / sound_api.c
blob2e16ff51b315cbe438e606dee191456e28f5c7d3
2 /* usb device play sound api */
4 #include <mqx.h>
5 #include <bsp.h>
6 #include "pcm_lib.h"
8 #define DAC_CODEC /* If the sample define DAC_CODEC to playback at dac then the pcm lib must define KINETS_K60DAC in soc_config.h and rebuild ! */
9 struct snd_pcm_params u_params;
11 void * pcm_handle = NULL;
14 * default set is the sample rate 44100, 16 bits, 2 channel
15 * umute
17 int32_t snd_init(void)
19 _mem_zero((void *) &u_params, sizeof(u_params));
20 u_params.access = SNDRV_PCM_ACCESS_INTERLEAVED;
21 u_params.channels = 2;
22 u_params.format = SNDRV_PCM_FORMAT_S16;
23 #ifdef DAC_CODEC
24 u_params.periods = 4;
25 u_params.period_size = 512;
26 #else
27 u_params.periods = 4 ;
28 u_params.period_size = 128;
29 #endif
31 u_params.silence_size = /* u_params.period_size*/0;
32 u_params.silence_threshold = THRESHOLD_BOUNDARY; /* THRESHOLD_BOUNDARY -> 0*/
33 u_params.rate = 44100;
35 u_params.start_threshold = u_params.periods * u_params.period_size / 2; /* start at the half of the buffer */
36 u_params.stop_threshold = u_params.periods * u_params.period_size;
38 if(pcm_stream_init(&pcm_handle,SNDRV_PCM_STREAM_PLAYBACK,&u_params)) {
39 printf(" pcm init failed\n");
40 return -1;
43 printf("snd_init");
44 return 0;
47 #ifdef DAC_CODEC
48 extern void dac_skew_sample_rate(int skew);
49 #endif
52 * write samples to device
53 * must have correct set before write
55 int32_t snd_write(uint8_t * pcmStream, uint32_t pcmCnt)
57 #ifdef DAC_CODEC
58 int avail_rate = snd_pcm_get_avail_rate (pcm_handle);
59 int res = 100 - avail_rate; /* residue */
61 if (avail_rate > 0) { /* these get from ADK2012 */
62 static int lastres[2];
63 //if (res > (AUDBUFSIZE / 2)) {
64 if (res > (50)) {
65 // we're overrunning the dac, increase its sample rate
66 static int a = 0;
67 if (lastres[1] < lastres[0] && lastres[0] < res) {
68 a++;
69 if (a > 5) {
70 int adj = res * 20 ;
71 dac_skew_sample_rate(adj);
72 //dbgPrintf("o%d +%d %d\n", res, adj, audsamplerate);
73 a = 0;
76 } else {
77 // we're underunning the dac, decrease its sample rate
78 static int a = 0;
80 if (res == 1 || lastres[1] > lastres[0] && lastres[0] > res) {
81 a++;
82 if (a > 5) {
83 int adj = avail_rate * 20;
84 dac_skew_sample_rate(-adj);
85 //dbgPrintf("u%d -%d %d\n", res, adj, audsamplerate);
86 a = 0;
90 lastres[1] = lastres[0];
91 lastres[0] = res;
94 #endif
95 return u_audio_playback(pcm_handle, pcmStream, pcmCnt);
98 int32_t snd_read(uint8_t * pcmStream, uint32_t pcmCnt)
100 #if 0
101 ssize_t result;
102 snd_pcm_sframes_t frames;
104 struct snd_pcm_runtime *runtime = (struct snd_pcm_runtime *)handle;
106 frames = bytes_to_frames(runtime, pcmCnt);
107 result = snd_pcm_lib_read(runtime,pcmStream,frames,NON_BLOCK /* RW_BLOCK*/);
109 return result;
110 #endif
111 return 0;
115 * collect resources of sound device
117 int32_t snd_deinit(void)
119 if (pcm_handle) {
120 printf("snd_deinit\n");
121 pcm_stream_deinit(pcm_handle);
122 pcm_handle = NULL;
124 else {
125 printf("denit pcm stream ,but handle is null\n");
127 return 0;
131 * set pcm sound format: sample rate, bit width, channel number
133 int32_t snd_set_format(uint32_t sampleRate, uint8_t bitWidth, uint8_t chNum)
135 _mem_zero((void *) &u_params, sizeof(u_params));
137 #ifdef DAC_CODEC
138 u_params.access = SNDRV_PCM_ACCESS_INTERLEAVED;//SNDRV_PCM_ACCESS_NONINTERLEAVED;
139 #else
140 u_params.access = SNDRV_PCM_ACCESS_INTERLEAVED;
141 #endif
142 u_params.channels = 2;
144 u_params.format = SNDRV_PCM_FORMAT_S16;
146 u_params.periods = 4;
147 u_params.period_size = 128;
149 u_params.silence_size = u_params.period_size;
150 //u_params.silence_size = 0 ;
151 u_params.silence_threshold = THRESHOLD_BOUNDARY; /* THRESHOLD_BOUNDARY -> 0*/
152 u_params.rate = 44100;
154 u_params.start_threshold = u_params.periods * u_params.period_size / 2; /* start at the half of the buffer */
155 u_params.stop_threshold = u_params.periods * u_params.period_size;
157 switch (bitWidth)
159 case 16:
160 u_params.format = SNDRV_PCM_FORMAT_S16;
161 break;
162 case 24:
163 u_params.format = SNDRV_PCM_FORMAT_S24_3LE ; /* SNDRV_PCM_FORMAT_S24 */
164 break;
165 default:
166 printf("err:only support sample bits equal 16 or 24\n");
167 return -1;
170 u_params.rate = sampleRate;
171 if(sampleRate > 48000) {
172 u_params.periods = 4;
173 u_params.period_size = 256;
174 //u_params.silence_size = u_params.period_size;
175 u_params.silence_size = 0 ;
177 else {
178 #ifdef DAC_CODEC
179 u_params.periods = 4;
180 u_params.period_size = 512;
181 #else
182 u_params.periods = 4;
183 u_params.period_size = 128;
184 #endif
185 #ifdef DAC_CODEC
186 u_params.silence_size = 0;
187 #else
188 u_params.silence_size = u_params.period_size ;
189 #endif
192 /* start at the half of the buffer */
193 u_params.start_threshold = u_params.periods * u_params.period_size / 2;
194 u_params.stop_threshold = u_params.periods * u_params.period_size;
196 if (pcm_handle) {
197 pcm_stream_deinit(pcm_handle);
198 pcm_handle = NULL;
200 _time_delay(1);
201 if(pcm_stream_init(&pcm_handle,SNDRV_PCM_STREAM_PLAYBACK,&u_params)) {
202 printf(" set params failed\n");
203 return -1;
206 int snd_pcm_params(void * handle,
207 struct snd_pcm_params *params) */
209 return 0;
213 * turn up sound volume
215 int32_t snd_vol_up(void)
217 // todo
218 return 0;
222 * turn down sound volume
224 int32_t snd_vol_down(void)
226 // todo
227 return 0;
231 * mute sound device
233 int32_t snd_mute(void)
235 // todo
236 return 0;
239 * umute device
241 int32_t snd_umute(void)
243 // todo
244 return 0;
248 * flush the pcm stream out
251 int32_t snd_flush(void)
253 // todo
254 return 0;