test: add volume class support for the test program
[profile/ivi/avsystem.git] / avsys-audio-pasimple.c
1 /*
2  * avsystem
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "avsys-audio-pasimple.h"
26 #include "avsys-types.h"
27 #include "avsys-error.h"
28 #include "avsys-debug.h"
29
30 #ifndef MURPHY_SUPPORT
31 #define PA_PROP_MEDIA_POLICY   "media.policy"
32 #endif
33
34 #define PA_SIMPLE_SAMPLES_PER_PERIOD_DEFAULT                            1536    /* frames */
35 #define PA_SIMPLE_PERIODS_PER_BUFFER_FASTMODE                           4
36 #define PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT                            6
37 #define PA_SIMPLE_PERIODS_PER_BUFFER_PLAYBACK                           8
38 #define PA_SIMPLE_PERIODS_PER_BUFFER_CAPTURE                            12
39 #define PA_SIMPLE_PERIODS_PER_BUFFER_VIDEO                                      10
40
41 #define PA_SIMPLE_PERIOD_TIME_FOR_ULOW_LATENCY_MSEC                     20
42 #define PA_SIMPLE_PERIOD_TIME_FOR_LOW_LATENCY_MSEC                      25
43 #define PA_SIMPLE_PERIOD_TIME_FOR_MID_LATENCY_MSEC                      50
44 #define PA_SIMPLE_PERIOD_TIME_FOR_HIGH_LATENCY_MSEC                     75
45
46 #define MSEC_TO_SAMPLE(samplerate,period_time)          (samplerate*period_time/1000)
47
48 #define CHECK_VALID_HANDLE(handle) \
49 do { \
50         if (handle == NULL) { \
51                 return AVSYS_STATE_ERR_NULL_POINTER; \
52         } \
53         device = (avsys_audio_pasimple_handle_t *)handle->device; \
54                 if (device == NULL) { \
55                         return AVSYS_STATE_ERR_NULL_POINTER; \
56                 } \
57         if (device->pasimple_handle == NULL) { \
58                 return AVSYS_STATE_ERR_NULL_POINTER; \
59         } \
60 } while (0)
61
62 #define SET_PA_ATTR(pt,spp,ppb,pb,mr,tl,ml,fs)  \
63 do { \
64         period_time = pt; \
65         samples_per_period = spp; \
66         periods_per_buffer = ppb; \
67         attr.prebuf = pb; \
68         attr.minreq = mr; \
69         attr.tlength = tl; \
70         attr.maxlength = ml; \
71         attr.fragsize = fs; \
72 } while (0)
73
74 #define MEDIA_POLICY_AUTO       "auto"
75 #define MEDIA_POLICY_PHONE      "phone"
76 #define MEDIA_POLICY_ALL        "all"
77
78 int avsys_audio_pasimple_open_device(const int mode, const unsigned int format, const unsigned int channel, const unsigned int samplerate, avsys_audio_handle_t *handle, int policy)
79 {
80         pa_simple *s = NULL;
81         pa_sample_spec ss;
82         avsys_audio_pasimple_handle_t *device = NULL;
83         pa_buffer_attr attr;
84         int err = AVSYS_STATE_SUCCESS;
85         int period_time = PA_SIMPLE_PERIOD_TIME_FOR_MID_LATENCY_MSEC;
86         int samples_per_period = PA_SIMPLE_SAMPLES_PER_PERIOD_DEFAULT;
87         int periods_per_buffer = PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT;
88         int vol_conf_type = AVSYS_AUDIO_VOLUME_CONFIG_TYPE(handle->gain_setting.volume_config);
89         pa_channel_map channel_map;
90
91         int p_time = PA_SIMPLE_PERIOD_TIME_FOR_HIGH_LATENCY_MSEC;
92         int p_count = PA_SIMPLE_PERIODS_PER_BUFFER_PLAYBACK;
93         char *time = getenv("AVSYS_PERIOD_TIME");
94         char *count = getenv("AVSYS_PERIOD_COUNT");
95         if(time)
96                 p_time = atoi(time);
97         if(count)
98                 p_count = atoi(count);
99
100 #ifdef MURPHY_SUPPORT
101         const char *media_role;
102 #endif
103
104         avsys_info(AVAUDIO, ">>>[%s] mode=%d, format=%d, channel=%d, samplerate=%d\n", __func__, mode, format, channel, samplerate);
105         avsys_assert(handle != NULL);
106
107         if (channel < AVSYS_CHANNEL_MIN || channel > AVSYS_CHANNEL_MAX)
108                 return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT;
109
110         device = (avsys_audio_pasimple_handle_t *)malloc(sizeof(avsys_audio_pasimple_handle_t));
111         if (device == NULL) {
112                 avsys_critical(AVAUDIO, "PA Simple handle alloc fail\n");
113                 return AVSYS_STATE_ERR_ALLOCATION;
114         }
115
116         ss.rate = samplerate;
117         ss.channels = channel;
118
119         pa_channel_map_init_auto(&channel_map, ss.channels, PA_CHANNEL_MAP_ALSA);
120
121         switch (format) {
122         case AVSYS_AUDIO_FORMAT_8BIT:
123                 ss.format = PA_SAMPLE_U8;
124                 device->samplesize = 1 * channel;
125                 break;
126         case AVSYS_AUDIO_FORMAT_16BIT:
127
128                 ss.format = PA_SAMPLE_S16LE;
129                 device->samplesize = 2 * channel;
130                 break;
131         default:
132                 free(device);
133                 avsys_error(AVAUDIO, "Invalid format\n");
134                 return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT;
135         }
136         handle->device = (void *)device;
137
138         pa_proplist *proplist = pa_proplist_new();
139
140         /* Set policy property */
141         avsys_info(AVAUDIO, ">>>[%s] policy=[%d], vol_type=[%d]\n", __func__, policy, vol_conf_type);
142
143 #ifdef MURPHY_SUPPORT
144     switch (vol_conf_type) {
145
146         case AVSYS_AUDIO_VOLUME_TYPE_SYSTEM:
147             media_role = "system";
148             break;
149
150         case AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION:
151             media_role = "event";
152             break;
153
154         case AVSYS_AUDIO_VOLUME_TYPE_ALARM:
155             media_role = "alarm";
156             break;
157
158         case AVSYS_AUDIO_VOLUME_TYPE_RINGTONE:
159             media_role = "ringtone";
160             break;
161
162         case AVSYS_AUDIO_VOLUME_TYPE_MEDIA:
163             media_role = "music";
164             break;
165
166         case AVSYS_AUDIO_VOLUME_TYPE_CALL:
167             media_role = "phone";
168             break;
169
170         case AVSYS_AUDIO_VOLUME_TYPE_FIXED:
171         case AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA:
172     default:
173             media_role = "music";
174             break;
175         }
176
177         avsys_info(AVAUDIO, ": set media role to '%s'\n", media_role);
178         pa_proplist_sets(proplist, PA_PROP_MEDIA_ROLE, media_role);
179 #else
180         if (policy == AVSYS_AUDIO_HANDLE_ROUTE_HANDSET_ONLY) {
181                 avsys_info(AVAUDIO, ": set media plicy to PHONE\n");
182                 pa_proplist_sets(proplist, PA_PROP_MEDIA_POLICY, MEDIA_POLICY_PHONE);
183         } else {
184                 /* AVSYS_AUDIO_HANDLE_ROUTE_FOLLOWING_POLICY */
185                 /* check stream type (vol type) */
186
187                 switch (vol_conf_type)
188                 {
189                 case AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION:
190                 case AVSYS_AUDIO_VOLUME_TYPE_ALARM:
191                         avsys_info(AVAUDIO, ": set media plicy to ALL\n");
192                         pa_proplist_sets(proplist, PA_PROP_MEDIA_POLICY, MEDIA_POLICY_ALL);
193                         break;
194
195                 case AVSYS_AUDIO_VOLUME_TYPE_FIXED:     /* Used for Emergency */
196                         avsys_info(AVAUDIO, ": set media plicy to PHONE\n");
197                         pa_proplist_sets(proplist, PA_PROP_MEDIA_POLICY, MEDIA_POLICY_PHONE);
198                         break;
199
200                 default:
201                         avsys_info(AVAUDIO, ": set media plicy to AUTO\n");
202                         pa_proplist_sets(proplist, PA_PROP_MEDIA_POLICY, MEDIA_POLICY_AUTO);
203                         break;
204                 }
205         }
206 #endif
207
208         handle->handle_route = policy;
209
210         memset(&attr, '\0', sizeof(attr));
211
212         switch (mode) {
213         case AVSYS_AUDIO_MODE_INPUT:
214                 SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_MID_LATENCY_MSEC,
215                                         MSEC_TO_SAMPLE(samplerate,period_time),
216                                         PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT,
217                                         0, -1, -1, -1, samples_per_period * device->samplesize);
218
219                 s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_RECORD, NULL, "CAPTURE", &ss, &channel_map, &attr, proplist, &err);
220                 break;
221
222         case AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY:
223                 SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_ULOW_LATENCY_MSEC,
224                                         MSEC_TO_SAMPLE(samplerate,period_time),
225                                         PA_SIMPLE_PERIODS_PER_BUFFER_FASTMODE,
226                                         0, -1, -1, -1, samples_per_period * device->samplesize);
227
228                 s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_RECORD, NULL, "LOW LATENCY CAPTURE", &ss, &channel_map, &attr, proplist, &err);
229                 break;
230
231         case AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY:
232                 SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_HIGH_LATENCY_MSEC,
233                                         MSEC_TO_SAMPLE(samplerate,period_time),
234                                         PA_SIMPLE_PERIODS_PER_BUFFER_CAPTURE,
235                                         0, -1, -1, -1, samples_per_period * device->samplesize);
236
237                 s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_RECORD, NULL, "HIGH LATENCY CAPTURE", &ss, &channel_map, &attr, proplist, &err);
238                 break;
239
240         case AVSYS_AUDIO_MODE_OUTPUT:   /* mid latency playback for normal audio case. */
241                 SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_MID_LATENCY_MSEC,
242                                                 MSEC_TO_SAMPLE(samplerate,period_time),
243                                                 PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT,
244                                                 -1, -1, periods_per_buffer * samples_per_period * device->samplesize, attr.tlength, 0);
245
246                 s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "PLAYBACK", &ss, &channel_map, &attr, proplist, &err);
247                 break;
248
249         case AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY:       /* This is special case for touch sound playback */
250                 SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_LOW_LATENCY_MSEC,
251                                         MSEC_TO_SAMPLE(samplerate,period_time),
252                                         PA_SIMPLE_PERIODS_PER_BUFFER_FASTMODE,
253                                         samples_per_period * device->samplesize, -1, samples_per_period * device->samplesize + 3430, (uint32_t)-1, 0);
254
255                 s = pa_simple_new_proplist(NULL,"AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "LOW LATENCY PLAYBACK", &ss, &channel_map, &attr, proplist, &err);
256                 break;
257         case AVSYS_AUDIO_MODE_OUTPUT_CLOCK: /* high latency playback - lager buffer size */
258                 SET_PA_ATTR(p_time,
259                                         MSEC_TO_SAMPLE(samplerate,period_time),
260                                         p_count,
261                                         (uint32_t) -1, (uint32_t) -1, periods_per_buffer * samples_per_period * device->samplesize, (uint32_t)-1, 0);
262
263                 s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "HIGH LATENCY PLAYBACK", &ss, &channel_map, &attr, proplist, &err);
264                 break;
265
266         case AVSYS_AUDIO_MODE_OUTPUT_VIDEO:     /* low latency playback */
267                 SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_LOW_LATENCY_MSEC,
268                                         MSEC_TO_SAMPLE(samplerate,period_time),
269                                         PA_SIMPLE_PERIODS_PER_BUFFER_VIDEO,
270                                         4*(samples_per_period * device->samplesize), samples_per_period * device->samplesize, periods_per_buffer * samples_per_period * device->samplesize, (uint32_t)-1, 0);
271
272                 s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "LOW LATENCY PLAYBACK", &ss, &channel_map, &attr, proplist, &err);
273                 break;
274
275         case AVSYS_AUDIO_MODE_OUTPUT_AP_CALL:
276 #if defined(_MMFW_I386_ALL_SIMULATOR)
277                 avsys_warning(AVAUDIO, "Does not support AP call mode at i386 simulator\n");
278                 s = NULL;
279 #else
280                 SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_LOW_LATENCY_MSEC,
281                                         MSEC_TO_SAMPLE(samplerate,period_time),
282                                         PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT,
283                                         (uint32_t) -1, (uint32_t) -1, periods_per_buffer * samples_per_period * device->samplesize, attr.tlength, 0);
284
285
286                 s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "VoIP PLAYBACK", &ss, &channel_map, &attr, proplist, &err);
287 #endif
288                 break;
289         case AVSYS_AUDIO_MODE_INPUT_AP_CALL:
290 #if defined(_MMFW_I386_ALL_SIMULATOR)
291                 avsys_warning(AVAUDIO, "Does not support AP call mode at i386 simulator\n");
292                 s = NULL;
293 #else
294                 SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_LOW_LATENCY_MSEC,
295                                         MSEC_TO_SAMPLE(samplerate,period_time),
296                                         PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT,
297                                         0, (uint32_t) -1, (uint32_t) -1, (uint32_t) -1, samples_per_period * device->samplesize);
298
299                 s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_RECORD, NULL, "VoIP CAPTURE", &ss, &channel_map, &attr, proplist, &err);
300 #endif
301                 break;
302         case AVSYS_AUDIO_MODE_CALL_OUT:
303         case AVSYS_AUDIO_MODE_CALL_IN:
304                 //TODO
305                 avsys_error(AVAUDIO, "Does not support call device handling\n");
306                 avsys_assert_r(0);
307                 break;
308         default:
309                 avsys_critical_r(AVAUDIO, "Invalid open mode %d\n", mode);
310                 avsys_assert_r(0);
311                 return AVSYS_STATE_ERR_INVALID_MODE;
312                 break;
313         }
314
315         if (!s) {
316                 avsys_error_r(AVAUDIO, "Open pulseaudio handle has failed - %s\n", pa_strerror(err));
317                 err = AVSYS_STATE_ERR_INTERNAL;
318                 goto fail;
319         }
320
321         avsys_info(AVAUDIO, "Samples(per period) : %d\t Periods(per buffer) : %d\n", samples_per_period, periods_per_buffer);
322
323         device->pasimple_handle = (void *)s;
324         device->mode = mode;
325         device->period_frames = samples_per_period;
326         device->buffer_frames = periods_per_buffer * device->period_frames;
327         device->periods_per_buffer = periods_per_buffer;
328         handle->period = device->period_frames * device->samplesize;
329         handle->msec_per_period = period_time;
330         if (0 > pa_simple_get_stream_index(s, &handle->stream_index, &err)) {
331                 avsys_error(AVAUDIO, "Can not get stream index %s\n", pa_strerror(err));
332                 err = AVSYS_STATE_ERR_INVALID_HANDLE;
333         }
334
335 fail:
336         if (proplist)
337                 pa_proplist_free(proplist);
338
339         return err;
340 }
341
342 int avsys_audio_pasimple_close_device(avsys_audio_handle_t *handle)
343 {
344         int err = 0;
345         avsys_audio_pasimple_handle_t *device = NULL;
346         pa_simple *s = NULL;
347
348         avsys_info(AVAUDIO, "%s\n", __func__);
349
350         avsys_assert(handle != NULL);
351         CHECK_VALID_HANDLE(handle);
352
353         switch (handle->mode) {
354         case AVSYS_AUDIO_MODE_CALL_OUT:
355         case AVSYS_AUDIO_MODE_CALL_IN:
356                 avsys_warning(AVAUDIO, "Unsupported close mode in pa function\n");
357                 return AVSYS_STATE_ERR_INVALID_MODE;
358         case AVSYS_AUDIO_MODE_OUTPUT_AP_CALL:
359         case AVSYS_AUDIO_MODE_INPUT_AP_CALL:
360 #if defined(_MMFW_I386_ALL_SIMULATOR)
361                 avsys_warning(AVAUDIO, "Skip close call device in SDK");
362                 return AVSYS_STATE_SUCCESS;
363 #endif
364         default:
365                 break;
366         }
367
368         s = (pa_simple *)device->pasimple_handle;
369         avsys_assert(s != NULL);
370
371         switch (handle->mode) {
372         case AVSYS_AUDIO_MODE_OUTPUT:
373         case AVSYS_AUDIO_MODE_OUTPUT_CLOCK:
374         case AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY:
375         case AVSYS_AUDIO_MODE_OUTPUT_AP_CALL:
376         case AVSYS_AUDIO_MODE_OUTPUT_VIDEO:
377                 if (0 > pa_simple_flush(s, &err)) {
378                         avsys_error(AVAUDIO, "pa_simple_flush() failed with %s\n", pa_strerror(err));
379                 }
380                 break;
381         default:
382                 break;
383         }
384
385         pa_simple_free(s);
386
387         device->pasimple_handle = NULL;
388         free(device);
389
390         return AVSYS_STATE_SUCCESS;
391 }
392
393 int avsys_audio_pasimple_write(avsys_audio_handle_t *handle, const void *buf, int size)
394 {
395         pa_simple *s = NULL;
396         avsys_audio_pasimple_handle_t *device = NULL;
397         int err = 0;
398
399         if (buf == NULL)
400                         return AVSYS_STATE_ERR_NULL_POINTER;
401         CHECK_VALID_HANDLE(handle);
402
403         if (size < 0)
404                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
405         else if (size == 0)
406                 return 0;
407
408         s = (pa_simple *)device->pasimple_handle;
409
410         if (0 > pa_simple_write(s, buf, size, &err)) {
411                 avsys_error(AVAUDIO, "pa_simple_write() failed with %s\n", pa_strerror(err));
412                 return AVSYS_STATE_ERR_INTERNAL;
413         }
414
415         return size;
416 }
417
418 int avsys_audio_pasimple_read(avsys_audio_handle_t *handle, void *buf, int size)
419 {
420         pa_simple *s = NULL;
421         avsys_audio_pasimple_handle_t *device = NULL;
422         int err = 0;
423
424         if (buf == NULL)
425                         return AVSYS_STATE_ERR_NULL_POINTER;
426         CHECK_VALID_HANDLE(handle);
427
428         if (size < 0)
429                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
430         else if (size == 0)
431                 return 0;
432
433         s = (pa_simple *)device->pasimple_handle;
434
435         if (0 > pa_simple_read(s, buf, size, &err)) {
436                 avsys_error(AVAUDIO, "pa_simple_read() failed with %s\n", pa_strerror(err));
437                 return AVSYS_STATE_ERR_INTERNAL;
438         }
439
440         return size;
441 }
442
443 int avsys_audio_pasimple_reset(avsys_audio_handle_t *handle)
444 {
445         pa_simple *s = NULL;
446         avsys_audio_pasimple_handle_t *device = NULL;
447         int err = 0;
448
449         CHECK_VALID_HANDLE(handle);
450
451         if (handle->mode == AVSYS_AUDIO_MODE_INPUT || handle->mode == AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY) {
452                 avsys_warning(AVAUDIO, "Skip pa_simple_flush() when input mode\n");
453                 return AVSYS_STATE_SUCCESS;
454         }
455
456         s = (pa_simple *)device->pasimple_handle;
457
458         if (0 > pa_simple_flush(s, &err)) {
459                 avsys_error(AVAUDIO, "pa_simple_flush() failed with %s\n", pa_strerror(err));
460                 return AVSYS_STATE_ERR_INTERNAL;
461         }
462
463         return AVSYS_STATE_SUCCESS;
464 }
465
466 int avsys_audio_pasimple_drain(avsys_audio_handle_t *handle)
467 {
468         pa_simple *s = NULL;
469         avsys_audio_pasimple_handle_t *device = NULL;
470         int err = 0;
471
472         CHECK_VALID_HANDLE(handle);
473
474         s = (pa_simple *)device->pasimple_handle;
475
476         if (0 > pa_simple_drain(s, &err)) {
477                 avsys_error(AVAUDIO, "pa_simple_drain() failed with %s\n", pa_strerror(err));
478                 return AVSYS_STATE_ERR_INTERNAL;
479         }
480
481         return AVSYS_STATE_SUCCESS;
482 }
483
484 int avsys_audio_pasimple_set_volume(avsys_audio_handle_t *handle, int volume)
485 {
486         pa_simple *s = NULL;
487         avsys_audio_pasimple_handle_t *device = NULL;
488         int err = 0;
489
490         CHECK_VALID_HANDLE(handle);
491
492         s = (pa_simple *)device->pasimple_handle;
493
494         if (0 > pa_simple_set_volume(s, volume, &err)) {
495                 avsys_error(AVAUDIO, "pa_simple_set_volume() failed with %s\n", pa_strerror(err));
496                 return AVSYS_STATE_ERR_INTERNAL;
497         }
498
499         return AVSYS_STATE_SUCCESS;
500 }
501
502 #define USEC_TO_SAMPLE(usec, rate)      ((usec*rate)/1000000)
503 #define SAMPLES_TO_USEC(samples,rate)   ((samples*1000000)/rate)
504 #define BYTES_TO_USEC(bytes,size_per_sample,rate)       ((bytes*1000000)/(size_per_sample*rate))
505
506 int avsys_audio_pasimple_delay(avsys_audio_handle_t *handle, int *delay)
507 {
508         pa_simple *s = NULL;
509         avsys_audio_pasimple_handle_t *device = NULL;
510         int err = 0;
511         pa_usec_t latency_time = 0;
512         unsigned int latency_frames = 0;
513
514         if (delay == NULL) {
515                 return AVSYS_STATE_ERR_NULL_POINTER;
516         }
517         CHECK_VALID_HANDLE(handle);
518
519         s = (pa_simple *)device->pasimple_handle;
520
521         latency_time = pa_simple_get_latency(s, &err);
522         if (err > 0 && latency_time == 0) {
523                 avsys_error(AVAUDIO, "pa_simple_get_latency() failed with %s\n", pa_strerror(err));
524                 return AVSYS_STATE_ERR_INTERNAL;
525         }
526         /* convert time to sample */
527         latency_frames = USEC_TO_SAMPLE(latency_time, handle->samplerate);
528         *delay = latency_frames;
529
530         return AVSYS_STATE_SUCCESS;
531 }
532
533 int avsys_audio_pasimple_get_period_buffer_time(avsys_audio_handle_t *handle, unsigned int *period_time, unsigned int *buffer_time)
534 {
535         avsys_audio_pasimple_handle_t *device = NULL;
536
537         if ((period_time == NULL) || (buffer_time == NULL))
538                 return AVSYS_STATE_ERR_INTERNAL;
539
540         CHECK_VALID_HANDLE(handle);
541
542         *period_time = SAMPLES_TO_USEC(device->period_frames,handle->samplerate);
543         *buffer_time = *period_time * device->periods_per_buffer;
544
545         avsys_info(AVAUDIO, "[%s][%d] period = %d, buffer = %d\n", __func__, __LINE__, *period_time, *buffer_time);
546
547         return AVSYS_STATE_SUCCESS;
548 }
549
550 int avsys_audio_pasimple_cork(avsys_audio_handle_t *handle, int cork)
551 {
552         pa_simple *s = NULL;
553         avsys_audio_pasimple_handle_t *device = NULL;
554         int err = 0;
555
556         CHECK_VALID_HANDLE(handle);
557
558         s = (pa_simple *)device->pasimple_handle;
559
560         if (0 > pa_simple_cork(s, cork, &err)) {
561                 avsys_error(AVAUDIO, "pa_simple_cork() failed with %s\n", pa_strerror(err));
562                 return AVSYS_STATE_ERR_INTERNAL;
563         }
564
565         return AVSYS_STATE_SUCCESS;
566 }
567
568 int avsys_audio_pasimple_is_corked(avsys_audio_handle_t *handle, int *is_corked)
569 {
570         pa_simple *s = NULL;
571         avsys_audio_pasimple_handle_t *device = NULL;
572         int err = 0;
573
574         if (is_corked == NULL)
575                 return AVSYS_STATE_ERR_INTERNAL;
576
577         CHECK_VALID_HANDLE(handle);
578
579         s = (pa_simple *)device->pasimple_handle;
580
581         *is_corked = pa_simple_is_corked(s);
582
583         return AVSYS_STATE_SUCCESS;
584 }
585
586