[DEV] try to add a list of device for pulse
This commit is contained in:
parent
57c9cc1132
commit
4b5bbd9626
@ -19,15 +19,15 @@ void audio::orchestra::DeviceInfo::display(int32_t _tabNumber) const {
|
|||||||
for (int32_t iii=0; iii<_tabNumber; ++iii) {
|
for (int32_t iii=0; iii<_tabNumber; ++iii) {
|
||||||
space += " ";
|
space += " ";
|
||||||
}
|
}
|
||||||
ATA_INFO(space + "probe=" << probed);
|
ATA_PRINT(space + "probe=" << probed);
|
||||||
ATA_INFO(space + "name=" << name);
|
ATA_PRINT(space + "name=" << name);
|
||||||
ATA_INFO(space + "outputChannels=" << outputChannels);
|
ATA_PRINT(space + "outputChannels=" << outputChannels);
|
||||||
ATA_INFO(space + "inputChannels=" << inputChannels);
|
ATA_PRINT(space + "inputChannels=" << inputChannels);
|
||||||
ATA_INFO(space + "duplexChannels=" << duplexChannels);
|
ATA_PRINT(space + "duplexChannels=" << duplexChannels);
|
||||||
ATA_INFO(space + "isDefaultOutput=" << (isDefaultOutput==true?"true":"false"));
|
ATA_PRINT(space + "isDefaultOutput=" << (isDefaultOutput==true?"true":"false"));
|
||||||
ATA_INFO(space + "isDefaultInput=" << (isDefaultInput==true?"true":"false"));
|
ATA_PRINT(space + "isDefaultInput=" << (isDefaultInput==true?"true":"false"));
|
||||||
ATA_INFO(space + "rates=" << sampleRates);
|
ATA_PRINT(space + "rates=" << sampleRates);
|
||||||
ATA_INFO(space + "native Format: " << nativeFormats);
|
ATA_PRINT(space + "native Format: " << nativeFormats);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& audio::orchestra::operator <<(std::ostream& _os, const audio::orchestra::DeviceInfo& _obj) {
|
std::ostream& audio::orchestra::operator <<(std::ostream& _os, const audio::orchestra::DeviceInfo& _obj) {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <pulse/simple.h>
|
#include <pulse/simple.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <etk/thread/tools.h>
|
#include <etk/thread/tools.h>
|
||||||
|
#include <audio/orchestra/api/PulseDeviceList.h>
|
||||||
|
|
||||||
#undef __class__
|
#undef __class__
|
||||||
#define __class__ "api::Pulse"
|
#define __class__ "api::Pulse"
|
||||||
@ -53,15 +54,13 @@ namespace audio {
|
|||||||
namespace api {
|
namespace api {
|
||||||
class PulsePrivate {
|
class PulsePrivate {
|
||||||
public:
|
public:
|
||||||
pa_simple *s_play;
|
pa_simple* handle;
|
||||||
pa_simple *s_rec;
|
|
||||||
std11::shared_ptr<std11::thread> thread;
|
std11::shared_ptr<std11::thread> thread;
|
||||||
bool threadRunning;
|
bool threadRunning;
|
||||||
std11::condition_variable runnable_cv;
|
std11::condition_variable runnable_cv;
|
||||||
bool runnable;
|
bool runnable;
|
||||||
PulsePrivate() :
|
PulsePrivate() :
|
||||||
s_play(0),
|
handle(0),
|
||||||
s_rec(0),
|
|
||||||
threadRunning(false),
|
threadRunning(false),
|
||||||
runnable(false) {
|
runnable(false) {
|
||||||
|
|
||||||
@ -82,16 +81,23 @@ audio::orchestra::api::Pulse::~Pulse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t audio::orchestra::api::Pulse::getDeviceCount() {
|
uint32_t audio::orchestra::api::Pulse::getDeviceCount() {
|
||||||
return 1;
|
#if 0
|
||||||
|
std::vector<audio::orchestra::api::pulse::Element> list = audio::orchestra::api::pulse::getDeviceList();
|
||||||
|
return list.size();
|
||||||
|
#else
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
audio::orchestra::DeviceInfo audio::orchestra::api::Pulse::getDeviceInfo(uint32_t _device) {
|
audio::orchestra::DeviceInfo audio::orchestra::api::Pulse::getDeviceInfo(uint32_t _device) {
|
||||||
audio::orchestra::DeviceInfo info;
|
audio::orchestra::DeviceInfo info;
|
||||||
|
//std::vector<audio::orchestra::api::pulse::Element> list = audio::orchestra::api::pulse::getDeviceList();
|
||||||
|
// TODO : Do it better... it is a little poor ...
|
||||||
info.probed = true;
|
info.probed = true;
|
||||||
info.name = "PulseAudio";
|
info.name = "PulseAudio";
|
||||||
info.outputChannels = 2;
|
info.outputChannels = 2;
|
||||||
info.inputChannels = 2;
|
info.inputChannels = 2;
|
||||||
info.duplexChannels = 2;
|
info.duplexChannels = 0;
|
||||||
info.isDefaultOutput = true;
|
info.isDefaultOutput = true;
|
||||||
info.isDefaultInput = true;
|
info.isDefaultInput = true;
|
||||||
for (const uint32_t *sr = SUPPORTED_SAMPLERATES; *sr; ++sr) {
|
for (const uint32_t *sr = SUPPORTED_SAMPLERATES; *sr; ++sr) {
|
||||||
@ -124,13 +130,11 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::closeStream() {
|
|||||||
}
|
}
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
m_private->thread->join();
|
m_private->thread->join();
|
||||||
if (m_private->s_play) {
|
if (m_mode == audio::orchestra::mode_output) {
|
||||||
pa_simple_flush(m_private->s_play, nullptr);
|
pa_simple_flush(m_private->handle, nullptr);
|
||||||
pa_simple_free(m_private->s_play);
|
|
||||||
}
|
|
||||||
if (m_private->s_rec) {
|
|
||||||
pa_simple_free(m_private->s_rec);
|
|
||||||
}
|
}
|
||||||
|
pa_simple_free(m_private->handle);
|
||||||
|
m_private->handle = nullptr;
|
||||||
m_userBuffer[0].clear();
|
m_userBuffer[0].clear();
|
||||||
m_userBuffer[1].clear();
|
m_userBuffer[1].clear();
|
||||||
m_state = audio::orchestra::state_closed;
|
m_state = audio::orchestra::state_closed;
|
||||||
@ -173,8 +177,7 @@ void audio::orchestra::api::Pulse::callbackEventOneCycle() {
|
|||||||
}
|
}
|
||||||
int32_t pa_error;
|
int32_t pa_error;
|
||||||
size_t bytes;
|
size_t bytes;
|
||||||
if ( m_mode == audio::orchestra::mode_output
|
if (m_mode == audio::orchestra::mode_output) {
|
||||||
|| m_mode == audio::orchestra::mode_duplex) {
|
|
||||||
if (m_doConvertBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)]) {
|
if (m_doConvertBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)]) {
|
||||||
convertBuffer(m_deviceBuffer,
|
convertBuffer(m_deviceBuffer,
|
||||||
&m_userBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)][0],
|
&m_userBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)][0],
|
||||||
@ -183,18 +186,18 @@ void audio::orchestra::api::Pulse::callbackEventOneCycle() {
|
|||||||
} else {
|
} else {
|
||||||
bytes = m_nUserChannels[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)] * m_bufferSize * audio::getFormatBytes(m_userFormat);
|
bytes = m_nUserChannels[audio::orchestra::modeToIdTable(audio::orchestra::mode_output)] * m_bufferSize * audio::getFormatBytes(m_userFormat);
|
||||||
}
|
}
|
||||||
if (pa_simple_write(m_private->s_play, pulse_out, bytes, &pa_error) < 0) {
|
if (pa_simple_write(m_private->handle, pulse_out, bytes, &pa_error) < 0) {
|
||||||
ATA_ERROR("audio write error, " << pa_strerror(pa_error) << ".");
|
ATA_ERROR("audio write error, " << pa_strerror(pa_error) << ".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_mode == audio::orchestra::mode_input || m_mode == audio::orchestra::mode_duplex) {
|
if (m_mode == audio::orchestra::mode_input) {
|
||||||
if (m_doConvertBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)]) {
|
if (m_doConvertBuffer[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)]) {
|
||||||
bytes = m_nDeviceChannels[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)] * m_bufferSize * audio::getFormatBytes(m_deviceFormat[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)]);
|
bytes = m_nDeviceChannels[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)] * m_bufferSize * audio::getFormatBytes(m_deviceFormat[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)]);
|
||||||
} else {
|
} else {
|
||||||
bytes = m_nUserChannels[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)] * m_bufferSize * audio::getFormatBytes(m_userFormat);
|
bytes = m_nUserChannels[audio::orchestra::modeToIdTable(audio::orchestra::mode_input)] * m_bufferSize * audio::getFormatBytes(m_userFormat);
|
||||||
}
|
}
|
||||||
if (pa_simple_read(m_private->s_rec, pulse_in, bytes, &pa_error) < 0) {
|
if (pa_simple_read(m_private->handle, pulse_in, bytes, &pa_error) < 0) {
|
||||||
ATA_ERROR("audio read error, " << pa_strerror(pa_error) << ".");
|
ATA_ERROR("audio read error, " << pa_strerror(pa_error) << ".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -244,9 +247,11 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::stopStream() {
|
|||||||
}
|
}
|
||||||
m_state = audio::orchestra::state_stopped;
|
m_state = audio::orchestra::state_stopped;
|
||||||
m_mutex.lock();
|
m_mutex.lock();
|
||||||
if (m_private->s_play) {
|
if ( m_private != nullptr
|
||||||
|
&& m_private->handle != nullptr
|
||||||
|
&& m_mode == audio::orchestra::mode_output) {
|
||||||
int32_t pa_error;
|
int32_t pa_error;
|
||||||
if (pa_simple_drain(m_private->s_play, &pa_error) < 0) {
|
if (pa_simple_drain(m_private->handle, &pa_error) < 0) {
|
||||||
ATA_ERROR("error draining output device, " << pa_strerror(pa_error) << ".");
|
ATA_ERROR("error draining output device, " << pa_strerror(pa_error) << ".");
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
return audio::orchestra::error_systemError;
|
return audio::orchestra::error_systemError;
|
||||||
@ -268,9 +273,11 @@ enum audio::orchestra::error audio::orchestra::api::Pulse::abortStream() {
|
|||||||
}
|
}
|
||||||
m_state = audio::orchestra::state_stopped;
|
m_state = audio::orchestra::state_stopped;
|
||||||
m_mutex.lock();
|
m_mutex.lock();
|
||||||
if (m_private && m_private->s_play) {
|
if ( m_private != nullptr
|
||||||
|
&& m_private->handle != nullptr
|
||||||
|
&& m_mode == audio::orchestra::mode_output) {
|
||||||
int32_t pa_error;
|
int32_t pa_error;
|
||||||
if (pa_simple_flush(m_private->s_play, &pa_error) < 0) {
|
if (pa_simple_flush(m_private->handle, &pa_error) < 0) {
|
||||||
ATA_ERROR("error flushing output device, " << pa_strerror(pa_error) << ".");
|
ATA_ERROR("error flushing output device, " << pa_strerror(pa_error) << ".");
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
return audio::orchestra::error_systemError;
|
return audio::orchestra::error_systemError;
|
||||||
@ -376,15 +383,15 @@ bool audio::orchestra::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
int32_t error;
|
int32_t error;
|
||||||
switch (_mode) {
|
switch (_mode) {
|
||||||
case audio::orchestra::mode_input:
|
case audio::orchestra::mode_input:
|
||||||
m_private->s_rec = pa_simple_new(nullptr, "orchestra", PA_STREAM_RECORD, nullptr, "Record", &ss, nullptr, nullptr, &error);
|
m_private->handle = pa_simple_new(nullptr, "orchestra", PA_STREAM_RECORD, nullptr, "Record", &ss, nullptr, nullptr, &error);
|
||||||
if (!m_private->s_rec) {
|
if (m_private->handle == nullptr) {
|
||||||
ATA_ERROR("error connecting input to PulseAudio server.");
|
ATA_ERROR("error connecting input to PulseAudio server.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case audio::orchestra::mode_output:
|
case audio::orchestra::mode_output:
|
||||||
m_private->s_play = pa_simple_new(nullptr, "orchestra", PA_STREAM_PLAYBACK, nullptr, "Playback", &ss, nullptr, nullptr, &error);
|
m_private->handle = pa_simple_new(nullptr, "orchestra", PA_STREAM_PLAYBACK, nullptr, "Playback", &ss, nullptr, nullptr, &error);
|
||||||
if (!m_private->s_play) {
|
if (m_private->handle == nullptr) {
|
||||||
ATA_ERROR("error connecting output to PulseAudio server.");
|
ATA_ERROR("error connecting output to PulseAudio server.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -394,12 +401,10 @@ bool audio::orchestra::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
}
|
}
|
||||||
if (m_mode == audio::orchestra::mode_unknow) {
|
if (m_mode == audio::orchestra::mode_unknow) {
|
||||||
m_mode = _mode;
|
m_mode = _mode;
|
||||||
} else if (m_mode == _mode) {
|
} else {
|
||||||
goto error;
|
goto error;
|
||||||
}else {
|
|
||||||
m_mode = audio::orchestra::mode_duplex;
|
|
||||||
}
|
}
|
||||||
if (!m_private->threadRunning) {
|
if (m_private->threadRunning == false) {
|
||||||
m_private->threadRunning = true;
|
m_private->threadRunning = true;
|
||||||
m_private->thread = std11::make_shared<std11::thread>(&pulseaudio_callback, this);
|
m_private->thread = std11::make_shared<std11::thread>(&pulseaudio_callback, this);
|
||||||
if (m_private->thread == nullptr) {
|
if (m_private->thread == nullptr) {
|
||||||
@ -410,8 +415,8 @@ bool audio::orchestra::api::Pulse::probeDeviceOpen(uint32_t _device,
|
|||||||
m_state = audio::orchestra::state_stopped;
|
m_state = audio::orchestra::state_stopped;
|
||||||
return true;
|
return true;
|
||||||
error:
|
error:
|
||||||
for (int32_t i=0; i<2; i++) {
|
for (int32_t iii=0; iii<2; ++iii) {
|
||||||
m_userBuffer[i].clear();
|
m_userBuffer[iii].clear();
|
||||||
}
|
}
|
||||||
if (m_deviceBuffer) {
|
if (m_deviceBuffer) {
|
||||||
free(m_deviceBuffer);
|
free(m_deviceBuffer);
|
||||||
|
153
audio/orchestra/api/PulseDeviceList.cpp
Normal file
153
audio/orchestra/api/PulseDeviceList.cpp
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
* @fork from RTAudio
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pulse/pulseaudio.h>
|
||||||
|
#include <audio/orchestra/api/PulseDeviceList.h>
|
||||||
|
#include <audio/orchestra/debug.h>
|
||||||
|
|
||||||
|
// This callback gets called when our context changes state. We really only
|
||||||
|
// care about when it's ready or if it has failed
|
||||||
|
static void callbackStateMachine(pa_context* _contex, void *_userdata) {
|
||||||
|
pa_context_state_t state;
|
||||||
|
int *pulseAudioReady = static_cast<int*>(_userdata);
|
||||||
|
state = pa_context_get_state(_contex);
|
||||||
|
switch (state) {
|
||||||
|
// There are just here for reference
|
||||||
|
case PA_CONTEXT_UNCONNECTED:
|
||||||
|
ATA_INFO("pulse state: PA_CONTEXT_UNCONNECTED");
|
||||||
|
break;
|
||||||
|
case PA_CONTEXT_CONNECTING:
|
||||||
|
ATA_INFO("pulse state: PA_CONTEXT_CONNECTING");
|
||||||
|
break;
|
||||||
|
case PA_CONTEXT_AUTHORIZING:
|
||||||
|
ATA_INFO("pulse state: PA_CONTEXT_AUTHORIZING");
|
||||||
|
break;
|
||||||
|
case PA_CONTEXT_SETTING_NAME:
|
||||||
|
ATA_INFO("pulse state: PA_CONTEXT_SETTING_NAME");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ATA_INFO("pulse state: default");
|
||||||
|
break;
|
||||||
|
case PA_CONTEXT_FAILED:
|
||||||
|
*pulseAudioReady = 2;
|
||||||
|
ATA_INFO("pulse state: PA_CONTEXT_FAILED");
|
||||||
|
break;
|
||||||
|
case PA_CONTEXT_TERMINATED:
|
||||||
|
*pulseAudioReady = 2;
|
||||||
|
ATA_INFO("pulse state: PA_CONTEXT_TERMINATED");
|
||||||
|
break;
|
||||||
|
case PA_CONTEXT_READY:
|
||||||
|
*pulseAudioReady = 1;
|
||||||
|
ATA_INFO("pulse state: PA_CONTEXT_READY");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Callback on getting data from pulseaudio:
|
||||||
|
static void callbackGetSinkList(pa_context* _contex, const pa_sink_info* _info, int _eol, void* _userdata) {
|
||||||
|
std::vector<audio::orchestra::api::pulse::Element>* list = static_cast<std::vector<audio::orchestra::api::pulse::Element>*>(_userdata);
|
||||||
|
// If eol is set to a positive number, you're at the end of the list
|
||||||
|
if (_eol > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ATA_INFO("find output : " << _info->name);
|
||||||
|
list->push_back(audio::orchestra::api::pulse::Element(_info->index, false, _info->name, _info->description));
|
||||||
|
}
|
||||||
|
|
||||||
|
// allback to get data from pulseaudio:
|
||||||
|
static void callbackGetSourceList(pa_context* _contex, const pa_source_info* _info, int _eol, void* _userdata) {
|
||||||
|
std::vector<audio::orchestra::api::pulse::Element>* list = static_cast<std::vector<audio::orchestra::api::pulse::Element>*>(_userdata);
|
||||||
|
if (_eol > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ATA_INFO("find input : " << _info->name);
|
||||||
|
list->push_back(audio::orchestra::api::pulse::Element(_info->index, true, _info->name, _info->description));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<audio::orchestra::api::pulse::Element> audio::orchestra::api::pulse::getDeviceList() {
|
||||||
|
// Define our pulse audio loop and connection variables
|
||||||
|
pa_mainloop* pulseAudioMainLoop;
|
||||||
|
pa_mainloop_api* pulseAudioMainLoopAPI;
|
||||||
|
pa_operation* pulseAudioOperation;
|
||||||
|
pa_context* pulseAudioContex;
|
||||||
|
pa_context_flags_t pulseAudioFlags;
|
||||||
|
std::vector<audio::orchestra::api::pulse::Element> out;
|
||||||
|
// We'll need these state variables to keep track of our requests
|
||||||
|
int state = 0;
|
||||||
|
int pulseAudioReady = 0;
|
||||||
|
// Create a mainloop API and connection to the default server
|
||||||
|
pulseAudioMainLoop = pa_mainloop_new();
|
||||||
|
pulseAudioMainLoopAPI = pa_mainloop_get_api(pulseAudioMainLoop);
|
||||||
|
pulseAudioContex = pa_context_new(pulseAudioMainLoopAPI, "test");
|
||||||
|
// This function connects to the pulse server
|
||||||
|
pa_context_connect(pulseAudioContex, NULL, pulseAudioFlags, NULL);
|
||||||
|
// If there's an error, the callback will set pulseAudioReady
|
||||||
|
pa_context_set_state_callback(pulseAudioContex, callbackStateMachine, &pulseAudioReady);
|
||||||
|
ATA_INFO("start main loop...");
|
||||||
|
while (true) {
|
||||||
|
ATA_INFO("loop");
|
||||||
|
// We can't do anything until PA is ready, so just iterate the mainloop
|
||||||
|
// and continue
|
||||||
|
if (pulseAudioReady == 0) {
|
||||||
|
ATA_INFO("Pulse not ready");
|
||||||
|
pa_mainloop_iterate(pulseAudioMainLoop, 1, nullptr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// We couldn't get a connection to the server, so exit out
|
||||||
|
if (pulseAudioReady == 2) {
|
||||||
|
ATA_INFO("pulse not ready");
|
||||||
|
pa_context_disconnect(pulseAudioContex);
|
||||||
|
pa_context_unref(pulseAudioContex);
|
||||||
|
pa_mainloop_free(pulseAudioMainLoop);
|
||||||
|
ATA_ERROR("Pulse interface error: Can not connect to the pulseaudio iterface...");
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
// At this point, we're connected to the server and ready to make
|
||||||
|
// requests
|
||||||
|
switch (state) {
|
||||||
|
// State 0: we haven't done anything yet
|
||||||
|
case 0:
|
||||||
|
ATA_INFO("Request sink list");
|
||||||
|
pulseAudioOperation = pa_context_get_sink_info_list(pulseAudioContex,
|
||||||
|
callbackGetSinkList,
|
||||||
|
&out);
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// Now we wait for our operation to complete. When it's
|
||||||
|
// complete our pa_output_devicelist is filled out, and we move
|
||||||
|
// along to the next state
|
||||||
|
if (pa_operation_get_state(pulseAudioOperation) == PA_OPERATION_DONE) {
|
||||||
|
pa_operation_unref(pulseAudioOperation);
|
||||||
|
ATA_INFO("Request sources list");
|
||||||
|
pulseAudioOperation = pa_context_get_source_info_list(pulseAudioContex,
|
||||||
|
callbackGetSourceList,
|
||||||
|
&out);
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (pa_operation_get_state(pulseAudioOperation) == PA_OPERATION_DONE) {
|
||||||
|
ATA_INFO("All is done");
|
||||||
|
// Now we're done, clean up and disconnect and return
|
||||||
|
pa_operation_unref(pulseAudioOperation);
|
||||||
|
pa_context_disconnect(pulseAudioContex);
|
||||||
|
pa_context_unref(pulseAudioContex);
|
||||||
|
pa_mainloop_free(pulseAudioMainLoop);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// We should never see this state
|
||||||
|
ATA_ERROR("Error in getting the devices list ...");
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
// Iterate the main loop ..
|
||||||
|
pa_mainloop_iterate(pulseAudioMainLoop, 1, nullptr);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
50
audio/orchestra/api/PulseDeviceList.h
Normal file
50
audio/orchestra/api/PulseDeviceList.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
* @fork from RTAudio
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__AUDIO_ORCHESTRA_API_PULSE_DEVICE_H__) && defined(ORCHESTRA_BUILD_PULSE)
|
||||||
|
#define __AUDIO_ORCHESTRA_API_PULSE_DEVICE_H__
|
||||||
|
|
||||||
|
#include <etk/types.h>
|
||||||
|
|
||||||
|
namespace audio {
|
||||||
|
namespace orchestra {
|
||||||
|
namespace api {
|
||||||
|
namespace pulse {
|
||||||
|
class Element {
|
||||||
|
private:
|
||||||
|
size_t m_index;
|
||||||
|
bool m_input;
|
||||||
|
std::string m_name;
|
||||||
|
std::string m_description;
|
||||||
|
public:
|
||||||
|
Element(size_t _index, bool _input, const std::string& _name, const std::string& _desc) :
|
||||||
|
m_index(_index),
|
||||||
|
m_input(_input),
|
||||||
|
m_name(_name),
|
||||||
|
m_description(_desc) {
|
||||||
|
// nothing to do...
|
||||||
|
}
|
||||||
|
size_t getIndex() const {
|
||||||
|
return m_index;
|
||||||
|
}
|
||||||
|
bool isInput() const {
|
||||||
|
return m_input;
|
||||||
|
}
|
||||||
|
const std::string& getName() const {
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
const std::string& getDescription() const {
|
||||||
|
return m_description;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::vector<audio::orchestra::api::pulse::Element> getDeviceList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -17,6 +17,7 @@ namespace audio {
|
|||||||
}
|
}
|
||||||
#define ATA_BASE(info,data) TK_LOG_BASE(audio::orchestra::getLogId(),info,data)
|
#define ATA_BASE(info,data) TK_LOG_BASE(audio::orchestra::getLogId(),info,data)
|
||||||
|
|
||||||
|
#define ATA_PRINT(data) ATA_BASE(-1, data)
|
||||||
#define ATA_CRITICAL(data) ATA_BASE(1, data)
|
#define ATA_CRITICAL(data) ATA_BASE(1, data)
|
||||||
#define ATA_ERROR(data) ATA_BASE(2, data)
|
#define ATA_ERROR(data) ATA_BASE(2, data)
|
||||||
#define ATA_WARNING(data) ATA_BASE(3, data)
|
#define ATA_WARNING(data) ATA_BASE(3, data)
|
||||||
|
@ -44,6 +44,7 @@ def create(target):
|
|||||||
'audio/orchestra/api/Alsa.cpp',
|
'audio/orchestra/api/Alsa.cpp',
|
||||||
'audio/orchestra/api/Jack.cpp',
|
'audio/orchestra/api/Jack.cpp',
|
||||||
'audio/orchestra/api/Pulse.cpp',
|
'audio/orchestra/api/Pulse.cpp',
|
||||||
|
'audio/orchestra/api/PulseDeviceList.cpp',
|
||||||
'audio/orchestra/api/Oss.cpp'
|
'audio/orchestra/api/Oss.cpp'
|
||||||
])
|
])
|
||||||
myModule.add_optionnal_module_depend('alsa', ["c++", "-DORCHESTRA_BUILD_ALSA"])
|
myModule.add_optionnal_module_depend('alsa', ["c++", "-DORCHESTRA_BUILD_ALSA"])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user