Skip to content

Commit

Permalink
Merge pull request robotology#2987 from randaz81/yarpaudiocontrolgui
Browse files Browse the repository at this point in the history
yarpaudiocontrolgui
  • Loading branch information
randaz81 authored Jul 8, 2023
2 parents 0109a47 + edb6b7a commit ab76c06
Show file tree
Hide file tree
Showing 5 changed files with 286 additions and 0 deletions.
4 changes: 4 additions & 0 deletions cmake/YarpFindDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,10 @@ yarp_dependent_option(
YARP_COMPILE_yarpbatterygui "Do you want to compile yarpbatterygui?" ON
"YARP_COMPILE_EXECUTABLES;YARP_COMPILE_GUIS;YARP_HAS_Qt5" OFF
)
yarp_dependent_option(
YARP_COMPILE_yarpaudiocontrolgui "Do you want to compile yarpaudiocontrolgui?" ON
"YARP_COMPILE_EXECUTABLES;YARP_COMPILE_GUIS;YARP_HAS_Qt5" OFF
)
yarp_dependent_option(
YARP_COMPILE_yarpmobilebasegui "Do you want to compile yarpmobilebasegui?" ON
"YARP_COMPILE_EXECUTABLES;YARP_COMPILE_GUIS;YARP_HAS_Qt5" OFF
Expand Down
8 changes: 8 additions & 0 deletions doc/release/yarp_3_9_master/yarpaudiocontrolgui.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
yarpaudiocontrolgui {#master}
-------------------

### gui

#### `yarpaudiocontrolgui`

Added new gui `yarpaudiocontrolgui` to start/stop an `audioRecorder_nwc_yarp` or an `audioPlayer_nwc_yarp` device
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ if(YARP_COMPILE_EXECUTABLES)
add_subdirectory(yarpmobilebasegui)
add_subdirectory(yarplaserscannergui)
add_subdirectory(yarpviz)
add_subdirectory(yarpaudiocontrolgui)
endif()

# Robot Testing Framework addons
Expand Down
55 changes: 55 additions & 0 deletions src/yarpaudiocontrolgui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT)
# SPDX-License-Identifier: BSD-3-Clause

if(YARP_COMPILE_yarpaudiocontrolgui)

include(YarpUseQt5)
include(YarpMacOSUtilities)

add_executable(yarpaudiocontrolgui WIN32)

set(gui_SRCS
main.cpp
)
source_group(
TREE "${CMAKE_CURRENT_SOURCE_DIR}"
PREFIX "Source Files"
FILES ${gui_SRCS}
)

target_sources(yarpaudiocontrolgui
PRIVATE
${gui_SRCS}
)

target_include_directories(yarpaudiocontrolgui
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}"
)

target_link_libraries(yarpaudiocontrolgui
PRIVATE
YARP::YARP_os
YARP::YARP_init
YARP::YARP_sig
YARP::YARP_dev
Qt5::Widgets
Qt5::Gui
)

install(
TARGETS yarpaudiocontrolgui
COMPONENT utilities
DESTINATION ${CMAKE_INSTALL_BINDIR}
)

set_property(TARGET yarpaudiocontrolgui PROPERTY FOLDER "Graphical User Interfaces")

yarp_macos_duplicate_and_add_bundle(
TARGET yarpaudiocontrolgui
INSTALL_COMPONENT utilities
INSTALL_DESTINATION "${CMAKE_INSTALL_BINDIR}"
)

endif()
218 changes: 218 additions & 0 deletions src/yarpaudiocontrolgui/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
/*
* SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT)
* SPDX-License-Identifier: BSD-3-Clause
*/

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QHBoxLayout>
#include <QLabel>
#include <QThread>
#include <QVBoxLayout>

#include <yarp/os/Os.h>
#include <yarp/os/Log.h>
#include <yarp/os/LogStream.h>
#include <yarp/os/Network.h>
#include <yarp/os/RFModule.h>
#include <yarp/os/Property.h>
#include <yarp/os/Thread.h>
#include <yarp/dev/PolyDriver.h>
#include <yarp/dev/AudioGrabberInterfaces.h>

#ifdef _WIN32
#include <Windows.h>
#endif

#include <iostream>

