16 constexpr
size_t DEFAULT_MIN_NUMBER_OF_SAMPLES_OVER_NETWORK = 11250;
17 constexpr
size_t DEFAULT_MAX_NUMBER_OF_SAMPLES_OVER_NETWORK = 11250;
18 constexpr
double DEFAULT_GETSOUND_TIMEOUT = 1.0;
25 m_min_number_of_samples_over_network(DEFAULT_MIN_NUMBER_OF_SAMPLES_OVER_NETWORK),
26 m_max_number_of_samples_over_network(DEFAULT_MAX_NUMBER_OF_SAMPLES_OVER_NETWORK),
27 m_getSound_timeout(DEFAULT_GETSOUND_TIMEOUT)
42 if (config.
check(
"period"))
47 if (config.
check(
"subdevice"))
54 if (!m_driver.open(p) || !m_driver.isValid())
56 yCError(AUDIORECORDERWRAPPER) <<
"Failed to open subdevice.. check params";
60 driverlist.
push(&m_driver,
"1");
61 if (!attachAll(driverlist))
63 yCError(AUDIORECORDERWRAPPER) <<
"Failed to open subdevice.. check params";
66 m_isDeviceOwned =
true;
71 yCError(AUDIORECORDERWRAPPER,
"Failed to open IAudioGrabberSound interface");
76 if (config.
check(
"min_samples_over_network"))
78 m_min_number_of_samples_over_network = config.
find(
"min_samples_over_network").
asInt64();
80 if (config.
check(
"max_samples_over_network"))
82 m_max_number_of_samples_over_network = config.
find(
"max_samples_over_network").
asInt64();
84 yCInfo(AUDIORECORDERWRAPPER) <<
"Wrapper configured to produce packets with the following size (in samples): " <<
85 m_min_number_of_samples_over_network <<
" < samples < " << m_max_number_of_samples_over_network;
89 if (config.
check(
"max_samples_timeout"))
91 m_getSound_timeout = config.
find(
"max_samples_timeout").
asFloat64();
93 yCInfo(AUDIORECORDERWRAPPER) <<
"Wrapper configured with max_samples_timeout: " << m_getSound_timeout <<
"s";
96 std::string portname =
"/audioRecorderWrapper";
97 if (config.
check(
"name"))
101 if (m_streamingPort.open(portname +
"/audio:o") ==
false)
103 yCError(AUDIORECORDERWRAPPER) <<
"Unable to open port" << portname +
"/audio:o";
106 if (m_statusPort.open(portname +
"/status:o") ==
false)
108 yCError(AUDIORECORDERWRAPPER) <<
"Unable to open port" << portname +
"/status:o";
112 if (m_rpcPort.open(portname +
"/rpc") ==
false)
114 yCError(AUDIORECORDERWRAPPER) <<
"Unable to open port" << portname +
"/rpc";
117 m_rpcPort.setReader(*
this);
119 bool b = m_mic->getRecordingAudioBufferMaxSize(m_max_buffer_size);
122 yCError(AUDIORECORDERWRAPPER,
"getPlaybackAudioBufferMaxSize failed\n");
127 if (config.
check(
"start")) {
129 m_mic->startRecording();
130 m_mic->isRecording(m_isRecording);
138 if (m_mic !=
nullptr)
140 m_dataThread->stop();
141 m_statusThread->stop();
142 m_mic->stopRecording();
145 m_streamingPort.interrupt();
146 m_streamingPort.close();
147 m_rpcPort.interrupt();
149 m_statusPort.interrupt();
150 m_statusPort.close();
161 bool ok = command.
read(connection);
169 m_mic->startRecording();
170 m_mic->isRecording(m_isRecording);
175 m_mic->stopRecording();
176 m_mic->isRecording(m_isRecording);
179 else if (command.
get(0).
asString() ==
"sw_audio_gain")
184 m_mic->setSWGain(val);
189 yCError(AUDIORECORDERWRAPPER) <<
"Invalid audio gain";
193 else if (command.
get(0).
asString() ==
"hw_audio_gain")
198 m_mic->setHWGain(val);
203 yCError(AUDIORECORDERWRAPPER) <<
"Invalid audio gain";
209 m_mic->resetRecordingAudioBuffer();
223 yCError(AUDIORECORDERWRAPPER) <<
"Invalid command";
228 if (returnToSender !=
nullptr)
230 reply.
write(*returnToSender);
237 if (device2attach.
size() != 1)
239 yCError(AUDIORECORDERWRAPPER,
"Cannot attach more than one device");
247 Idevice2attach->
view(m_mic);
250 if (
nullptr == m_mic)
252 yCError(AUDIORECORDERWRAPPER,
"Subdevice passed to attach method is invalid");
259 m_dataThread->setPeriod(m_period);
260 m_dataThread->start();
261 m_statusThread->start();
267 if (m_dataThread->isRunning())
269 m_dataThread->stop();
271 if (m_statusThread->isRunning())
273 m_statusThread->stop();
286 if (m_dataThread->isRunning())
288 m_dataThread->stop();
290 if (m_statusThread->isRunning())
292 m_statusThread->stop();
299 m_ARW->m_mic->getRecordingAudioBufferCurrentSize(m_ARW->m_current_buffer_size);
300 if (m_ARW->m_debug_enabled)
305 yCDebug(AUDIORECORDERWRAPPER) << m_ARW->m_current_buffer_size.getSamples() <<
"/" << m_ARW->m_max_buffer_size.getSamples() <<
"samples";
310 m_ARW->m_mic->isRecording(m_ARW->m_isRecording);
314 status.
enabled = m_ARW->m_isRecording;
317 m_ARW->m_statusPort.write(status);
326 yCDebug(AUDIORECORDERWRAPPER) << (current_time - m_ARW->m_debug_last_time);
327 m_ARW->m_debug_last_time = current_time;
330 if (m_ARW->m_mic ==
nullptr)
332 yCError(AUDIORECORDERWRAPPER) <<
"The IAudioGrabberSound interface is not available yet!";
336 #ifdef PRINT_DEBUG_MESSAGES
338 audio_buffer_size buf_max;
339 audio_buffer_size buf_cur;
340 mic->getRecordingAudioBufferMaxSize(buf_max);
341 mic->getRecordingAudioBufferCurrentSize(buf_cur);
342 yCDebug(AUDIORECORDERWRAPPER) <<
"BEFORE Buffer status:" << buf_cur.getBytes() <<
"/" << buf_max.getBytes() <<
"bytes";
347 m_ARW->m_mic->getSound(snd, m_ARW->m_min_number_of_samples_over_network, m_ARW->m_max_number_of_samples_over_network, m_ARW->m_getSound_timeout);
349 if (snd.
getSamples() < m_ARW->m_min_number_of_samples_over_network ||
350 snd.
getSamples() < m_ARW->m_max_number_of_samples_over_network)
352 yCWarning(AUDIORECORDERWRAPPER) <<
"subdevice->getSound() is not producing sounds of the requested size ("
353 << m_ARW->m_min_number_of_samples_over_network <<
"<"
355 << m_ARW->m_max_number_of_samples_over_network <<
") failed";
358 #ifdef PRINT_DEBUG_MESSAGES
360 audio_buffer_size buf_max;
361 audio_buffer_size buf_cur;
362 mic->getRecordingAudioBufferMaxSize(buf_max);
363 mic->getRecordingAudioBufferCurrentSize(buf_cur);
364 yCDebug(AUDIORECORDERWRAPPER) <<
"AFTER Buffer status:" << buf_cur.getBytes() <<
"/" << buf_max.getBytes() <<
"bytes";
367 #ifdef PRINT_DEBUG_MESSAGES
373 m_ARW->m_stamp.update();
374 m_ARW->m_streamingPort.setEnvelope(m_ARW->m_stamp);
379 yCError(AUDIORECORDERWRAPPER) <<
"Subdevice produced sound of 0 samples!";
384 yCError(AUDIORECORDERWRAPPER) <<
"Subdevice produced sound of 0 channels!";
389 yCError(AUDIORECORDERWRAPPER) <<
"Subdevice produced sound with 0 frequency!";
394 m_ARW->m_streamingPort.write(snd);
constexpr yarp::conf::vocab32_t VOCAB_OK
constexpr yarp::conf::vocab32_t VOCAB_ERR
constexpr double DEFAULT_THREAD_PERIOD
void run() override
Loop function.
void run() override
Loop function.
AudioRecorderWrapper: A Wrapper which streams audio over the network, after grabbing it from a device
bool detachAll() override
Detach the object (you must have first called attach).
bool close() override
Close the DeviceDriver.
bool attachAll(const yarp::dev::PolyDriverList &p) override
Attach to a list of objects.
~AudioRecorderWrapper() override
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
void attach(yarp::dev::IAudioGrabberSound *igrab)
bool read(yarp::os::ConnectionReader &connection) override
Read this object from a network connection.
AudioRecorderStatus: A class used to describe the status of an audio recorder device.
bool enabled
true if the playback is currently enabled
size_t current_buffer_size
the size of the audio buffer [samples]
size_t max_buffer_size
the max_size of the audio buffer [samples]
bool view(T *&x)
Get an interface to the device driver.
Read a YARP-format sound block from a device.
void push(PolyDriver *p, const char *k)
A container for a device driver.
bool isValid() const
Check if device is valid.
A simple collection of objects that can be described and transmitted in a portable way.
void addVocab32(yarp::conf::vocab32_t x)
Places a vocabulary item in the bottle, at the end of the list.
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
void clear()
Empties the bottle of any objects it contains.
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
void addString(const char *str)
Places a string in the bottle, at the end of the list.
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.
A class for storing options and configuration information.
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
A base class for nested structures that can be searched.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
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.
static void delaySystem(double seconds)
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
virtual std::int64_t asInt64() const
Get 64-bit integer value.
virtual std::string asString() const
Get string value.
Class for storing sounds See Audio in YARP for additional documentation on YARP audio.
size_t getBytesPerSample() const
Get the number of bytes per sample.
size_t getChannels() const
Get the number of channels of the sound.
int getFrequency() const
Get the frequency of the sound (i.e.
size_t getSamples() const
Get the number of samples contained in the sound.
#define yCInfo(component,...)
#define yCError(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
An interface for the device drivers.
double now()
Return the current time in seconds, relative to an arbitrary starting point.
An interface to the operating system, including Port based communication.