From 8224e4371c2dc60def6c51b849abfbd7c02e2787 Mon Sep 17 00:00:00 2001 From: yanmorin <yanmorin> Date: Mon, 7 Nov 2005 18:07:59 +0000 Subject: [PATCH] Add driver in/out capacity (experimental) Add switch <CSeq> audiodriver command (experimental) --- CHANGES | 1 + src/audio/audiolayer.cpp | 17 ++-- src/audio/audiolayer.h | 5 +- src/gui/guiframework.cpp | 6 ++ src/gui/guiframework.h | 1 + src/gui/server/requestconfig.cpp | 20 +++++ src/gui/server/requestconfig.h | 8 ++ src/gui/server/requestfactory.cpp | 2 + src/managerimpl.cpp | 126 ++++++++++++++++++++++++++---- src/managerimpl.h | 6 +- src/user_cfg.h | 2 + 11 files changed, 169 insertions(+), 25 deletions(-) diff --git a/CHANGES b/CHANGES index 6f1eb920e7..99fdef7f2d 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,7 @@ SFLphoned/SFLphone (0.6) / 2005-11-04 * accept reinvite call * cleaning headers * improving bash launcher script + * select audio input and output device SFLphoned/SFLphone (0.5a) / 2005-10-17 * sflphoned diff --git a/src/audio/audiolayer.cpp b/src/audio/audiolayer.cpp index f24cb1ef58..0d39679dfc 100644 --- a/src/audio/audiolayer.cpp +++ b/src/audio/audiolayer.cpp @@ -59,23 +59,30 @@ AudioLayer::closeStream (void) } } +bool +AudioLayer::hasStream(void) { + ost::MutexLock guard(_mutex); + return (_stream!=0 ? true : false); +} + + void -AudioLayer::openDevice (int index) +AudioLayer::openDevice (int indexIn, int indexOut) { closeStream(); try { // Set up the parameters required to open a (Callback)Stream: portaudio::DirectionSpecificStreamParameters - outParams(portaudio::System::instance().deviceByIndex(index), + outParams(portaudio::System::instance().deviceByIndex(indexOut), 2, portaudio::INT16, true, - portaudio::System::instance().deviceByIndex(index).defaultLowOutputLatency(), + portaudio::System::instance().deviceByIndex(indexOut).defaultLowOutputLatency(), NULL); portaudio::DirectionSpecificStreamParameters - inParams(portaudio::System::instance().deviceByIndex(index), + inParams(portaudio::System::instance().deviceByIndex(indexIn), 2, portaudio::INT16, true, - portaudio::System::instance().deviceByIndex(index).defaultLowInputLatency(), + portaudio::System::instance().deviceByIndex(indexIn).defaultLowInputLatency(), NULL); // we could put paFramesPerBufferUnspecified instead of FRAME_PER_BUFFER to be variable diff --git a/src/audio/audiolayer.h b/src/audio/audiolayer.h index 8ba2d34370..2fe4632e0a 100644 --- a/src/audio/audiolayer.h +++ b/src/audio/audiolayer.h @@ -43,10 +43,11 @@ public: AudioLayer(); ~AudioLayer(void); - void openDevice(int); + void openDevice(int, int); void startStream(void); void stopStream(void); void sleep(int); + bool hasStream(void); bool isStreamActive(void); bool isStreamStopped(void); @@ -63,6 +64,8 @@ public: void setErrorMessage(const std::string& error) { _errorMessage = error; } std::string getErrorMessage() { return _errorMessage; } + enum IODEVICE {InputDevice=0x01, OutputDevice=0x02 }; + private: void closeStream (void); RingBuffer _urgentRingBuffer; diff --git a/src/gui/guiframework.cpp b/src/gui/guiframework.cpp index aea6061070..8fb60f27a8 100644 --- a/src/gui/guiframework.cpp +++ b/src/gui/guiframework.cpp @@ -280,3 +280,9 @@ GuiFramework::getRegistrationState(std::string& stateCode, std::string& stateMes } return returnValue; } + +bool +GuiFramework::setSwitch(const std::string& switchName) +{ + return Manager::instance().setSwitch(switchName); +} diff --git a/src/gui/guiframework.h b/src/gui/guiframework.h index a823eb3e56..06047252f3 100644 --- a/src/gui/guiframework.h +++ b/src/gui/guiframework.h @@ -88,6 +88,7 @@ public: bool setMicVolume(int volume); int getSpkrVolume(); int getMicVolume(); + bool setSwitch(const std::string& switchName); bool hasLoadedSetup(); CALLID getCurrentId(); diff --git a/src/gui/server/requestconfig.cpp b/src/gui/server/requestconfig.cpp index 6b75a34ad6..08eff1ce47 100644 --- a/src/gui/server/requestconfig.cpp +++ b/src/gui/server/requestconfig.cpp @@ -261,4 +261,24 @@ RequestUnregister::execute() } } +RequestSwitch::RequestSwitch(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId,argList) +{ + TokenList::iterator iter = _argList.begin(); + if (iter != _argList.end()) { + _switchName = *iter; + } else { + throw RequestConstructorException(); + } +} + +ResponseMessage +RequestSwitch::execute() +{ + if (GUIServer::instance().setSwitch(_switchName)) { + return message("200", "OK"); + } else { + return message("500","Server Error"); + } +} + diff --git a/src/gui/server/requestconfig.h b/src/gui/server/requestconfig.h index db50c74b77..ad0581e618 100644 --- a/src/gui/server/requestconfig.h +++ b/src/gui/server/requestconfig.h @@ -121,5 +121,13 @@ public: RequestUnregister(const std::string &sequenceId, const TokenList& argList) : RequestGlobal(sequenceId, argList) {} ResponseMessage execute(); }; +class RequestSwitch : public RequestGlobal { +public: + RequestSwitch(const std::string &sequenceId, const TokenList& argList); + ResponseMessage execute(); +private: + std::string _switchName; +}; + #endif // __REQUESTCONFIG_H__ diff --git a/src/gui/server/requestfactory.cpp b/src/gui/server/requestfactory.cpp index 6bbbf03c48..5ebd8d09b7 100644 --- a/src/gui/server/requestfactory.cpp +++ b/src/gui/server/requestfactory.cpp @@ -130,4 +130,6 @@ RequestFactory::registerAll() { registerRequest<RequestVolumeMic> ("setmicvolume"); registerRequest<RequestRegister> ("register"); registerRequest<RequestUnregister> ("unregister"); + + registerRequest<RequestSwitch> ("switch"); } diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index cd9affdf97..b6246dfa64 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -118,16 +118,20 @@ ManagerImpl::init() _telephoneTone = new TelephoneTone(country); try { + initAudioDriver(); selectAudioDriver(); } catch (const portaudio::PaException &e) { getAudioDriver()->setErrorMessage(e.paErrorText()); + _debug("Portaudio exception: %s\n", e.paErrorText()); } catch (const portaudio::PaCppException &e) { getAudioDriver()->setErrorMessage(e.what()); + _debug("Portaudio exception: %s\n", e.what()); } catch (const std::runtime_error &e) { getAudioDriver()->setErrorMessage(e.what()); + _debug("Portaudio exception: %s\n", e.what()); } catch (...) { displayError("An unknown exception occured while selecting audio driver."); @@ -1211,6 +1215,8 @@ ManagerImpl::initConfigFile (void) section = AUDIO; fill_config_int(DRIVER_NAME, DFT_DRIVER_STR); + fill_config_int(DRIVER_NAME_IN, DFT_DRIVER_STR); + fill_config_int(DRIVER_NAME_OUT, DFT_DRIVER_STR); fill_config_str(CODEC1, DFT_CODEC); fill_config_str(CODEC2, DFT_CODEC); fill_config_str(CODEC3, DFT_CODEC); @@ -1263,24 +1269,56 @@ ManagerImpl::unloadAudioCodec() * Initialization: Main Thread */ void -ManagerImpl::selectAudioDriver (void) +ManagerImpl::initAudioDriver(void) { #if defined(AUDIO_PORTAUDIO) try { _debugInit("AudioLayer Creation"); _audiodriverPA = new AudioLayer(); - int noDevice = getConfigInt(AUDIO, DRIVER_NAME); + } catch(...) { + throw; + } +#else +# error You must define one AUDIO driver to use. +#endif +} + +/** + * Initialization: Main Thread and gui + */ +void +ManagerImpl::selectAudioDriver (void) +{ +#if defined(AUDIO_PORTAUDIO) + try { + int noDevice = getConfigInt(AUDIO, DRIVER_NAME); + int noDeviceIn = getConfigInt(AUDIO, DRIVER_NAME_IN); + int noDeviceOut = getConfigInt(AUDIO, DRIVER_NAME_OUT); + + // this is when no audio device in/out are set + // or the audio device in/out are set to 0 + // we take the nodevice instead + if (noDeviceIn == 0 && noDeviceOut == 0) { + noDeviceIn = noDeviceOut = noDevice; + } _debugInit(" AudioLayer Device Count"); int nbDevice = portaudio::System::instance().deviceCount(); if (nbDevice == 0) { throw std::runtime_error("Portaudio detect no sound card."); - } else if (noDevice >= nbDevice) { - _debug(" Portaudio auto-select device #0 because device #%d is not found\n", noDevice); - _setupLoaded = false; - noDevice = 0; + } else { + if (noDeviceIn >= nbDevice) { + _debug(" Portaudio auto-select device #0 for input because device #%d is not found\n", noDeviceIn); + _setupLoaded = false; + noDeviceIn = 0; + } + if (noDeviceOut >= nbDevice) { + _debug(" Portaudio auto-select device #0 for output because device #%d is not found\n", noDeviceOut); + _setupLoaded = false; + noDeviceOut = 0; + } } _debugInit(" AudioLayer Opening Device"); - _audiodriverPA->openDevice(noDevice); + _audiodriverPA->openDevice(noDeviceIn, noDeviceOut); } catch(...) { throw; } @@ -1358,6 +1396,8 @@ ManagerImpl::getZeroconf(const std::string& sequenceId) } returnValue = true; } +#else + (void)sequenceId; #endif return returnValue; } @@ -1378,6 +1418,9 @@ ManagerImpl::attachZeroconfEvents(const std::string& sequenceId, Pattern::Observ _DNSService->attach(observer); returnValue = true; } +#else + (void)sequenceId; + (void)observer; #endif return returnValue; } @@ -1390,6 +1433,8 @@ ManagerImpl::detachZeroconfEvents(Pattern::Observer& observer) _DNSService->detach(observer); returnValue = true; } +#else + (void)observer; #endif return returnValue; } @@ -1559,7 +1604,11 @@ ManagerImpl::getConfigList(const std::string& sequenceId, const std::string& nam path = std::string(HOMEDIR) + DIR_SEPARATOR_STR + "." + PROGDIR + DIR_SEPARATOR_STR + RINGDIR; getDirListing(sequenceId, path, &nbFile); } else if (name=="audiodevice") { - returnValue = getAudioDeviceList(sequenceId); + returnValue = getAudioDeviceList(sequenceId, AudioLayer::InputDevice | AudioLayer::OutputDevice); + } else if (name=="audiodevicein") { + returnValue = getAudioDeviceList(sequenceId, AudioLayer::InputDevice); + } else if (name=="audiodeviceout") { + returnValue = getAudioDeviceList(sequenceId, AudioLayer::OutputDevice); } else if (name=="countrytones") { returnValue = getCountryTones(sequenceId); } @@ -1570,7 +1619,7 @@ ManagerImpl::getConfigList(const std::string& sequenceId, const std::string& nam * User request Main Thread (list) */ bool -ManagerImpl::getAudioDeviceList(const std::string& sequenceId) +ManagerImpl::getAudioDeviceList(const std::string& sequenceId, int ioDeviceMask) { bool returnValue = false; try { @@ -1583,14 +1632,19 @@ ManagerImpl::getAudioDeviceList(const std::string& sequenceId) for (int index = 0; index < sys.deviceCount(); index++ ) { portaudio::Device& device = sys.deviceByIndex(index); - hostApiName = device.hostApi().name(); - deviceName = device.name(); - tk.clear(); - std::ostringstream str; str << index; tk.push_back(str.str()); - tk.push_back(deviceName); - tk.push_back(std::string(hostApiName)); - _gui->sendMessage("100", sequenceId, tk); + if ((ioDeviceMask == AudioLayer::InputDevice && !device.isOutputOnlyDevice()) || + (ioDeviceMask == AudioLayer::OutputDevice && !device.isInputOnlyDevice() ) || + device.isFullDuplexDevice()) { + hostApiName = device.hostApi().name(); + deviceName = device.name(); + + tk.clear(); + std::ostringstream str; str << index; tk.push_back(str.str()); + tk.push_back(deviceName); + tk.push_back(std::string(hostApiName)); + _gui->sendMessage("100", sequenceId, tk); + } } returnValue = true; } catch (...) { @@ -1666,4 +1720,42 @@ ManagerImpl::switchCall(CALLID id) } } - +/** + * Main Thread - Gui + * Experimental... + */ +bool +ManagerImpl::setSwitch(const std::string& switchName) { + if (switchName == "audiodriver" ) { + try + { + selectAudioDriver(); + return true; + } + catch (const portaudio::PaException &e) + { + getAudioDriver()->setErrorMessage(e.paErrorText()); + _debug("Portaudio exception: %s\n", e.paErrorText()); + return false; + } + catch (const portaudio::PaCppException &e) + { + getAudioDriver()->setErrorMessage(e.what()); + _debug("Portaudio exception: %s\n", e.what()); + return false; + } + catch (const std::runtime_error &e) + { + getAudioDriver()->setErrorMessage(e.what()); + _debug("Portaudio exception: %s\n", e.what()); + return false; + } + catch(...) + { + _debug("Portaudio exception: <unknown>\n"); + return false; + } + } else { + return false; + } +} diff --git a/src/managerimpl.h b/src/managerimpl.h index 0cf41d603a..dbd7c1e677 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -175,6 +175,8 @@ public: bool setConfig(const std::string& section, const std::string& name, const std::string& value); bool setConfig(const std::string& section, const std::string& name, int value); bool getConfigList(const std::string& sequenceId, const std::string& name); + void selectAudioDriver(void); + bool setSwitch(const std::string& switchName); // configuration function for extern // throw an Conf::ConfigTreeItemException if not found @@ -269,7 +271,7 @@ private: /* * Initialize audiodriver */ - void selectAudioDriver (void); + void initAudioDriver(void); /* * Initialize zeroconf module and scanning @@ -290,7 +292,7 @@ private: * Configuration */ bool getDirListing(const std::string& sequenceId, const std::string& path, int *nbFile); - bool getAudioDeviceList(const std::string& sequenceId); + bool getAudioDeviceList(const std::string& sequenceId, int ioDeviceMask); Conf::ConfigTree _config; bool getCountryTones(const std::string& sequenceId); void sendCountryTone(const std::string& sequenceId, int index, const std::string& name); diff --git a/src/user_cfg.h b/src/user_cfg.h index 343e0c887e..49aed13606 100644 --- a/src/user_cfg.h +++ b/src/user_cfg.h @@ -54,6 +54,8 @@ #define STUN_SERVER "STUN.STUNserver" #define USE_STUN "STUN.useStun" #define DRIVER_NAME "Drivers.driverName" +#define DRIVER_NAME_IN "Drivers.driverNameIn" +#define DRIVER_NAME_OUT "Drivers.driverNameOut" #define NB_CODEC "Codecs.nbCodec" #define CODEC1 "Codecs.codec1" #define CODEC2 "Codecs.codec2" -- GitLab