summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Willmann <d.willmann@samsung.com>2013-06-14 13:42:23 +0100
committerDaniel Willmann <d.willmann@samsung.com>2013-06-14 13:42:23 +0100
commit2eec30815d617e39811586f48513d74ab05e9b37 (patch)
tree1f73e5523e7f9b54ab70905e1a171149646c24d5
parent1c6aa0c8656f953699680e44005e8ce252855d3b (diff)
Signed-off-by: Daniel Willmann <d.willmann@samsung.com>
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_out_alsa.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/src/lib/ecore_audio/ecore_audio_obj_out_alsa.c b/src/lib/ecore_audio/ecore_audio_obj_out_alsa.c
index 38a5fd9ef9..cc2e7906a5 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_out_alsa.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_out_alsa.c
@@ -34,11 +34,25 @@ typedef struct _Ecore_Audio_Alsa Ecore_Audio_Alsa;
34struct _Ecore_Audio_Alsa_Data 34struct _Ecore_Audio_Alsa_Data
35{ 35{
36 snd_pcm_t *handle; 36 snd_pcm_t *handle;
37 Ecore_Timer *timer; 37 Ecore_Idler *idler;
38}; 38};
39 39
40typedef struct _Ecore_Audio_Alsa_Data Ecore_Audio_Alsa_Data; 40typedef struct _Ecore_Audio_Alsa_Data Ecore_Audio_Alsa_Data;
41 41
42
43static Eina_Bool _close_cb(void *data)
44{
45 snd_pcm_t *handle = data;
46 snd_pcm_close(handle);
47
48 return EINA_FALSE;
49}
50
51static void _delayed_close(snd_pcm_t *handle)
52{
53 ecore_timer_add(2, _close_cb, handle);
54}
55
42static void _volume_set(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list) 56static void _volume_set(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list)
43{ 57{
44 Eo *in; 58 Eo *in;
@@ -69,23 +83,39 @@ static Eina_Bool _write_cb(void *data)
69 83
70 size_t avail; 84 size_t avail;
71 ssize_t bread; 85 ssize_t bread;
72 int ret; 86 int ret, channels;
73 87
74 eo_do(in, eo_base_data_get("alsa_data", (void **)&alsa)); 88 eo_do(in, eo_base_data_get("alsa_data", (void **)&alsa));
75 89
76 avail = snd_pcm_avail_update(alsa->handle); 90 eo_do(in, ecore_audio_obj_in_channels_get(&channels));
91
92 avail = snd_pcm_avail(alsa->handle);
93
94 if (avail < 1000)
95 return EINA_TRUE;
77 96
78 buf = calloc(1, sizeof(float) * avail * 8); 97 buf = calloc(1, sizeof(float) * avail * channels);
79 98
80 eo_do(in, ecore_audio_obj_in_read(buf, avail*8, &bread)); 99 eo_do(in, ecore_audio_obj_in_read(buf, avail*channels, &bread));
81 100
82 ret = snd_pcm_writei(alsa->handle, buf, bread/8); 101 ERR("ALSA: avail %i, read %i", avail, bread/channels);
102
103 if (bread == 0)
104 goto end;
105
106 ret = snd_pcm_writei(alsa->handle, buf, bread/channels);
83 if (ret < 0) 107 if (ret < 0)
84 { 108 {
85 ERR("Error when writing: %s", snd_strerror(ret)); 109 ERR("Error when writing: %s (avail %i, read %i)", snd_strerror(ret), avail, bread);
86 snd_pcm_recover(alsa->handle, ret, 0); 110 snd_pcm_recover(alsa->handle, ret, 0);
87 } 111 }
88 112
113 if (bread<avail*channels)
114 snd_pcm_start(alsa->handle);
115
116 ERR("Success: written %i", ret);
117end:
118 free(buf);
89 return EINA_TRUE; 119 return EINA_TRUE;
90} 120}
91 121
@@ -159,7 +189,7 @@ static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in)
159 if (ea_obj->paused) 189 if (ea_obj->paused)
160 return EINA_TRUE; 190 return EINA_TRUE;
161 191
162 alsa->timer = ecore_timer_add(0.3, _write_cb, in); 192 alsa->idler = ecore_idler_add(_write_cb, in);
163 193
164 return EINA_TRUE; 194 return EINA_TRUE;
165} 195}
@@ -193,9 +223,9 @@ static void _input_detach(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list)
193 223
194 eo_do(in, eo_base_data_get("alsa_data", (void **)&alsa)); 224 eo_do(in, eo_base_data_get("alsa_data", (void **)&alsa));
195 225
196 ecore_timer_del(alsa->timer); 226 ecore_idler_del(alsa->idler);
197 227
198 snd_pcm_close(alsa->handle); 228 _delayed_close(alsa->handle);
199 229
200 eo_do(in, eo_base_data_del("alsa_data")); 230 eo_do(in, eo_base_data_del("alsa_data"));
201 231