FIX: [droid] set "remote as keyboard" default to true
[vuplus_xbmc] / xbmc / cores / AudioEngine / Sinks / AESinkPULSE.cpp
1 /*
2  *      Copyright (C) 2010-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20 #include "system.h"
21 #ifdef HAS_PULSEAUDIO
22 #include "AESinkPULSE.h"
23 #include "utils/log.h"
24 #include "Util.h"
25 #include "guilib/LocalizeStrings.h"
26 #include "Application.h"
27
28 using namespace std;
29
30 static const char *ContextStateToString(pa_context_state s)
31 {
32   switch (s)
33   {
34     case PA_CONTEXT_UNCONNECTED:
35       return "unconnected";
36     case PA_CONTEXT_CONNECTING:
37       return "connecting";
38     case PA_CONTEXT_AUTHORIZING:
39       return "authorizing";
40     case PA_CONTEXT_SETTING_NAME:
41       return "setting name";
42     case PA_CONTEXT_READY:
43       return "ready";
44     case PA_CONTEXT_FAILED:
45       return "failed";
46     case PA_CONTEXT_TERMINATED:
47       return "terminated";
48     default:
49       return "none";
50   }
51 }
52
53 static const char *StreamStateToString(pa_stream_state s)
54 {
55   switch(s)
56   {
57     case PA_STREAM_UNCONNECTED:
58       return "unconnected";
59     case PA_STREAM_CREATING:
60       return "creating";
61     case PA_STREAM_READY:
62       return "ready";
63     case PA_STREAM_FAILED:
64       return "failed";
65     case PA_STREAM_TERMINATED:
66       return "terminated";
67     default:
68       return "none";
69   }
70 }
71
72 static pa_sample_format AEFormatToPulseFormat(AEDataFormat format)
73 {
74   switch (format)
75   {
76     case AE_FMT_U8    : return PA_SAMPLE_U8;
77     case AE_FMT_S16LE : return PA_SAMPLE_S16LE;
78     case AE_FMT_S16BE : return PA_SAMPLE_S16BE;
79     case AE_FMT_S16NE : return PA_SAMPLE_S16NE;
80     case AE_FMT_S24LE3: return PA_SAMPLE_S24LE;
81     case AE_FMT_S24BE3: return PA_SAMPLE_S24BE;
82     case AE_FMT_S24NE3: return PA_SAMPLE_S24NE;
83     case AE_FMT_S24LE4: return PA_SAMPLE_S24_32LE;
84     case AE_FMT_S24BE4: return PA_SAMPLE_S24_32BE;
85     case AE_FMT_S24NE4: return PA_SAMPLE_S24_32NE;
86     case AE_FMT_S32BE : return PA_SAMPLE_S32BE;
87     case AE_FMT_S32LE : return PA_SAMPLE_S32LE;
88     case AE_FMT_S32NE : return PA_SAMPLE_S32NE;
89     case AE_FMT_FLOAT : return PA_SAMPLE_FLOAT32;
90
91     case AE_FMT_AC3:
92     case AE_FMT_DTS:
93     case AE_FMT_EAC3:
94       return PA_SAMPLE_S16NE;
95
96     default:
97       return PA_SAMPLE_INVALID;
98   }
99 }
100
101 static pa_encoding AEFormatToPulseEncoding(AEDataFormat format)
102 {
103   switch (format)
104   {
105     case AE_FMT_AC3   : return PA_ENCODING_AC3_IEC61937;
106     case AE_FMT_DTS   : return PA_ENCODING_DTS_IEC61937;
107     case AE_FMT_EAC3  : return PA_ENCODING_EAC3_IEC61937;
108
109     default:
110       return PA_ENCODING_PCM;
111   }
112 }
113
114 static AEDataFormat defaultDataFormats[] = {
115   AE_FMT_U8,
116   AE_FMT_S16LE,
117   AE_FMT_S16BE,
118   AE_FMT_S16NE,
119   AE_FMT_S24LE3,
120   AE_FMT_S24BE3,
121   AE_FMT_S24NE3,
122   AE_FMT_S24LE4,
123   AE_FMT_S24BE4,
124   AE_FMT_S24NE4,
125   AE_FMT_S32BE,
126   AE_FMT_S32LE,
127   AE_FMT_S32NE,
128   AE_FMT_FLOAT
129 };
130
131 static unsigned int defaultSampleRates[] = {
132   5512,
133   8000,
134   11025,
135   16000,
136   22050,
137   32000,
138   44100,
139   48000,
140   64000,
141   88200,
142   96000,
143   176400,
144   192000,
145   384000
146 };
147
148 /* Static callback functions */
149
150 static void ContextStateCallback(pa_context *c, void *userdata)
151 {
152   pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata;
153   switch (pa_context_get_state(c))
154   {
155     case PA_CONTEXT_READY:
156     case PA_CONTEXT_TERMINATED:
157     case PA_CONTEXT_UNCONNECTED:
158     case PA_CONTEXT_CONNECTING:
159     case PA_CONTEXT_AUTHORIZING:
160     case PA_CONTEXT_SETTING_NAME:
161     case PA_CONTEXT_FAILED:
162       pa_threaded_mainloop_signal(m, 0);
163       break;
164   }
165 }
166
167 static void StreamStateCallback(pa_stream *s, void *userdata)
168 {
169   pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata;
170   switch (pa_stream_get_state(s))
171   {
172     case PA_STREAM_UNCONNECTED:
173     case PA_STREAM_CREATING:
174     case PA_STREAM_READY:
175     case PA_STREAM_FAILED:
176     case PA_STREAM_TERMINATED:
177       pa_threaded_mainloop_signal(m, 0);
178       break;
179   }
180 }
181
182 static void StreamRequestCallback(pa_stream *s, size_t length, void *userdata)
183 {
184   pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata;
185   pa_threaded_mainloop_signal(m, 0);
186 }
187
188 static void StreamLatencyUpdateCallback(pa_stream *s, void *userdata)
189 {
190   pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata;
191   pa_threaded_mainloop_signal(m, 0);
192 }
193
194 static void SinkChangedCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata)
195 {
196   CAESinkPULSE* p = (CAESinkPULSE*) userdata;
197   if(!p)
198     return;
199
200   CSingleLock lock(p->m_sec);
201   if (p->IsInitialized())
202   {
203     if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW)
204     {
205        CLog::Log(LOGDEBUG, "Sink appeared");
206        CAEFactory::DeviceChange();
207     }
208     else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
209     {
210       CLog::Log(LOGDEBUG, "Sink removed");
211       CAEFactory::DeviceChange();
212     }
213     else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_CHANGE)
214     {
215       CLog::Log(LOGDEBUG, "Sink changed");
216       //CAEFactory::DeviceChange();
217     }    
218   }
219 }
220
221 struct SinkInfoStruct
222 {
223   AEDeviceInfoList *list;
224   bool isHWDevice;
225   bool device_found;
226   pa_threaded_mainloop *mainloop;
227   int samplerate;
228   SinkInfoStruct()
229   {
230     list = NULL;
231     isHWDevice = false;
232     device_found = true;
233     mainloop = NULL;
234     samplerate = 0;
235   }
236 };
237
238 struct SinkInputInfoStruct
239 {
240   bool is_valid;
241   int mute;
242   int index;
243   pa_cvolume volume;
244   pa_threaded_mainloop *mainloop;
245   SinkInputInfoStruct()
246   {
247     is_valid = false;
248     mute = 0;
249     mainloop = NULL;
250   }
251 };
252
253 static void SinkInfoCallback(pa_context *c, const pa_sink_info *i, int eol, void *userdata)
254 {
255   SinkInfoStruct *sinkStruct = (SinkInfoStruct *)userdata;
256   if(i)
257   {
258     if (i->flags && (i->flags & PA_SINK_HARDWARE))
259       sinkStruct->isHWDevice = true;
260
261     sinkStruct->samplerate = i->sample_spec.rate;
262     sinkStruct->device_found = true;
263   }
264   pa_threaded_mainloop_signal(sinkStruct->mainloop, 0);
265 }
266
267 static void SinkInputInfoCallback(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata)
268 {
269   SinkInputInfoStruct *siiStruct = (SinkInputInfoStruct *)userdata;
270   if(i && i->has_volume)
271   {
272     siiStruct->is_valid = true;
273     siiStruct->volume = i->volume;
274     siiStruct->mute = i->mute;
275     siiStruct->index = i->index;
276   }
277   pa_threaded_mainloop_signal(siiStruct->mainloop, 0);
278 }
279
280 static AEChannel PAChannelToAEChannel(pa_channel_position_t channel)
281 {
282   AEChannel ae_channel;
283   switch (channel)
284   {
285     case PA_CHANNEL_POSITION_FRONT_LEFT:            ae_channel = AE_CH_FL; break;
286     case PA_CHANNEL_POSITION_FRONT_RIGHT:           ae_channel = AE_CH_FR; break;
287     case PA_CHANNEL_POSITION_FRONT_CENTER:          ae_channel = AE_CH_FC; break;
288     case PA_CHANNEL_POSITION_LFE:                   ae_channel = AE_CH_LFE; break;
289     case PA_CHANNEL_POSITION_REAR_LEFT:             ae_channel = AE_CH_BL; break;
290     case PA_CHANNEL_POSITION_REAR_RIGHT:            ae_channel = AE_CH_BR; break;
291     case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER:  ae_channel = AE_CH_FLOC; break;
292     case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: ae_channel = AE_CH_FROC; break;
293     case PA_CHANNEL_POSITION_REAR_CENTER:           ae_channel = AE_CH_BC; break;
294     case PA_CHANNEL_POSITION_SIDE_LEFT:             ae_channel = AE_CH_SL; break;
295     case PA_CHANNEL_POSITION_SIDE_RIGHT:            ae_channel = AE_CH_SR; break;
296     case PA_CHANNEL_POSITION_TOP_FRONT_LEFT:        ae_channel = AE_CH_TFL; break;
297     case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT:       ae_channel = AE_CH_TFR; break;
298     case PA_CHANNEL_POSITION_TOP_FRONT_CENTER:      ae_channel = AE_CH_TFC; break;
299     case PA_CHANNEL_POSITION_TOP_CENTER:            ae_channel = AE_CH_TC; break;
300     case PA_CHANNEL_POSITION_TOP_REAR_LEFT:         ae_channel = AE_CH_TBL; break;
301     case PA_CHANNEL_POSITION_TOP_REAR_RIGHT:        ae_channel = AE_CH_TBR; break;
302     case PA_CHANNEL_POSITION_TOP_REAR_CENTER:       ae_channel = AE_CH_TBC; break;
303     default:                                        ae_channel = AE_CH_NULL; break;
304   }
305   return ae_channel;
306 }
307
308 static pa_channel_position_t AEChannelToPAChannel(AEChannel ae_channel)
309 {
310   pa_channel_position_t pa_channel;
311   switch (ae_channel)
312   {
313     case AE_CH_FL:    pa_channel = PA_CHANNEL_POSITION_FRONT_LEFT; break;
314     case AE_CH_FR:    pa_channel = PA_CHANNEL_POSITION_FRONT_RIGHT; break;
315     case AE_CH_FC:    pa_channel = PA_CHANNEL_POSITION_FRONT_CENTER; break;
316     case AE_CH_LFE:   pa_channel = PA_CHANNEL_POSITION_LFE; break;
317     case AE_CH_BL:    pa_channel = PA_CHANNEL_POSITION_REAR_LEFT; break;
318     case AE_CH_BR:    pa_channel = PA_CHANNEL_POSITION_REAR_RIGHT; break;
319     case AE_CH_FLOC:  pa_channel = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER; break;
320     case AE_CH_FROC:  pa_channel = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER; break;
321     case AE_CH_BC:    pa_channel = PA_CHANNEL_POSITION_REAR_CENTER; break;
322     case AE_CH_SL:    pa_channel = PA_CHANNEL_POSITION_SIDE_LEFT; break;
323     case AE_CH_SR:    pa_channel = PA_CHANNEL_POSITION_SIDE_RIGHT; break;
324     case AE_CH_TFL:   pa_channel = PA_CHANNEL_POSITION_TOP_FRONT_LEFT; break;
325     case AE_CH_TFR:   pa_channel = PA_CHANNEL_POSITION_TOP_FRONT_RIGHT; break;
326     case AE_CH_TFC:   pa_channel = PA_CHANNEL_POSITION_TOP_FRONT_CENTER; break;
327     case AE_CH_TC:    pa_channel = PA_CHANNEL_POSITION_TOP_CENTER; break;
328     case AE_CH_TBL:   pa_channel = PA_CHANNEL_POSITION_TOP_REAR_LEFT; break;
329     case AE_CH_TBR:   pa_channel = PA_CHANNEL_POSITION_TOP_REAR_RIGHT; break;
330     case AE_CH_TBC:   pa_channel = PA_CHANNEL_POSITION_TOP_REAR_CENTER; break;
331     default:          pa_channel = PA_CHANNEL_POSITION_INVALID; break;
332   }
333   return pa_channel;
334 }
335
336 static pa_channel_map AEChannelMapToPAChannel(CAEChannelInfo info)
337 {
338   pa_channel_map map;
339   pa_channel_map_init(&map);
340   pa_channel_position_t pos;
341   for (unsigned int i = 0; i < info.Count(); ++i)
342   {
343     pos = AEChannelToPAChannel(info[i]);
344     if(pos != PA_CHANNEL_POSITION_INVALID)
345     {
346       // remember channel name and increase channel count
347       map.map[map.channels++] = pos;
348     }
349   }
350   return map;
351 }
352
353 static CAEChannelInfo PAChannelToAEChannelMap(pa_channel_map channels)
354 {
355   CAEChannelInfo info;
356   AEChannel ch;
357   info.Reset();
358   for (unsigned int i=0; i<channels.channels; i++)
359   {
360     ch = PAChannelToAEChannel(channels.map[i]);
361     if(ch != AE_CH_NULL)
362       info += ch;
363   }
364   return info;
365 }
366
367 static void SinkInfoRequestCallback(pa_context *c, const pa_sink_info *i, int eol, void *userdata)
368 {
369
370   SinkInfoStruct *sinkStruct = (SinkInfoStruct *)userdata;
371
372   if(sinkStruct && sinkStruct->list->empty())
373   {
374     //add a default device first
375     CAEDeviceInfo defaultDevice;
376     defaultDevice.m_deviceName = std::string("Default");
377     defaultDevice.m_displayName = std::string("Default");
378     defaultDevice.m_displayNameExtra = std::string("Default Output Device (PULSEAUDIO)");
379     defaultDevice.m_dataFormats.insert(defaultDevice.m_dataFormats.end(), defaultDataFormats, defaultDataFormats + sizeof(defaultDataFormats) / sizeof(defaultDataFormats[0]));
380     defaultDevice.m_channels = CAEChannelInfo(AE_CH_LAYOUT_2_0);
381     defaultDevice.m_sampleRates.assign(defaultSampleRates, defaultSampleRates + sizeof(defaultSampleRates) / sizeof(defaultSampleRates[0]));
382     defaultDevice.m_deviceType = AE_DEVTYPE_PCM;
383     sinkStruct->list->push_back(defaultDevice);
384   }
385   bool valid = true;
386   if (i && i->name)
387   {
388     CAEDeviceInfo device;
389
390     device.m_deviceName = string(i->name);
391     device.m_displayName = string(i->description);
392     if (i->active_port && i->active_port->description)
393       device.m_displayNameExtra = std::string((i->active_port->description)).append(" (PULSEAUDIO)");
394     else
395       device.m_displayNameExtra = std::string((i->description)).append(" (PULSEAUDIO)");
396     unsigned int device_type = AE_DEVTYPE_PCM; //0
397
398     device.m_channels = PAChannelToAEChannelMap(i->channel_map);
399
400     // Don't add devices that would not have a channel map
401     if(device.m_channels.Count() == 0)
402       valid = false;
403
404     device.m_sampleRates.assign(defaultSampleRates, defaultSampleRates + sizeof(defaultSampleRates) / sizeof(defaultSampleRates[0]));
405
406     for (unsigned int j = 0; j < i->n_formats; j++)
407     {
408       switch(i->formats[j]->encoding)
409       {
410         case PA_ENCODING_AC3_IEC61937:
411           device.m_dataFormats.push_back(AE_FMT_AC3);
412           device_type = AE_DEVTYPE_IEC958;
413           break;
414         case PA_ENCODING_DTS_IEC61937:
415           device.m_dataFormats.push_back(AE_FMT_DTS);
416           device_type = AE_DEVTYPE_IEC958;
417           break;
418         case PA_ENCODING_EAC3_IEC61937:
419           device.m_dataFormats.push_back(AE_FMT_EAC3);
420           device_type = AE_DEVTYPE_IEC958;
421           break;
422         case PA_ENCODING_PCM:
423           device.m_dataFormats.insert(device.m_dataFormats.end(), defaultDataFormats, defaultDataFormats + sizeof(defaultDataFormats) / sizeof(defaultDataFormats[0]));
424           break;
425         default:
426           break;
427       }
428     }
429     // passthrough is only working when device has Stereo channel config
430     if (device_type > AE_DEVTYPE_PCM && device.m_channels.Count() == 2)
431       device.m_deviceType = AE_DEVTYPE_IEC958;
432     else
433       device.m_deviceType = AE_DEVTYPE_PCM;
434     if(valid)
435     {
436       CLog::Log(LOGDEBUG, "PulseAudio: Found %s with devicestring %s", device.m_displayName.c_str(), device.m_deviceName.c_str());
437       sinkStruct->list->push_back(device);
438     }
439     else
440     {
441       CLog::Log(LOGDEBUG, "PulseAudio: Skipped %s with devicestring %s", device.m_displayName.c_str(), device.m_deviceName.c_str());
442     }
443  }
444   pa_threaded_mainloop_signal(sinkStruct->mainloop, 0);
445 }
446
447 /* PulseAudio class memberfunctions*/
448
449
450 CAESinkPULSE::CAESinkPULSE()
451 {
452   m_IsAllocated = false;
453   m_passthrough = false;
454   m_MainLoop = NULL;
455   m_BytesPerSecond = 0;
456   m_BufferSize = 0;
457   m_Channels = 0;
458   m_Stream = NULL;
459   m_Context = NULL;
460 }
461
462 CAESinkPULSE::~CAESinkPULSE()
463 {
464   Deinitialize();
465 }
466
467 bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device)
468 {
469   {
470     CSingleLock lock(m_sec);
471     m_IsAllocated = false;
472   }
473   m_passthrough = false;
474   m_BytesPerSecond = 0;
475   m_BufferSize = 0;
476   m_Channels = 0;
477   m_Stream = NULL;
478   m_Context = NULL;
479
480   if (!SetupContext(NULL, &m_Context, &m_MainLoop))
481   {
482     CLog::Log(LOGNOTICE, "PulseAudio might not be running. Context was not created.");
483     Deinitialize();
484     return false;
485   }
486
487   pa_threaded_mainloop_lock(m_MainLoop);
488
489   {
490     // Register Callback for Sink changes
491     CSingleLock lock(m_sec);
492     pa_context_set_subscribe_callback(m_Context, SinkChangedCallback, this);
493     const pa_subscription_mask_t mask = PA_SUBSCRIPTION_MASK_SINK;
494     pa_operation *op = pa_context_subscribe(m_Context, mask, NULL, this);
495     if (op != NULL)
496       pa_operation_unref(op);
497   }
498
499   struct pa_channel_map map;
500   pa_channel_map_init(&map);
501
502   m_passthrough = AE_IS_RAW(format.m_dataFormat);
503
504   if(m_passthrough)
505   {
506     map.channels = 2;
507     format.m_channelLayout = AE_CH_LAYOUT_2_0;
508   }
509   else
510   {
511     map = AEChannelMapToPAChannel(format.m_channelLayout);
512     // if count has changed we need to fit the AE Map
513     if(map.channels != format.m_channelLayout.Count())
514       format.m_channelLayout = PAChannelToAEChannelMap(map);
515   }
516   m_Channels = format.m_channelLayout.Count();
517
518   // store information about current sink
519   SinkInfoStruct sinkStruct;
520   sinkStruct.mainloop = m_MainLoop;
521   sinkStruct.device_found = false;
522
523   // get real sample rate of the device we want to open - to avoid resampling
524   bool isDefaultDevice = (device == "Default");
525   WaitForOperation(pa_context_get_sink_info_by_name(m_Context, isDefaultDevice ? NULL : device.c_str(), SinkInfoCallback, &sinkStruct), m_MainLoop, "Get Sink Info");
526   // only check if the device is existing - don't alter the sample rate
527   if (!sinkStruct.device_found)
528   {
529     CLog::Log(LOGERROR, "PulseAudio: Sink %s not found", device.c_str());
530     pa_threaded_mainloop_unlock(m_MainLoop);
531     Deinitialize();
532     return false;
533   }
534
535   // Pulse can resample everything between 1 hz and 192000 hz
536   // Make sure we are in the range that we originally added
537   format.m_sampleRate = std::max(5512U, std::min(format.m_sampleRate, 192000U));
538
539   pa_format_info *info[1];
540   info[0] = pa_format_info_new();
541   info[0]->encoding = AEFormatToPulseEncoding(format.m_dataFormat);
542   if(!m_passthrough)
543   {
544     pa_format_info_set_sample_format(info[0], AEFormatToPulseFormat(format.m_dataFormat));
545     pa_format_info_set_channel_map(info[0], &map);
546   }
547   pa_format_info_set_channels(info[0], m_Channels);
548
549   // PA requires m_encodedRate in order to do EAC3
550   unsigned int samplerate;
551   if (m_passthrough)
552   {
553     if (format.m_encodedRate == 0 || format.m_encodedRate > format.m_sampleRate)
554     {
555       CLog::Log(LOGNOTICE, "PulseAudio: Passthrough in use but m_encodedRate is not set or too large: %u - fallback to m_sampleRate", format.m_encodedRate);
556       samplerate = format.m_sampleRate;
557     }
558     else
559       samplerate = format.m_encodedRate;
560   }
561   else
562     samplerate = format.m_sampleRate;
563
564   pa_format_info_set_rate(info[0], samplerate);
565
566   if (!pa_format_info_valid(info[0]))
567   {
568     CLog::Log(LOGERROR, "PulseAudio: Invalid format info");
569     pa_format_info_free(info[0]);
570     pa_threaded_mainloop_unlock(m_MainLoop);
571     Deinitialize();
572     return false;
573   }
574
575   pa_sample_spec spec;
576   #if PA_CHECK_VERSION(2,0,0)
577     pa_format_info_to_sample_spec(info[0], &spec, NULL);
578   #else
579     spec.rate = (AEFormatToPulseEncoding(format.m_dataFormat) == PA_ENCODING_EAC3_IEC61937) ? 4 * samplerate : samplerate;
580     spec.format = AEFormatToPulseFormat(format.m_dataFormat);
581     spec.channels = m_Channels;
582   #endif
583   if (!pa_sample_spec_valid(&spec))
584   {
585     CLog::Log(LOGERROR, "PulseAudio: Invalid sample spec");
586     pa_format_info_free(info[0]);
587     pa_threaded_mainloop_unlock(m_MainLoop);
588     Deinitialize();
589     return false;
590   }
591
592   m_BytesPerSecond = pa_bytes_per_second(&spec);
593   unsigned int frameSize = pa_frame_size(&spec);
594
595   m_Stream = pa_stream_new_extended(m_Context, "xbmc audio stream", info, 1, NULL);
596   pa_format_info_free(info[0]);
597
598   if (m_Stream == NULL)
599   {
600     CLog::Log(LOGERROR, "PulseAudio: Could not create a stream");
601     pa_threaded_mainloop_unlock(m_MainLoop);
602     Deinitialize();
603     return false;
604   }
605
606   pa_stream_set_state_callback(m_Stream, StreamStateCallback, m_MainLoop);
607   pa_stream_set_write_callback(m_Stream, StreamRequestCallback, m_MainLoop);
608   pa_stream_set_latency_update_callback(m_Stream, StreamLatencyUpdateCallback, m_MainLoop);
609
610   pa_buffer_attr buffer_attr;
611
612   // 200ms max latency
613   // 50ms min packet size
614   if(sinkStruct.isHWDevice || isDefaultDevice)
615   {
616     unsigned int latency = m_BytesPerSecond / 5;
617     unsigned int process_time = latency / 4;
618     memset(&buffer_attr, 0, sizeof(buffer_attr));
619     buffer_attr.tlength = (uint32_t) latency;
620     buffer_attr.minreq = (uint32_t) process_time;
621     buffer_attr.maxlength = (uint32_t) -1;
622     buffer_attr.prebuf = (uint32_t) -1;
623     buffer_attr.fragsize = (uint32_t) latency;
624   }
625
626   if (pa_stream_connect_playback(m_Stream, isDefaultDevice ? NULL : device.c_str(), sinkStruct.isHWDevice ? &buffer_attr : NULL, ((pa_stream_flags)(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_ADJUST_LATENCY)), NULL, NULL) < 0)
627   {
628     CLog::Log(LOGERROR, "PulseAudio: Failed to connect stream to output");
629     pa_threaded_mainloop_unlock(m_MainLoop);
630     Deinitialize();
631     return false;
632   }
633
634   /* Wait until the stream is ready */
635   do
636   {
637     pa_threaded_mainloop_wait(m_MainLoop);
638     CLog::Log(LOGDEBUG, "PulseAudio: Stream %s", StreamStateToString(pa_stream_get_state(m_Stream)));
639   }
640   while (pa_stream_get_state(m_Stream) != PA_STREAM_READY && pa_stream_get_state(m_Stream) != PA_STREAM_FAILED);
641
642   if (pa_stream_get_state(m_Stream) == PA_STREAM_FAILED)
643   {
644     CLog::Log(LOGERROR, "PulseAudio: Waited for the stream but it failed");
645     pa_threaded_mainloop_unlock(m_MainLoop);
646     Deinitialize();
647     return false;
648   }
649
650   //update local volume if we are in non passthrough mode
651   if (!m_passthrough)
652   {
653     unsigned int sink_input_idx = pa_stream_get_index(m_Stream);
654     SinkInputInfoStruct sii;
655     sii.mainloop = m_MainLoop;
656     bool success = WaitForOperation(pa_context_get_sink_input_info(m_Context, sink_input_idx, SinkInputInfoCallback, &sii), m_MainLoop, "Get Sink Input Info");
657     if(success && sii.is_valid)
658     {
659       // we don't have per channel values so use avg of them
660       pa_volume_t p_vol = pa_cvolume_avg(&sii.volume);
661       // store it internally
662       m_Volume = sii.volume;
663       float sValue = (float) pa_sw_volume_to_linear(p_vol);
664       CLog::Log(LOGDEBUG, "Restored Stream value to %f", sValue);
665       g_application.SetVolume(sValue, false);
666       if (sii.mute && sValue > 0)
667       {
668         CLog::Log(LOGDEBUG, "PulseAudio: Stream is muted - perhaps was a user wish - if volume is changed we unmute");
669       }
670     } 
671   }
672
673   const pa_buffer_attr *a;
674
675   if (!(a = pa_stream_get_buffer_attr(m_Stream)))
676   {
677     CLog::Log(LOGERROR, "PulseAudio: %s", pa_strerror(pa_context_errno(m_Context)));
678     pa_threaded_mainloop_unlock(m_MainLoop);
679     Deinitialize();
680     return false;
681   }
682   else
683   {
684     unsigned int packetSize = a->minreq;
685     m_BufferSize = a->tlength;
686
687     format.m_frames = packetSize / frameSize;
688   }
689
690   pa_threaded_mainloop_unlock(m_MainLoop);
691   
692   format.m_frameSize = frameSize;
693   format.m_frameSamples = format.m_frames * format.m_channelLayout.Count();
694   m_format = format;
695   format.m_dataFormat = m_passthrough ? AE_FMT_S16NE : format.m_dataFormat;
696
697   Pause(false);
698   {
699     CSingleLock lock(m_sec);
700     m_IsAllocated = true;
701   }
702
703   return true;
704 }
705
706 void CAESinkPULSE::Deinitialize()
707 {
708   CSingleLock lock(m_sec);
709   m_IsAllocated = false;
710   m_passthrough = false;
711
712   if (m_Stream)
713     Drain();
714
715   if (m_MainLoop)
716     pa_threaded_mainloop_stop(m_MainLoop);
717
718   if (m_Stream)
719   {
720     pa_stream_disconnect(m_Stream);
721     pa_stream_unref(m_Stream);
722     m_Stream = NULL;
723   }
724
725   if (m_Context)
726   {
727     pa_context_disconnect(m_Context);
728     pa_context_unref(m_Context);
729     m_Context = NULL;
730   }
731
732   if (m_MainLoop)
733   {
734     pa_threaded_mainloop_free(m_MainLoop);
735     m_MainLoop = NULL;
736   }
737 }
738
739 double CAESinkPULSE::GetDelay()
740 {
741   if (!m_IsAllocated)
742     return 0;
743
744   int error = 0;
745   pa_usec_t latency = (pa_usec_t) -1;
746   pa_threaded_mainloop_lock(m_MainLoop);
747   if ((error = pa_stream_get_latency(m_Stream, &latency, NULL)) < 0)
748   {
749     if (error == -PA_ERR_NODATA)
750     {
751       WaitForOperation(pa_stream_update_timing_info(m_Stream, NULL,NULL), m_MainLoop, "Update Timing Information");
752       if ((error = pa_stream_get_latency(m_Stream, &latency, NULL)) < 0)
753       {
754         CLog::Log(LOGDEBUG, "GetDelay - Failed to get Latency %d", error); 
755       }
756     }
757   }
758   if (error < 0 )
759     latency = (pa_usec_t) 0;
760
761   pa_threaded_mainloop_unlock(m_MainLoop);
762   return latency / 1000000.0;
763 }
764
765 double CAESinkPULSE::GetCacheTotal()
766 {
767   return (float)m_BufferSize / (float)m_BytesPerSecond;
768 }
769
770 unsigned int CAESinkPULSE::AddPackets(uint8_t *data, unsigned int frames, bool hasAudio, bool blocking)
771 {
772   if (!m_IsAllocated)
773     return frames;
774
775   pa_threaded_mainloop_lock(m_MainLoop);
776
777   unsigned int available = frames * m_format.m_frameSize;
778   unsigned int length = 0;
779   // revisit me after Gotham - should use a callback for the write function
780   while ((length = pa_stream_writable_size(m_Stream)) == 0)
781     pa_threaded_mainloop_wait(m_MainLoop);
782
783   length =  std::min((unsigned int)length, available);
784
785   int error = pa_stream_write(m_Stream, data, length, NULL, 0, PA_SEEK_RELATIVE);
786   pa_threaded_mainloop_unlock(m_MainLoop);
787
788   if (error)
789   {
790     CLog::Log(LOGERROR, "CPulseAudioDirectSound::AddPackets - pa_stream_write failed\n");
791     return 0;
792   }
793
794   return (unsigned int)(length / m_format.m_frameSize);
795 }
796
797 void CAESinkPULSE::Drain()
798 {
799   if (!m_IsAllocated)
800     return;
801
802   pa_threaded_mainloop_lock(m_MainLoop);
803   WaitForOperation(pa_stream_drain(m_Stream, NULL, NULL), m_MainLoop, "Drain");
804   pa_threaded_mainloop_unlock(m_MainLoop);
805 }
806
807 void CAESinkPULSE::SetVolume(float volume)
808 {
809   if (m_IsAllocated && !m_passthrough)
810   {
811     // clamp possibly too large / low values
812     float per_cent_volume = std::max(0.0f, std::min(volume, 1.0f));
813
814     pa_threaded_mainloop_lock(m_MainLoop);
815     bool external_change = false;
816     //check if internal volume and sink input volume do not match
817     unsigned int sink_input_idx = pa_stream_get_index(m_Stream);
818     SinkInputInfoStruct sii;
819     sii.mainloop = m_MainLoop;
820     bool success = WaitForOperation(pa_context_get_sink_input_info(m_Context, sink_input_idx, SinkInputInfoCallback, &sii), m_MainLoop, "Get Sink Input Info");
821     float sValue = 0.0f;
822     if(success && sii.is_valid)
823     {
824       // we don't have per channel values so use avg of them
825       pa_volume_t n_vol = pa_cvolume_avg(&sii.volume);
826       pa_volume_t o_vol = pa_cvolume_avg(&m_Volume);
827       sValue = (float) pa_sw_volume_to_linear(n_vol);
828       if (n_vol != o_vol)
829       {
830         external_change = true;
831         // update internal volume
832         m_Volume = sii.volume;
833         CLog::Log(LOGDEBUG, "Restored Volume cause of external change to value to %f", sValue);
834         g_application.SetVolume(sValue, false);
835       }
836       // unmute if we should not be muted
837       if (sii.mute && sValue > 0)
838       {
839         pa_operation *op = pa_context_set_sink_input_mute(m_Context, sii.index, 0, NULL, NULL);
840         if (op == NULL)
841           CLog::Log(LOGERROR, "PulseAudio: Failed to unmute the stream");
842         else
843           pa_operation_unref(op);
844       }
845     }
846     else // we don't know stream volume so don't change anything
847     {
848       external_change = true;
849     }
850     if (!external_change)
851     {
852       pa_volume_t pavolume = pa_sw_volume_from_linear(per_cent_volume);
853       if ( pavolume <= 0 )
854         pa_cvolume_mute(&m_Volume, m_Channels);
855       else
856         pa_cvolume_set(&m_Volume, m_Channels, pavolume);
857       pa_operation *op = pa_context_set_sink_input_volume(m_Context, sink_input_idx, &m_Volume, NULL, NULL);
858       if (op == NULL)
859         CLog::Log(LOGERROR, "PulseAudio: Failed to set volume");
860       else
861         pa_operation_unref(op);
862     }
863     pa_threaded_mainloop_unlock(m_MainLoop);
864   }
865 }
866
867 void CAESinkPULSE::EnumerateDevicesEx(AEDeviceInfoList &list, bool force)
868 {
869   pa_context *context;
870   pa_threaded_mainloop *mainloop;
871
872   if (!SetupContext(NULL, &context, &mainloop))
873   {
874     CLog::Log(LOGNOTICE, "PulseAudio might not be running. Context was not created.");
875     return;
876   }
877
878   pa_threaded_mainloop_lock(mainloop);
879
880   SinkInfoStruct sinkStruct;
881   sinkStruct.mainloop = mainloop;
882   sinkStruct.list = &list;
883   WaitForOperation(pa_context_get_sink_info_list(context, SinkInfoRequestCallback, &sinkStruct), mainloop, "EnumerateAudioSinks");
884
885   pa_threaded_mainloop_unlock(mainloop);
886
887   if (mainloop)
888     pa_threaded_mainloop_stop(mainloop);
889
890   if (context)
891   {
892     pa_context_disconnect(context);
893     pa_context_unref(context);
894     context = NULL;
895   }
896
897   if (mainloop)
898   {
899     pa_threaded_mainloop_free(mainloop);
900     mainloop = NULL;
901   }
902 }
903
904 bool CAESinkPULSE::IsInitialized()
905 {
906  CSingleLock lock(m_sec);
907  return m_IsAllocated; 
908 }
909
910 bool CAESinkPULSE::Pause(bool pause)
911 {
912   pa_threaded_mainloop_lock(m_MainLoop);
913
914   if (!WaitForOperation(pa_stream_cork(m_Stream, pause ? 1 : 0, NULL, NULL), m_MainLoop, pause ? "Pause" : "Resume"))
915     pause = !pause;
916
917   pa_threaded_mainloop_unlock(m_MainLoop);
918
919   return pause;
920 }
921
922 inline bool CAESinkPULSE::WaitForOperation(pa_operation *op, pa_threaded_mainloop *mainloop, const char *LogEntry = "")
923 {
924   if (op == NULL)
925     return false;
926
927   bool sucess = true;
928
929   while (pa_operation_get_state(op) == PA_OPERATION_RUNNING)
930     pa_threaded_mainloop_wait(mainloop);
931
932   if (pa_operation_get_state(op) != PA_OPERATION_DONE)
933   {
934     CLog::Log(LOGERROR, "PulseAudio: %s Operation failed", LogEntry);
935     sucess = false;
936   }
937
938   pa_operation_unref(op);
939   return sucess;
940 }
941
942 bool CAESinkPULSE::SetupContext(const char *host, pa_context **context, pa_threaded_mainloop **mainloop)
943 {
944   if ((*mainloop = pa_threaded_mainloop_new()) == NULL)
945   {
946     CLog::Log(LOGERROR, "PulseAudio: Failed to allocate main loop");
947     return false;
948   }
949
950   if (((*context) = pa_context_new(pa_threaded_mainloop_get_api(*mainloop), "XBMC")) == NULL)
951   {
952     CLog::Log(LOGERROR, "PulseAudio: Failed to allocate context");
953     return false;
954   }
955
956   pa_context_set_state_callback(*context, ContextStateCallback, *mainloop);
957
958   if (pa_context_connect(*context, host, (pa_context_flags_t)0, NULL) < 0)
959   {
960     CLog::Log(LOGERROR, "PulseAudio: Failed to connect context");
961     return false;
962   }
963   pa_threaded_mainloop_lock(*mainloop);
964
965   if (pa_threaded_mainloop_start(*mainloop) < 0)
966   {
967     CLog::Log(LOGERROR, "PulseAudio: Failed to start MainLoop");
968     pa_threaded_mainloop_unlock(*mainloop);
969     return false;
970   }
971
972   /* Wait until the context is ready */
973   do
974   {
975     pa_threaded_mainloop_wait(*mainloop);
976     CLog::Log(LOGDEBUG, "PulseAudio: Context %s", ContextStateToString(pa_context_get_state(*context)));
977   }
978   while (pa_context_get_state(*context) != PA_CONTEXT_READY && pa_context_get_state(*context) != PA_CONTEXT_FAILED);
979
980   if (pa_context_get_state(*context) == PA_CONTEXT_FAILED)
981   {
982     CLog::Log(LOGERROR, "PulseAudio: Waited for the Context but it failed");
983     pa_threaded_mainloop_unlock(*mainloop);
984     return false;
985   }
986
987   pa_threaded_mainloop_unlock(*mainloop);
988   return true;
989 }
990 #endif