2015-04-10 22:06:17 +02:00
/** @file
* @ author Edouard DUPIN
* @ copyright 2011 , Edouard DUPIN , all right reserved
* @ license APACHE v2 .0 ( see license file )
* @ fork from RTAudio
*/
2016-10-02 22:06:09 +02:00
//#include <etk/types.hpp>
# include <audio/orchestra/Interface.hpp>
# include <audio/orchestra/debug.hpp>
2015-04-10 22:06:17 +02:00
# include <iostream>
2016-10-02 22:06:09 +02:00
# include <audio/orchestra/api/Alsa.hpp>
# include <audio/orchestra/api/Android.hpp>
# include <audio/orchestra/api/Asio.hpp>
# include <audio/orchestra/api/Core.hpp>
# include <audio/orchestra/api/CoreIos.hpp>
# include <audio/orchestra/api/Ds.hpp>
# include <audio/orchestra/api/Dummy.hpp>
# include <audio/orchestra/api/Jack.hpp>
# include <audio/orchestra/api/Pulse.hpp>
2015-04-10 22:06:17 +02:00
2015-06-11 21:39:56 +02:00
std : : vector < std : : string > audio : : orchestra : : Interface : : getListApi ( ) {
std : : vector < std : : string > apis ;
2015-04-10 22:06:17 +02:00
// The order here will control the order of RtAudio's API search in
// the constructor.
for ( size_t iii = 0 ; iii < m_apiAvaillable . size ( ) ; + + iii ) {
apis . push_back ( m_apiAvaillable [ iii ] . first ) ;
}
return apis ;
}
2015-06-11 21:39:56 +02:00
void audio : : orchestra : : Interface : : openApi ( const std : : string & _api ) {
2015-06-23 21:09:57 +02:00
m_api . reset ( ) ;
2015-04-10 22:06:17 +02:00
for ( size_t iii = 0 ; iii < m_apiAvaillable . size ( ) ; + + iii ) {
ATA_INFO ( " try open " < < m_apiAvaillable [ iii ] . first ) ;
if ( _api = = m_apiAvaillable [ iii ] . first ) {
ATA_INFO ( " ==> call it " ) ;
2015-06-14 18:32:08 +02:00
m_api = m_apiAvaillable [ iii ] . second ( ) ;
if ( m_api ! = nullptr ) {
2015-04-10 22:06:17 +02:00
return ;
}
}
}
// TODO : An error occured ...
ATA_ERROR ( " Error in open API ... " ) ;
}
audio : : orchestra : : Interface : : Interface ( ) :
2015-06-14 18:32:08 +02:00
m_api ( nullptr ) {
2015-04-10 22:06:17 +02:00
ATA_DEBUG ( " Add interface: " ) ;
# if defined(ORCHESTRA_BUILD_JACK)
2016-04-29 23:16:07 +02:00
addInterface ( audio : : orchestra : : typeJack , audio : : orchestra : : api : : Jack : : create ) ;
2015-04-10 22:06:17 +02:00
# endif
# if defined(ORCHESTRA_BUILD_ALSA)
2016-04-29 23:16:07 +02:00
addInterface ( audio : : orchestra : : typeAlsa , audio : : orchestra : : api : : Alsa : : create ) ;
2015-04-10 22:06:17 +02:00
# endif
# if defined(ORCHESTRA_BUILD_PULSE)
2016-04-29 23:16:07 +02:00
addInterface ( audio : : orchestra : : typePulse , audio : : orchestra : : api : : Pulse : : create ) ;
2015-04-10 22:06:17 +02:00
# endif
# if defined(ORCHESTRA_BUILD_ASIO)
2016-04-29 23:16:07 +02:00
addInterface ( audio : : orchestra : : typeAsio , audio : : orchestra : : api : : Asio : : create ) ;
2015-04-10 22:06:17 +02:00
# endif
# if defined(ORCHESTRA_BUILD_DS)
2016-04-29 23:16:07 +02:00
addInterface ( audio : : orchestra : : typeDs , audio : : orchestra : : api : : Ds : : create ) ;
2015-04-10 22:06:17 +02:00
# endif
# if defined(ORCHESTRA_BUILD_MACOSX_CORE)
2016-04-29 23:16:07 +02:00
addInterface ( audio : : orchestra : : typeCoreOSX , audio : : orchestra : : api : : Core : : create ) ;
2015-04-10 22:06:17 +02:00
# endif
# if defined(ORCHESTRA_BUILD_IOS_CORE)
2016-04-29 23:16:07 +02:00
addInterface ( audio : : orchestra : : typeCoreIOS , audio : : orchestra : : api : : CoreIos : : create ) ;
2015-04-10 22:06:17 +02:00
# endif
# if defined(ORCHESTRA_BUILD_JAVA)
2016-04-29 23:16:07 +02:00
addInterface ( audio : : orchestra : : typeJava , audio : : orchestra : : api : : Android : : create ) ;
2015-04-10 22:06:17 +02:00
# endif
# if defined(ORCHESTRA_BUILD_DUMMY)
2016-04-29 23:16:07 +02:00
addInterface ( audio : : orchestra : : typeDummy , audio : : orchestra : : api : : Dummy : : create ) ;
2015-04-10 22:06:17 +02:00
# endif
}
2016-07-19 21:43:58 +02:00
void audio : : orchestra : : Interface : : addInterface ( const std : : string & _api , ememory : : SharedPtr < Api > ( * _callbackCreate ) ( ) ) {
m_apiAvaillable . push_back ( std : : pair < std : : string , ememory : : SharedPtr < Api > ( * ) ( ) > ( _api , _callbackCreate ) ) ;
2015-04-10 22:06:17 +02:00
}
2015-06-11 21:39:56 +02:00
enum audio : : orchestra : : error audio : : orchestra : : Interface : : clear ( ) {
ATA_INFO ( " Clear API ... " ) ;
2015-06-14 18:32:08 +02:00
if ( m_api = = nullptr ) {
2015-06-11 21:39:56 +02:00
ATA_WARNING ( " Interface NOT started! " ) ;
return audio : : orchestra : : error_none ;
}
2015-06-23 21:09:57 +02:00
m_api . reset ( ) ;
2015-06-11 21:39:56 +02:00
return audio : : orchestra : : error_none ;
}
enum audio : : orchestra : : error audio : : orchestra : : Interface : : instanciate ( const std : : string & _api ) {
2015-04-10 22:06:17 +02:00
ATA_INFO ( " Instanciate API ... " ) ;
2015-06-14 18:32:08 +02:00
if ( m_api ! = nullptr ) {
2015-06-11 21:39:56 +02:00
ATA_WARNING ( " Interface already started! " ) ;
2015-04-10 22:06:17 +02:00
return audio : : orchestra : : error_none ;
}
2016-04-29 23:16:07 +02:00
if ( _api ! = audio : : orchestra : : typeUndefined ) {
2015-04-10 22:06:17 +02:00
ATA_INFO ( " API specified : " < < _api ) ;
// Attempt to open the specified API.
2015-06-11 21:39:56 +02:00
openApi ( _api ) ;
2015-06-14 18:32:08 +02:00
if ( m_api ! = nullptr ) {
if ( m_api - > getDeviceCount ( ) ! = 0 ) {
2015-04-10 22:06:17 +02:00
ATA_INFO ( " ==> api open " ) ;
}
return audio : : orchestra : : error_none ;
}
// No compiled support for specified API value. Issue a debug
// warning and continue as if no API was specified.
2015-06-14 18:32:08 +02:00
ATA_ERROR ( " API NOT Supported ' " < < _api < < " ' not in " < < getListApi ( ) ) ;
2015-04-10 22:06:17 +02:00
return audio : : orchestra : : error_fail ;
}
ATA_INFO ( " Auto choice API : " ) ;
// Iterate through the compiled APIs and return as soon as we find
// one with at least one device or we reach the end of the list.
2015-06-11 21:39:56 +02:00
std : : vector < std : : string > apis = getListApi ( ) ;
2015-04-10 22:06:17 +02:00
ATA_INFO ( " find : " < < apis . size ( ) < < " apis. " ) ;
for ( size_t iii = 0 ; iii < apis . size ( ) ; + + iii ) {
ATA_INFO ( " try open ... " ) ;
2015-06-11 21:39:56 +02:00
openApi ( apis [ iii ] ) ;
2015-06-14 18:32:08 +02:00
if ( m_api = = nullptr ) {
2015-04-10 22:06:17 +02:00
ATA_ERROR ( " ==> can not create ... " ) ;
continue ;
}
2015-06-14 18:32:08 +02:00
if ( m_api - > getDeviceCount ( ) ! = 0 ) {
2015-04-10 22:06:17 +02:00
ATA_INFO ( " ==> api open " ) ;
break ;
2015-09-24 21:44:04 +02:00
} else {
ATA_INFO ( " ==> Interface exist, but have no devices: " < < m_api - > getDeviceCount ( ) ) ;
2015-04-10 22:06:17 +02:00
}
}
2015-06-14 18:32:08 +02:00
if ( m_api ! = nullptr ) {
2015-04-10 22:06:17 +02:00
return audio : : orchestra : : error_none ;
}
2015-06-14 18:32:08 +02:00
ATA_ERROR ( " API NOT Supported ' " < < _api < < " ' not in " < < getListApi ( ) ) ;
2015-04-10 22:06:17 +02:00
return audio : : orchestra : : error_fail ;
}
audio : : orchestra : : Interface : : ~ Interface ( ) {
ATA_INFO ( " Remove interface " ) ;
2015-06-23 21:09:57 +02:00
m_api . reset ( ) ;
2015-04-10 22:06:17 +02:00
}
enum audio : : orchestra : : error audio : : orchestra : : Interface : : openStream ( audio : : orchestra : : StreamParameters * _outputParameters ,
audio : : orchestra : : StreamParameters * _inputParameters ,
audio : : format _format ,
uint32_t _sampleRate ,
uint32_t * _bufferFrames ,
audio : : orchestra : : AirTAudioCallback _callback ,
const audio : : orchestra : : StreamOptions & _options ) {
2015-06-14 18:32:08 +02:00
if ( m_api = = nullptr ) {
2015-04-10 22:06:17 +02:00
return audio : : orchestra : : error_inputNull ;
}
2015-06-14 18:32:08 +02:00
return m_api - > openStream ( _outputParameters ,
2015-04-10 22:06:17 +02:00
_inputParameters ,
_format ,
_sampleRate ,
_bufferFrames ,
_callback ,
_options ) ;
}
bool audio : : orchestra : : Interface : : isMasterOf ( audio : : orchestra : : Interface & _interface ) {
2015-06-14 18:32:08 +02:00
if ( m_api = = nullptr ) {
2015-04-10 22:06:17 +02:00
ATA_ERROR ( " Current Master API is nullptr ... " ) ;
return false ;
}
2015-06-14 18:32:08 +02:00
if ( _interface . m_api = = nullptr ) {
2015-04-10 22:06:17 +02:00
ATA_ERROR ( " Current Slave API is nullptr ... " ) ;
return false ;
}
2015-06-14 18:32:08 +02:00
if ( m_api - > getCurrentApi ( ) ! = _interface . m_api - > getCurrentApi ( ) ) {
2015-04-10 22:06:17 +02:00
ATA_ERROR ( " Can not link 2 Interface with not the same Low level type (?) " ) ; //" << _interface.m_adac->getCurrentApi() << " != " << m_adac->getCurrentApi() << ")");
return false ;
}
2016-04-29 23:16:07 +02:00
if ( m_api - > getCurrentApi ( ) ! = audio : : orchestra : : typeAlsa ) {
ATA_ERROR ( " Link 2 device together work only if the interafec is ? " ) ; // << audio::orchestra::type::alsa << " not for " << m_api->getCurrentApi());
2015-04-10 22:06:17 +02:00
return false ;
}
2015-06-14 18:32:08 +02:00
return m_api - > isMasterOf ( _interface . m_api ) ;
2015-04-10 22:06:17 +02:00
}