@ -14,31 +14,68 @@
# include "common/logging/log.h"
# include "common/logging/log.h"
namespace AudioCore {
namespace AudioCore {
namespace {
struct SinkDetails {
using FactoryFn = std : : unique_ptr < Sink > ( * ) ( std : : string_view ) ;
using ListDevicesFn = std : : vector < std : : string > ( * ) ( ) ;
// g_sink_details is ordered in terms of desirability, with the best choice at the top.
/// Name for this sink.
const std : : vector < SinkDetails > g_sink_details = {
const char * id ;
/// A method to call to construct an instance of this type of sink.
FactoryFn factory ;
/// A method to call to list available devices.
ListDevicesFn list_devices ;
} ;
// sink_details is ordered in terms of desirability, with the best choice at the top.
constexpr SinkDetails sink_details [ ] = {
# ifdef HAVE_CUBEB
# ifdef HAVE_CUBEB
SinkDetails { " cubeb " , & std : : make_unique < CubebSink , std : : string > , & ListCubebSinkDevices } ,
SinkDetails { " cubeb " ,
[ ] ( std : : string_view device_id ) - > std : : unique_ptr < Sink > {
return std : : make_unique < CubebSink > ( device_id ) ;
} ,
& ListCubebSinkDevices } ,
# endif
# endif
SinkDetails { " null " , & std : : make_unique < NullSink , std : : string > ,
SinkDetails { " null " ,
[ ] ( std : : string_view device_id ) - > std : : unique_ptr < Sink > {
return std : : make_unique < NullSink > ( device_id ) ;
} ,
[ ] { return std : : vector < std : : string > { " null " } ; } } ,
[ ] { return std : : vector < std : : string > { " null " } ; } } ,
} ;
} ;
const SinkDetails & GetSinkDetails ( std : : string_view sink_id ) {
const SinkDetails & GetSinkDetails ( std : : string_view sink_id ) {
auto iter =
auto iter =
std : : find_if ( g_sink_details. begin ( ) , g_sink_details . end ( ) ,
std : : find_if ( std: : begin ( sink_details ) , std : : end ( sink_details ) ,
[ sink_id ] ( const auto & sink_detail ) { return sink_detail . id = = sink_id ; } ) ;
[ sink_id ] ( const auto & sink_detail ) { return sink_detail . id = = sink_id ; } ) ;
if ( sink_id = = " auto " | | iter = = g_sink_details. end ( ) ) {
if ( sink_id = = " auto " | | iter = = std: : end ( sink_details ) ) {
if ( sink_id ! = " auto " ) {
if ( sink_id ! = " auto " ) {
LOG_ERROR ( Audio , " AudioCore::SelectSink given invalid sink_id {} " , sink_id ) ;
LOG_ERROR ( Audio , " AudioCore::SelectSink given invalid sink_id {} " , sink_id ) ;
}
}
// Auto-select.
// Auto-select.
// g_ sink_details is ordered in terms of desirability, with the best choice at the front.
// sink_details is ordered in terms of desirability, with the best choice at the front.
iter = g_sink_details. begin ( ) ;
iter = std: : begin ( sink_details ) ;
}
}
return * iter ;
return * iter ;
}
}
} // Anonymous namespace
std : : vector < const char * > GetSinkIDs ( ) {
std : : vector < const char * > sink_ids ( std : : size ( sink_details ) ) ;
std : : transform ( std : : begin ( sink_details ) , std : : end ( sink_details ) , std : : begin ( sink_ids ) ,
[ ] ( const auto & sink ) { return sink . id ; } ) ;
return sink_ids ;
}
std : : vector < std : : string > GetDeviceListForSink ( std : : string_view sink_id ) {
return GetSinkDetails ( sink_id ) . list_devices ( ) ;
}
std : : unique_ptr < Sink > CreateSinkFromID ( std : : string_view sink_id , std : : string_view device_id ) {
return GetSinkDetails ( sink_id ) . factory ( device_id ) ;
}
} // namespace AudioCore
} // namespace AudioCore