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