class CustomWidget : public QWidget, public yarp::os::Thread
{
Q_OBJECT
private:
QPushButton* startButton = nullptr;
QPushButton* stopButton = nullptr;
QVBoxLayout* vlayout = nullptr;
QHBoxLayout* hlayout = nullptr;
QLabel* label = nullptr;

public:
virtual ~CustomWidget ()
{
this->stop();
hlayout->removeWidget(startButton);
hlayout->removeWidget(stopButton);
if (startButton) { delete startButton; startButton = nullptr;}
if (stopButton) { delete stopButton; stopButton = nullptr;}
vlayout->removeWidget(label);
if (label) { delete label; label = nullptr; }
vlayout->removeItem(hlayout);
if (vlayout) { delete vlayout; vlayout = nullptr;}
if (hlayout) {delete hlayout; hlayout = nullptr;}
}

CustomWidget(QWidget *parent = nullptr) : QWidget(parent)
{
startButton = new QPushButton("Start", this);
stopButton = new QPushButton("Stop", this);
vlayout = new QVBoxLayout;
hlayout = new QHBoxLayout;
label = new QLabel("Device status: - - -");
hlayout->addWidget(startButton);
hlayout->addWidget(stopButton);
vlayout->addLayout(hlayout);
vlayout->addWidget(label);
setLayout(vlayout);

connect(startButton, &QPushButton::clicked, this, &CustomWidget::startFunction);
connect(stopButton, &QPushButton::clicked, this, &CustomWidget::stopFunction);
}

void run() override
{
while(!isStopping())
{
if (m_iAudioRec)
{
bool enabled;
m_iAudioRec->isRecording(enabled);
if (enabled) label->setText("Device status : recording");
else label->setText("Device status : idle");
}
if (m_iAudioPlay)
{
bool enabled;
m_iAudioPlay->isPlaying(enabled);
if (enabled) label->setText("Device status : playing");
else label->setText("Device status : idle");
}
yarp::os::Time::delay(1);
}
}

public slots:
void startFunction()
{
if (m_iAudioRec) { m_iAudioRec->startRecording(); }
if (m_iAudioPlay) { m_iAudioPlay->startPlayback(); }
}

void stopFunction()
{
if (m_iAudioRec) { m_iAudioRec->stopRecording(); }
if (m_iAudioPlay) { m_iAudioPlay->stopPlayback(); }
}

public:
void setInterface(yarp::dev::IAudioGrabberSound* audio_rec_interface, yarp::dev::IAudioRender* audio_play_interface)
{
m_iAudioRec = audio_rec_interface;
m_iAudioPlay = audio_play_interface;
this->start();
}

private:
yarp::dev::IAudioGrabberSound* m_iAudioRec = nullptr;
yarp::dev::IAudioRender* m_iAudioPlay = nullptr;
};

#define ERROR_RETURN_CODE 0
int main(int argc, char *argv[])
{
//console output on windows
#ifdef _WIN32
AllocConsole();
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
#endif

// Yarp initialization
yarp::os::Network yarp(yarp::os::YARP_CLOCK_SYSTEM);
if (!yarp.checkNetwork())
{
yError("Error initializing yarp network (is yarpserver running?)");
return ERROR_RETURN_CODE;
}
yarp::os::ResourceFinder rf;
rf.configure(argc, argv);

//check parameters
if (rf.check("help"))
{
yInfo() << "yarpaudiocontrolgui accepts the following options:";
yInfo() << "--local <portname> an optional parameter which defines the name of the local port. Default is /yarpaudiocontrolgui. Multiple yarpaudiocontrolgui must use different local names.";
yInfo() << "--remote-rec <portname> an optional parameter which defines the name of the rpc port of a audioRecorder_nws_yarp device.";
yInfo() << "--remote-play <portname> an optional parameter which defines the name of the rpc port of a audioPlayer_nws_yarp device.";
yInfo() << "NOTE: remote-rec and remote-play options are mutually exclusive.";
return 0;
}

std::string local = rf.find("local").asString();
std::string remote_rec = rf.find("remote-rec").asString();
std::string remote_play = rf.find("remote-play").asString();
if (local.empty()) { local = "/yarpaudiocontrolgui"; }
if (remote_play.empty() && remote_rec.empty())
{
yError() << "Please choose at least a recorder or a player device. Use --help for list of options.";
return ERROR_RETURN_CODE;
}
if (!remote_play.empty() && !remote_rec.empty())
{
yError() << "Please choose either a recorder or a player device, not both. remote-rec and remote-play options are mutually exclusive.";
return ERROR_RETURN_CODE;
}

//yarp audio client instance
yarp::dev::IAudioGrabberSound* iAudioRec = nullptr;
yarp::dev::IAudioRender* iAudioPlay = nullptr;
yarp::dev::PolyDriver ddPlay;
yarp::dev::PolyDriver ddRec;

if (!remote_play.empty())
{
yarp::os::Property p_cfgPlay;
p_cfgPlay.put("device", "audioPlayer_nwc_yarp");
p_cfgPlay.put("remote", remote_play);
p_cfgPlay.put("local", local);
ddPlay.open(p_cfgPlay);
ddPlay.view(iAudioPlay);
if (iAudioPlay == nullptr)
{
yError()<<"Failed to open audioPlayerInterface";
return ERROR_RETURN_CODE;
}
}
if (!remote_rec.empty())
{
yarp::os::Property p_cfgRec;
p_cfgRec.put("device", "audioRecorder_nwc_yarp");
p_cfgRec.put("remote", remote_rec);
p_cfgRec.put("local", local);
ddRec.open(p_cfgRec);
ddRec.view(iAudioRec);
if (iAudioRec == nullptr)
{
yError() << "Failed to open audioRecorderInterface";
return ERROR_RETURN_CODE;
}
}

//qt initialization
QApplication app(argc, argv);
CustomWidget* widget = new CustomWidget;
widget->setInterface(iAudioRec, iAudioPlay);
widget->setMinimumWidth(400);
widget->show();
int r = app.exec();

//clean up
if (widget) {delete widget; widget = nullptr;}
ddRec.close();
ddPlay.close();

yInfo() << "yarpaudiocontrolgui says goodbye!";
return r;
}

#include "main.moc"

0 comments on commit ab76c06

Please sign in to comment.