Skip to content
Snippets Groups Projects
Commit deb9ce85 authored by Alexandre Savard's avatar Alexandre Savard
Browse files

[#1962] Update internal sink/source list when pluging/unpluging new device

parent 4d492670
Branches
Tags
No related merge requests found
...@@ -76,23 +76,6 @@ static void stream_moved_callback(pa_stream *s, void *userdata) { ...@@ -76,23 +76,6 @@ static void stream_moved_callback(pa_stream *s, void *userdata) {
} }
/*
PA_SUBSCRIPTION_EVENT_SINK = 0x0000U,
PA_SUBSCRIPTION_EVENT_SOURCE = 0x0001U,
PA_SUBSCRIPTION_EVENT_SINK_INPUT = 0x0002U,
PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT = 0x0003U,
PA_SUBSCRIPTION_EVENT_MODULE = 0x0004U,
PA_SUBSCRIPTION_EVENT_CLIENT = 0x0005U,
PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE = 0x0006U,
PA_SUBSCRIPTION_EVENT_SERVER = 0x0007U,
PA_SUBSCRIPTION_EVENT_CARD = 0x0009U,
PA_SUBSCRIPTION_EVENT_FACILITY_MASK = 0x000FU,
PA_SUBSCRIPTION_EVENT_NEW = 0x0000U,
PA_SUBSCRIPTION_EVENT_CHANGE = 0x0010U,
PA_SUBSCRIPTION_EVENT_REMOVE = 0x0020U,
PA_SUBSCRIPTION_EVENT_TYPE_MASK = 0x0030U
*/
static void pa_success_callback(pa_context *c, int success, void *userdata) { static void pa_success_callback(pa_context *c, int success, void *userdata) {
_debug("Audio: Success callback"); _debug("Audio: Success callback");
...@@ -101,14 +84,11 @@ static void pa_success_callback(pa_context *c, int success, void *userdata) { ...@@ -101,14 +84,11 @@ static void pa_success_callback(pa_context *c, int success, void *userdata) {
static void sink_input_info_callback(pa_context *c, const pa_sink_info *i, int eol, void *userdata) { static void sink_input_info_callback(pa_context *c, const pa_sink_info *i, int eol, void *userdata) {
char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
if(!eol) { _debug("******** sink_input_info_callback");
_debug("Sink_input_info_callback: %d", eol);
// _debug("Audio: Sink info name: %s", i->name); if(!eol) {
// _debug("Audio: Sing info index: %d", i->index);
printf("Sink #%u\n" printf("Sink %u\n"
" Name: %s\n" " Name: %s\n"
" Driver: %s\n" " Driver: %s\n"
" Description: %s\n" " Description: %s\n"
...@@ -134,29 +114,67 @@ static void sink_input_info_callback(pa_context *c, const pa_sink_info *i, int e ...@@ -134,29 +114,67 @@ static void sink_input_info_callback(pa_context *c, const pa_sink_info *i, int e
i->flags & PA_SINK_HARDWARE ? "HARDWARE" : ""); i->flags & PA_SINK_HARDWARE ? "HARDWARE" : "");
std::string deviceName(i->name); std::string deviceName(i->name);
((PulseLayer *)userdata)->getDevicelist()->push_back(deviceName); ((PulseLayer *)userdata)->getSinkList()->push_back(deviceName);
} }
} }
static void source_input_info_callback(pa_context *c, const pa_source_info *i, int eol, void *userdata) {
char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
_debug("******** source_input_info_callback");
if(!eol) {
printf("Sink %u\n"
" Name: %s\n"
" Driver: %s\n"
" Description: %s\n"
" Sample Specification: %s\n"
" Channel Map: %s\n"
" Owner Module: %u\n"
" Volume: %s\n"
" Monitor if Sink: %u\n"
" Latency: %0.0f usec\n"
" Flags: %s%s%s\n",
i->index,
i->name,
i->driver,
i->description,
pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),
pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
i->owner_module,
i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume),
i->monitor_of_sink,
(double) i->latency,
i->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
i->flags & PA_SOURCE_LATENCY ? "LATENCY " : "",
i->flags & PA_SOURCE_HARDWARE ? "HARDWARE" : "");
std::string deviceName(i->name);
((PulseLayer *)userdata)->getSourceList()->push_back(deviceName);
}
}
static void context_changed_callback(pa_context* c, pa_subscription_event_type_t t, uint32_t idx, void* userdata) static void context_changed_callback(pa_context* c, pa_subscription_event_type_t t, uint32_t idx, void* userdata)
{ {
_debug("---------------------- context_changed_callback %d ----------------------------", idx); _debug("---------------------- context_changed_callback %d ----------------------------", idx);
// AudioStream* ringtone = ((PulseLayer *)userdata)->getRingtoneStream();
switch(t) { switch(t) {
case PA_SUBSCRIPTION_EVENT_SINK: case PA_SUBSCRIPTION_EVENT_SINK:
pa_context_get_sink_info_list(c, sink_input_info_callback, userdata);
_debug("Audio: PA_SUBSCRIPTION_EVENT_SINK"); _debug("Audio: PA_SUBSCRIPTION_EVENT_SINK");
((PulseLayer *)userdata)->getSinkList()->clear();
pa_context_get_sink_info_list(c, sink_input_info_callback, userdata);
break; break;
case PA_SUBSCRIPTION_EVENT_SOURCE: case PA_SUBSCRIPTION_EVENT_SOURCE:
pa_context_get_sink_info_list(c, sink_input_info_callback, userdata);
_debug("Audio: PA_SUBSCRIPTION_EVENT_SOURCE"); _debug("Audio: PA_SUBSCRIPTION_EVENT_SOURCE");
((PulseLayer *)userdata)->getSourceList()->clear();
pa_context_get_source_info_list(c, source_input_info_callback, userdata);
break; break;
case PA_SUBSCRIPTION_EVENT_SINK_INPUT: case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
_debug("Audio: PA_SUBSCRIPTION_EVENT_SINK_INPUT"); _debug("Audio: PA_SUBSCRIPTION_EVENT_SINK_INPUT");
...@@ -183,13 +201,14 @@ static void context_changed_callback(pa_context* c, pa_subscription_event_type_t ...@@ -183,13 +201,14 @@ static void context_changed_callback(pa_context* c, pa_subscription_event_type_t
_debug("Audio: PA_SUBSCRIPTION_EVENT_FACILITY_MASK"); _debug("Audio: PA_SUBSCRIPTION_EVENT_FACILITY_MASK");
break; break;
case PA_SUBSCRIPTION_EVENT_CHANGE: case PA_SUBSCRIPTION_EVENT_CHANGE:
// pa_context_get_sink_info_by_index(c, idx, sink_input_info_callback, userdata);
// pa_context_get_sink_info_list(c, sink_input_info_callback, userdata);
_debug("Audio: PA_SUBSCRIPTION_EVENT_CHANGE"); _debug("Audio: PA_SUBSCRIPTION_EVENT_CHANGE");
break; break;
case PA_SUBSCRIPTION_EVENT_REMOVE: case PA_SUBSCRIPTION_EVENT_REMOVE:
// pa_context_get_sink_info_list(c, sink_input_info_callback, userdata);
_debug("Audio: PA_SUBSCRIPTION_EVENT_REMOVE"); _debug("Audio: PA_SUBSCRIPTION_EVENT_REMOVE");
((PulseLayer *)userdata)->getSinkList()->clear();
((PulseLayer *)userdata)->getSourceList()->clear();
pa_context_get_sink_info_list(c, sink_input_info_callback, userdata);
pa_context_get_source_info_list(c, source_input_info_callback, userdata);
break; break;
case PA_SUBSCRIPTION_EVENT_TYPE_MASK: case PA_SUBSCRIPTION_EVENT_TYPE_MASK:
_debug("Audio: PA_SUBSCRIPTION_EVENT_TYPE_MASK"); _debug("Audio: PA_SUBSCRIPTION_EVENT_TYPE_MASK");
...@@ -375,7 +394,7 @@ void PulseLayer::context_state_callback (pa_context* c, void* user_data) ...@@ -375,7 +394,7 @@ void PulseLayer::context_state_callback (pa_context* c, void* user_data)
pa_context_subscribe (c, (pa_subscription_mask_t)(PA_SUBSCRIPTION_MASK_SINK| pa_context_subscribe (c, (pa_subscription_mask_t)(PA_SUBSCRIPTION_MASK_SINK|
PA_SUBSCRIPTION_MASK_SOURCE), NULL, pulse); PA_SUBSCRIPTION_MASK_SOURCE), NULL, pulse);
pa_context_set_subscribe_callback (c, context_changed_callback, pulse); pa_context_set_subscribe_callback (c, context_changed_callback, pulse);
pulse->updateDeviceList(); pulse->updateSinkList();
break; break;
case PA_CONTEXT_TERMINATED: case PA_CONTEXT_TERMINATED:
...@@ -406,25 +425,51 @@ bool PulseLayer::openDevice (int indexIn UNUSED, int indexOut UNUSED, int sample ...@@ -406,25 +425,51 @@ bool PulseLayer::openDevice (int indexIn UNUSED, int indexOut UNUSED, int sample
} }
void PulseLayer::updateDeviceList(void) { void PulseLayer::updateSinkList(void) {
_debug("Audio: Update device list"); _debug("Audio: Update sink list");
getDevicelist()->clear(); getSinkList()->clear();
pa_context_get_sink_info_list(context, sink_input_info_callback, this); pa_context_get_sink_info_list(context, sink_input_info_callback, this);
} }
bool PulseLayer::inDevicelist(std::string deviceName) { void PulseLayer::updateSourceList(void) {
_debug("Audio: in device list %s", deviceName.c_str()); _debug("Audio: Update source list");
getSourceList()->clear();
pa_context_get_source_info_list(context, source_input_info_callback, this);
}
bool PulseLayer::inSinkList(std::string deviceName) {
// _debug("Audio: in device list %s", deviceName.c_str());
DeviceList::iterator iter = _sinkList.begin();
// _debug("_deviceList.size() %d", _sinkList.size());
while(iter != _sinkList.end()) {
if (*iter == deviceName) {
// _debug("device name in list: %s", (*iter).c_str());
return true;
}
iter++;
}
return false;
}
bool PulseLayer::inSourceList(std::string deviceName) {
DeviceList::iterator iter = _deviceList.begin(); DeviceList::iterator iter = _sourceList.begin();
_debug("_deviceList.size() %d", _deviceList.size()); while(iter != _sourceList.end()) {
while(iter != _deviceList.end()) {
if(*iter == deviceName) { if(*iter == deviceName) {
_debug("device name in list: %s", (*iter).c_str());
return true; return true;
} }
...@@ -457,7 +502,7 @@ bool PulseLayer::createStreams (pa_context* c) ...@@ -457,7 +502,7 @@ bool PulseLayer::createStreams (pa_context* c)
playbackParam->mainloop = m; playbackParam->mainloop = m;
playback = new AudioStream(playbackParam, _audioSampleRate); playback = new AudioStream(playbackParam, _audioSampleRate);
if(inDevicelist(playbackDevice)) { if(inSinkList(playbackDevice)) {
playback->connectStream(&playbackDevice); playback->connectStream(&playbackDevice);
} }
else { else {
...@@ -478,7 +523,7 @@ bool PulseLayer::createStreams (pa_context* c) ...@@ -478,7 +523,7 @@ bool PulseLayer::createStreams (pa_context* c)
recordParam->mainloop = m; recordParam->mainloop = m;
record = new AudioStream (recordParam, _audioSampleRate); record = new AudioStream (recordParam, _audioSampleRate);
if(inDevicelist(recordDevice)) { if(inSinkList(recordDevice)) {
record->connectStream(NULL); record->connectStream(NULL);
} }
else { else {
...@@ -497,7 +542,7 @@ bool PulseLayer::createStreams (pa_context* c) ...@@ -497,7 +542,7 @@ bool PulseLayer::createStreams (pa_context* c)
ringtoneParam->mainloop = m; ringtoneParam->mainloop = m;
ringtone = new AudioStream (ringtoneParam, _audioSampleRate); ringtone = new AudioStream (ringtoneParam, _audioSampleRate);
if(inDevicelist(ringtoneDevice)) { if(inSourceList(ringtoneDevice)) {
ringtone->connectStream(&ringtoneDevice); ringtone->connectStream(&ringtoneDevice);
} }
else { else {
......
...@@ -67,11 +67,17 @@ class PulseLayer : public AudioLayer { ...@@ -67,11 +67,17 @@ class PulseLayer : public AudioLayer {
*/ */
bool openDevice(int indexIn, int indexOut, int sampleRate, int frameSize , int stream, std::string plugin) ; bool openDevice(int indexIn, int indexOut, int sampleRate, int frameSize , int stream, std::string plugin) ;
DeviceList* getDevicelist(void) { return &_deviceList; } DeviceList* getSinkList(void) { return &_sinkList; }
void updateDeviceList(void); DeviceList* getSourceList(void) { return &_sourceList; }
bool inDevicelist(std::string deviceName); void updateSinkList(void);
void updateSourceList(void);
bool inSinkList(std::string deviceName);
bool inSourceList(std::string deviceName);
void startStream(void); void startStream(void);
...@@ -236,7 +242,9 @@ class PulseLayer : public AudioLayer { ...@@ -236,7 +242,9 @@ class PulseLayer : public AudioLayer {
DcBlocker* dcblocker; DcBlocker* dcblocker;
DeviceList _deviceList; DeviceList _sinkList;
DeviceList _sourceList;
// private: // private:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment