YARP
Yet Another Robot Platform
ServerSoundGrabber.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006 Julio Gomes
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #include "ServerSoundGrabber.h"
11 
12 #include <yarp/os/Bottle.h>
13 #include <yarp/os/LogComponent.h>
14 #include <yarp/os/LogStream.h>
15 #include <yarp/os/Time.h>
16 #include <yarp/os/Vocab.h>
17 
18 #include <yarp/dev/GenericVocabs.h>
19 
20 
21 namespace {
22 YARP_LOG_COMPONENT(SERVERSOUNDGRABBER, "yarp.device.ServerSoundGrabber")
23 }
24 
26 #ifdef DEBUG_TIME_SPENT
27  : last_time(yarp::os::Time::now())
28 #endif
29 {
30 }
31 
33 {
34  if (mic != nullptr) {
35  close();
36  }
37 }
38 
50 {
51  yarp::os::Value* name;
52  if (config.check("subdevice", name)) {
53  yCDebug(SERVERSOUNDGRABBER, "Subdevice %s", name->toString().c_str());
54  if (name->isString()) {
55  // maybe user isn't doing nested configuration
57  p.fromString(config.toString());
58  p.put("device", name->toString());
59  poly.open(p);
60  } else {
61  poly.open(*name);
62  }
63  } else {
64  yCError(SERVERSOUNDGRABBER, "\"--subdevice <name>\" not set for server_soundgrabber");
65  return false;
66  }
67 
68  if (poly.isValid()) {
69  poly.view(mic);
70  } else {
71  yCError(SERVERSOUNDGRABBER, "cannot make <%s>", name->toString().c_str());
72  return false;
73  }
74 
75  if (mic == nullptr) {
76  yCError(SERVERSOUNDGRABBER, "failed to open interface");
77  return false;
78  }
79 
80  //set the streaming port
81  std::string portname = "/sound_grabber";
82  if (config.check("name", name)) {
83  portname = name->asString();
84  }
85  if (streamingPort.open(portname) == false) {
86  yCError(SERVERSOUNDGRABBER) << "Unable to open port" << portname;
87  return false;
88  }
89 
90  //set the RPC port
91  if (rpcPort.open(portname + "/rpc") == false) {
92  yCError(SERVERSOUNDGRABBER) << "Unable to open port" << portname + "/rpc";
93  return false;
94  }
95  rpcPort.setReader(*this);
96 
97  //wait a little and then start
99 
100  //mic->startRecording();
101  this->start();
102 
103  return true;
104 }
105 
107 {
108  if (mic != nullptr) {
109  stop();
110  mic = nullptr;
111 
112  streamingPort.interrupt();
113  streamingPort.close();
114  rpcPort.interrupt();
115  rpcPort.close();
116 
117  return true;
118  }
119  return false;
120 }
121 
123 {
124  while (!isStopping()) {
125 #ifdef DEBUG_TIME_SPENT
126  double current_time = yarp::os::Time::now();
127  yCDebug(SERVERSOUNDGRABBER) << current_time - last_time;
128  last_time = current_time;
129 #endif
130 
131  if (mic != nullptr) {
132  yarp::sig::Sound snd;
133 #ifdef PRINT_DEBUG_MESSAGES
134  {
135  audio_buffer_size buf_max;
136  audio_buffer_size buf_cur;
137  mic->getRecordingAudioBufferMaxSize(buf_max);
139  yCDebug(SERVERSOUNDGRABBER) << "BEFORE Buffer status:" << buf_cur.getBytes() << "/" << buf_max.getBytes() << "bytes";
140  }
141 #endif
142  mic->getSound(snd, 44100, 44100, 0.0);
143 #ifdef PRINT_DEBUG_MESSAGES
144  {
145  audio_buffer_size buf_max;
146  audio_buffer_size buf_cur;
147  mic->getRecordingAudioBufferMaxSize(buf_max);
149  yCDebug(SERVERSOUNDGRABBER) << "AFTER Buffer status:" << buf_cur.getBytes() << "/" << buf_max.getBytes() << "bytes";
150  }
151 #endif
152 #ifdef PRINT_DEBUG_MESSAGES
153  yCDebug(SERVERSOUNDGRABBER) << "Sound size:" << snd.getSamples() * snd.getChannels() * snd.getBytesPerSample() << " bytes";
154  yCDebug(SERVERSOUNDGRABBER);
155 #endif
156  stamp.update();
157  streamingPort.setEnvelope(stamp);
158  streamingPort.write(snd);
159  }
160  }
161  yCInfo(SERVERSOUNDGRABBER, "Sound grabber stopping");
162 }
163 
165 {
166  yarp::os::Bottle command;
167  yarp::os::Bottle reply;
168  bool ok = command.read(connection);
169  if (!ok)
170  return false;
171  reply.clear();
172 
173  if (command.get(0).asString() == "start") {
174  mic->startRecording();
175  reply.addVocab(VOCAB_OK);
176  } else if (command.get(0).asString() == "stop") {
177  mic->stopRecording();
178  reply.addVocab(VOCAB_OK);
179  } else if (command.get(0).asString() == "help") {
180  reply.addVocab(yarp::os::Vocab::encode("many"));
181  reply.addString("start");
182  reply.addString("stop");
183  } else {
184  yCError(SERVERSOUNDGRABBER) << "Invalid command";
185  reply.addVocab(VOCAB_ERR);
186  }
187 
188  yarp::os::ConnectionWriter* returnToSender = connection.getWriter();
189  if (returnToSender != nullptr) {
190  reply.write(*returnToSender);
191  }
192  return true;
193 }
yarp::os::Port::close
void close() override
Stop port activity.
Definition: Port.cpp:357
LogStream.h
yarp::os::Bottle
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
yarp::os::Property::put
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition: Property.cpp:998
yarp::os::Bottle::clear
void clear()
Empties the bottle of any objects it contains.
Definition: Bottle.cpp:124
yarp::os::Searchable
A base class for nested structures that can be searched.
Definition: Searchable.h:69
ServerSoundGrabber::close
bool close() override
Close the DeviceDriver.
Definition: ServerSoundGrabber.cpp:106
yarp::sig::Sound::getSamples
size_t getSamples() const
Get the number of samples contained in the sound.
Definition: Sound.cpp:404
yarp::os::Searchable::toString
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
yarp::os::Property::fromString
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
Definition: Property.cpp:1046
yarp::dev::PolyDriver::isValid
bool isValid() const
Check if device is valid.
Definition: PolyDriver.cpp:199
YARP_LOG_COMPONENT
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:80
yarp::dev::DeviceDriver::view
bool view(T *&x)
Get an interface to the device driver.
Definition: DeviceDriver.h:77
yarp::sig::Sound::getChannels
size_t getChannels() const
Get the number of channels of the sound.
Definition: Sound.cpp:409
yarp::os::Port::open
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
Definition: Port.cpp:82
yarp::dev::IAudioGrabberSound::getRecordingAudioBufferMaxSize
virtual bool getRecordingAudioBufferMaxSize(yarp::dev::AudioBufferSize &size)=0
ServerSoundGrabber::open
bool open(yarp::os::Searchable &config) override
Configure with a set of options.
Definition: ServerSoundGrabber.cpp:49
yarp::dev::IAudioGrabberSound::startRecording
virtual bool startRecording()=0
Start the recording.
yarp::dev::PolyDriver::open
bool open(const std::string &txt)
Construct and configure a device by its common name.
Definition: PolyDriver.cpp:143
yarp::os::Time::now
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition: Time.cpp:124
yarp::os::Port::setEnvelope
bool setEnvelope(PortWriter &envelope) override
Set an envelope (e.g., a timestamp) to the next message which will be sent.
Definition: Port.cpp:541
yarp::os::Value::isString
virtual bool isString() const
Checks if value is a string.
Definition: Value.cpp:159
ServerSoundGrabber.h
yarp::os::Bottle::get
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:249
yarp::os::Bottle::write
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
Definition: Bottle.cpp:233
yarp::os::ConnectionWriter
An interface for writing to a network connection.
Definition: ConnectionWriter.h:40
yarp::os::SystemClock::delaySystem
static void delaySystem(double seconds)
Definition: SystemClock.cpp:32
yarp::os::Value::asString
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
yarp::dev::IAudioGrabberSound::getRecordingAudioBufferCurrentSize
virtual bool getRecordingAudioBufferCurrentSize(yarp::dev::AudioBufferSize &size)=0
yarp::os::Searchable::check
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
yarp::os::Vocab::encode
NetInt32 encode(const std::string &str)
Convert a string into a vocabulary identifier.
Definition: Vocab.cpp:14
ServerSoundGrabber::read
bool read(yarp::os::ConnectionReader &connection) override
Read this object from a network connection.
Definition: ServerSoundGrabber.cpp:164
yarp::os::ConnectionReader::getWriter
virtual ConnectionWriter * getWriter()=0
Gets a way to reply to the message, if possible.
yarp::os::Bottle::addString
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition: Bottle.cpp:173
yarp::os::Port::setReader
void setReader(PortReader &reader) override
Set an external reader for port data.
Definition: Port.cpp:505
yarp::os::Bottle::addVocab
void addVocab(int x)
Places a vocabulary item in the bottle, at the end of the list.
Definition: Bottle.cpp:167
LogComponent.h
VOCAB_ERR
constexpr yarp::conf::vocab32_t VOCAB_ERR
Definition: GenericVocabs.h:20
yarp::os::ConnectionReader
An interface for reading from a network connection.
Definition: ConnectionReader.h:40
yCError
#define yCError(component,...)
Definition: LogComponent.h:157
ServerSoundGrabber::~ServerSoundGrabber
~ServerSoundGrabber() override
Definition: ServerSoundGrabber.cpp:32
yarp::os::Port::write
bool write(const PortWriter &writer, const PortWriter *callback=nullptr) const override
Write an object to the port.
Definition: Port.cpp:430
yarp::os::Thread::isStopping
bool isStopping()
Returns true if the thread is stopping (Thread::stop has been called).
Definition: Thread.cpp:102
yarp::os::Stamp::update
void update()
Set the timestamp to the current time, and increment the sequence number (wrapping to 0 if the sequen...
Definition: Stamp.cpp:113
yCInfo
#define yCInfo(component,...)
Definition: LogComponent.h:135
yCDebug
#define yCDebug(component,...)
Definition: LogComponent.h:112
yarp::sig::Sound
Class for storing sounds.
Definition: Sound.h:28
ServerSoundGrabber::run
void run() override
Main body of the new thread.
Definition: ServerSoundGrabber.cpp:122
yarp::dev::IAudioGrabberSound::getSound
virtual bool getSound(yarp::sig::Sound &sound, size_t min_number_of_samples, size_t max_number_of_samples, double max_samples_timeout_s)=0
Get a sound from a device.
ServerSoundGrabber::ServerSoundGrabber
ServerSoundGrabber()
Definition: ServerSoundGrabber.cpp:25
Vocab.h
yarp::os::Bottle::read
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Definition: Bottle.cpp:243
yarp::os::Port::interrupt
void interrupt() override
Interrupt any current reads or writes attached to the port.
Definition: Port.cpp:377
yarp::os::Thread::start
bool start()
Start the new thread running.
Definition: Thread.cpp:96
Time.h
yarp::dev::IAudioGrabberSound::stopRecording
virtual bool stopRecording()=0
Stop the recording.
yarp::sig::Sound::getBytesPerSample
size_t getBytesPerSample() const
Get the number of bytes per sample.
Definition: Sound.cpp:399
yarp::os::Value::toString
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Value.cpp:359
yarp::os::Value
A single value (typically within a Bottle).
Definition: Value.h:47
yarp::os::Thread::stop
bool stop()
Stop the thread.
Definition: Thread.cpp:84
GenericVocabs.h
Bottle.h
VOCAB_OK
constexpr yarp::conf::vocab32_t VOCAB_OK
Definition: GenericVocabs.h:18
yarp::os::Property
A class for storing options and configuration information.
Definition: Property.h:37