From 53ebc1b75c8d3ba62cd1fcf335faf82a4c808e8f Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Mon, 12 Mar 2018 20:01:46 +0100 Subject: [PATCH 01/45] Add method to create entity based on TCP transport --- .../autoapp/Projection/AndroidAutoEntityFactory.hpp | 4 ++++ .../autoapp/Projection/IAndroidAutoEntityFactory.hpp | 2 ++ src/autoapp/Projection/AndroidAutoEntityFactory.cpp | 12 ++++++++++++ 3 files changed, 18 insertions(+) diff --git a/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp index aa3017c2..1df64dc7 100644 --- a/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp +++ b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include #include @@ -41,8 +42,11 @@ class AndroidAutoEntityFactory: public IAndroidAutoEntityFactory IServiceFactory& serviceFactory); IAndroidAutoEntity::Pointer create(aasdk::usb::DeviceHandle deviceHandle) override; + IAndroidAutoEntity::Pointer create(aasdk::tcp::ITCPEndpoint::Pointer tcpEndpoint) override; private: + IAndroidAutoEntity::Pointer create(aasdk::transport::ITransport::Pointer transport); + aasdk::usb::IUSBWrapper& usbWrapper_; boost::asio::io_service& ioService_; configuration::IConfiguration::Pointer configuration_; diff --git a/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp index ab51c4f1..945c2475 100644 --- a/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp +++ b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp @@ -18,6 +18,7 @@ #pragma once +#include #include #include @@ -36,6 +37,7 @@ class IAndroidAutoEntityFactory virtual ~IAndroidAutoEntityFactory() = default; virtual IAndroidAutoEntity::Pointer create(aasdk::usb::DeviceHandle deviceHandle) = 0; + virtual IAndroidAutoEntity::Pointer create(aasdk::tcp::ITCPEndpoint::Pointer tcpEndpoint) = 0; }; } diff --git a/src/autoapp/Projection/AndroidAutoEntityFactory.cpp b/src/autoapp/Projection/AndroidAutoEntityFactory.cpp index 612b8189..cc31faed 100644 --- a/src/autoapp/Projection/AndroidAutoEntityFactory.cpp +++ b/src/autoapp/Projection/AndroidAutoEntityFactory.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,17 @@ IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::usb::DeviceH auto aoapDevice(aasdk::usb::AOAPDevice::create(usbWrapper_, ioService_, deviceHandle)); auto transport(std::make_shared(ioService_, aoapDevice)); + return create(std::move(transport)); +} + +IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::tcp::ITCPEndpoint::Pointer tcpEndpoint) +{ + auto transport(std::make_shared(ioService_, std::move(tcpEndpoint))); + return create(std::move(transport)); +} + +IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::transport::ITransport::Pointer transport) +{ auto sslWrapper(std::make_shared()); auto cryptor(std::make_shared(std::move(sslWrapper))); From 799ed557ec67a7da856a6a8fa8e80e7e33d02eba Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Wed, 14 Mar 2018 17:20:59 +0100 Subject: [PATCH 02/45] Implement and use configuration of video margins --- .../autoapp/Configuration/Configuration.hpp | 5 +++++ .../autoapp/Configuration/IConfiguration.hpp | 3 +++ .../openauto/autoapp/Projection/IVideoOutput.hpp | 2 ++ .../openauto/autoapp/Projection/VideoOutput.hpp | 1 + src/autoapp/Configuration/Configuration.cpp | 16 ++++++++++++++++ src/autoapp/Projection/VideoOutput.cpp | 5 +++++ src/autoapp/Projection/VideoService.cpp | 6 ++++-- 7 files changed, 36 insertions(+), 2 deletions(-) diff --git a/include/f1x/openauto/autoapp/Configuration/Configuration.hpp b/include/f1x/openauto/autoapp/Configuration/Configuration.hpp index 2498977e..93d44b33 100644 --- a/include/f1x/openauto/autoapp/Configuration/Configuration.hpp +++ b/include/f1x/openauto/autoapp/Configuration/Configuration.hpp @@ -52,6 +52,8 @@ class Configuration: public IConfiguration void setScreenDPI(size_t value) override; void setOMXLayerIndex(int32_t value) override; int32_t getOMXLayerIndex() const override; + void setVideoMargins(QRect value) override; + QRect getVideoMargins() const override; bool getTouchscreenEnabled() const override; void setTouchscreenEnabled(bool value) override; @@ -79,6 +81,7 @@ class Configuration: public IConfiguration aasdk::proto::enums::VideoResolution::Enum videoResolution_; size_t screenDPI_; int32_t omxLayerIndex_; + QRect videoMargins_; bool enableTouchscreen_; ButtonCodes buttonCodes_; BluetoothAdapterType bluetoothAdapterType_; @@ -95,6 +98,8 @@ class Configuration: public IConfiguration static const std::string cVideoResolutionKey; static const std::string cVideoScreenDPIKey; static const std::string cVideoOMXLayerIndexKey; + static const std::string cVideoMarginWidth; + static const std::string cVideoMarginHeight; static const std::string cAudioMusicAudioChannelEnabled; static const std::string cAudioSpeechAudioChannelEnabled; diff --git a/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp b/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp index 48437f6f..2f086cd9 100644 --- a/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp +++ b/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include #include @@ -59,6 +60,8 @@ class IConfiguration virtual void setScreenDPI(size_t value) = 0; virtual void setOMXLayerIndex(int32_t value) = 0; virtual int32_t getOMXLayerIndex() const = 0; + virtual void setVideoMargins(QRect value) = 0; + virtual QRect getVideoMargins() const = 0; virtual bool getTouchscreenEnabled() const = 0; virtual void setTouchscreenEnabled(bool value) = 0; diff --git a/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp b/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp index c1ada0d6..1c483bc1 100644 --- a/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include #include @@ -47,6 +48,7 @@ class IVideoOutput virtual aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const = 0; virtual aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const = 0; virtual size_t getScreenDPI() const = 0; + virtual QRect getVideoMargins() const = 0; }; } diff --git a/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp b/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp index 7cfac93b..3c67cf6b 100644 --- a/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp @@ -38,6 +38,7 @@ class VideoOutput: public IVideoOutput aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const override; aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const override; size_t getScreenDPI() const override; + QRect getVideoMargins() const override; protected: configuration::IConfiguration::Pointer configuration_; diff --git a/src/autoapp/Configuration/Configuration.cpp b/src/autoapp/Configuration/Configuration.cpp index c1c42297..72e51e16 100644 --- a/src/autoapp/Configuration/Configuration.cpp +++ b/src/autoapp/Configuration/Configuration.cpp @@ -37,6 +37,8 @@ const std::string Configuration::cVideoFPSKey = "Video.FPS"; const std::string Configuration::cVideoResolutionKey = "Video.Resolution"; const std::string Configuration::cVideoScreenDPIKey = "Video.ScreenDPI"; const std::string Configuration::cVideoOMXLayerIndexKey = "Video.OMXLayerIndex"; +const std::string Configuration::cVideoMarginWidth = "Video.MarginWidth"; +const std::string Configuration::cVideoMarginHeight = "Video.MarginHeight"; const std::string Configuration::cAudioMusicAudioChannelEnabled = "Audio.MusicAudioChannelEnabled"; const std::string Configuration::cAudioSpeechAudioChannelEnabled = "Audio.SpeechAudioChannelEnabled"; @@ -87,6 +89,7 @@ void Configuration::load() screenDPI_ = iniConfig.get(cVideoScreenDPIKey, 140); omxLayerIndex_ = iniConfig.get(cVideoOMXLayerIndexKey, 1); + videoMargins_ = QRect(0, 0, iniConfig.get(cVideoMarginWidth, 0), iniConfig.get(cVideoMarginHeight, 0)); enableTouchscreen_ = iniConfig.get(cInputEnableTouchscreenKey, true); this->readButtonCodes(iniConfig); @@ -116,6 +119,7 @@ void Configuration::reset() videoResolution_ = aasdk::proto::enums::VideoResolution::_480p; screenDPI_ = 140; omxLayerIndex_ = 1; + videoMargins_ = QRect(0, 0, 0, 0); enableTouchscreen_ = true; buttonCodes_.clear(); bluetoothAdapterType_ = BluetoothAdapterType::NONE; @@ -134,6 +138,8 @@ void Configuration::save() iniConfig.put(cVideoResolutionKey, static_cast(videoResolution_)); iniConfig.put(cVideoScreenDPIKey, screenDPI_); iniConfig.put(cVideoOMXLayerIndexKey, omxLayerIndex_); + iniConfig.put(cVideoMarginWidth, videoMargins_.width()); + iniConfig.put(cVideoMarginHeight, videoMargins_.height()); iniConfig.put(cInputEnableTouchscreenKey, enableTouchscreen_); this->writeButtonCodes(iniConfig); @@ -206,6 +212,16 @@ int32_t Configuration::getOMXLayerIndex() const return omxLayerIndex_; } +void Configuration::setVideoMargins(QRect value) +{ + videoMargins_ = value; +} + +QRect Configuration::getVideoMargins() const +{ + return videoMargins_; +} + bool Configuration::getTouchscreenEnabled() const { return enableTouchscreen_; diff --git a/src/autoapp/Projection/VideoOutput.cpp b/src/autoapp/Projection/VideoOutput.cpp index 1b0c4e4d..dca398df 100644 --- a/src/autoapp/Projection/VideoOutput.cpp +++ b/src/autoapp/Projection/VideoOutput.cpp @@ -48,6 +48,11 @@ size_t VideoOutput::getScreenDPI() const return configuration_->getScreenDPI(); } +QRect VideoOutput::getVideoMargins() const +{ + return configuration_->getVideoMargins(); +} + } } } diff --git a/src/autoapp/Projection/VideoService.cpp b/src/autoapp/Projection/VideoService.cpp index 251e0379..b419d4a4 100644 --- a/src/autoapp/Projection/VideoService.cpp +++ b/src/autoapp/Projection/VideoService.cpp @@ -144,8 +144,10 @@ void VideoService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse auto* videoConfig1 = videoChannel->add_video_configs(); videoConfig1->set_video_resolution(videoOutput_->getVideoResolution()); videoConfig1->set_video_fps(videoOutput_->getVideoFPS()); - videoConfig1->set_margin_height(0); - videoConfig1->set_margin_width(0); + + const auto& videoMargins = videoOutput_->getVideoMargins(); + videoConfig1->set_margin_height(videoMargins.height()); + videoConfig1->set_margin_width(videoMargins.width()); videoConfig1->set_dpi(videoOutput_->getScreenDPI()); } From d483040d764822d4d23285dbe10a2e025761ac57 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Wed, 14 Mar 2018 17:33:28 +0100 Subject: [PATCH 03/45] Add fields to set margin values --- src/autoapp/UI/settingswindow.ui | 134 +++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 43 deletions(-) diff --git a/src/autoapp/UI/settingswindow.ui b/src/autoapp/UI/settingswindow.ui index 11e6ad49..e476b55e 100644 --- a/src/autoapp/UI/settingswindow.ui +++ b/src/autoapp/UI/settingswindow.ui @@ -260,48 +260,6 @@ color: rgb(238, 238, 236); - - - - 20 - 390 - 531 - 31 - - - - 400 - - - Qt::Horizontal - - - - - - 20 - 360 - 91 - 17 - - - - Screen DPI - - - - - - 570 - 380 - 41 - 51 - - - - 400 - - @@ -312,7 +270,7 @@ color: rgb(238, 238, 236); - OMX Layer index + Display @@ -363,6 +321,94 @@ color: rgb(238, 238, 236); + + + + 200 + 40 + 101 + 21 + + + + Margin width: + + + + + + 310 + 30 + 71 + 41 + + + + + + + 410 + 40 + 111 + 21 + + + + Margin height: + + + + + + 520 + 30 + 71 + 41 + + + + + + + + 0 + 360 + 621 + 81 + + + + Screen DPI + + + + + 570 + 40 + 41 + 31 + + + + 400 + + + + + + 20 + 40 + 531 + 31 + + + + 400 + + + Qt::Horizontal + + @@ -912,6 +958,8 @@ color: rgb(238, 238, 236); radioButton720p radioButton1080p spinBoxOmxLayerIndex + spinBoxVideoMarginWidth + spinBoxVideoMarginHeight horizontalSliderScreenDPI checkBoxMusicAudioChannel checkBoxSpeechAudioChannel From 3c1e65792fede9826d36cc34e5dc69acf219edb0 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Wed, 14 Mar 2018 17:45:03 +0100 Subject: [PATCH 04/45] Set margin values on ui controls --- src/autoapp/UI/SettingsWindow.cpp | 8 ++++++++ src/autoapp/UI/settingswindow.ui | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/autoapp/UI/SettingsWindow.cpp b/src/autoapp/UI/SettingsWindow.cpp index dd55a570..3117cf3f 100644 --- a/src/autoapp/UI/SettingsWindow.cpp +++ b/src/autoapp/UI/SettingsWindow.cpp @@ -73,6 +73,10 @@ void SettingsWindow::onSave() configuration_->setScreenDPI(static_cast(ui_->horizontalSliderScreenDPI->value())); configuration_->setOMXLayerIndex(ui_->spinBoxOmxLayerIndex->value()); + + QRect videoMargins(0, 0, ui_->spinBoxVideoMarginWidth->value(), ui_->spinBoxVideoMarginHeight->value()); + configuration_->setVideoMargins(std::move(videoMargins)); + configuration_->setTouchscreenEnabled(ui_->checkBoxEnableTouchscreen->isChecked()); this->saveButtonCheckBoxes(); @@ -130,6 +134,10 @@ void SettingsWindow::load() ui_->horizontalSliderScreenDPI->setValue(static_cast(configuration_->getScreenDPI())); ui_->spinBoxOmxLayerIndex->setValue(configuration_->getOMXLayerIndex()); + const auto& videoMargins = configuration_->getVideoMargins(); + ui_->spinBoxVideoMarginWidth->setValue(videoMargins.width()); + ui_->spinBoxVideoMarginHeight->setValue(videoMargins.height()); + ui_->checkBoxEnableTouchscreen->setChecked(configuration_->getTouchscreenEnabled()); this->loadButtonCheckBoxes(); diff --git a/src/autoapp/UI/settingswindow.ui b/src/autoapp/UI/settingswindow.ui index e476b55e..63ad7a25 100644 --- a/src/autoapp/UI/settingswindow.ui +++ b/src/autoapp/UI/settingswindow.ui @@ -343,6 +343,9 @@ color: rgb(238, 238, 236); 41 + + 99999 + @@ -366,6 +369,9 @@ color: rgb(238, 238, 236); 41 + + 99999 + From 28cff9c53bc3a625af78c9f042a2f0a49c521119 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 17 Mar 2018 01:20:48 +0100 Subject: [PATCH 05/45] Enumerate connected devices with AOAP capabilities --- include/f1x/openauto/autoapp/USB/USBApp.hpp | 6 +++++- src/autoapp/USB/USBApp.cpp | 18 +++++++++++++++++- src/autoapp/USB/USBMain.cpp | 8 ++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/include/f1x/openauto/autoapp/USB/USBApp.hpp b/include/f1x/openauto/autoapp/USB/USBApp.hpp index 76c6955e..6b0a81b4 100644 --- a/include/f1x/openauto/autoapp/USB/USBApp.hpp +++ b/include/f1x/openauto/autoapp/USB/USBApp.hpp @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include @@ -36,7 +37,8 @@ class USBApp: public projection::IAndroidAutoEntityEventHandler, public std::ena public: typedef std::shared_ptr Pointer; - USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub); + USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, + aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator); void start(); void stop(); @@ -45,6 +47,7 @@ class USBApp: public projection::IAndroidAutoEntityEventHandler, public std::ena private: using std::enable_shared_from_this::shared_from_this; + void enumerateDevices(); void waitForDevice(); void aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle); void onUSBHubError(const aasdk::error::Error& error); @@ -53,6 +56,7 @@ class USBApp: public projection::IAndroidAutoEntityEventHandler, public std::ena boost::asio::io_service::strand strand_; projection::IAndroidAutoEntityFactory& androidAutoEntityFactory_; aasdk::usb::IUSBHub::Pointer usbHub_; + aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator_; projection::IAndroidAutoEntity::Pointer androidAutoEntity_; bool isStopped_; }; diff --git a/src/autoapp/USB/USBApp.cpp b/src/autoapp/USB/USBApp.cpp index 7f1af9a9..d535ccfb 100644 --- a/src/autoapp/USB/USBApp.cpp +++ b/src/autoapp/USB/USBApp.cpp @@ -29,11 +29,13 @@ namespace autoapp namespace usb { -USBApp::USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub) +USBApp::USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, + aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator) : ioService_(ioService) , strand_(ioService_) , androidAutoEntityFactory_(androidAutoEntityFactory) , usbHub_(std::move(usbHub)) + , connectedAccessoriesEnumerator_(std::move(connectedAccessoriesEnumerator)) , isStopped_(false) { @@ -43,6 +45,7 @@ void USBApp::start() { strand_.dispatch([this, self = this->shared_from_this()]() { this->waitForDevice(); + this->enumerateDevices(); }); } @@ -84,6 +87,19 @@ void USBApp::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle) } } +void USBApp::enumerateDevices() +{ + auto promise = aasdk::usb::IConnectedAccessoriesEnumerator::Promise::defer(strand_); + promise->then([this, self = this->shared_from_this()](auto result) { + OPENAUTO_LOG(info) << "[USBApp] Devices enumeration result: " << result; + }, + [this, self = this->shared_from_this()](auto e) { + OPENAUTO_LOG(error) << "[USBApp] Devices enumeration failed: " << e.what(); + }); + + connectedAccessoriesEnumerator_->enumerate(std::move(promise)); +} + void USBApp::waitForDevice() { OPENAUTO_LOG(info) << "[USBApp] Waiting for device..."; diff --git a/src/autoapp/USB/USBMain.cpp b/src/autoapp/USB/USBMain.cpp index 42429204..6c3602f2 100644 --- a/src/autoapp/USB/USBMain.cpp +++ b/src/autoapp/USB/USBMain.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -42,8 +43,11 @@ USBMain::USBMain(libusb_context* context) , serviceFactory_(ioService_, configuration_) , androidAutoEntityFactory_(usbWrapper_, ioService_, configuration_, serviceFactory_) { - aasdk::usb::IUSBHub::Pointer usbHub(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); - usbApp_ = std::make_shared(ioService_, androidAutoEntityFactory_, std::move(usbHub)); + auto usbHub(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); + auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); + + usbApp_ = std::make_shared(ioService_, androidAutoEntityFactory_, + std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); } int USBMain::exec(int argc, char* argv[]) From c4e4192cf82eb5b9ae1e8c6a96b6ecd249e4d083 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 17 Mar 2018 02:00:06 +0100 Subject: [PATCH 06/45] Cancel device enumeration when app is stopped --- src/autoapp/USB/USBApp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/autoapp/USB/USBApp.cpp b/src/autoapp/USB/USBApp.cpp index d535ccfb..fe4064b6 100644 --- a/src/autoapp/USB/USBApp.cpp +++ b/src/autoapp/USB/USBApp.cpp @@ -53,6 +53,7 @@ void USBApp::stop() { strand_.dispatch([this, self = this->shared_from_this()]() { isStopped_ = true; + connectedAccessoriesEnumerator_->cancel(); usbHub_->cancel(); if(androidAutoEntity_ != nullptr) From 9e114226a9753e50bf46131ac8a145d87442f8f5 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 17 Mar 2018 17:17:41 +0100 Subject: [PATCH 07/45] Move Qt related stuff outside USBMain.cpp --- include/f1x/openauto/autoapp/USB/USBMain.hpp | 20 ++---- src/autoapp/Main.cpp | 75 ++++++++++++++++++-- src/autoapp/USB/USBMain.cpp | 73 +++---------------- 3 files changed, 85 insertions(+), 83 deletions(-) diff --git a/include/f1x/openauto/autoapp/USB/USBMain.hpp b/include/f1x/openauto/autoapp/USB/USBMain.hpp index 481d84bb..32f79771 100644 --- a/include/f1x/openauto/autoapp/USB/USBMain.hpp +++ b/include/f1x/openauto/autoapp/USB/USBMain.hpp @@ -18,7 +18,6 @@ #pragma once -#include #include #include #include @@ -28,6 +27,8 @@ #include #include +class QApplication; + namespace f1x { namespace openauto @@ -40,26 +41,19 @@ namespace usb class USBMain { public: - USBMain(libusb_context* context); + USBMain(aasdk::usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration); - int exec(int argc, char* argv[]); + void start(); + void stop(); private: - typedef std::vector ThreadPool; - - void startUSBWorkers(); - void startIOServiceWorkers(); - - libusb_context* usbContext_; - aasdk::usb::USBWrapper usbWrapper_; - boost::asio::io_service ioService_; + aasdk::usb::IUSBWrapper& usbWrapper_; + boost::asio::io_service& ioService_; aasdk::usb::AccessoryModeQueryFactory queryFactory_; aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory_; - configuration::IConfiguration::Pointer configuration_; projection::ServiceFactory serviceFactory_; projection::AndroidAutoEntityFactory androidAutoEntityFactory_; autoapp::usb::USBApp::Pointer usbApp_; - ThreadPool threadPool_; }; } diff --git a/src/autoapp/Main.cpp b/src/autoapp/Main.cpp index 0f7783a7..e5de25d5 100644 --- a/src/autoapp/Main.cpp +++ b/src/autoapp/Main.cpp @@ -16,24 +16,89 @@ * along with openauto. If not, see . */ +#include +#include +#include +#include +#include #include #include namespace aasdk = f1x::aasdk; namespace autoapp = f1x::openauto::autoapp; +using ThreadPool = std::vector; + +void startUSBWorkers(boost::asio::io_service& ioService, libusb_context* usbContext, ThreadPool& threadPool) +{ + auto usbWorker = [&ioService, usbContext]() { + timeval libusbEventTimeout{180, 0}; + + while(!ioService.stopped()) + { + libusb_handle_events_timeout_completed(usbContext, &libusbEventTimeout, nullptr); + } + }; + + threadPool.emplace_back(usbWorker); + threadPool.emplace_back(usbWorker); + threadPool.emplace_back(usbWorker); + threadPool.emplace_back(usbWorker); +} + +void startIOServiceWorkers(boost::asio::io_service& ioService, ThreadPool& threadPool) +{ + auto ioServiceWorker = [&ioService]() { + ioService.run(); + }; + + threadPool.emplace_back(ioServiceWorker); + threadPool.emplace_back(ioServiceWorker); + threadPool.emplace_back(ioServiceWorker); + threadPool.emplace_back(ioServiceWorker); +} int main(int argc, char* argv[]) { - libusb_context* context; - if(libusb_init(&context) != 0) + libusb_context* usbContext; + if(libusb_init(&usbContext) != 0) { OPENAUTO_LOG(error) << "[OpenAuto] libusb init failed."; return 1; } - autoapp::usb::USBMain main(context); - auto result = main.exec(argc, argv); + QApplication qApplication(argc, argv); + boost::asio::io_service ioService; + boost::asio::io_service::work work(ioService); + + autoapp::ui::MainWindow mainWindow; + //mainWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + mainWindow.showFullScreen(); + + auto configuration = std::make_shared(); + autoapp::ui::SettingsWindow settingsWindow(configuration); + //settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + + qApplication.setOverrideCursor(Qt::BlankCursor); + bool cursorVisible = false; + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::toggleCursor, [&cursorVisible, &qApplication]() { + cursorVisible = !cursorVisible; + qApplication.setOverrideCursor(cursorVisible ? Qt::ArrowCursor : Qt::BlankCursor); + }); + + aasdk::usb::USBWrapper usbWrapper(usbContext); + autoapp::usb::USBMain main(usbWrapper, ioService, configuration); + + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openSettings, &settingsWindow, &autoapp::ui::SettingsWindow::showFullScreen); + + std::vector threadPool; + startUSBWorkers(ioService, usbContext, threadPool); + startIOServiceWorkers(ioService, threadPool); + main.start(); + + auto result = qApplication.exec(); + std::for_each(threadPool.begin(), threadPool.end(), std::bind(&std::thread::join, std::placeholders::_1)); - libusb_exit(context); + libusb_exit(usbContext); return result; } diff --git a/src/autoapp/USB/USBMain.cpp b/src/autoapp/USB/USBMain.cpp index 6c3602f2..b4ddb2ef 100644 --- a/src/autoapp/USB/USBMain.cpp +++ b/src/autoapp/USB/USBMain.cpp @@ -17,12 +17,8 @@ */ #include -#include #include #include -#include -#include -#include #include namespace f1x @@ -34,14 +30,13 @@ namespace autoapp namespace usb { -USBMain::USBMain(libusb_context* context) - : usbContext_(context) - , usbWrapper_(usbContext_) +USBMain::USBMain(aasdk::usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration) + : usbWrapper_(usbWrapper) + , ioService_(ioService) , queryFactory_(usbWrapper_, ioService_) , queryChainFactory_(usbWrapper_, ioService_, queryFactory_) - , configuration_(std::make_shared()) - , serviceFactory_(ioService_, configuration_) - , androidAutoEntityFactory_(usbWrapper_, ioService_, configuration_, serviceFactory_) + , serviceFactory_(ioService_, configuration) + , androidAutoEntityFactory_(usbWrapper_, ioService_, configuration, serviceFactory_) { auto usbHub(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); @@ -50,66 +45,14 @@ USBMain::USBMain(libusb_context* context) std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); } -int USBMain::exec(int argc, char* argv[]) +void USBMain::start() { - QApplication qApplication(argc, argv); - - ui::MainWindow mainWindow; - mainWindow.setWindowFlags(Qt::WindowStaysOnTopHint); - - ui::SettingsWindow settingsWindow(configuration_); - settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); - - QObject::connect(&mainWindow, &ui::MainWindow::exit, []() { std::exit(0); }); - QObject::connect(&mainWindow, &ui::MainWindow::openSettings, &settingsWindow, &ui::SettingsWindow::showFullScreen); - - qApplication.setOverrideCursor(Qt::BlankCursor); - bool cursorVisible = false; - QObject::connect(&mainWindow, &ui::MainWindow::toggleCursor, [&cursorVisible, &qApplication]() { - cursorVisible = !cursorVisible; - qApplication.setOverrideCursor(cursorVisible ? Qt::ArrowCursor : Qt::BlankCursor); - }); - - mainWindow.showFullScreen(); - - boost::asio::io_service::work work(ioService_); - this->startIOServiceWorkers(); - this->startUSBWorkers(); usbApp_->start(); - - auto result = qApplication.exec(); - std::for_each(threadPool_.begin(), threadPool_.end(), std::bind(&std::thread::join, std::placeholders::_1)); - return result; -} - -void USBMain::startUSBWorkers() -{ - auto usbWorker = [this]() { - timeval libusbEventTimeout{180, 0}; - - while(!ioService_.stopped()) - { - libusb_handle_events_timeout_completed(usbContext_, &libusbEventTimeout, nullptr); - } - }; - threadPool_.emplace_back(usbWorker); - threadPool_.emplace_back(usbWorker); - threadPool_.emplace_back(usbWorker); - threadPool_.emplace_back(usbWorker); } -void USBMain::startIOServiceWorkers() +void USBMain::stop() { - auto ioServiceWorker = [this]() { - while(!ioService_.stopped()) - { - ioService_.run(); - } - }; - threadPool_.emplace_back(ioServiceWorker); - threadPool_.emplace_back(ioServiceWorker); - threadPool_.emplace_back(ioServiceWorker); - threadPool_.emplace_back(ioServiceWorker); + usbApp_->stop(); } } From 9cef110bc419529a7fb01e428d4c59a139728190 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 17 Mar 2018 17:27:24 +0100 Subject: [PATCH 08/45] Remove USB package from autoapp --- .../autoapp/{USB/USBApp.hpp => App.hpp} | 13 +-- .../autoapp/{USB/USBMain.hpp => Main.hpp} | 13 +-- src/autoapp/{USB/USBApp.cpp => App.cpp} | 43 ++++---- src/autoapp/Main.cpp | 100 +++++------------ src/autoapp/USB/USBMain.cpp | 61 ---------- src/autoapp/autoapp.cpp | 104 ++++++++++++++++++ 6 files changed, 160 insertions(+), 174 deletions(-) rename include/f1x/openauto/autoapp/{USB/USBApp.hpp => App.hpp} (77%) rename include/f1x/openauto/autoapp/{USB/USBMain.hpp => Main.hpp} (84%) rename src/autoapp/{USB/USBApp.cpp => App.cpp} (66%) delete mode 100644 src/autoapp/USB/USBMain.cpp create mode 100644 src/autoapp/autoapp.cpp diff --git a/include/f1x/openauto/autoapp/USB/USBApp.hpp b/include/f1x/openauto/autoapp/App.hpp similarity index 77% rename from include/f1x/openauto/autoapp/USB/USBApp.hpp rename to include/f1x/openauto/autoapp/App.hpp index 6b0a81b4..f31e2d5c 100644 --- a/include/f1x/openauto/autoapp/USB/USBApp.hpp +++ b/include/f1x/openauto/autoapp/App.hpp @@ -29,23 +29,21 @@ namespace openauto { namespace autoapp { -namespace usb -{ -class USBApp: public projection::IAndroidAutoEntityEventHandler, public std::enable_shared_from_this +class App: public projection::IAndroidAutoEntityEventHandler, public std::enable_shared_from_this { public: - typedef std::shared_ptr Pointer; + typedef std::shared_ptr Pointer; - USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, - aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator); + App(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, + aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator); void start(); void stop(); void onAndroidAutoQuit() override; private: - using std::enable_shared_from_this::shared_from_this; + using std::enable_shared_from_this::shared_from_this; void enumerateDevices(); void waitForDevice(); @@ -64,4 +62,3 @@ class USBApp: public projection::IAndroidAutoEntityEventHandler, public std::ena } } } -} diff --git a/include/f1x/openauto/autoapp/USB/USBMain.hpp b/include/f1x/openauto/autoapp/Main.hpp similarity index 84% rename from include/f1x/openauto/autoapp/USB/USBMain.hpp rename to include/f1x/openauto/autoapp/Main.hpp index 32f79771..4cb6746f 100644 --- a/include/f1x/openauto/autoapp/USB/USBMain.hpp +++ b/include/f1x/openauto/autoapp/Main.hpp @@ -22,26 +22,22 @@ #include #include #include -#include +#include #include #include #include -class QApplication; - namespace f1x { namespace openauto { namespace autoapp { -namespace usb -{ -class USBMain +class Main { public: - USBMain(aasdk::usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration); + Main(aasdk::usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration); void start(); void stop(); @@ -53,10 +49,9 @@ class USBMain aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory_; projection::ServiceFactory serviceFactory_; projection::AndroidAutoEntityFactory androidAutoEntityFactory_; - autoapp::usb::USBApp::Pointer usbApp_; + autoapp::App::Pointer app_; }; } } } -} diff --git a/src/autoapp/USB/USBApp.cpp b/src/autoapp/App.cpp similarity index 66% rename from src/autoapp/USB/USBApp.cpp rename to src/autoapp/App.cpp index fe4064b6..73a7b3d3 100644 --- a/src/autoapp/USB/USBApp.cpp +++ b/src/autoapp/App.cpp @@ -17,7 +17,7 @@ */ #include -#include +#include #include namespace f1x @@ -26,11 +26,9 @@ namespace openauto { namespace autoapp { -namespace usb -{ -USBApp::USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, - aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator) +App::App(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, + aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator) : ioService_(ioService) , strand_(ioService_) , androidAutoEntityFactory_(androidAutoEntityFactory) @@ -41,7 +39,7 @@ USBApp::USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntit } -void USBApp::start() +void App::start() { strand_.dispatch([this, self = this->shared_from_this()]() { this->waitForDevice(); @@ -49,7 +47,7 @@ void USBApp::start() }); } -void USBApp::stop() +void App::stop() { strand_.dispatch([this, self = this->shared_from_this()]() { isStopped_ = true; @@ -63,9 +61,9 @@ void USBApp::stop() }); } -void USBApp::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle) +void App::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle) { - OPENAUTO_LOG(info) << "[USBApp] Device connected."; + OPENAUTO_LOG(info) << "[App] Device connected."; if(androidAutoEntity_ == nullptr) { @@ -76,7 +74,7 @@ void USBApp::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle) } catch(const aasdk::error::Error& error) { - OPENAUTO_LOG(error) << "[USBApp] AndroidAutoEntity create error: " << error.what(); + OPENAUTO_LOG(error) << "[App] AndroidAutoEntity create error: " << error.what(); androidAutoEntity_.reset(); this->waitForDevice(); @@ -84,37 +82,37 @@ void USBApp::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle) } else { - OPENAUTO_LOG(warning) << "[USBApp] android auto entity is still running."; + OPENAUTO_LOG(warning) << "[App] android auto entity is still running."; } } -void USBApp::enumerateDevices() +void App::enumerateDevices() { auto promise = aasdk::usb::IConnectedAccessoriesEnumerator::Promise::defer(strand_); promise->then([this, self = this->shared_from_this()](auto result) { - OPENAUTO_LOG(info) << "[USBApp] Devices enumeration result: " << result; + OPENAUTO_LOG(info) << "[App] Devices enumeration result: " << result; }, [this, self = this->shared_from_this()](auto e) { - OPENAUTO_LOG(error) << "[USBApp] Devices enumeration failed: " << e.what(); + OPENAUTO_LOG(error) << "[App] Devices enumeration failed: " << e.what(); }); connectedAccessoriesEnumerator_->enumerate(std::move(promise)); } -void USBApp::waitForDevice() +void App::waitForDevice() { - OPENAUTO_LOG(info) << "[USBApp] Waiting for device..."; + OPENAUTO_LOG(info) << "[App] Waiting for device..."; auto promise = aasdk::usb::IUSBHub::Promise::defer(strand_); - promise->then(std::bind(&USBApp::aoapDeviceHandler, this->shared_from_this(), std::placeholders::_1), - std::bind(&USBApp::onUSBHubError, this->shared_from_this(), std::placeholders::_1)); + promise->then(std::bind(&App::aoapDeviceHandler, this->shared_from_this(), std::placeholders::_1), + std::bind(&App::onUSBHubError, this->shared_from_this(), std::placeholders::_1)); usbHub_->start(std::move(promise)); } -void USBApp::onAndroidAutoQuit() +void App::onAndroidAutoQuit() { strand_.dispatch([this, self = this->shared_from_this()]() { - OPENAUTO_LOG(info) << "[USBApp] quit."; + OPENAUTO_LOG(info) << "[App] quit."; androidAutoEntity_->stop(); androidAutoEntity_.reset(); @@ -126,9 +124,9 @@ void USBApp::onAndroidAutoQuit() }); } -void USBApp::onUSBHubError(const aasdk::error::Error& error) +void App::onUSBHubError(const aasdk::error::Error& error) { - OPENAUTO_LOG(error) << "[USBApp] usb hub error: " << error.what(); + OPENAUTO_LOG(error) << "[App] usb hub error: " << error.what(); if(error.getCode() == aasdk::error::ErrorCode::OPERATION_ABORTED || error.getCode() == aasdk::error::ErrorCode::OPERATION_IN_PROGRESS) @@ -140,4 +138,3 @@ void USBApp::onUSBHubError(const aasdk::error::Error& error) } } } -} diff --git a/src/autoapp/Main.cpp b/src/autoapp/Main.cpp index e5de25d5..84ea91e7 100644 --- a/src/autoapp/Main.cpp +++ b/src/autoapp/Main.cpp @@ -16,89 +16,43 @@ * along with openauto. If not, see . */ -#include #include -#include -#include -#include -#include -#include +#include +#include +#include -namespace aasdk = f1x::aasdk; -namespace autoapp = f1x::openauto::autoapp; -using ThreadPool = std::vector; - -void startUSBWorkers(boost::asio::io_service& ioService, libusb_context* usbContext, ThreadPool& threadPool) +namespace f1x +{ +namespace openauto +{ +namespace autoapp { - auto usbWorker = [&ioService, usbContext]() { - timeval libusbEventTimeout{180, 0}; - while(!ioService.stopped()) - { - libusb_handle_events_timeout_completed(usbContext, &libusbEventTimeout, nullptr); - } - }; +Main::Main(aasdk::usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration) + : usbWrapper_(usbWrapper) + , ioService_(ioService) + , queryFactory_(usbWrapper_, ioService_) + , queryChainFactory_(usbWrapper_, ioService_, queryFactory_) + , serviceFactory_(ioService_, configuration) + , androidAutoEntityFactory_(usbWrapper_, ioService_, configuration, serviceFactory_) +{ + auto usbHub(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); + auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); - threadPool.emplace_back(usbWorker); - threadPool.emplace_back(usbWorker); - threadPool.emplace_back(usbWorker); - threadPool.emplace_back(usbWorker); + app_ = std::make_shared(ioService_, androidAutoEntityFactory_, + std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); } -void startIOServiceWorkers(boost::asio::io_service& ioService, ThreadPool& threadPool) +void Main::start() { - auto ioServiceWorker = [&ioService]() { - ioService.run(); - }; - - threadPool.emplace_back(ioServiceWorker); - threadPool.emplace_back(ioServiceWorker); - threadPool.emplace_back(ioServiceWorker); - threadPool.emplace_back(ioServiceWorker); + app_->start(); } -int main(int argc, char* argv[]) +void Main::stop() { - libusb_context* usbContext; - if(libusb_init(&usbContext) != 0) - { - OPENAUTO_LOG(error) << "[OpenAuto] libusb init failed."; - return 1; - } - - QApplication qApplication(argc, argv); - boost::asio::io_service ioService; - boost::asio::io_service::work work(ioService); - - autoapp::ui::MainWindow mainWindow; - //mainWindow.setWindowFlags(Qt::WindowStaysOnTopHint); - mainWindow.showFullScreen(); - - auto configuration = std::make_shared(); - autoapp::ui::SettingsWindow settingsWindow(configuration); - //settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); - - qApplication.setOverrideCursor(Qt::BlankCursor); - bool cursorVisible = false; - QObject::connect(&mainWindow, &autoapp::ui::MainWindow::toggleCursor, [&cursorVisible, &qApplication]() { - cursorVisible = !cursorVisible; - qApplication.setOverrideCursor(cursorVisible ? Qt::ArrowCursor : Qt::BlankCursor); - }); - - aasdk::usb::USBWrapper usbWrapper(usbContext); - autoapp::usb::USBMain main(usbWrapper, ioService, configuration); - - QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); - QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openSettings, &settingsWindow, &autoapp::ui::SettingsWindow::showFullScreen); - - std::vector threadPool; - startUSBWorkers(ioService, usbContext, threadPool); - startIOServiceWorkers(ioService, threadPool); - main.start(); - - auto result = qApplication.exec(); - std::for_each(threadPool.begin(), threadPool.end(), std::bind(&std::thread::join, std::placeholders::_1)); + app_->stop(); +} - libusb_exit(usbContext); - return result; +} +} } diff --git a/src/autoapp/USB/USBMain.cpp b/src/autoapp/USB/USBMain.cpp deleted file mode 100644 index b4ddb2ef..00000000 --- a/src/autoapp/USB/USBMain.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* -* This file is part of openauto project. -* Copyright (C) 2018 f1x.studio (Michal Szwaj) -* -* openauto is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 3 of the License, or -* (at your option) any later version. - -* openauto is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with openauto. If not, see . -*/ - -#include -#include -#include -#include - -namespace f1x -{ -namespace openauto -{ -namespace autoapp -{ -namespace usb -{ - -USBMain::USBMain(aasdk::usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration) - : usbWrapper_(usbWrapper) - , ioService_(ioService) - , queryFactory_(usbWrapper_, ioService_) - , queryChainFactory_(usbWrapper_, ioService_, queryFactory_) - , serviceFactory_(ioService_, configuration) - , androidAutoEntityFactory_(usbWrapper_, ioService_, configuration, serviceFactory_) -{ - auto usbHub(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); - auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); - - usbApp_ = std::make_shared(ioService_, androidAutoEntityFactory_, - std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); -} - -void USBMain::start() -{ - usbApp_->start(); -} - -void USBMain::stop() -{ - usbApp_->stop(); -} - -} -} -} -} diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp new file mode 100644 index 00000000..0eaaf700 --- /dev/null +++ b/src/autoapp/autoapp.cpp @@ -0,0 +1,104 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include + +namespace aasdk = f1x::aasdk; +namespace autoapp = f1x::openauto::autoapp; +using ThreadPool = std::vector; + +void startUSBWorkers(boost::asio::io_service& ioService, libusb_context* usbContext, ThreadPool& threadPool) +{ + auto usbWorker = [&ioService, usbContext]() { + timeval libusbEventTimeout{180, 0}; + + while(!ioService.stopped()) + { + libusb_handle_events_timeout_completed(usbContext, &libusbEventTimeout, nullptr); + } + }; + + threadPool.emplace_back(usbWorker); + threadPool.emplace_back(usbWorker); + threadPool.emplace_back(usbWorker); + threadPool.emplace_back(usbWorker); +} + +void startIOServiceWorkers(boost::asio::io_service& ioService, ThreadPool& threadPool) +{ + auto ioServiceWorker = [&ioService]() { + ioService.run(); + }; + + threadPool.emplace_back(ioServiceWorker); + threadPool.emplace_back(ioServiceWorker); + threadPool.emplace_back(ioServiceWorker); + threadPool.emplace_back(ioServiceWorker); +} + +int main(int argc, char* argv[]) +{ + libusb_context* usbContext; + if(libusb_init(&usbContext) != 0) + { + OPENAUTO_LOG(error) << "[OpenAuto] libusb init failed."; + return 1; + } + + QApplication qApplication(argc, argv); + boost::asio::io_service ioService; + boost::asio::io_service::work work(ioService); + + autoapp::ui::MainWindow mainWindow; + //mainWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + mainWindow.showFullScreen(); + + auto configuration = std::make_shared(); + autoapp::ui::SettingsWindow settingsWindow(configuration); + //settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + + qApplication.setOverrideCursor(Qt::BlankCursor); + bool cursorVisible = false; + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::toggleCursor, [&cursorVisible, &qApplication]() { + cursorVisible = !cursorVisible; + qApplication.setOverrideCursor(cursorVisible ? Qt::ArrowCursor : Qt::BlankCursor); + }); + + aasdk::usb::USBWrapper usbWrapper(usbContext); + autoapp::Main main(usbWrapper, ioService, configuration); + + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openSettings, &settingsWindow, &autoapp::ui::SettingsWindow::showFullScreen); + + std::vector threadPool; + startUSBWorkers(ioService, usbContext, threadPool); + startIOServiceWorkers(ioService, threadPool); + main.start(); + + auto result = qApplication.exec(); + std::for_each(threadPool.begin(), threadPool.end(), std::bind(&std::thread::join, std::placeholders::_1)); + + libusb_exit(usbContext); + return result; +} From 58f782f8e6dd4ac7aa6e4dc6772d807d6c78a5be Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 17 Mar 2018 17:29:31 +0100 Subject: [PATCH 09/45] Restore stay on top --- src/autoapp/autoapp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index 0eaaf700..4b4b4b5d 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -71,12 +71,12 @@ int main(int argc, char* argv[]) boost::asio::io_service::work work(ioService); autoapp::ui::MainWindow mainWindow; - //mainWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + mainWindow.setWindowFlags(Qt::WindowStaysOnTopHint); mainWindow.showFullScreen(); auto configuration = std::make_shared(); autoapp::ui::SettingsWindow settingsWindow(configuration); - //settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); qApplication.setOverrideCursor(Qt::BlankCursor); bool cursorVisible = false; From 5c31630155a1166448081fa77fdbf6cc98015e39 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 17 Mar 2018 21:47:10 +0100 Subject: [PATCH 10/45] Add btservice to the project --- CMakeLists.txt | 19 +++++++++++++++++-- include/f1x/openauto/Common/Log.hpp | 2 +- src/btservice/btservice.cpp | 4 ++++ 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 src/btservice/btservice.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 773c1438..cf4f326a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,10 +62,13 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) +set(common_include_directory ${include_directory}/f1x/openauto/Common) + set(autoapp_sources_directory ${sources_directory}/autoapp) -file(GLOB_RECURSE source_files ${autoapp_sources_directory}/*.ui ${autoapp_sources_directory}/*.cpp ${include_directory}/*.hpp ${resources_directory}/*.qrc) +set(autoapp_include_directory ${include_directory}/f1x/openauto/autoapp) +file(GLOB_RECURSE autoapp_source_files ${autoapp_sources_directory}/*.ui ${autoapp_sources_directory}/*.cpp ${autoapp_include_directory}/*.hpp ${common_include_directory}/*.hpp ${resources_directory}/*.qrc) -add_executable(autoapp ${source_files}) +add_executable(autoapp ${autoapp_source_files}) target_link_libraries(autoapp ${Boost_LIBRARIES} @@ -79,3 +82,15 @@ target_link_libraries(autoapp ${WINSOCK2_LIBRARIES} ${AASDK_PROTO_LIBRARIES} ${AASDK_LIBRARIES}) + +set(btservice_sources_directory ${sources_directory}/btservice) +set(btservice_include_directory ${include_directory}/f1x/openauto/btservice) +file(GLOB_RECURSE btservice_source_files ${btservice_sources_directory}/*.cpp ${btservice_include_directory}/*.hpp ${common_include_directory}/*.hpp) + +add_executable(btservice ${btservice_source_files}) + +target_link_libraries(btservice + ${Boost_LIBRARIES} + ${Qt5Bluetooth_LIBRARIES} + ${PROTOBUF_LIBRARIES} + ${AASDK_PROTO_LIBRARIES}) diff --git a/include/f1x/openauto/Common/Log.hpp b/include/f1x/openauto/Common/Log.hpp index f0f544a5..42159617 100644 --- a/include/f1x/openauto/Common/Log.hpp +++ b/include/f1x/openauto/Common/Log.hpp @@ -20,4 +20,4 @@ #include -#define OPENAUTO_LOG(severity) BOOST_LOG_TRIVIAL(severity) << "[AaApp] " +#define OPENAUTO_LOG(severity) BOOST_LOG_TRIVIAL(severity) << "[OpenAuto] " diff --git a/src/btservice/btservice.cpp b/src/btservice/btservice.cpp new file mode 100644 index 00000000..905869df --- /dev/null +++ b/src/btservice/btservice.cpp @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} From 083040426fff90c8e61ce2bb3241b8dc7f27b25f Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 17 Mar 2018 23:30:04 +0100 Subject: [PATCH 11/45] Draft of bluetooth services --- .../btservice/AndroidBluetoothServer.hpp | 51 +++++++++++++++ .../btservice/AndroidBluetoothService.hpp | 45 +++++++++++++ .../btservice/IAndroidBluetoothServer.hpp | 40 ++++++++++++ .../btservice/IAndroidBluetoothService.hpp | 41 ++++++++++++ src/btservice/AndroidBluetoothServer.cpp | 56 +++++++++++++++++ src/btservice/AndroidBluetoothService.cpp | 63 +++++++++++++++++++ src/btservice/btservice.cpp | 57 ++++++++++++++++- 7 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 include/f1x/openauto/btservice/AndroidBluetoothServer.hpp create mode 100644 include/f1x/openauto/btservice/AndroidBluetoothService.hpp create mode 100644 include/f1x/openauto/btservice/IAndroidBluetoothServer.hpp create mode 100644 include/f1x/openauto/btservice/IAndroidBluetoothService.hpp create mode 100644 src/btservice/AndroidBluetoothServer.cpp create mode 100644 src/btservice/AndroidBluetoothService.cpp diff --git a/include/f1x/openauto/btservice/AndroidBluetoothServer.hpp b/include/f1x/openauto/btservice/AndroidBluetoothServer.hpp new file mode 100644 index 00000000..4e159bc5 --- /dev/null +++ b/include/f1x/openauto/btservice/AndroidBluetoothServer.hpp @@ -0,0 +1,51 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace btservice +{ + +class AndroidBluetoothServer: public QObject, public IAndroidBluetoothServer +{ + Q_OBJECT + +public: + AndroidBluetoothServer(); + + bool start(const QBluetoothAddress& address, uint16_t portNumber) override; + +private slots: + void onClientConnected(); + +private: + std::unique_ptr rfcommServer_; +}; + +} +} +} diff --git a/include/f1x/openauto/btservice/AndroidBluetoothService.hpp b/include/f1x/openauto/btservice/AndroidBluetoothService.hpp new file mode 100644 index 00000000..ebbb8609 --- /dev/null +++ b/include/f1x/openauto/btservice/AndroidBluetoothService.hpp @@ -0,0 +1,45 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace btservice +{ + +class AndroidBluetoothService: public IAndroidBluetoothService +{ +public: + AndroidBluetoothService(uint16_t portNumber); + + bool registerService(const QBluetoothAddress& bluetoothAddress) override; + bool unregisterService() override; + +private: + QBluetoothServiceInfo serviceInfo_; +}; + +} +} +} diff --git a/include/f1x/openauto/btservice/IAndroidBluetoothServer.hpp b/include/f1x/openauto/btservice/IAndroidBluetoothServer.hpp new file mode 100644 index 00000000..fb109ed9 --- /dev/null +++ b/include/f1x/openauto/btservice/IAndroidBluetoothServer.hpp @@ -0,0 +1,40 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace openauto +{ +namespace btservice +{ + +class IAndroidBluetoothServer +{ +public: + virtual ~IAndroidBluetoothServer() = default; + + virtual bool start(const QBluetoothAddress& address, uint16_t portNumber) = 0; +}; + +} +} +} diff --git a/include/f1x/openauto/btservice/IAndroidBluetoothService.hpp b/include/f1x/openauto/btservice/IAndroidBluetoothService.hpp new file mode 100644 index 00000000..71352c9d --- /dev/null +++ b/include/f1x/openauto/btservice/IAndroidBluetoothService.hpp @@ -0,0 +1,41 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include + +namespace f1x +{ +namespace openauto +{ +namespace btservice +{ + +class IAndroidBluetoothService +{ +public: + virtual ~IAndroidBluetoothService() = default; + + virtual bool registerService(const QBluetoothAddress& bluetoothAddress) = 0; + virtual bool unregisterService() = 0; +}; + +} +} +} diff --git a/src/btservice/AndroidBluetoothServer.cpp b/src/btservice/AndroidBluetoothServer.cpp new file mode 100644 index 00000000..c827e2b6 --- /dev/null +++ b/src/btservice/AndroidBluetoothServer.cpp @@ -0,0 +1,56 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace btservice +{ + +AndroidBluetoothServer::AndroidBluetoothServer() + : rfcommServer_(std::make_unique(QBluetoothServiceInfo::RfcommProtocol, this)) +{ + connect(rfcommServer_.get(), &QBluetoothServer::newConnection, this, &AndroidBluetoothServer::onClientConnected); +} + +bool AndroidBluetoothServer::start(const QBluetoothAddress& address, uint16_t portNumber) +{ + return rfcommServer_->listen(address, portNumber); +} + +void AndroidBluetoothServer::onClientConnected() +{ + auto socket = rfcommServer_->nextPendingConnection(); + + if(socket != nullptr) + { + OPENAUTO_LOG(info) << "[AndroidBluetoothServer] rfcomm client connected, peer name: " << socket->peerName().toStdString(); + } + else + { + OPENAUTO_LOG(error) << "[AndroidBluetoothServer] received null socket during client connection."; + } +} + +} +} +} diff --git a/src/btservice/AndroidBluetoothService.cpp b/src/btservice/AndroidBluetoothService.cpp new file mode 100644 index 00000000..4da48676 --- /dev/null +++ b/src/btservice/AndroidBluetoothService.cpp @@ -0,0 +1,63 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include + +namespace f1x +{ +namespace openauto +{ +namespace btservice +{ + +AndroidBluetoothService::AndroidBluetoothService(uint16_t portNumber) +{ + serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceName, "OpenAuto Bluetooth Service"); + serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceDescription, "AndroidAuto WiFi projection automatic setup"); + serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceProvider, "f1xstudio.com"); + + //"4de17a00-52cb-11e6-bdf4-0800200c9a66"; + //"669a0c20-0008-f4bd-e611-cb52007ae14d"; + serviceInfo_.setServiceUuid(QBluetoothUuid(QString("4de17a00-52cb-11e6-bdf4-0800200c9a66"))); + + QBluetoothServiceInfo::Sequence publicBrowse; + publicBrowse << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); + serviceInfo_.setAttribute(QBluetoothServiceInfo::BrowseGroupList, publicBrowse); + + QBluetoothServiceInfo::Sequence protocolDescriptorList; + QBluetoothServiceInfo::Sequence protocol; + + protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm)) + << QVariant::fromValue(portNumber); + protocolDescriptorList.append(QVariant::fromValue(protocol)); + serviceInfo_.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList); +} + +bool AndroidBluetoothService::registerService(const QBluetoothAddress& bluetoothAddress) +{ + return serviceInfo_.registerService(bluetoothAddress); +} + +bool AndroidBluetoothService::unregisterService() +{ + return serviceInfo_.unregisterService(); +} + +} +} +} diff --git a/src/btservice/btservice.cpp b/src/btservice/btservice.cpp index 905869df..bf015c6e 100644 --- a/src/btservice/btservice.cpp +++ b/src/btservice/btservice.cpp @@ -1,4 +1,59 @@ -int main() +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include +#include + +namespace btservice = f1x::openauto::btservice; + +int main(int argc, char* argv[]) { + QCoreApplication qApplication(argc, argv); + + const QBluetoothAddress address; + const uint16_t portNumber = 5000; + btservice::AndroidBluetoothService androidBluetoothService(portNumber); + + if(!androidBluetoothService.registerService(address)) + { + OPENAUTO_LOG(error) << "[btservice] Service registration failed."; + return 1; + } + else + { + OPENAUTO_LOG(info) << "[btservice] Service registered, port: " << portNumber; + } + + btservice::AndroidBluetoothServer androidBluetoothServer; + + if(!androidBluetoothServer.start(address, portNumber)) + { + OPENAUTO_LOG(error) << "[btservice] Server start failed."; + return 2; + } + + OPENAUTO_LOG(info) << "[btservice] Listening for connections, address: " << address.toString().toStdString() + << ", port: " << portNumber; + + qApplication.exec(); + androidBluetoothService.unregisterService(); + return 0; } From 2c84f2afc5110d5107ec244e38f7fa87d62e0666 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 18 Mar 2018 00:04:21 +0100 Subject: [PATCH 12/45] Use QApplication --- CMakeLists.txt | 1 + src/btservice/btservice.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cf4f326a..7a530db9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,5 +92,6 @@ add_executable(btservice ${btservice_source_files}) target_link_libraries(btservice ${Boost_LIBRARIES} ${Qt5Bluetooth_LIBRARIES} + ${Qt5MultimediaWidgets_LIBRARIES} ${PROTOBUF_LIBRARIES} ${AASDK_PROTO_LIBRARIES}) diff --git a/src/btservice/btservice.cpp b/src/btservice/btservice.cpp index bf015c6e..3bdc2095 100644 --- a/src/btservice/btservice.cpp +++ b/src/btservice/btservice.cpp @@ -16,7 +16,7 @@ * along with openauto. If not, see . */ -#include +#include #include #include #include @@ -25,7 +25,7 @@ namespace btservice = f1x::openauto::btservice; int main(int argc, char* argv[]) { - QCoreApplication qApplication(argc, argv); + QApplication qApplication(argc, argv); const QBluetoothAddress address; const uint16_t portNumber = 5000; From 68bf0e39903cf30a712652c7cc2fc49279d3a410 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 18 Mar 2018 00:46:20 +0100 Subject: [PATCH 13/45] Change service registration data --- src/btservice/AndroidBluetoothService.cpp | 20 ++++++++++++++------ src/btservice/btservice.cpp | 23 +++++++++++------------ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/btservice/AndroidBluetoothService.cpp b/src/btservice/AndroidBluetoothService.cpp index 4da48676..f178662f 100644 --- a/src/btservice/AndroidBluetoothService.cpp +++ b/src/btservice/AndroidBluetoothService.cpp @@ -27,13 +27,19 @@ namespace btservice AndroidBluetoothService::AndroidBluetoothService(uint16_t portNumber) { + //"4de17a00-52cb-11e6-bdf4-0800200c9a66"; + //"669a0c20-0008-f4bd-e611-cb52007ae14d"; + const QBluetoothUuid serviceUuid(QLatin1String("4de17a00-52cb-11e6-bdf4-0800200c9a66")); + + QBluetoothServiceInfo::Sequence classId; + classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort)); + serviceInfo_.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList, classId); + classId.prepend(QVariant::fromValue(serviceUuid)); + serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId); serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceName, "OpenAuto Bluetooth Service"); serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceDescription, "AndroidAuto WiFi projection automatic setup"); serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceProvider, "f1xstudio.com"); - - //"4de17a00-52cb-11e6-bdf4-0800200c9a66"; - //"669a0c20-0008-f4bd-e611-cb52007ae14d"; - serviceInfo_.setServiceUuid(QBluetoothUuid(QString("4de17a00-52cb-11e6-bdf4-0800200c9a66"))); + serviceInfo_.setServiceUuid(serviceUuid); QBluetoothServiceInfo::Sequence publicBrowse; publicBrowse << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); @@ -41,9 +47,11 @@ AndroidBluetoothService::AndroidBluetoothService(uint16_t portNumber) QBluetoothServiceInfo::Sequence protocolDescriptorList; QBluetoothServiceInfo::Sequence protocol; - + protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap)); + protocolDescriptorList.append(QVariant::fromValue(protocol)); + protocol.clear(); protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm)) - << QVariant::fromValue(portNumber); + << QVariant::fromValue(quint16(portNumber)); protocolDescriptorList.append(QVariant::fromValue(protocol)); serviceInfo_.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList); } diff --git a/src/btservice/btservice.cpp b/src/btservice/btservice.cpp index 3bdc2095..e759c81c 100644 --- a/src/btservice/btservice.cpp +++ b/src/btservice/btservice.cpp @@ -29,20 +29,8 @@ int main(int argc, char* argv[]) const QBluetoothAddress address; const uint16_t portNumber = 5000; - btservice::AndroidBluetoothService androidBluetoothService(portNumber); - - if(!androidBluetoothService.registerService(address)) - { - OPENAUTO_LOG(error) << "[btservice] Service registration failed."; - return 1; - } - else - { - OPENAUTO_LOG(info) << "[btservice] Service registered, port: " << portNumber; - } btservice::AndroidBluetoothServer androidBluetoothServer; - if(!androidBluetoothServer.start(address, portNumber)) { OPENAUTO_LOG(error) << "[btservice] Server start failed."; @@ -52,6 +40,17 @@ int main(int argc, char* argv[]) OPENAUTO_LOG(info) << "[btservice] Listening for connections, address: " << address.toString().toStdString() << ", port: " << portNumber; + btservice::AndroidBluetoothService androidBluetoothService(portNumber); + if(!androidBluetoothService.registerService(address)) + { + OPENAUTO_LOG(error) << "[btservice] Service registration failed."; + return 1; + } + else + { + OPENAUTO_LOG(info) << "[btservice] Service registered, port: " << portNumber; + } + qApplication.exec(); androidBluetoothService.unregisterService(); From 339f0075c8a6d3431ad08be9e0f8c85fa48556b1 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Mon, 19 Mar 2018 16:14:09 +0100 Subject: [PATCH 14/45] Use game category for audio output to reduce audio latency --- src/autoapp/Projection/AudioOutput.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/autoapp/Projection/AudioOutput.cpp b/src/autoapp/Projection/AudioOutput.cpp index 7b309d5b..f211987d 100644 --- a/src/autoapp/Projection/AudioOutput.cpp +++ b/src/autoapp/Projection/AudioOutput.cpp @@ -52,8 +52,9 @@ void AudioOutput::createAudioOutput() OPENAUTO_LOG(debug) << "[AudioOutput] create."; audioOutput_ = std::make_unique(QAudioDeviceInfo::defaultOutputDevice(), audioFormat_); - // Default volume level (max) produces crackles - audioOutput_->setVolume(static_cast(0.90)); + // Setting this category switching to the low latency mode + // See: http://code.qt.io/cgit/qt/qtmultimedia.git/tree/src/plugins/pulseaudio/qaudiooutput_pulse.cpp?h=5.7#n58 + audioOutput_->setCategory("game"); } bool AudioOutput::open() @@ -103,15 +104,12 @@ void AudioOutput::onStartPlayback() audioOutput_->start(&audioBuffer_); playbackStarted_ = true; } - else - { - audioOutput_->resume(); - } } void AudioOutput::onSuspendPlayback() { - audioOutput_->suspend(); + // QAudioOutput is in pull mode so suspending/resuming are not needed. + // Keep this interface for any further purposes } void AudioOutput::onStopPlayback() From 21ff97fe8aa682a9bc137aeae390260412d9f9c3 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Mon, 19 Mar 2018 20:58:40 +0100 Subject: [PATCH 15/45] Remove Main class --- include/f1x/openauto/autoapp/App.hpp | 2 +- include/f1x/openauto/autoapp/Main.hpp | 57 -------------------------- src/autoapp/App.cpp | 2 +- src/autoapp/Main.cpp | 58 --------------------------- src/autoapp/autoapp.cpp | 46 +++++++++++++-------- 5 files changed, 32 insertions(+), 133 deletions(-) delete mode 100644 include/f1x/openauto/autoapp/Main.hpp delete mode 100644 src/autoapp/Main.cpp diff --git a/include/f1x/openauto/autoapp/App.hpp b/include/f1x/openauto/autoapp/App.hpp index f31e2d5c..461743de 100644 --- a/include/f1x/openauto/autoapp/App.hpp +++ b/include/f1x/openauto/autoapp/App.hpp @@ -38,7 +38,7 @@ class App: public projection::IAndroidAutoEntityEventHandler, public std::enable App(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator); - void start(); + void waitForUSBDevice(); void stop(); void onAndroidAutoQuit() override; diff --git a/include/f1x/openauto/autoapp/Main.hpp b/include/f1x/openauto/autoapp/Main.hpp deleted file mode 100644 index 4cb6746f..00000000 --- a/include/f1x/openauto/autoapp/Main.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* -* This file is part of openauto project. -* Copyright (C) 2018 f1x.studio (Michal Szwaj) -* -* openauto is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 3 of the License, or -* (at your option) any later version. - -* openauto is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with openauto. If not, see . -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace f1x -{ -namespace openauto -{ -namespace autoapp -{ - -class Main -{ -public: - Main(aasdk::usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration); - - void start(); - void stop(); - -private: - aasdk::usb::IUSBWrapper& usbWrapper_; - boost::asio::io_service& ioService_; - aasdk::usb::AccessoryModeQueryFactory queryFactory_; - aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory_; - projection::ServiceFactory serviceFactory_; - projection::AndroidAutoEntityFactory androidAutoEntityFactory_; - autoapp::App::Pointer app_; -}; - -} -} -} diff --git a/src/autoapp/App.cpp b/src/autoapp/App.cpp index 73a7b3d3..7b00e074 100644 --- a/src/autoapp/App.cpp +++ b/src/autoapp/App.cpp @@ -39,7 +39,7 @@ App::App(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFacto } -void App::start() +void App::waitForUSBDevice() { strand_.dispatch([this, self = this->shared_from_this()]() { this->waitForDevice(); diff --git a/src/autoapp/Main.cpp b/src/autoapp/Main.cpp deleted file mode 100644 index 84ea91e7..00000000 --- a/src/autoapp/Main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* -* This file is part of openauto project. -* Copyright (C) 2018 f1x.studio (Michal Szwaj) -* -* openauto is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 3 of the License, or -* (at your option) any later version. - -* openauto is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with openauto. If not, see . -*/ - -#include -#include -#include -#include - -namespace f1x -{ -namespace openauto -{ -namespace autoapp -{ - -Main::Main(aasdk::usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration) - : usbWrapper_(usbWrapper) - , ioService_(ioService) - , queryFactory_(usbWrapper_, ioService_) - , queryChainFactory_(usbWrapper_, ioService_, queryFactory_) - , serviceFactory_(ioService_, configuration) - , androidAutoEntityFactory_(usbWrapper_, ioService_, configuration, serviceFactory_) -{ - auto usbHub(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); - auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); - - app_ = std::make_shared(ioService_, androidAutoEntityFactory_, - std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); -} - -void Main::start() -{ - app_->start(); -} - -void Main::stop() -{ - app_->stop(); -} - -} -} -} diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index 4b4b4b5d..6a2e3e9d 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -18,10 +18,18 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -#include #include namespace aasdk = f1x::aasdk; @@ -66,35 +74,41 @@ int main(int argc, char* argv[]) return 1; } - QApplication qApplication(argc, argv); boost::asio::io_service ioService; boost::asio::io_service::work work(ioService); + std::vector threadPool; + startUSBWorkers(ioService, usbContext, threadPool); + startIOServiceWorkers(ioService, threadPool); + QApplication qApplication(argc, argv); autoapp::ui::MainWindow mainWindow; mainWindow.setWindowFlags(Qt::WindowStaysOnTopHint); - mainWindow.showFullScreen(); auto configuration = std::make_shared(); autoapp::ui::SettingsWindow settingsWindow(configuration); settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openSettings, &settingsWindow, &autoapp::ui::SettingsWindow::showFullScreen); + qApplication.setOverrideCursor(Qt::BlankCursor); - bool cursorVisible = false; - QObject::connect(&mainWindow, &autoapp::ui::MainWindow::toggleCursor, [&cursorVisible, &qApplication]() { - cursorVisible = !cursorVisible; - qApplication.setOverrideCursor(cursorVisible ? Qt::ArrowCursor : Qt::BlankCursor); + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::toggleCursor, [&qApplication]() { + const auto cursor = qApplication.overrideCursor()->shape() == Qt::BlankCursor ? Qt::ArrowCursor : Qt::BlankCursor; + qApplication.setOverrideCursor(cursor); }); - aasdk::usb::USBWrapper usbWrapper(usbContext); - autoapp::Main main(usbWrapper, ioService, configuration); - - QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); - QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openSettings, &settingsWindow, &autoapp::ui::SettingsWindow::showFullScreen); + mainWindow.showFullScreen(); - std::vector threadPool; - startUSBWorkers(ioService, usbContext, threadPool); - startIOServiceWorkers(ioService, threadPool); - main.start(); + aasdk::usb::USBWrapper usbWrapper(usbContext); + aasdk::usb::AccessoryModeQueryFactory queryFactory(usbWrapper, ioService); + aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory(usbWrapper, ioService, queryFactory); + autoapp::projection::ServiceFactory serviceFactory(ioService, configuration); + autoapp::projection::AndroidAutoEntityFactory androidAutoEntityFactory(usbWrapper, ioService, configuration, serviceFactory); + + auto usbHub(std::make_shared(usbWrapper, ioService, queryChainFactory)); + auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); + auto app = std::make_shared(ioService, androidAutoEntityFactory, std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); + app->waitForUSBDevice(); auto result = qApplication.exec(); std::for_each(threadPool.begin(), threadPool.end(), std::bind(&std::thread::join, std::placeholders::_1)); From 2ecdd83e76b417f1200e0c11278a0b1ce349e82b Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Mon, 19 Mar 2018 21:34:32 +0100 Subject: [PATCH 16/45] Implement creating of tcp AA entity --- include/f1x/openauto/autoapp/App.hpp | 8 +++- .../Projection/AndroidAutoEntityFactory.hpp | 6 +-- .../Projection/IAndroidAutoEntityFactory.hpp | 4 +- src/autoapp/App.cpp | 46 +++++++++++++++++-- .../Projection/AndroidAutoEntityFactory.cpp | 12 ++--- src/autoapp/autoapp.cpp | 6 ++- 6 files changed, 60 insertions(+), 22 deletions(-) diff --git a/include/f1x/openauto/autoapp/App.hpp b/include/f1x/openauto/autoapp/App.hpp index 461743de..5bbdbe2c 100644 --- a/include/f1x/openauto/autoapp/App.hpp +++ b/include/f1x/openauto/autoapp/App.hpp @@ -20,6 +20,9 @@ #include #include +#include +#include +#include #include #include @@ -35,10 +38,11 @@ class App: public projection::IAndroidAutoEntityEventHandler, public std::enable public: typedef std::shared_ptr Pointer; - App(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, + App(boost::asio::io_service& ioService, aasdk::usb::USBWrapper& usbWrapper, aasdk::tcp::ITCPWrapper& tcpWrapper, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator); void waitForUSBDevice(); + void start(aasdk::tcp::ITCPEndpoint::SocketPointer socket); void stop(); void onAndroidAutoQuit() override; @@ -51,6 +55,8 @@ class App: public projection::IAndroidAutoEntityEventHandler, public std::enable void onUSBHubError(const aasdk::error::Error& error); boost::asio::io_service& ioService_; + aasdk::usb::USBWrapper& usbWrapper_; + aasdk::tcp::ITCPWrapper& tcpWrapper_; boost::asio::io_service::strand strand_; projection::IAndroidAutoEntityFactory& androidAutoEntityFactory_; aasdk::usb::IUSBHub::Pointer usbHub_; diff --git a/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp index 1df64dc7..73b8696b 100644 --- a/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp +++ b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp @@ -36,18 +36,16 @@ namespace projection class AndroidAutoEntityFactory: public IAndroidAutoEntityFactory { public: - AndroidAutoEntityFactory(aasdk::usb::IUSBWrapper& usbWrapper, - boost::asio::io_service& ioService, + AndroidAutoEntityFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration, IServiceFactory& serviceFactory); - IAndroidAutoEntity::Pointer create(aasdk::usb::DeviceHandle deviceHandle) override; + IAndroidAutoEntity::Pointer create(aasdk::usb::IAOAPDevice::Pointer aoapDevice) override; IAndroidAutoEntity::Pointer create(aasdk::tcp::ITCPEndpoint::Pointer tcpEndpoint) override; private: IAndroidAutoEntity::Pointer create(aasdk::transport::ITransport::Pointer transport); - aasdk::usb::IUSBWrapper& usbWrapper_; boost::asio::io_service& ioService_; configuration::IConfiguration::Pointer configuration_; IServiceFactory& serviceFactory_; diff --git a/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp index 945c2475..f9f37c34 100644 --- a/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp +++ b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp @@ -19,7 +19,7 @@ #pragma once #include -#include +#include #include namespace f1x @@ -36,7 +36,7 @@ class IAndroidAutoEntityFactory public: virtual ~IAndroidAutoEntityFactory() = default; - virtual IAndroidAutoEntity::Pointer create(aasdk::usb::DeviceHandle deviceHandle) = 0; + virtual IAndroidAutoEntity::Pointer create(aasdk::usb::IAOAPDevice::Pointer aoapDevice) = 0; virtual IAndroidAutoEntity::Pointer create(aasdk::tcp::ITCPEndpoint::Pointer tcpEndpoint) = 0; }; diff --git a/src/autoapp/App.cpp b/src/autoapp/App.cpp index 7b00e074..441b4d6f 100644 --- a/src/autoapp/App.cpp +++ b/src/autoapp/App.cpp @@ -17,6 +17,8 @@ */ #include +#include +#include #include #include @@ -27,9 +29,11 @@ namespace openauto namespace autoapp { -App::App(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, +App::App(boost::asio::io_service& ioService, aasdk::usb::USBWrapper& usbWrapper, aasdk::tcp::ITCPWrapper& tcpWrapper, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator) : ioService_(ioService) + , usbWrapper_(usbWrapper) + , tcpWrapper_(tcpWrapper) , strand_(ioService_) , androidAutoEntityFactory_(androidAutoEntityFactory) , usbHub_(std::move(usbHub)) @@ -47,6 +51,35 @@ void App::waitForUSBDevice() }); } +void App::start(aasdk::tcp::ITCPEndpoint::SocketPointer socket) +{ + strand_.dispatch([this, self = this->shared_from_this(), socket = std::move(socket)]() mutable { + if(androidAutoEntity_ == nullptr) + { + try + { + usbHub_->cancel(); + connectedAccessoriesEnumerator_->cancel(); + + auto tcpEndpoint(std::make_shared(tcpWrapper_, std::move(socket))); + androidAutoEntity_ = androidAutoEntityFactory_.create(std::move(tcpEndpoint)); + androidAutoEntity_->start(*this); + } + catch(const aasdk::error::Error& error) + { + OPENAUTO_LOG(error) << "[App] TCP AndroidAutoEntity create error: " << error.what(); + + androidAutoEntity_.reset(); + this->waitForDevice(); + } + } + else + { + OPENAUTO_LOG(warning) << "[App] android auto entity is still running."; + } + }); +} + void App::stop() { strand_.dispatch([this, self = this->shared_from_this()]() { @@ -69,12 +102,15 @@ void App::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle) { try { - androidAutoEntity_ = androidAutoEntityFactory_.create(std::move(deviceHandle)); + connectedAccessoriesEnumerator_->cancel(); + + auto aoapDevice(aasdk::usb::AOAPDevice::create(usbWrapper_, ioService_, deviceHandle)); + androidAutoEntity_ = androidAutoEntityFactory_.create(std::move(aoapDevice)); androidAutoEntity_->start(*this); } catch(const aasdk::error::Error& error) { - OPENAUTO_LOG(error) << "[App] AndroidAutoEntity create error: " << error.what(); + OPENAUTO_LOG(error) << "[App] USB AndroidAutoEntity create error: " << error.what(); androidAutoEntity_.reset(); this->waitForDevice(); @@ -128,8 +164,8 @@ void App::onUSBHubError(const aasdk::error::Error& error) { OPENAUTO_LOG(error) << "[App] usb hub error: " << error.what(); - if(error.getCode() == aasdk::error::ErrorCode::OPERATION_ABORTED || - error.getCode() == aasdk::error::ErrorCode::OPERATION_IN_PROGRESS) + if(error.getCode() != aasdk::error::ErrorCode::OPERATION_ABORTED && + error.getCode() != aasdk::error::ErrorCode::OPERATION_IN_PROGRESS) { this->waitForDevice(); } diff --git a/src/autoapp/Projection/AndroidAutoEntityFactory.cpp b/src/autoapp/Projection/AndroidAutoEntityFactory.cpp index cc31faed..0eb69428 100644 --- a/src/autoapp/Projection/AndroidAutoEntityFactory.cpp +++ b/src/autoapp/Projection/AndroidAutoEntityFactory.cpp @@ -33,23 +33,19 @@ namespace autoapp namespace projection { -AndroidAutoEntityFactory::AndroidAutoEntityFactory(aasdk::usb::IUSBWrapper& usbWrapper, - boost::asio::io_service& ioService, +AndroidAutoEntityFactory::AndroidAutoEntityFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration, IServiceFactory& serviceFactory) - : usbWrapper_(usbWrapper) - , ioService_(ioService) + : ioService_(ioService) , configuration_(std::move(configuration)) , serviceFactory_(serviceFactory) { } -IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::usb::DeviceHandle deviceHandle) +IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::usb::IAOAPDevice::Pointer aoapDevice) { - auto aoapDevice(aasdk::usb::AOAPDevice::create(usbWrapper_, ioService_, deviceHandle)); - auto transport(std::make_shared(ioService_, aoapDevice)); - + auto transport(std::make_shared(ioService_, std::move(aoapDevice))); return create(std::move(transport)); } diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index 6a2e3e9d..d88863ae 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -99,15 +100,16 @@ int main(int argc, char* argv[]) mainWindow.showFullScreen(); + aasdk::tcp::TCPWrapper tcpWrapper; aasdk::usb::USBWrapper usbWrapper(usbContext); aasdk::usb::AccessoryModeQueryFactory queryFactory(usbWrapper, ioService); aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory(usbWrapper, ioService, queryFactory); autoapp::projection::ServiceFactory serviceFactory(ioService, configuration); - autoapp::projection::AndroidAutoEntityFactory androidAutoEntityFactory(usbWrapper, ioService, configuration, serviceFactory); + autoapp::projection::AndroidAutoEntityFactory androidAutoEntityFactory(ioService, configuration, serviceFactory); auto usbHub(std::make_shared(usbWrapper, ioService, queryChainFactory)); auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); - auto app = std::make_shared(ioService, androidAutoEntityFactory, std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); + auto app = std::make_shared(ioService, usbWrapper, tcpWrapper, androidAutoEntityFactory, std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); app->waitForUSBDevice(); auto result = qApplication.exec(); From 3819f5e75289bb89573871f414ee9d67c9e0ef80 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Mon, 19 Mar 2018 21:45:12 +0100 Subject: [PATCH 17/45] Close socket when entity is still running --- src/autoapp/App.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/autoapp/App.cpp b/src/autoapp/App.cpp index 441b4d6f..b3f92a00 100644 --- a/src/autoapp/App.cpp +++ b/src/autoapp/App.cpp @@ -75,6 +75,7 @@ void App::start(aasdk::tcp::ITCPEndpoint::SocketPointer socket) } else { + tcpWrapper_.close(*socket); OPENAUTO_LOG(warning) << "[App] android auto entity is still running."; } }); From 69d6cf835ba0959d705aa62904a2acc270848e67 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Wed, 21 Mar 2018 19:38:20 +0100 Subject: [PATCH 18/45] Draft of Connect dialog --- .../f1x/openauto/autoapp/UI/ConnectDialog.hpp | 33 +++++ .../f1x/openauto/autoapp/UI/MainWindow.hpp | 1 + src/autoapp/UI/ConnectDialog.cpp | 28 ++++ src/autoapp/UI/MainWindow.cpp | 1 + src/autoapp/UI/connectdialog.ui | 120 ++++++++++++++++++ src/autoapp/UI/mainwindow.ui | 50 +++++--- src/autoapp/UI/settingswindow.ui | 2 +- src/autoapp/autoapp.cpp | 9 +- 8 files changed, 221 insertions(+), 23 deletions(-) create mode 100644 include/f1x/openauto/autoapp/UI/ConnectDialog.hpp create mode 100644 src/autoapp/UI/ConnectDialog.cpp create mode 100644 src/autoapp/UI/connectdialog.ui diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp new file mode 100644 index 00000000..db90ca4b --- /dev/null +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include + +namespace Ui { +class ConnectDialog; +} + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace ui +{ + +class ConnectDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ConnectDialog(QWidget *parent = nullptr); + ~ConnectDialog() override; + +private: + Ui::ConnectDialog *ui; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/UI/MainWindow.hpp b/include/f1x/openauto/autoapp/UI/MainWindow.hpp index 2c823309..b7e23545 100644 --- a/include/f1x/openauto/autoapp/UI/MainWindow.hpp +++ b/include/f1x/openauto/autoapp/UI/MainWindow.hpp @@ -46,6 +46,7 @@ class MainWindow : public QMainWindow void exit(); void openSettings(); void toggleCursor(); + void openConnectDialog(); private: Ui::MainWindow* ui_; diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp new file mode 100644 index 00000000..b663f514 --- /dev/null +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -0,0 +1,28 @@ +#include +#include "ui_connectdialog.h" + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace ui +{ + +ConnectDialog::ConnectDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ConnectDialog) +{ + ui->setupUi(this); +} + +ConnectDialog::~ConnectDialog() +{ + delete ui; +} + +} +} +} +} diff --git a/src/autoapp/UI/MainWindow.cpp b/src/autoapp/UI/MainWindow.cpp index 8569c06f..49954f81 100644 --- a/src/autoapp/UI/MainWindow.cpp +++ b/src/autoapp/UI/MainWindow.cpp @@ -37,6 +37,7 @@ MainWindow::MainWindow(QWidget *parent) connect(ui_->pushButtonSettings, &QPushButton::clicked, this, &MainWindow::openSettings); connect(ui_->pushButtonExit, &QPushButton::clicked, this, &MainWindow::exit); connect(ui_->pushButtonToggleCursor, &QPushButton::clicked, this, &MainWindow::toggleCursor); + connect(ui_->pushButtonWirelessConnection, &QPushButton::clicked, this, &MainWindow::openConnectDialog); } MainWindow::~MainWindow() diff --git a/src/autoapp/UI/connectdialog.ui b/src/autoapp/UI/connectdialog.ui new file mode 100644 index 00000000..ba7b6eef --- /dev/null +++ b/src/autoapp/UI/connectdialog.ui @@ -0,0 +1,120 @@ + + + ConnectDialog + + + + 0 + 0 + 301 + 389 + + + + Connect to device + + + + + 10 + 10 + 281 + 61 + + + + IP Address + + + + + 10 + 30 + 261 + 25 + + + + + + + + 10 + 80 + 281 + 181 + + + + Recent + + + + + 10 + 30 + 261 + 141 + + + + + + + + 60 + 260 + 221 + 81 + + + + <html><head/><body><p><span style=" font-style:italic;">In order to use wireless mode you must enable head unit server in developer settings.</span></p></body></html> + + + true + + + + + + 20 + 290 + 21 + 21 + + + + <html><head/><body><p><img src=":/ico_info.png"/></p></body></html> + + + + + + 100 + 340 + 89 + 41 + + + + Cancel + + + + + + 200 + 340 + 89 + 41 + + + + Connect + + + + + + diff --git a/src/autoapp/UI/mainwindow.ui b/src/autoapp/UI/mainwindow.ui index 8bf52917..7432822b 100644 --- a/src/autoapp/UI/mainwindow.ui +++ b/src/autoapp/UI/mainwindow.ui @@ -48,7 +48,7 @@ color: rgb(238, 238, 236); 630 - 340 + 370 161 41 @@ -67,7 +67,7 @@ color: rgb(238, 238, 236); 630 - 390 + 420 161 41 @@ -79,7 +79,7 @@ color: rgb(238, 238, 236); false - + 340 @@ -92,11 +92,11 @@ color: rgb(238, 238, 236); <html><head/><body><p><span style=" font-style:italic; color:#eeeeec;">Plug in your device to start AndroidAuto (tm).</span></p></body></html> - + 10 - 410 + 440 271 21 @@ -167,20 +167,20 @@ color: rgb(238, 238, 236); 220 - 376 + 400 21 - 21 + 31 <html><head/><body><p><img src=":/ico_info.png"/></p></body></html> - + 250 - 370 + 400 361 31 @@ -193,7 +193,7 @@ color: rgb(238, 238, 236); 630 - 290 + 270 161 41 @@ -208,21 +208,31 @@ color: rgb(238, 238, 236); false - - - - - 0 - 0 - 800 - 22 - - + + + + 630 + 320 + 161 + 41 + + + + Wireless connection + + + false + + + false + + pushButtonToggleCursor + pushButtonWirelessConnection pushButtonSettings pushButtonExit diff --git a/src/autoapp/UI/settingswindow.ui b/src/autoapp/UI/settingswindow.ui index 63ad7a25..b066a78e 100644 --- a/src/autoapp/UI/settingswindow.ui +++ b/src/autoapp/UI/settingswindow.ui @@ -23,7 +23,7 @@ - Form + Settings background-color: rgb(46, 52, 54); diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index d88863ae..f063a2dc 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include namespace aasdk = f1x::aasdk; @@ -89,8 +90,12 @@ int main(int argc, char* argv[]) autoapp::ui::SettingsWindow settingsWindow(configuration); settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + autoapp::ui::ConnectDialog connectDialog; + connectDialog.setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint); + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openSettings, &settingsWindow, &autoapp::ui::SettingsWindow::showFullScreen); + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openConnectDialog, &connectDialog, &autoapp::ui::ConnectDialog::exec); qApplication.setOverrideCursor(Qt::BlankCursor); QObject::connect(&mainWindow, &autoapp::ui::MainWindow::toggleCursor, [&qApplication]() { @@ -108,8 +113,8 @@ int main(int argc, char* argv[]) autoapp::projection::AndroidAutoEntityFactory androidAutoEntityFactory(ioService, configuration, serviceFactory); auto usbHub(std::make_shared(usbWrapper, ioService, queryChainFactory)); - auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); - auto app = std::make_shared(ioService, usbWrapper, tcpWrapper, androidAutoEntityFactory, std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); + auto connectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); + auto app = std::make_shared(ioService, usbWrapper, tcpWrapper, androidAutoEntityFactory, std::move(usbHub), std::move(connectedAccessoriesEnumerator)); app->waitForUSBDevice(); auto result = qApplication.exec(); From 7c31bafa10b583cb7cc84e4aaed0ac6b5104b987 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Wed, 21 Mar 2018 23:51:31 +0100 Subject: [PATCH 19/45] Implement connecting to the device --- .../f1x/openauto/autoapp/UI/ConnectDialog.hpp | 17 +++++++- src/autoapp/UI/ConnectDialog.cpp | 42 ++++++++++++++++--- src/autoapp/autoapp.cpp | 11 +++-- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index db90ca4b..c0b0c42f 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -1,6 +1,8 @@ #pragma once #include +#include +#include namespace Ui { class ConnectDialog; @@ -20,11 +22,22 @@ class ConnectDialog : public QDialog Q_OBJECT public: - explicit ConnectDialog(QWidget *parent = nullptr); + explicit ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, QWidget *parent = nullptr); ~ConnectDialog() override; +signals: + void connectToDevice(const QString& ipAddress); + void connected(aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void connectionFailed(); + +private slots: + void onConnectButtonClicked(); + void onConnectionFailed(); + private: - Ui::ConnectDialog *ui; + boost::asio::io_service& ioService_; + aasdk::tcp::ITCPWrapper& tcpWrapper_; + Ui::ConnectDialog *ui_; }; } diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index b663f514..54337b65 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -1,3 +1,4 @@ +#include #include #include "ui_connectdialog.h" @@ -10,16 +11,47 @@ namespace autoapp namespace ui { -ConnectDialog::ConnectDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::ConnectDialog) +ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, QWidget *parent) + : QDialog(parent) + , ioService_(ioService) + , tcpWrapper_(tcpWrapper) + , ui_(new Ui::ConnectDialog) { - ui->setupUi(this); + qRegisterMetaType("aasdk::tcp::ITCPEndpoint::SocketPointer"); + + ui_->setupUi(this); + connect(ui_->pushButtonCancel, &QPushButton::clicked, this, &ConnectDialog::close); + connect(ui_->pushButtonConnect, &QPushButton::clicked, this, &ConnectDialog::onConnectButtonClicked); + connect(this, &ConnectDialog::connectionFailed, this, &ConnectDialog::onConnectionFailed); } ConnectDialog::~ConnectDialog() { - delete ui; + delete ui_; +} + +void ConnectDialog::onConnectButtonClicked() +{ + const auto& ipAddress = ui_->lineEditIPAddress->text().toStdString(); + auto socket = std::make_shared(ioService_); + + // !ec means no error + if(!tcpWrapper_.connect(*socket, ipAddress, 5277)) + { + emit connected(socket); + this->close(); + } + else + { + emit connectionFailed(); + } +} + +void ConnectDialog::onConnectionFailed() +{ + QMessageBox errorMessage(QMessageBox::Critical, "Error", "Connection failed.", QMessageBox::Ok); + errorMessage.setWindowFlags(Qt::WindowStaysOnTopHint); + errorMessage.exec(); } } diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index f063a2dc..0c238cf5 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -90,8 +90,9 @@ int main(int argc, char* argv[]) autoapp::ui::SettingsWindow settingsWindow(configuration); settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); - autoapp::ui::ConnectDialog connectDialog; - connectDialog.setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint); + aasdk::tcp::TCPWrapper tcpWrapper; + autoapp::ui::ConnectDialog connectDialog(ioService, tcpWrapper); + connectDialog.setWindowFlags(Qt::WindowStaysOnTopHint); QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openSettings, &settingsWindow, &autoapp::ui::SettingsWindow::showFullScreen); @@ -105,7 +106,6 @@ int main(int argc, char* argv[]) mainWindow.showFullScreen(); - aasdk::tcp::TCPWrapper tcpWrapper; aasdk::usb::USBWrapper usbWrapper(usbContext); aasdk::usb::AccessoryModeQueryFactory queryFactory(usbWrapper, ioService); aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory(usbWrapper, ioService, queryFactory); @@ -115,6 +115,11 @@ int main(int argc, char* argv[]) auto usbHub(std::make_shared(usbWrapper, ioService, queryChainFactory)); auto connectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); auto app = std::make_shared(ioService, usbWrapper, tcpWrapper, androidAutoEntityFactory, std::move(usbHub), std::move(connectedAccessoriesEnumerator)); + + QObject::connect(&connectDialog, &autoapp::ui::ConnectDialog::connected, [&app](auto socket) { + app->start(std::move(socket)); + }); + app->waitForUSBDevice(); auto result = qApplication.exec(); From f77cbca8766d9b43844b41eea491817acc1c6c5f Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Thu, 22 Mar 2018 16:33:23 +0100 Subject: [PATCH 20/45] Indicate connection progress --- .../f1x/openauto/autoapp/UI/ConnectDialog.hpp | 4 +- src/autoapp/UI/ConnectDialog.cpp | 38 +++++++++++---- src/autoapp/UI/connectdialog.ui | 47 +++++++++++++++++-- src/autoapp/autoapp.cpp | 2 +- 4 files changed, 74 insertions(+), 17 deletions(-) diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index c0b0c42f..a1d348b2 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -27,12 +27,14 @@ class ConnectDialog : public QDialog signals: void connectToDevice(const QString& ipAddress); - void connected(aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket); void connectionFailed(); private slots: void onConnectButtonClicked(); void onConnectionFailed(); + void onConnectionSucceed(); + void setControlsEnabledStatus(bool status); private: boost::asio::io_service& ioService_; diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index 54337b65..98490520 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -22,6 +22,7 @@ ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITC ui_->setupUi(this); connect(ui_->pushButtonCancel, &QPushButton::clicked, this, &ConnectDialog::close); connect(ui_->pushButtonConnect, &QPushButton::clicked, this, &ConnectDialog::onConnectButtonClicked); + connect(this, &ConnectDialog::connectionSucceed, this, &ConnectDialog::onConnectionSucceed); connect(this, &ConnectDialog::connectionFailed, this, &ConnectDialog::onConnectionFailed); } @@ -32,28 +33,45 @@ ConnectDialog::~ConnectDialog() void ConnectDialog::onConnectButtonClicked() { + this->setControlsEnabledStatus(false); + const auto& ipAddress = ui_->lineEditIPAddress->text().toStdString(); auto socket = std::make_shared(ioService_); + tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, [this, socket](auto ec) mutable { + if(!ec) + { + emit connectionSucceed(std::move(socket)); + this->close(); + } + else + { + emit connectionFailed(); + } + }); +} - // !ec means no error - if(!tcpWrapper_.connect(*socket, ipAddress, 5277)) - { - emit connected(socket); - this->close(); - } - else - { - emit connectionFailed(); - } +void ConnectDialog::onConnectionSucceed() +{ + this->setControlsEnabledStatus(true); } void ConnectDialog::onConnectionFailed() { + this->setControlsEnabledStatus(true); + QMessageBox errorMessage(QMessageBox::Critical, "Error", "Connection failed.", QMessageBox::Ok); errorMessage.setWindowFlags(Qt::WindowStaysOnTopHint); errorMessage.exec(); } +void ConnectDialog::setControlsEnabledStatus(bool status) +{ + ui_->pushButtonConnect->setVisible(status); + ui_->pushButtonCancel->setEnabled(status); + ui_->lineEditIPAddress->setEnabled(status); + ui_->listViewRecent->setEnabled(status); +} + } } } diff --git a/src/autoapp/UI/connectdialog.ui b/src/autoapp/UI/connectdialog.ui index ba7b6eef..a9adb5d8 100644 --- a/src/autoapp/UI/connectdialog.ui +++ b/src/autoapp/UI/connectdialog.ui @@ -59,7 +59,7 @@ - + 60 @@ -91,9 +91,9 @@ - 100 + 40 340 - 89 + 121 41 @@ -104,9 +104,9 @@ - 200 + 170 340 - 89 + 121 41 @@ -114,6 +114,43 @@ Connect + + + + 170 + 340 + 121 + 41 + + + + 0 + + + 0 + + + + + + 188 + 350 + 91 + 20 + + + + Connecting... + + + groupBoxIPAddress + groupBoxRecent + labelHeadUnitServerInfo + labelCopyrightsInfoIcon + pushButtonCancel + progressBarConnect + labelConnecting + pushButtonConnect diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index 0c238cf5..81fe3cd7 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -116,7 +116,7 @@ int main(int argc, char* argv[]) auto connectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); auto app = std::make_shared(ioService, usbWrapper, tcpWrapper, androidAutoEntityFactory, std::move(usbHub), std::move(connectedAccessoriesEnumerator)); - QObject::connect(&connectDialog, &autoapp::ui::ConnectDialog::connected, [&app](auto socket) { + QObject::connect(&connectDialog, &autoapp::ui::ConnectDialog::connectionSucceed, [&app](auto socket) { app->start(std::move(socket)); }); From 991f31bc771b0271492fe6ff9931a49b6e1073cb Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Thu, 22 Mar 2018 17:12:37 +0100 Subject: [PATCH 21/45] Handle invalid IP address --- .../f1x/openauto/autoapp/UI/ConnectDialog.hpp | 5 ++- src/autoapp/UI/ConnectDialog.cpp | 37 ++++++++++++------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index a1d348b2..fe654ca6 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -28,13 +28,14 @@ class ConnectDialog : public QDialog signals: void connectToDevice(const QString& ipAddress); void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket); - void connectionFailed(); + void connectionFailed(const QString& message); private slots: void onConnectButtonClicked(); - void onConnectionFailed(); + void onConnectionFailed(const QString& message); void onConnectionSucceed(); void setControlsEnabledStatus(bool status); + void connectHandler(const boost::system::error_code& ec, aasdk::tcp::ITCPEndpoint::SocketPointer socket); private: boost::asio::io_service& ioService_; diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index 98490520..69a2e02c 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -37,17 +37,28 @@ void ConnectDialog::onConnectButtonClicked() const auto& ipAddress = ui_->lineEditIPAddress->text().toStdString(); auto socket = std::make_shared(ioService_); - tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, [this, socket](auto ec) mutable { - if(!ec) - { - emit connectionSucceed(std::move(socket)); - this->close(); - } - else - { - emit connectionFailed(); - } - }); + + try + { + tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, std::bind(&ConnectDialog::connectHandler, this, std::placeholders::_1, socket)); + } + catch(const boost::system::system_error& se) + { + emit connectionFailed(QString(se.what())); + } +} + +void ConnectDialog::connectHandler(const boost::system::error_code& ec, aasdk::tcp::ITCPEndpoint::SocketPointer socket) +{ + if(!ec) + { + emit connectionSucceed(std::move(socket)); + this->close(); + } + else + { + emit connectionFailed(QString::fromStdString(ec.message())); + } } void ConnectDialog::onConnectionSucceed() @@ -55,11 +66,11 @@ void ConnectDialog::onConnectionSucceed() this->setControlsEnabledStatus(true); } -void ConnectDialog::onConnectionFailed() +void ConnectDialog::onConnectionFailed(const QString& message) { this->setControlsEnabledStatus(true); - QMessageBox errorMessage(QMessageBox::Critical, "Error", "Connection failed.", QMessageBox::Ok); + QMessageBox errorMessage(QMessageBox::Critical, "Connect error", message, QMessageBox::Ok); errorMessage.setWindowFlags(Qt::WindowStaysOnTopHint); errorMessage.exec(); } From 42c15ec0097b82a3edf1059fed8072399b63b534 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Thu, 22 Mar 2018 17:16:56 +0100 Subject: [PATCH 22/45] Remove status bar --- src/autoapp/UI/mainwindow.ui | 1 - 1 file changed, 1 deletion(-) diff --git a/src/autoapp/UI/mainwindow.ui b/src/autoapp/UI/mainwindow.ui index 7432822b..6da956e8 100644 --- a/src/autoapp/UI/mainwindow.ui +++ b/src/autoapp/UI/mainwindow.ui @@ -228,7 +228,6 @@ color: rgb(238, 238, 236); - pushButtonToggleCursor From e4771d0d1cf139b7bbe1ea0b6f27f596875dbb67 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 24 Mar 2018 01:04:26 +0100 Subject: [PATCH 23/45] Add Qt prefixes to audio class implementations --- .../{AudioInput.hpp => QtAudioInput.hpp} | 4 +- .../{AudioOutput.hpp => QtAudioOutput.hpp} | 4 +- .../{AudioInput.cpp => QtAudioInput.cpp} | 34 +++++++------- .../{AudioOutput.cpp => QtAudioOutput.cpp} | 47 +++++++++---------- src/autoapp/Projection/ServiceFactory.cpp | 12 ++--- 5 files changed, 50 insertions(+), 51 deletions(-) rename include/f1x/openauto/autoapp/Projection/{AudioInput.hpp => QtAudioInput.hpp} (92%) rename include/f1x/openauto/autoapp/Projection/{AudioOutput.hpp => QtAudioOutput.hpp} (92%) rename src/autoapp/Projection/{AudioInput.cpp => QtAudioInput.cpp} (77%) rename src/autoapp/Projection/{AudioOutput.cpp => QtAudioOutput.cpp} (62%) diff --git a/include/f1x/openauto/autoapp/Projection/AudioInput.hpp b/include/f1x/openauto/autoapp/Projection/QtAudioInput.hpp similarity index 92% rename from include/f1x/openauto/autoapp/Projection/AudioInput.hpp rename to include/f1x/openauto/autoapp/Projection/QtAudioInput.hpp index 1dd7db0d..97816eab 100644 --- a/include/f1x/openauto/autoapp/Projection/AudioInput.hpp +++ b/include/f1x/openauto/autoapp/Projection/QtAudioInput.hpp @@ -32,11 +32,11 @@ namespace autoapp namespace projection { -class AudioInput: public QObject, public IAudioInput +class QtAudioInput: public QObject, public IAudioInput { Q_OBJECT public: - AudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate); + QtAudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate); bool open() override; bool isActive() const override; diff --git a/include/f1x/openauto/autoapp/Projection/AudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/QtAudioOutput.hpp similarity index 92% rename from include/f1x/openauto/autoapp/Projection/AudioOutput.hpp rename to include/f1x/openauto/autoapp/Projection/QtAudioOutput.hpp index 9aa4d413..e026a917 100644 --- a/include/f1x/openauto/autoapp/Projection/AudioOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/QtAudioOutput.hpp @@ -32,12 +32,12 @@ namespace autoapp namespace projection { -class AudioOutput: public QObject, public IAudioOutput +class QtAudioOutput: public QObject, public IAudioOutput { Q_OBJECT public: - AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate); + QtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate); bool open() override; void write(const aasdk::common::DataConstBuffer& buffer) override; void start() override; diff --git a/src/autoapp/Projection/AudioInput.cpp b/src/autoapp/Projection/QtAudioInput.cpp similarity index 77% rename from src/autoapp/Projection/AudioInput.cpp rename to src/autoapp/Projection/QtAudioInput.cpp index 2fe3fbfb..15584302 100644 --- a/src/autoapp/Projection/AudioInput.cpp +++ b/src/autoapp/Projection/QtAudioInput.cpp @@ -17,7 +17,7 @@ */ #include -#include +#include #include namespace f1x @@ -29,7 +29,7 @@ namespace autoapp namespace projection { -AudioInput::AudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate) +QtAudioInput::QtAudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate) : ioDevice_(nullptr) { qRegisterMetaType("StartPromise::Pointer"); @@ -42,32 +42,32 @@ AudioInput::AudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t samp audioFormat_.setSampleType(QAudioFormat::SignedInt); this->moveToThread(QApplication::instance()->thread()); - connect(this, &AudioInput::startRecording, this, &AudioInput::onStartRecording, Qt::QueuedConnection); - connect(this, &AudioInput::stopRecording, this, &AudioInput::onStopRecording, Qt::QueuedConnection); + connect(this, &QtAudioInput::startRecording, this, &QtAudioInput::onStartRecording, Qt::QueuedConnection); + connect(this, &QtAudioInput::stopRecording, this, &QtAudioInput::onStopRecording, Qt::QueuedConnection); QMetaObject::invokeMethod(this, "createAudioInput", Qt::BlockingQueuedConnection); } -void AudioInput::createAudioInput() +void QtAudioInput::createAudioInput() { OPENAUTO_LOG(debug) << "[AudioInput] create."; audioInput_ = (std::make_unique(QAudioDeviceInfo::defaultInputDevice(), audioFormat_)); } -bool AudioInput::open() +bool QtAudioInput::open() { std::lock_guard lock(mutex_); return ioDevice_ == nullptr; } -bool AudioInput::isActive() const +bool QtAudioInput::isActive() const { std::lock_guard lock(mutex_); return ioDevice_ != nullptr; } -void AudioInput::read(ReadPromise::Pointer promise) +void QtAudioInput::read(ReadPromise::Pointer promise) { std::lock_guard lock(mutex_); @@ -85,32 +85,32 @@ void AudioInput::read(ReadPromise::Pointer promise) } } -void AudioInput::start(StartPromise::Pointer promise) +void QtAudioInput::start(StartPromise::Pointer promise) { emit startRecording(std::move(promise)); } -void AudioInput::stop() +void QtAudioInput::stop() { emit stopRecording(); } -uint32_t AudioInput::getSampleSize() const +uint32_t QtAudioInput::getSampleSize() const { return audioFormat_.sampleSize(); } -uint32_t AudioInput::getChannelCount() const +uint32_t QtAudioInput::getChannelCount() const { return audioFormat_.channelCount(); } -uint32_t AudioInput::getSampleRate() const +uint32_t QtAudioInput::getSampleRate() const { return audioFormat_.sampleRate(); } -void AudioInput::onStartRecording(StartPromise::Pointer promise) +void QtAudioInput::onStartRecording(StartPromise::Pointer promise) { std::lock_guard lock(mutex_); @@ -118,7 +118,7 @@ void AudioInput::onStartRecording(StartPromise::Pointer promise) if(ioDevice_ != nullptr) { - connect(ioDevice_, &QIODevice::readyRead, this, &AudioInput::onReadyRead, Qt::QueuedConnection); + connect(ioDevice_, &QIODevice::readyRead, this, &QtAudioInput::onReadyRead, Qt::QueuedConnection); promise->resolve(); } else @@ -127,7 +127,7 @@ void AudioInput::onStartRecording(StartPromise::Pointer promise) } } -void AudioInput::onStopRecording() +void QtAudioInput::onStopRecording() { std::lock_guard lock(mutex_); @@ -147,7 +147,7 @@ void AudioInput::onStopRecording() audioInput_->stop(); } -void AudioInput::onReadyRead() +void QtAudioInput::onReadyRead() { std::lock_guard lock(mutex_); diff --git a/src/autoapp/Projection/AudioOutput.cpp b/src/autoapp/Projection/QtAudioOutput.cpp similarity index 62% rename from src/autoapp/Projection/AudioOutput.cpp rename to src/autoapp/Projection/QtAudioOutput.cpp index f211987d..959ca1fa 100644 --- a/src/autoapp/Projection/AudioOutput.cpp +++ b/src/autoapp/Projection/QtAudioOutput.cpp @@ -17,7 +17,7 @@ */ #include -#include +#include #include namespace f1x @@ -29,7 +29,7 @@ namespace autoapp namespace projection { -AudioOutput::AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate) +QtAudioOutput::QtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate) : playbackStarted_(false) { audioFormat_.setChannelCount(channelCount); @@ -40,79 +40,78 @@ AudioOutput::AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sa audioFormat_.setSampleType(QAudioFormat::SignedInt); this->moveToThread(QApplication::instance()->thread()); - connect(this, &AudioOutput::startPlayback, this, &AudioOutput::onStartPlayback); - connect(this, &AudioOutput::suspendPlayback, this, &AudioOutput::onSuspendPlayback); - connect(this, &AudioOutput::stopPlayback, this, &AudioOutput::onStopPlayback); + connect(this, &QtAudioOutput::startPlayback, this, &QtAudioOutput::onStartPlayback); + connect(this, &QtAudioOutput::suspendPlayback, this, &QtAudioOutput::onSuspendPlayback); + connect(this, &QtAudioOutput::stopPlayback, this, &QtAudioOutput::onStopPlayback); QMetaObject::invokeMethod(this, "createAudioOutput", Qt::BlockingQueuedConnection); } -void AudioOutput::createAudioOutput() +void QtAudioOutput::createAudioOutput() { - OPENAUTO_LOG(debug) << "[AudioOutput] create."; + OPENAUTO_LOG(debug) << "[QtAudioOutput] create."; audioOutput_ = std::make_unique(QAudioDeviceInfo::defaultOutputDevice(), audioFormat_); - - // Setting this category switching to the low latency mode - // See: http://code.qt.io/cgit/qt/qtmultimedia.git/tree/src/plugins/pulseaudio/qaudiooutput_pulse.cpp?h=5.7#n58 - audioOutput_->setCategory("game"); } -bool AudioOutput::open() +bool QtAudioOutput::open() { return audioBuffer_.open(QIODevice::ReadWrite); } -void AudioOutput::write(const aasdk::common::DataConstBuffer& buffer) +void QtAudioOutput::write(const aasdk::common::DataConstBuffer& buffer) { audioBuffer_.write(reinterpret_cast(buffer.cdata), buffer.size); } -void AudioOutput::start() +void QtAudioOutput::start() { emit startPlayback(); } -void AudioOutput::stop() +void QtAudioOutput::stop() { emit stopPlayback(); } -void AudioOutput::suspend() +void QtAudioOutput::suspend() { emit suspendPlayback(); } -uint32_t AudioOutput::getSampleSize() const +uint32_t QtAudioOutput::getSampleSize() const { return audioFormat_.sampleSize(); } -uint32_t AudioOutput::getChannelCount() const +uint32_t QtAudioOutput::getChannelCount() const { return audioFormat_.channelCount(); } -uint32_t AudioOutput::getSampleRate() const +uint32_t QtAudioOutput::getSampleRate() const { return audioFormat_.sampleRate(); } -void AudioOutput::onStartPlayback() +void QtAudioOutput::onStartPlayback() { if(!playbackStarted_) { audioOutput_->start(&audioBuffer_); playbackStarted_ = true; } + else + { + audioOutput_->resume(); + } } -void AudioOutput::onSuspendPlayback() +void QtAudioOutput::onSuspendPlayback() { - // QAudioOutput is in pull mode so suspending/resuming are not needed. - // Keep this interface for any further purposes + audioOutput_->suspend(); } -void AudioOutput::onStopPlayback() +void QtAudioOutput::onStopPlayback() { if(playbackStarted_) { diff --git a/src/autoapp/Projection/ServiceFactory.cpp b/src/autoapp/Projection/ServiceFactory.cpp index ade1e386..9205b257 100644 --- a/src/autoapp/Projection/ServiceFactory.cpp +++ b/src/autoapp/Projection/ServiceFactory.cpp @@ -32,8 +32,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -59,22 +59,22 @@ ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messeng { ServiceList serviceList; - IAudioInput::Pointer audioInput(new AudioInput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + IAudioInput::Pointer audioInput(new QtAudioInput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(audioInput))); if(configuration_->musicAudioChannelEnabled()) { - IAudioOutput::Pointer mediaAudioOutput(new AudioOutput(2, 16, 48000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + IAudioOutput::Pointer mediaAudioOutput(new QtAudioOutput(2, 16, 48000), std::bind(&QObject::deleteLater, std::placeholders::_1)); serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(mediaAudioOutput))); } if(configuration_->speechAudioChannelEnabled()) { - IAudioOutput::Pointer speechAudioOutput(new AudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + IAudioOutput::Pointer speechAudioOutput(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(speechAudioOutput))); } - IAudioOutput::Pointer systemAudioOutput(new AudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + IAudioOutput::Pointer systemAudioOutput(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(systemAudioOutput))); serviceList.emplace_back(std::make_shared(ioService_, messenger)); From 023c7619c7680ca3d69500e662c2fb396a3b6384 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 24 Mar 2018 01:16:04 +0100 Subject: [PATCH 24/45] Add cmake to find rtaudio library --- CMakeLists.txt | 3 ++ cmake_modules/Findrtaudio.cmake | 70 +++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 cmake_modules/Findrtaudio.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a530db9..fc87b2e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ find_package(libusb-1.0 REQUIRED) find_package(Qt5 COMPONENTS Multimedia MultimediaWidgets Bluetooth) find_package(Protobuf REQUIRED) find_package(OpenSSL REQUIRED) +find_package(rtaudio REQUIRED) if(WIN32) set(WINSOCK2_LIBRARIES "ws2_32") @@ -54,6 +55,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} ${LIBUSB_1_INCLUDE_DIRS} ${PROTOBUF_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} + ${RTAUDIO_INCLUDE_DIRS} ${AASDK_PROTO_INCLUDE_DIRS} ${AASDK_INCLUDE_DIRS} ${BCM_HOST_INCLUDE_DIRS} @@ -80,6 +82,7 @@ target_link_libraries(autoapp ${BCM_HOST_LIBRARIES} ${ILCLIENT_LIBRARIES} ${WINSOCK2_LIBRARIES} + ${RTAUDIO_LIBRARIES} ${AASDK_PROTO_LIBRARIES} ${AASDK_LIBRARIES}) diff --git a/cmake_modules/Findrtaudio.cmake b/cmake_modules/Findrtaudio.cmake new file mode 100644 index 00000000..60b9384c --- /dev/null +++ b/cmake_modules/Findrtaudio.cmake @@ -0,0 +1,70 @@ +# +# This file is part of openauto project. +# Copyright (C) 2018 f1x.studio (Michal Szwaj) +# +# openauto is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# openauto is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with openauto. If not, see . +# + +if (RTAUDIO_LIBRARIES AND RTAUDIO_INCLUDE_DIRS) + # in cache already + set(RTAUDIO_FOUND TRUE) +else (RTAUDIO_LIBRARIES AND RTAUDIO_INCLUDE_DIRS) + find_path(RTAUDIO_INCLUDE_DIR + NAMES + RtAudio.h + PATHS + /usr/include + /usr/local/include + /opt/local/include + /sw/include + PATH_SUFFIXES + rtaudio + ) + + find_library(RTAUDIO_LIBRARY + NAMES + rtaudio + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /sw/lib + ) + + set(RTAUDIO_INCLUDE_DIRS + ${RTAUDIO_INCLUDE_DIR} + ) + set(RTAUDIO_LIBRARIES + ${RTAUDIO_LIBRARY} +) + + if (RTAUDIO_INCLUDE_DIRS AND RTAUDIO_LIBRARIES) + set(RTAUDIO_FOUND TRUE) + endif (RTAUDIO_INCLUDE_DIRS AND RTAUDIO_LIBRARIES) + + if (RTAUDIO_FOUND) + if (NOT rtaudio_FIND_QUIETLY) + message(STATUS "Found rtaudio:") + message(STATUS " - Includes: ${RTAUDIO_INCLUDE_DIRS}") + message(STATUS " - Libraries: ${RTAUDIO_LIBRARIES}") + endif (NOT rtaudio_FIND_QUIETLY) + else (RTAUDIO_FOUND) + if (rtaudio_FIND_REQUIRED) + message(FATAL_ERROR "Could not find rtaudio") + endif (rtaudio_FIND_REQUIRED) + endif (RTAUDIO_FOUND) + + mark_as_advanced(RTAUDIO_INCLUDE_DIRS RTAUDIO_LIBRARIES) + +endif (RTAUDIO_LIBRARIES AND RTAUDIO_INCLUDE_DIRS) From bd6013081ae20b752911a8c33d4e6b2185566727 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 24 Mar 2018 02:52:03 +0100 Subject: [PATCH 25/45] Implement RtAudio backend --- .../autoapp/Projection/RtAudioOutput.hpp | 63 ++++++++ src/autoapp/Projection/AudioService.cpp | 6 + src/autoapp/Projection/RtAudioOutput.cpp | 148 ++++++++++++++++++ src/autoapp/Projection/ServiceFactory.cpp | 6 +- 4 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp create mode 100644 src/autoapp/Projection/RtAudioOutput.cpp diff --git a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp new file mode 100644 index 00000000..1e111b84 --- /dev/null +++ b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp @@ -0,0 +1,63 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +class RtAudioOutput: public IAudioOutput +{ +public: + RtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate); + bool open() override; + void write(const aasdk::common::DataConstBuffer& buffer) override; + void start() override; + void stop() override; + void suspend() override; + uint32_t getSampleSize() const override; + uint32_t getChannelCount() const override; + uint32_t getSampleRate() const override; + +private: + static int audioBufferReadHandler(void* outputBuffer, void* inputBuffer, unsigned int nBufferFrames, + double streamTime, RtAudioStreamStatus status, void* userData); + + uint32_t channelCount_; + uint32_t sampleSize_; + uint32_t sampleRate_; + SequentialBuffer audioBuffer_; + bool playbackStarted_; + RtAudio dac_; + std::mutex mutex_; +}; + +} +} +} +} diff --git a/src/autoapp/Projection/AudioService.cpp b/src/autoapp/Projection/AudioService.cpp index 3e68c11a..d5d2da59 100644 --- a/src/autoapp/Projection/AudioService.cpp +++ b/src/autoapp/Projection/AudioService.cpp @@ -93,6 +93,12 @@ void AudioService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpe OPENAUTO_LOG(info) << "[AudioService] open request" << ", channel: " << aasdk::messenger::channelIdToString(channel_->getId()) << ", priority: " << request.priority(); + + OPENAUTO_LOG(debug) << "[AudioService] channel: " << aasdk::messenger::channelIdToString(channel_->getId()) + << " audio output sample rate: " << audioOutput_->getSampleRate() + << ", sample size: " << audioOutput_->getSampleSize() + << ", channel count: " << audioOutput_->getChannelCount(); + const aasdk::proto::enums::Status::Enum status = audioOutput_->open() ? aasdk::proto::enums::Status::OK : aasdk::proto::enums::Status::FAIL; OPENAUTO_LOG(info) << "[AudioService] open status: " << status << ", channel: " << aasdk::messenger::channelIdToString(channel_->getId()); diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp new file mode 100644 index 00000000..68a1756d --- /dev/null +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -0,0 +1,148 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace projection +{ + +RtAudioOutput::RtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate) + : channelCount_(channelCount) + , sampleSize_(sampleSize) + , sampleRate_(sampleRate) + , playbackStarted_(false) +{ +} + +bool RtAudioOutput::open() +{ + std::lock_guard lock(mutex_); + + if(dac_.getDeviceCount() > 0) + { + RtAudio::StreamParameters parameters; + parameters.deviceId = dac_.getDefaultOutputDevice(); + parameters.nChannels = channelCount_; + parameters.firstChannel = 0; + + try + { + uint32_t bufferFrames = 256; + dac_.openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this)); + + return audioBuffer_.open(QIODevice::ReadWrite); + } + catch(const RtAudioError& e) + { + OPENAUTO_LOG(error) << "[RtAudioOutput] Failed to open audio output, what: " << e.what(); + } + } + else + { + OPENAUTO_LOG(error) << "[RtAudioOutput] No output devices found."; + } + + return false; +} + +void RtAudioOutput::write(const aasdk::common::DataConstBuffer& buffer) +{ + audioBuffer_.write(reinterpret_cast(buffer.cdata), buffer.size); +} + +void RtAudioOutput::start() +{ + std::lock_guard lock(mutex_); + + if(dac_.isStreamOpen() && !dac_.isStreamRunning()) + { + try + { + dac_.startStream(); + } + catch(const RtAudioError& e) + { + OPENAUTO_LOG(error) << "[RtAudioOutput] Failed to start audio output, what: " << e.what(); + } + } +} + +void RtAudioOutput::stop() +{ + std::lock_guard lock(mutex_); + + this->suspend(); + + if(dac_.isStreamOpen()) + { + dac_.closeStream(); + } +} + +void RtAudioOutput::suspend() +{ + std::lock_guard lock(mutex_); + + if(!dac_.isStreamOpen() && !dac_.isStreamRunning()) + { + try + { + dac_.stopStream(); + } + catch(const RtAudioError& e) + { + OPENAUTO_LOG(error) << "[RtAudioOutput] Failed to suspend audio output, what: " << e.what(); + } + } +} + +uint32_t RtAudioOutput::getSampleSize() const +{ + return sampleSize_; +} + +uint32_t RtAudioOutput::getChannelCount() const +{ + return channelCount_; +} + +uint32_t RtAudioOutput::getSampleRate() const +{ + return sampleRate_; +} + +int RtAudioOutput::audioBufferReadHandler(void* outputBuffer, void* inputBuffer, unsigned int nBufferFrames, + double streamTime, RtAudioStreamStatus status, void* userData) +{ + RtAudioOutput* self = static_cast(userData); + const auto bufferSize = nBufferFrames * (self->sampleSize_ / 8) * self->channelCount_; + self->audioBuffer_.read(reinterpret_cast(outputBuffer), bufferSize); + return 0; +} + +} +} +} +} diff --git a/src/autoapp/Projection/ServiceFactory.cpp b/src/autoapp/Projection/ServiceFactory.cpp index 9205b257..2e54710d 100644 --- a/src/autoapp/Projection/ServiceFactory.cpp +++ b/src/autoapp/Projection/ServiceFactory.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -64,17 +65,20 @@ ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messeng if(configuration_->musicAudioChannelEnabled()) { - IAudioOutput::Pointer mediaAudioOutput(new QtAudioOutput(2, 16, 48000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + //IAudioOutput::Pointer mediaAudioOutput(new QtAudioOutput(2, 16, 48000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + auto mediaAudioOutput(std::make_shared(2, 16, 48000)); serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(mediaAudioOutput))); } if(configuration_->speechAudioChannelEnabled()) { IAudioOutput::Pointer speechAudioOutput(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + //auto speechAudioOutput(std::make_shared(1, 16, 1600)); serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(speechAudioOutput))); } IAudioOutput::Pointer systemAudioOutput(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + //auto systemAudioOutput(std::make_shared(1, 16, 1600)); serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(systemAudioOutput))); serviceList.emplace_back(std::make_shared(ioService_, messenger)); From 66610efd33bdadf131958039e4a97b43b1932974 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 24 Mar 2018 03:28:31 +0100 Subject: [PATCH 26/45] Use RtAudio for all audio channels --- .../autoapp/Projection/RtAudioOutput.hpp | 3 +- src/autoapp/Projection/RtAudioOutput.cpp | 31 ++++++++++++------- src/autoapp/Projection/ServiceFactory.cpp | 8 ++--- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp index 1e111b84..7bfba51f 100644 --- a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp @@ -52,8 +52,7 @@ class RtAudioOutput: public IAudioOutput uint32_t sampleSize_; uint32_t sampleRate_; SequentialBuffer audioBuffer_; - bool playbackStarted_; - RtAudio dac_; + std::unique_ptr dac_; std::mutex mutex_; }; diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp index 68a1756d..d84428b3 100644 --- a/src/autoapp/Projection/RtAudioOutput.cpp +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -32,25 +32,34 @@ RtAudioOutput::RtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_ : channelCount_(channelCount) , sampleSize_(sampleSize) , sampleRate_(sampleRate) - , playbackStarted_(false) + , dac_() { + try + { + dac_ = std::make_unique(RtAudio::LINUX_PULSE); + } + catch(...) + { + // fallback + dac_ = std::make_unique(); + } } bool RtAudioOutput::open() { std::lock_guard lock(mutex_); - if(dac_.getDeviceCount() > 0) + if(dac_->getDeviceCount() > 0) { RtAudio::StreamParameters parameters; - parameters.deviceId = dac_.getDefaultOutputDevice(); + parameters.deviceId = dac_->getDefaultOutputDevice(); parameters.nChannels = channelCount_; parameters.firstChannel = 0; try { - uint32_t bufferFrames = 256; - dac_.openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this)); + uint32_t bufferFrames = 1024; + dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this)); return audioBuffer_.open(QIODevice::ReadWrite); } @@ -76,11 +85,11 @@ void RtAudioOutput::start() { std::lock_guard lock(mutex_); - if(dac_.isStreamOpen() && !dac_.isStreamRunning()) + if(dac_->isStreamOpen() && !dac_->isStreamRunning()) { try { - dac_.startStream(); + dac_->startStream(); } catch(const RtAudioError& e) { @@ -95,9 +104,9 @@ void RtAudioOutput::stop() this->suspend(); - if(dac_.isStreamOpen()) + if(dac_->isStreamOpen()) { - dac_.closeStream(); + dac_->closeStream(); } } @@ -105,11 +114,11 @@ void RtAudioOutput::suspend() { std::lock_guard lock(mutex_); - if(!dac_.isStreamOpen() && !dac_.isStreamRunning()) + if(!dac_->isStreamOpen() && !dac_->isStreamRunning()) { try { - dac_.stopStream(); + dac_->stopStream(); } catch(const RtAudioError& e) { diff --git a/src/autoapp/Projection/ServiceFactory.cpp b/src/autoapp/Projection/ServiceFactory.cpp index 2e54710d..82ede87a 100644 --- a/src/autoapp/Projection/ServiceFactory.cpp +++ b/src/autoapp/Projection/ServiceFactory.cpp @@ -72,13 +72,13 @@ ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messeng if(configuration_->speechAudioChannelEnabled()) { - IAudioOutput::Pointer speechAudioOutput(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); - //auto speechAudioOutput(std::make_shared(1, 16, 1600)); + //IAudioOutput::Pointer speechAudioOutput(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + auto speechAudioOutput(std::make_shared(1, 16, 16000)); serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(speechAudioOutput))); } - IAudioOutput::Pointer systemAudioOutput(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); - //auto systemAudioOutput(std::make_shared(1, 16, 1600)); + //IAudioOutput::Pointer systemAudioOutput(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + auto systemAudioOutput(std::make_shared(1, 16, 16000)); serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(systemAudioOutput))); serviceList.emplace_back(std::make_shared(ioService_, messenger)); From 205ed34468d4afb30897d16bbe21b0e72333cfb8 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 24 Mar 2018 03:33:32 +0100 Subject: [PATCH 27/45] Decrease audio buffer size --- src/autoapp/Projection/RtAudioOutput.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp index d84428b3..ca94bfc5 100644 --- a/src/autoapp/Projection/RtAudioOutput.cpp +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -58,7 +58,7 @@ bool RtAudioOutput::open() try { - uint32_t bufferFrames = 1024; + uint32_t bufferFrames = 128; dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this)); return audioBuffer_.open(QIODevice::ReadWrite); From 24bc8fda9d2b559b8563a61c556e84db57400ef5 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 24 Mar 2018 03:55:20 +0100 Subject: [PATCH 28/45] Synchronize audio buffer callback --- src/autoapp/Projection/RtAudioOutput.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp index ca94bfc5..eb0d4938 100644 --- a/src/autoapp/Projection/RtAudioOutput.cpp +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -32,7 +32,6 @@ RtAudioOutput::RtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_ : channelCount_(channelCount) , sampleSize_(sampleSize) , sampleRate_(sampleRate) - , dac_() { try { @@ -146,6 +145,8 @@ int RtAudioOutput::audioBufferReadHandler(void* outputBuffer, void* inputBuffer, double streamTime, RtAudioStreamStatus status, void* userData) { RtAudioOutput* self = static_cast(userData); + std::lock_guardmutex_)> lock(self->mutex_); + const auto bufferSize = nBufferFrames * (self->sampleSize_ / 8) * self->channelCount_; self->audioBuffer_.read(reinterpret_cast(outputBuffer), bufferSize); return 0; From 493b68e2a454f747e18691246a8ac5c6724c5281 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 24 Mar 2018 03:56:39 +0100 Subject: [PATCH 29/45] Update readme --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index aaf92178..fa433954 100644 --- a/Readme.md +++ b/Readme.md @@ -42,6 +42,7 @@ Copyrights (c) 2018 f1x.studio (Michal Szwaj) - [Boost libraries](http://www.boost.org/) - [Qt libraries](https://www.qt.io/) - [CMake](https://cmake.org/) + - [RtAudio](https://www.music.mcgill.ca/~gary/rtaudio/playback.html) - Broadcom ilclient from RaspberryPI 3 firmware - OpenMAX IL API From 8900c180e36c4a23f017ecc9bf4d9611e60b835d Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 24 Mar 2018 11:40:28 +0100 Subject: [PATCH 30/45] Fix deadlock when stopping audio output --- .../autoapp/Projection/RtAudioOutput.hpp | 1 + src/autoapp/Projection/RtAudioOutput.cpp | 30 +++++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp index 7bfba51f..f3d69d5f 100644 --- a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp @@ -45,6 +45,7 @@ class RtAudioOutput: public IAudioOutput uint32_t getSampleRate() const override; private: + void doSuspend(); static int audioBufferReadHandler(void* outputBuffer, void* inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void* userData); diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp index eb0d4938..416b58be 100644 --- a/src/autoapp/Projection/RtAudioOutput.cpp +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -101,7 +101,7 @@ void RtAudioOutput::stop() { std::lock_guard lock(mutex_); - this->suspend(); + this->doSuspend(); if(dac_->isStreamOpen()) { @@ -112,18 +112,7 @@ void RtAudioOutput::stop() void RtAudioOutput::suspend() { std::lock_guard lock(mutex_); - - if(!dac_->isStreamOpen() && !dac_->isStreamRunning()) - { - try - { - dac_->stopStream(); - } - catch(const RtAudioError& e) - { - OPENAUTO_LOG(error) << "[RtAudioOutput] Failed to suspend audio output, what: " << e.what(); - } - } + this->doSuspend(); } uint32_t RtAudioOutput::getSampleSize() const @@ -141,6 +130,21 @@ uint32_t RtAudioOutput::getSampleRate() const return sampleRate_; } +void RtAudioOutput::doSuspend() +{ + if(!dac_->isStreamOpen() && !dac_->isStreamRunning()) + { + try + { + dac_->stopStream(); + } + catch(const RtAudioError& e) + { + OPENAUTO_LOG(error) << "[RtAudioOutput] Failed to suspend audio output, what: " << e.what(); + } + } +} + int RtAudioOutput::audioBufferReadHandler(void* outputBuffer, void* inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void* userData) { From 258a6a3c59e8118e7c3f72bc52cadc3bbcb16d68 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 01:29:36 +0100 Subject: [PATCH 31/45] Impelemnt recent list --- .../Configuration/IRecentAddressesList.hpp | 46 ++++++++ .../Configuration/RecentAddressesList.hpp | 57 ++++++++++ .../f1x/openauto/autoapp/UI/ConnectDialog.hpp | 16 ++- .../Configuration/RecentAddressesList.cpp | 106 ++++++++++++++++++ src/autoapp/UI/ConnectDialog.cpp | 32 +++++- 5 files changed, 248 insertions(+), 9 deletions(-) create mode 100644 include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp create mode 100644 include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp create mode 100644 src/autoapp/Configuration/RecentAddressesList.cpp diff --git a/include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp b/include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp new file mode 100644 index 00000000..88213def --- /dev/null +++ b/include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp @@ -0,0 +1,46 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +class IRecentAddressesList +{ +public: + typedef std::deque RecentAddresses; + + virtual void read() = 0; + virtual void insertAddress(const std::string& address) = 0; + virtual RecentAddresses getList() const = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp b/include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp new file mode 100644 index 00000000..3c125913 --- /dev/null +++ b/include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp @@ -0,0 +1,57 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +class RecentAddressesList: public IRecentAddressesList +{ +public: + RecentAddressesList(size_t maxListSize); + + void read() override; + void insertAddress(const std::string& address) override; + RecentAddresses getList() const override; + +private: + void load(); + void save(); + + size_t maxListSize_; + RecentAddresses list_; + + static const std::string cConfigFileName; + static const std::string cRecentEntiresCount; + static const std::string cRecentEntryPrefix; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index fe654ca6..5395befc 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -1,8 +1,10 @@ #pragma once #include +#include #include #include +#include namespace Ui { class ConnectDialog; @@ -22,25 +24,31 @@ class ConnectDialog : public QDialog Q_OBJECT public: - explicit ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, QWidget *parent = nullptr); + explicit ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, openauto::autoapp::configuration::IRecentAddressesList& recentAddressesList, QWidget *parent = nullptr); ~ConnectDialog() override; signals: void connectToDevice(const QString& ipAddress); - void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, std::string ipAddress); void connectionFailed(const QString& message); private slots: void onConnectButtonClicked(); void onConnectionFailed(const QString& message); - void onConnectionSucceed(); + void onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, std::string ipAddress); void setControlsEnabledStatus(bool status); - void connectHandler(const boost::system::error_code& ec, aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void connectHandler(const boost::system::error_code& ec, std::string ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket); private: + void insertIpAddress(std::string ipAddress); + void loadRecentList(); + boost::asio::io_service& ioService_; aasdk::tcp::ITCPWrapper& tcpWrapper_; + openauto::autoapp::configuration::IRecentAddressesList& recentAddressesList_; Ui::ConnectDialog *ui_; + QStringListModel recentAddressesModel_; + QStringList recentAddressesModelList_; }; } diff --git a/src/autoapp/Configuration/RecentAddressesList.cpp b/src/autoapp/Configuration/RecentAddressesList.cpp new file mode 100644 index 00000000..7d8af3ec --- /dev/null +++ b/src/autoapp/Configuration/RecentAddressesList.cpp @@ -0,0 +1,106 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +const std::string RecentAddressesList::cConfigFileName = "openauto_wifi_recent.ini"; +const std::string RecentAddressesList::cRecentEntiresCount = "Recent.EntiresCount"; +const std::string RecentAddressesList::cRecentEntryPrefix = "Recent.Entry_"; + +RecentAddressesList::RecentAddressesList(size_t maxListSize) + : maxListSize_(maxListSize) +{ + +} + +void RecentAddressesList::read() +{ + this->load(); +} + +void RecentAddressesList::insertAddress(const std::string& address) +{ + list_.push_front(address); + this->save(); +} + +RecentAddressesList::RecentAddresses RecentAddressesList::getList() const +{ + return list_; +} + +void RecentAddressesList::load() +{ + boost::property_tree::ptree iniConfig; + + try + { + boost::property_tree::ini_parser::read_ini(cConfigFileName, iniConfig); + + const auto listSize = std::min(maxListSize_, iniConfig.get(cRecentEntiresCount, 0)); + + for(size_t i = 0; i < listSize; ++i) + { + const auto key = cRecentEntryPrefix + std::to_string(i); + const auto address = iniConfig.get(key, RecentAddresses::value_type()); + + if(!address.empty()) + { + list_.push_back(address); + } + } + } + catch(const boost::property_tree::ini_parser_error& e) + { + OPENAUTO_LOG(warning) << "[RecentAddressesList] failed to read configuration file: " << cConfigFileName + << ", error: " << e.what() + << ". Empty list will be used."; + } +} + +void RecentAddressesList::save() +{ + boost::property_tree::ptree iniConfig; + + const auto entiresCount = std::min(maxListSize_, list_.size()); + iniConfig.put(cRecentEntiresCount, entiresCount); + + for(size_t i = 0; i < entiresCount; ++i) + { + const auto key = cRecentEntryPrefix + std::to_string(i); + iniConfig.put(key, list_.at(i)); + } + + boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig); +} + +} +} +} +} diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index 69a2e02c..1a510cd6 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -11,10 +11,11 @@ namespace autoapp namespace ui { -ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, QWidget *parent) +ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, openauto::autoapp::configuration::IRecentAddressesList& recentAddressesList, QWidget *parent) : QDialog(parent) , ioService_(ioService) , tcpWrapper_(tcpWrapper) + , recentAddressesList_(recentAddressesList) , ui_(new Ui::ConnectDialog) { qRegisterMetaType("aasdk::tcp::ITCPEndpoint::SocketPointer"); @@ -24,6 +25,9 @@ ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITC connect(ui_->pushButtonConnect, &QPushButton::clicked, this, &ConnectDialog::onConnectButtonClicked); connect(this, &ConnectDialog::connectionSucceed, this, &ConnectDialog::onConnectionSucceed); connect(this, &ConnectDialog::connectionFailed, this, &ConnectDialog::onConnectionFailed); + + recentAddressesModel_.setStringList(recentAddressesModelList_); + ui_->listViewRecent->setModel(&recentAddressesModel_); } ConnectDialog::~ConnectDialog() @@ -40,7 +44,7 @@ void ConnectDialog::onConnectButtonClicked() try { - tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, std::bind(&ConnectDialog::connectHandler, this, std::placeholders::_1, socket)); + tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, std::bind(&ConnectDialog::connectHandler, this, std::placeholders::_1, ipAddress, socket)); } catch(const boost::system::system_error& se) { @@ -48,11 +52,11 @@ void ConnectDialog::onConnectButtonClicked() } } -void ConnectDialog::connectHandler(const boost::system::error_code& ec, aasdk::tcp::ITCPEndpoint::SocketPointer socket) +void ConnectDialog::connectHandler(const boost::system::error_code& ec, std::string ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket) { if(!ec) { - emit connectionSucceed(std::move(socket)); + emit connectionSucceed(std::move(socket), ipAddress); this->close(); } else @@ -61,8 +65,9 @@ void ConnectDialog::connectHandler(const boost::system::error_code& ec, aasdk::t } } -void ConnectDialog::onConnectionSucceed() +void ConnectDialog::onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer, std::string ipAddress) { + this->insertIpAddress(ipAddress); this->setControlsEnabledStatus(true); } @@ -83,6 +88,23 @@ void ConnectDialog::setControlsEnabledStatus(bool status) ui_->listViewRecent->setEnabled(status); } +void ConnectDialog::loadRecentList() +{ + recentAddressesModelList_.clear(); + const auto& configList = recentAddressesList_.getList(); + + for(const auto& element : configList) + { + recentAddressesModelList_.append(QString::fromStdString(element)); + } +} + +void ConnectDialog::insertIpAddress(std::string ipAddress) +{ + recentAddressesList_.insertAddress(ipAddress); + this->loadRecentList(); +} + } } } From f01f057b68720b806c63b186d04a1d8fd2c8374b Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 01:58:38 +0100 Subject: [PATCH 32/45] Load recent addresses list --- include/f1x/openauto/autoapp/UI/ConnectDialog.hpp | 11 +++++------ src/autoapp/UI/ConnectDialog.cpp | 15 +++++++++------ src/autoapp/autoapp.cpp | 6 +++++- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index 5395befc..dcb33263 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -29,26 +29,25 @@ class ConnectDialog : public QDialog signals: void connectToDevice(const QString& ipAddress); - void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, std::string ipAddress); + void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, const std::string& ipAddress); void connectionFailed(const QString& message); private slots: void onConnectButtonClicked(); void onConnectionFailed(const QString& message); - void onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, std::string ipAddress); - void setControlsEnabledStatus(bool status); - void connectHandler(const boost::system::error_code& ec, std::string ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, const std::string& ipAddress); private: - void insertIpAddress(std::string ipAddress); + void insertIpAddress(const std::string& ipAddress); void loadRecentList(); + void setControlsEnabledStatus(bool status); + void connectHandler(const boost::system::error_code& ec, const std::string& ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket); boost::asio::io_service& ioService_; aasdk::tcp::ITCPWrapper& tcpWrapper_; openauto::autoapp::configuration::IRecentAddressesList& recentAddressesList_; Ui::ConnectDialog *ui_; QStringListModel recentAddressesModel_; - QStringList recentAddressesModelList_; }; } diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index 1a510cd6..5e43c171 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -19,6 +19,7 @@ ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITC , ui_(new Ui::ConnectDialog) { qRegisterMetaType("aasdk::tcp::ITCPEndpoint::SocketPointer"); + qRegisterMetaType("std::string"); ui_->setupUi(this); connect(ui_->pushButtonCancel, &QPushButton::clicked, this, &ConnectDialog::close); @@ -26,8 +27,8 @@ ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITC connect(this, &ConnectDialog::connectionSucceed, this, &ConnectDialog::onConnectionSucceed); connect(this, &ConnectDialog::connectionFailed, this, &ConnectDialog::onConnectionFailed); - recentAddressesModel_.setStringList(recentAddressesModelList_); ui_->listViewRecent->setModel(&recentAddressesModel_); + this->loadRecentList(); } ConnectDialog::~ConnectDialog() @@ -52,7 +53,7 @@ void ConnectDialog::onConnectButtonClicked() } } -void ConnectDialog::connectHandler(const boost::system::error_code& ec, std::string ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket) +void ConnectDialog::connectHandler(const boost::system::error_code& ec, const std::string& ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket) { if(!ec) { @@ -65,7 +66,7 @@ void ConnectDialog::connectHandler(const boost::system::error_code& ec, std::str } } -void ConnectDialog::onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer, std::string ipAddress) +void ConnectDialog::onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer, const std::string& ipAddress) { this->insertIpAddress(ipAddress); this->setControlsEnabledStatus(true); @@ -90,16 +91,18 @@ void ConnectDialog::setControlsEnabledStatus(bool status) void ConnectDialog::loadRecentList() { - recentAddressesModelList_.clear(); + QStringList stringList; const auto& configList = recentAddressesList_.getList(); for(const auto& element : configList) { - recentAddressesModelList_.append(QString::fromStdString(element)); + stringList.append(QString::fromStdString(element)); } + + recentAddressesModel_.setStringList(stringList); } -void ConnectDialog::insertIpAddress(std::string ipAddress) +void ConnectDialog::insertIpAddress(const std::string& ipAddress) { recentAddressesList_.insertAddress(ipAddress); this->loadRecentList(); diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index 81fe3cd7..4d0d846d 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -90,8 +91,11 @@ int main(int argc, char* argv[]) autoapp::ui::SettingsWindow settingsWindow(configuration); settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + autoapp::configuration::RecentAddressesList recentAddressesList(5); + recentAddressesList.read(); + aasdk::tcp::TCPWrapper tcpWrapper; - autoapp::ui::ConnectDialog connectDialog(ioService, tcpWrapper); + autoapp::ui::ConnectDialog connectDialog(ioService, tcpWrapper, recentAddressesList); connectDialog.setWindowFlags(Qt::WindowStaysOnTopHint); QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); From 9db15b953e070d2ff7377b9d130e4cc64ce7659b Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 03:13:23 +0200 Subject: [PATCH 33/45] Implement selection of recent address --- include/f1x/openauto/autoapp/UI/ConnectDialog.hpp | 1 + src/autoapp/Configuration/RecentAddressesList.cpp | 7 +++++-- src/autoapp/UI/ConnectDialog.cpp | 11 +++++++++++ src/autoapp/UI/connectdialog.ui | 3 +++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index dcb33263..9e944aa7 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -36,6 +36,7 @@ private slots: void onConnectButtonClicked(); void onConnectionFailed(const QString& message); void onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, const std::string& ipAddress); + void onRecentAddressClicked(const QModelIndex& index); private: void insertIpAddress(const std::string& ipAddress); diff --git a/src/autoapp/Configuration/RecentAddressesList.cpp b/src/autoapp/Configuration/RecentAddressesList.cpp index 7d8af3ec..ebfa2d14 100644 --- a/src/autoapp/Configuration/RecentAddressesList.cpp +++ b/src/autoapp/Configuration/RecentAddressesList.cpp @@ -46,8 +46,11 @@ void RecentAddressesList::read() void RecentAddressesList::insertAddress(const std::string& address) { - list_.push_front(address); - this->save(); + if(std::find(list_.begin(), list_.end(), address) != list_.end()) + { + list_.push_front(address); + this->save(); + } } RecentAddressesList::RecentAddresses RecentAddressesList::getList() const diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index 5e43c171..127e2165 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -24,6 +24,7 @@ ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITC ui_->setupUi(this); connect(ui_->pushButtonCancel, &QPushButton::clicked, this, &ConnectDialog::close); connect(ui_->pushButtonConnect, &QPushButton::clicked, this, &ConnectDialog::onConnectButtonClicked); + connect(ui_->listViewRecent, &QListView::clicked, this, &ConnectDialog::onRecentAddressClicked); connect(this, &ConnectDialog::connectionSucceed, this, &ConnectDialog::onConnectionSucceed); connect(this, &ConnectDialog::connectionFailed, this, &ConnectDialog::onConnectionFailed); @@ -81,6 +82,16 @@ void ConnectDialog::onConnectionFailed(const QString& message) errorMessage.exec(); } +void ConnectDialog::onRecentAddressClicked(const QModelIndex& index) +{ + const auto& recentAddressesList = recentAddressesList_.getList(); + + if(static_cast(index.row()) <= recentAddressesList.size()) + { + ui_->lineEditIPAddress->setText(QString::fromStdString(recentAddressesList.at(index.row()))); + } +} + void ConnectDialog::setControlsEnabledStatus(bool status) { ui_->pushButtonConnect->setVisible(status); diff --git a/src/autoapp/UI/connectdialog.ui b/src/autoapp/UI/connectdialog.ui index a9adb5d8..445e962c 100644 --- a/src/autoapp/UI/connectdialog.ui +++ b/src/autoapp/UI/connectdialog.ui @@ -57,6 +57,9 @@ 141 + + QAbstractItemView::NoEditTriggers + From 9c529421227905da53870945357d344f39342f81 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 03:17:16 +0200 Subject: [PATCH 34/45] Fix condition of adding address to the recent list --- src/autoapp/Configuration/RecentAddressesList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/autoapp/Configuration/RecentAddressesList.cpp b/src/autoapp/Configuration/RecentAddressesList.cpp index ebfa2d14..3e192145 100644 --- a/src/autoapp/Configuration/RecentAddressesList.cpp +++ b/src/autoapp/Configuration/RecentAddressesList.cpp @@ -46,7 +46,7 @@ void RecentAddressesList::read() void RecentAddressesList::insertAddress(const std::string& address) { - if(std::find(list_.begin(), list_.end(), address) != list_.end()) + if(std::find(list_.begin(), list_.end(), address) == list_.end()) { list_.push_front(address); this->save(); From 50c2a437fa867a884a9a3a39ccfce27ce70d80ed Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 03:31:51 +0200 Subject: [PATCH 35/45] Replace last recent address with newer one --- src/autoapp/Configuration/RecentAddressesList.cpp | 13 ++++++++++--- src/autoapp/autoapp.cpp | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/autoapp/Configuration/RecentAddressesList.cpp b/src/autoapp/Configuration/RecentAddressesList.cpp index 3e192145..c29fdcf1 100644 --- a/src/autoapp/Configuration/RecentAddressesList.cpp +++ b/src/autoapp/Configuration/RecentAddressesList.cpp @@ -46,11 +46,18 @@ void RecentAddressesList::read() void RecentAddressesList::insertAddress(const std::string& address) { - if(std::find(list_.begin(), list_.end(), address) == list_.end()) + if(std::find(list_.begin(), list_.end(), address) != list_.end()) { - list_.push_front(address); - this->save(); + return; } + + if(list_.size() >= maxListSize_) + { + list_.pop_back(); + } + + list_.push_front(address); + this->save(); } RecentAddressesList::RecentAddresses RecentAddressesList::getList() const diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index 4d0d846d..8c2565c0 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -91,7 +91,7 @@ int main(int argc, char* argv[]) autoapp::ui::SettingsWindow settingsWindow(configuration); settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); - autoapp::configuration::RecentAddressesList recentAddressesList(5); + autoapp::configuration::RecentAddressesList recentAddressesList(7); recentAddressesList.read(); aasdk::tcp::TCPWrapper tcpWrapper; From 488d70c201bcd912a8c3570f2b391b5c47a974eb Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 04:42:32 +0200 Subject: [PATCH 36/45] Make audio output more realtime --- src/autoapp/Projection/RtAudioOutput.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp index 416b58be..e0d70371 100644 --- a/src/autoapp/Projection/RtAudioOutput.cpp +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -33,15 +33,9 @@ RtAudioOutput::RtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_ , sampleSize_(sampleSize) , sampleRate_(sampleRate) { - try - { - dac_ = std::make_unique(RtAudio::LINUX_PULSE); - } - catch(...) - { - // fallback - dac_ = std::make_unique(); - } + std::vector apis; + RtAudio::getCompiledApi(apis); + dac_ = std::find(apis.begin(), apis.end(), RtAudio::LINUX_PULSE) == apis.end() ? std::make_unique() : std::make_unique(RtAudio::LINUX_PULSE); } bool RtAudioOutput::open() @@ -57,9 +51,11 @@ bool RtAudioOutput::open() try { - uint32_t bufferFrames = 128; - dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this)); - + RtAudio::StreamOptions streamOptions; + streamOptions.numberOfBuffers = 1; + streamOptions.flags = RTAUDIO_MINIMIZE_LATENCY | RTAUDIO_SCHEDULE_REALTIME; + uint32_t bufferFrames = 64; + dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this), &streamOptions); return audioBuffer_.open(QIODevice::ReadWrite); } catch(const RtAudioError& e) From 18fa86b53290ba02706be7687d5c50f77af55fc3 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 11:45:47 +0200 Subject: [PATCH 37/45] Enable playback only when pcm data are available --- .../autoapp/Projection/RtAudioOutput.hpp | 1 + src/autoapp/Projection/RtAudioOutput.cpp | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp index f3d69d5f..4aae81b5 100644 --- a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp @@ -55,6 +55,7 @@ class RtAudioOutput: public IAudioOutput SequentialBuffer audioBuffer_; std::unique_ptr dac_; std::mutex mutex_; + bool playbackRequested_; }; } diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp index e0d70371..0da5cfb8 100644 --- a/src/autoapp/Projection/RtAudioOutput.cpp +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -32,6 +32,7 @@ RtAudioOutput::RtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_ : channelCount_(channelCount) , sampleSize_(sampleSize) , sampleRate_(sampleRate) + , playbackRequested_(false) { std::vector apis; RtAudio::getCompiledApi(apis); @@ -54,7 +55,7 @@ bool RtAudioOutput::open() RtAudio::StreamOptions streamOptions; streamOptions.numberOfBuffers = 1; streamOptions.flags = RTAUDIO_MINIMIZE_LATENCY | RTAUDIO_SCHEDULE_REALTIME; - uint32_t bufferFrames = 64; + uint32_t bufferFrames = 256; dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this), &streamOptions); return audioBuffer_.open(QIODevice::ReadWrite); } @@ -74,13 +75,10 @@ bool RtAudioOutput::open() void RtAudioOutput::write(const aasdk::common::DataConstBuffer& buffer) { audioBuffer_.write(reinterpret_cast(buffer.cdata), buffer.size); -} -void RtAudioOutput::start() -{ std::lock_guard lock(mutex_); - if(dac_->isStreamOpen() && !dac_->isStreamRunning()) + if(playbackRequested_ && dac_->isStreamOpen() && !dac_->isStreamRunning()) { try { @@ -91,6 +89,15 @@ void RtAudioOutput::start() OPENAUTO_LOG(error) << "[RtAudioOutput] Failed to start audio output, what: " << e.what(); } } + + playbackRequested_ = false; +} + +void RtAudioOutput::start() +{ + std::lock_guard lock(mutex_); + + playbackRequested_ = true; } void RtAudioOutput::stop() From f9692b76a1d23e26e9c7f5ac175f1cf2a3346c84 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 11:51:17 +0200 Subject: [PATCH 38/45] Revert last commit --- .../autoapp/Projection/RtAudioOutput.hpp | 1 - src/autoapp/Projection/RtAudioOutput.cpp | 17 +++++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp index 4aae81b5..f3d69d5f 100644 --- a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp @@ -55,7 +55,6 @@ class RtAudioOutput: public IAudioOutput SequentialBuffer audioBuffer_; std::unique_ptr dac_; std::mutex mutex_; - bool playbackRequested_; }; } diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp index 0da5cfb8..e0d70371 100644 --- a/src/autoapp/Projection/RtAudioOutput.cpp +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -32,7 +32,6 @@ RtAudioOutput::RtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_ : channelCount_(channelCount) , sampleSize_(sampleSize) , sampleRate_(sampleRate) - , playbackRequested_(false) { std::vector apis; RtAudio::getCompiledApi(apis); @@ -55,7 +54,7 @@ bool RtAudioOutput::open() RtAudio::StreamOptions streamOptions; streamOptions.numberOfBuffers = 1; streamOptions.flags = RTAUDIO_MINIMIZE_LATENCY | RTAUDIO_SCHEDULE_REALTIME; - uint32_t bufferFrames = 256; + uint32_t bufferFrames = 64; dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this), &streamOptions); return audioBuffer_.open(QIODevice::ReadWrite); } @@ -75,10 +74,13 @@ bool RtAudioOutput::open() void RtAudioOutput::write(const aasdk::common::DataConstBuffer& buffer) { audioBuffer_.write(reinterpret_cast(buffer.cdata), buffer.size); +} +void RtAudioOutput::start() +{ std::lock_guard lock(mutex_); - if(playbackRequested_ && dac_->isStreamOpen() && !dac_->isStreamRunning()) + if(dac_->isStreamOpen() && !dac_->isStreamRunning()) { try { @@ -89,15 +91,6 @@ void RtAudioOutput::write(const aasdk::common::DataConstBuffer& buffer) OPENAUTO_LOG(error) << "[RtAudioOutput] Failed to start audio output, what: " << e.what(); } } - - playbackRequested_ = false; -} - -void RtAudioOutput::start() -{ - std::lock_guard lock(mutex_); - - playbackRequested_ = true; } void RtAudioOutput::stop() From b550104e181c3f820bfa128f200f6fad43e78498 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 14:57:23 +0200 Subject: [PATCH 39/45] Revert to use pulse --- src/autoapp/Projection/RtAudioOutput.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp index e0d70371..a8a43ef2 100644 --- a/src/autoapp/Projection/RtAudioOutput.cpp +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -52,9 +52,8 @@ bool RtAudioOutput::open() try { RtAudio::StreamOptions streamOptions; - streamOptions.numberOfBuffers = 1; streamOptions.flags = RTAUDIO_MINIMIZE_LATENCY | RTAUDIO_SCHEDULE_REALTIME; - uint32_t bufferFrames = 64; + uint32_t bufferFrames = 256; dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this), &streamOptions); return audioBuffer_.open(QIODevice::ReadWrite); } From 00acf0ee3eebebb4f0ff8be28cd5722575445202 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 15:15:03 +0200 Subject: [PATCH 40/45] Use timestamp of audio output --- .../openauto/autoapp/Projection/IAudioOutput.hpp | 3 ++- .../openauto/autoapp/Projection/QtAudioOutput.hpp | 2 +- .../openauto/autoapp/Projection/RtAudioOutput.hpp | 2 +- src/autoapp/Projection/AudioService.cpp | 14 +++++++------- src/autoapp/Projection/QtAudioOutput.cpp | 2 +- src/autoapp/Projection/RtAudioOutput.cpp | 9 ++++++++- 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp index 383ad280..c41de312 100644 --- a/include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp @@ -19,6 +19,7 @@ #pragma once #include +#include #include namespace f1x @@ -39,7 +40,7 @@ class IAudioOutput virtual ~IAudioOutput() = default; virtual bool open() = 0; - virtual void write(const aasdk::common::DataConstBuffer& buffer) = 0; + virtual void write(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) = 0; virtual void start() = 0; virtual void stop() = 0; virtual void suspend() = 0; diff --git a/include/f1x/openauto/autoapp/Projection/QtAudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/QtAudioOutput.hpp index e026a917..742dbf8c 100644 --- a/include/f1x/openauto/autoapp/Projection/QtAudioOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/QtAudioOutput.hpp @@ -39,7 +39,7 @@ class QtAudioOutput: public QObject, public IAudioOutput public: QtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate); bool open() override; - void write(const aasdk::common::DataConstBuffer& buffer) override; + void write(aasdk::messenger::Timestamp::ValueType, const aasdk::common::DataConstBuffer& buffer) override; void start() override; void stop() override; void suspend() override; diff --git a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp index f3d69d5f..063d5b34 100644 --- a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp @@ -36,7 +36,7 @@ class RtAudioOutput: public IAudioOutput public: RtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate); bool open() override; - void write(const aasdk::common::DataConstBuffer& buffer) override; + void write(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) override; void start() override; void stop() override; void suspend() override; diff --git a/src/autoapp/Projection/AudioService.cpp b/src/autoapp/Projection/AudioService.cpp index d5d2da59..d09001fe 100644 --- a/src/autoapp/Projection/AudioService.cpp +++ b/src/autoapp/Projection/AudioService.cpp @@ -152,14 +152,9 @@ void AudioService::onAVChannelStopIndication(const aasdk::proto::messages::AVCha channel_->receive(this->shared_from_this()); } -void AudioService::onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType, const aasdk::common::DataConstBuffer& buffer) +void AudioService::onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) { - this->onAVMediaIndication(buffer); -} - -void AudioService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer) -{ - audioOutput_->write(buffer); + audioOutput_->write(timestamp, buffer); aasdk::proto::messages::AVMediaAckIndication indication; indication.set_session(session_); indication.set_value(1); @@ -170,6 +165,11 @@ void AudioService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buf channel_->receive(this->shared_from_this()); } +void AudioService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer) +{ + this->onAVMediaWithTimestampIndication(0, buffer); +} + void AudioService::onChannelError(const aasdk::error::Error& e) { OPENAUTO_LOG(error) << "[AudioService] channel error: " << e.what() diff --git a/src/autoapp/Projection/QtAudioOutput.cpp b/src/autoapp/Projection/QtAudioOutput.cpp index 959ca1fa..dff8049e 100644 --- a/src/autoapp/Projection/QtAudioOutput.cpp +++ b/src/autoapp/Projection/QtAudioOutput.cpp @@ -58,7 +58,7 @@ bool QtAudioOutput::open() return audioBuffer_.open(QIODevice::ReadWrite); } -void QtAudioOutput::write(const aasdk::common::DataConstBuffer& buffer) +void QtAudioOutput::write(aasdk::messenger::Timestamp::ValueType, const aasdk::common::DataConstBuffer& buffer) { audioBuffer_.write(reinterpret_cast(buffer.cdata), buffer.size); } diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp index a8a43ef2..b03ef595 100644 --- a/src/autoapp/Projection/RtAudioOutput.cpp +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -70,9 +70,16 @@ bool RtAudioOutput::open() return false; } -void RtAudioOutput::write(const aasdk::common::DataConstBuffer& buffer) +void RtAudioOutput::write(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) { audioBuffer_.write(reinterpret_cast(buffer.cdata), buffer.size); + + std::lock_guard lock(mutex_); + + if(dac_->isStreamOpen()) + { + dac_->setStreamTime(timestamp / 1000000); + } } void RtAudioOutput::start() From b0bb0c7b4fab0442251ebcd88d549114c26046f4 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 16:05:25 +0200 Subject: [PATCH 41/45] Remove stream options usage --- src/autoapp/Projection/RtAudioOutput.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp index b03ef595..eb054205 100644 --- a/src/autoapp/Projection/RtAudioOutput.cpp +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -51,10 +51,8 @@ bool RtAudioOutput::open() try { - RtAudio::StreamOptions streamOptions; - streamOptions.flags = RTAUDIO_MINIMIZE_LATENCY | RTAUDIO_SCHEDULE_REALTIME; - uint32_t bufferFrames = 256; - dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this), &streamOptions); + uint32_t bufferFrames = 128; + dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this), nullptr); return audioBuffer_.open(QIODevice::ReadWrite); } catch(const RtAudioError& e) @@ -73,13 +71,6 @@ bool RtAudioOutput::open() void RtAudioOutput::write(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) { audioBuffer_.write(reinterpret_cast(buffer.cdata), buffer.size); - - std::lock_guard lock(mutex_); - - if(dac_->isStreamOpen()) - { - dac_->setStreamTime(timestamp / 1000000); - } } void RtAudioOutput::start() From 4d5327776309694b9480ddfb87ed5186015cefe7 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 17:30:57 +0200 Subject: [PATCH 42/45] Add settings for selection of audio output backend --- .../Configuration/AudioOutputBackendType.hpp | 39 +++++++++++++++ .../autoapp/Configuration/Configuration.hpp | 4 ++ .../autoapp/Configuration/IConfiguration.hpp | 3 ++ .../autoapp/Projection/ServiceFactory.hpp | 1 + src/autoapp/Configuration/Configuration.cpp | 14 ++++++ src/autoapp/Projection/ServiceFactory.cpp | 47 +++++++++++-------- src/autoapp/UI/SettingsWindow.cpp | 5 ++ src/autoapp/UI/settingswindow.ui | 41 ++++++++++++++++ 8 files changed, 135 insertions(+), 19 deletions(-) create mode 100644 include/f1x/openauto/autoapp/Configuration/AudioOutputBackendType.hpp diff --git a/include/f1x/openauto/autoapp/Configuration/AudioOutputBackendType.hpp b/include/f1x/openauto/autoapp/Configuration/AudioOutputBackendType.hpp new file mode 100644 index 00000000..e954874a --- /dev/null +++ b/include/f1x/openauto/autoapp/Configuration/AudioOutputBackendType.hpp @@ -0,0 +1,39 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +enum class AudioOutputBackendType +{ + RTAUDIO, + QT +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Configuration/Configuration.hpp b/include/f1x/openauto/autoapp/Configuration/Configuration.hpp index 93d44b33..f4a0649c 100644 --- a/include/f1x/openauto/autoapp/Configuration/Configuration.hpp +++ b/include/f1x/openauto/autoapp/Configuration/Configuration.hpp @@ -69,6 +69,8 @@ class Configuration: public IConfiguration void setMusicAudioChannelEnabled(bool value) override; bool speechAudioChannelEnabled() const override; void setSpeechAudioChannelEnabled(bool value) override; + AudioOutputBackendType getAudioOutputBackendType() const override; + void setAudioOutputBackendType(AudioOutputBackendType value) override; private: void readButtonCodes(boost::property_tree::ptree& iniConfig); @@ -88,6 +90,7 @@ class Configuration: public IConfiguration std::string bluetoothRemoteAdapterAddress_; bool musicAudioChannelEnabled_; bool speechAudiochannelEnabled_; + AudioOutputBackendType audioOutputBackendType_; static const std::string cConfigFileName; @@ -103,6 +106,7 @@ class Configuration: public IConfiguration static const std::string cAudioMusicAudioChannelEnabled; static const std::string cAudioSpeechAudioChannelEnabled; + static const std::string cAudioOutputBackendType; static const std::string cBluetoothAdapterTypeKey; static const std::string cBluetoothRemoteAdapterAddressKey; diff --git a/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp b/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp index 2f086cd9..2165a688 100644 --- a/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp +++ b/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace f1x { @@ -77,6 +78,8 @@ class IConfiguration virtual void setMusicAudioChannelEnabled(bool value) = 0; virtual bool speechAudioChannelEnabled() const = 0; virtual void setSpeechAudioChannelEnabled(bool value) = 0; + virtual AudioOutputBackendType getAudioOutputBackendType() const = 0; + virtual void setAudioOutputBackendType(AudioOutputBackendType value) = 0; }; } diff --git a/include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp b/include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp index 0d929b66..f7fdbd20 100644 --- a/include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp +++ b/include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp @@ -40,6 +40,7 @@ class ServiceFactory: public IServiceFactory IService::Pointer createVideoService(aasdk::messenger::IMessenger::Pointer messenger); IService::Pointer createBluetoothService(aasdk::messenger::IMessenger::Pointer messenger); IService::Pointer createInputService(aasdk::messenger::IMessenger::Pointer messenger); + void createAudioServices(ServiceList& serviceList, aasdk::messenger::IMessenger::Pointer messenger); boost::asio::io_service& ioService_; configuration::IConfiguration::Pointer configuration_; diff --git a/src/autoapp/Configuration/Configuration.cpp b/src/autoapp/Configuration/Configuration.cpp index 72e51e16..0e79129b 100644 --- a/src/autoapp/Configuration/Configuration.cpp +++ b/src/autoapp/Configuration/Configuration.cpp @@ -42,6 +42,7 @@ const std::string Configuration::cVideoMarginHeight = "Video.MarginHeight"; const std::string Configuration::cAudioMusicAudioChannelEnabled = "Audio.MusicAudioChannelEnabled"; const std::string Configuration::cAudioSpeechAudioChannelEnabled = "Audio.SpeechAudioChannelEnabled"; +const std::string Configuration::cAudioOutputBackendType = "Audio.OutputBackendType"; const std::string Configuration::cBluetoothAdapterTypeKey = "Bluetooth.AdapterType"; const std::string Configuration::cBluetoothRemoteAdapterAddressKey = "Bluetooth.RemoteAdapterAddress"; @@ -101,6 +102,7 @@ void Configuration::load() musicAudioChannelEnabled_ = iniConfig.get(cAudioMusicAudioChannelEnabled, true); speechAudiochannelEnabled_ = iniConfig.get(cAudioSpeechAudioChannelEnabled, true); + audioOutputBackendType_ = static_cast(iniConfig.get(cAudioOutputBackendType, static_cast(AudioOutputBackendType::RTAUDIO))); } catch(const boost::property_tree::ini_parser_error& e) { @@ -126,6 +128,7 @@ void Configuration::reset() bluetoothRemoteAdapterAddress_ = ""; musicAudioChannelEnabled_ = true; speechAudiochannelEnabled_ = true; + audioOutputBackendType_ = AudioOutputBackendType::RTAUDIO; } void Configuration::save() @@ -149,6 +152,7 @@ void Configuration::save() iniConfig.put(cAudioMusicAudioChannelEnabled, musicAudioChannelEnabled_); iniConfig.put(cAudioSpeechAudioChannelEnabled, speechAudiochannelEnabled_); + iniConfig.put(cAudioOutputBackendType, static_cast(audioOutputBackendType_)); boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig); } @@ -282,6 +286,16 @@ void Configuration::setSpeechAudioChannelEnabled(bool value) speechAudiochannelEnabled_ = value; } +AudioOutputBackendType Configuration::getAudioOutputBackendType() const +{ + return audioOutputBackendType_; +} + +void Configuration::setAudioOutputBackendType(AudioOutputBackendType value) +{ + audioOutputBackendType_ = value; +} + void Configuration::readButtonCodes(boost::property_tree::ptree& iniConfig) { this->insertButtonCode(iniConfig, cInputPlayButtonKey, aasdk::proto::enums::ButtonCode::PLAY); diff --git a/src/autoapp/Projection/ServiceFactory.cpp b/src/autoapp/Projection/ServiceFactory.cpp index 82ede87a..d10ddff6 100644 --- a/src/autoapp/Projection/ServiceFactory.cpp +++ b/src/autoapp/Projection/ServiceFactory.cpp @@ -62,25 +62,7 @@ ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messeng IAudioInput::Pointer audioInput(new QtAudioInput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(audioInput))); - - if(configuration_->musicAudioChannelEnabled()) - { - //IAudioOutput::Pointer mediaAudioOutput(new QtAudioOutput(2, 16, 48000), std::bind(&QObject::deleteLater, std::placeholders::_1)); - auto mediaAudioOutput(std::make_shared(2, 16, 48000)); - serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(mediaAudioOutput))); - } - - if(configuration_->speechAudioChannelEnabled()) - { - //IAudioOutput::Pointer speechAudioOutput(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); - auto speechAudioOutput(std::make_shared(1, 16, 16000)); - serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(speechAudioOutput))); - } - - //IAudioOutput::Pointer systemAudioOutput(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); - auto systemAudioOutput(std::make_shared(1, 16, 16000)); - serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(systemAudioOutput))); - + this->createAudioServices(serviceList, messenger); serviceList.emplace_back(std::make_shared(ioService_, messenger)); serviceList.emplace_back(this->createVideoService(messenger)); serviceList.emplace_back(this->createBluetoothService(messenger)); @@ -145,6 +127,33 @@ IService::Pointer ServiceFactory::createInputService(aasdk::messenger::IMessenge return std::make_shared(ioService_, messenger, std::move(inputDevice)); } +void ServiceFactory::createAudioServices(ServiceList& serviceList, aasdk::messenger::IMessenger::Pointer messenger) +{ + if(configuration_->musicAudioChannelEnabled()) + { + auto mediaAudioOutput = configuration_->getAudioOutputBackendType() == configuration::AudioOutputBackendType::RTAUDIO ? + std::make_shared(2, 16, 48000) : + IAudioOutput::Pointer(new QtAudioOutput(2, 16, 48000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + + serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(mediaAudioOutput))); + } + + if(configuration_->speechAudioChannelEnabled()) + { + auto speechAudioOutput = configuration_->getAudioOutputBackendType() == configuration::AudioOutputBackendType::RTAUDIO ? + std::make_shared(1, 16, 16000) : + IAudioOutput::Pointer(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + + serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(speechAudioOutput))); + } + + auto systemAudioOutput = configuration_->getAudioOutputBackendType() == configuration::AudioOutputBackendType::RTAUDIO ? + std::make_shared(1, 16, 16000) : + IAudioOutput::Pointer(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); + + serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(systemAudioOutput))); +} + } } } diff --git a/src/autoapp/UI/SettingsWindow.cpp b/src/autoapp/UI/SettingsWindow.cpp index 3117cf3f..5f64b3e8 100644 --- a/src/autoapp/UI/SettingsWindow.cpp +++ b/src/autoapp/UI/SettingsWindow.cpp @@ -97,6 +97,7 @@ void SettingsWindow::onSave() configuration_->setMusicAudioChannelEnabled(ui_->checkBoxMusicAudioChannel->isChecked()); configuration_->setSpeechAudioChannelEnabled(ui_->checkBoxSpeechAudioChannel->isChecked()); + configuration_->setAudioOutputBackendType(ui_->radioButtonRtAudio->isChecked() ? configuration::AudioOutputBackendType::RTAUDIO : configuration::AudioOutputBackendType::QT); configuration_->save(); this->close(); @@ -149,6 +150,10 @@ void SettingsWindow::load() ui_->checkBoxMusicAudioChannel->setChecked(configuration_->musicAudioChannelEnabled()); ui_->checkBoxSpeechAudioChannel->setChecked(configuration_->speechAudioChannelEnabled()); + + const auto& audioOutputBackendType = configuration_->getAudioOutputBackendType(); + ui_->radioButtonRtAudio->setChecked(audioOutputBackendType == configuration::AudioOutputBackendType::RTAUDIO); + ui_->radioButtonQtAudio->setChecked(audioOutputBackendType == configuration::AudioOutputBackendType::QT); } void SettingsWindow::loadButtonCheckBoxes() diff --git a/src/autoapp/UI/settingswindow.ui b/src/autoapp/UI/settingswindow.ui index b066a78e..40284871 100644 --- a/src/autoapp/UI/settingswindow.ui +++ b/src/autoapp/UI/settingswindow.ui @@ -486,6 +486,45 @@ color: rgb(238, 238, 236); + + + + 0 + 130 + 621 + 61 + + + + Output backend + + + + + 10 + 30 + 112 + 23 + + + + RT audio + + + + + + 140 + 30 + 112 + 23 + + + + Qt + + + @@ -969,6 +1008,8 @@ color: rgb(238, 238, 236); horizontalSliderScreenDPI checkBoxMusicAudioChannel checkBoxSpeechAudioChannel + radioButtonRtAudio + radioButtonQtAudio checkBoxEnableTouchscreen listWidgetButtons checkBoxPlayButton From f32b01014f3eb1ca27ce2e0b2787c52afc258a4e Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Wed, 28 Mar 2018 17:01:26 +0200 Subject: [PATCH 43/45] Use specialized erase_begin to remove read data from sequential buffer --- src/autoapp/Projection/SequentialBuffer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/autoapp/Projection/SequentialBuffer.cpp b/src/autoapp/Projection/SequentialBuffer.cpp index bd90a453..a0a5632a 100644 --- a/src/autoapp/Projection/SequentialBuffer.cpp +++ b/src/autoapp/Projection/SequentialBuffer.cpp @@ -55,7 +55,8 @@ qint64 SequentialBuffer::readData(char *data, qint64 maxlen) const auto len = std::min(maxlen, data_.size()); std::copy(data_.begin(), data_.begin() + len, data); - data_.erase(data_.begin(), data_.begin() + len); + data_.erase_begin(len); + return len; } From 75297a84d72d1430b4410fc5c40fb82eae742051 Mon Sep 17 00:00:00 2001 From: Michal Szwaj Date: Wed, 28 Mar 2018 23:47:59 +0200 Subject: [PATCH 44/45] Update Readme.md --- Readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Readme.md b/Readme.md index fa433954..2deb2ebb 100644 --- a/Readme.md +++ b/Readme.md @@ -22,6 +22,8 @@ OpenAuto is an AndroidAuto(tm) headunit emulator based on aasdk library and Qt l - Touchscreen and buttons input - Bluetooth - Automatic launch after device hotplug + - Automatic detection of connected Android devices + - Wireless (WiFi) mode via head unit server (must be enabled in hidden developer settings) - User-friendly settings ### Supported platforms From 2c8daca961649730833146a414bab442c2a3945f Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sat, 31 Mar 2018 14:22:12 +0200 Subject: [PATCH 45/45] Adjust audio device buffer size --- src/autoapp/Projection/RtAudioOutput.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp index eb054205..139cd51a 100644 --- a/src/autoapp/Projection/RtAudioOutput.cpp +++ b/src/autoapp/Projection/RtAudioOutput.cpp @@ -51,8 +51,10 @@ bool RtAudioOutput::open() try { - uint32_t bufferFrames = 128; - dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this), nullptr); + RtAudio::StreamOptions streamOptions; + streamOptions.flags = RTAUDIO_MINIMIZE_LATENCY | RTAUDIO_SCHEDULE_REALTIME; + uint32_t bufferFrames = sampleRate_ == 16000 ? 1024 : 2048; //according to the observation of audio packets + dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this), &streamOptions); return audioBuffer_.open(QIODevice::ReadWrite); } catch(const RtAudioError& e) @@ -104,8 +106,7 @@ void RtAudioOutput::stop() void RtAudioOutput::suspend() { - std::lock_guard lock(mutex_); - this->doSuspend(); + //not needed } uint32_t RtAudioOutput::getSampleSize() const @@ -125,7 +126,7 @@ uint32_t RtAudioOutput::getSampleRate() const void RtAudioOutput::doSuspend() { - if(!dac_->isStreamOpen() && !dac_->isStreamRunning()) + if(dac_->isStreamOpen() && dac_->isStreamRunning()) { try {