YARP
Yet Another Robot Platform
AudioRecorderDeviceBase.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
9 #define _USE_MATH_DEFINES
10 
12 #include <yarp/os/LogStream.h>
13 #include <mutex>
14 #include <limits>
15 #include <cmath>
16 #include <functional>
17 
18 using namespace yarp::os;
19 using namespace yarp::dev;
20 using namespace std;
21 
22 #ifndef DEG2RAD
23 #define DEG2RAD M_PI/180.0
24 #endif
25 
26 constexpr double c_sleep_time=0.005;
27 
28 YARP_LOG_COMPONENT(AUDIORECORDER_BASE, "yarp.devices.AudioRecorderDeviceBase")
29 
30 //the following macros should never be modified and are used only for development purposes
31 #define AUTOMATIC_REC_START 0
32 #define DEBUG_TIME_SPENT 0
33 #define BUFFER_AUTOCLEAR 0
34 
35 bool AudioRecorderDeviceBase::getSound(yarp::sig::Sound& sound, size_t min_number_of_samples, size_t max_number_of_samples, double max_samples_timeout_s)
36 {
37  //check for something_to_record
38  {
39 #if AUTOMATIC_REC_START
40  if (m_isRecording == false)
41  {
42  this->startRecording();
43  }
44 #else
45  double debug_time = yarp::os::Time::now();
46  while (m_isRecording == false)
47  {
48  if (yarp::os::Time::now() - debug_time > 5.0)
49  {
50  yCInfo(AUDIORECORDER_BASE) << "getSound() is currently waiting. Use startRecording() to start the audio stream";
51  debug_time = yarp::os::Time::now();
52  }
54  }
55 #endif
56  }
57 
58  //prevents simultaneous start/stop/reset etc.
59  //std::lock_guard<std::mutex> lock(m_mutex); //This must be used carefully
60 
61  //check on input parameters
62  if (max_number_of_samples < min_number_of_samples)
63  {
64  yCError(AUDIORECORDER_BASE) << "max_number_of_samples must be greater than min_number_of_samples!";
65  return false;
66  }
67  if (max_number_of_samples > this->m_audiorecorder_cfg.numSamples)
68  {
69  yCWarning(AUDIORECORDER_BASE) << "max_number_of_samples bigger than the internal audio buffer! It will be truncated to:" << this->m_audiorecorder_cfg.numSamples;
70  max_number_of_samples = this->m_audiorecorder_cfg.numSamples;
71  }
72 
73  //wait until the desired number of samples are obtained
74  size_t buff_size = 0;
75  double start_time = yarp::os::Time::now();
76  double debug_time = yarp::os::Time::now();
77  do
78  {
79  buff_size = m_inputBuffer->size().getSamples();
80  if (buff_size >= max_number_of_samples) { break; }
81  if (buff_size >= min_number_of_samples && yarp::os::Time::now() - start_time > max_samples_timeout_s) { break; }
82  if (m_isRecording == false) { break; }
83 
84  if (yarp::os::Time::now() - debug_time > 1.0)
85  {
86  debug_time = yarp::os::Time::now();
87  yCDebug(AUDIORECORDER_BASE) << "getSound() Buffer size is " << buff_size << "/" << max_number_of_samples << " after 1s";
88  }
89 
91  } while (true);
92 
93  //prepare the sound data struct
94  size_t samples_to_be_copied = buff_size;
95  if (samples_to_be_copied > max_number_of_samples) samples_to_be_copied = max_number_of_samples;
96  if (sound.getChannels() != this->m_audiorecorder_cfg.numChannels && sound.getSamples() != samples_to_be_copied)
97  {
98  sound.resize(samples_to_be_copied, this->m_audiorecorder_cfg.numChannels);
99  }
100  sound.setFrequency(this->m_audiorecorder_cfg.frequency);
101 
102  //fill the sound data struct, reading samples from the circular buffer
103 #if DEBUG_TIME_SPENT
104  double ct1 = yarp::os::Time::now();
105 #endif
106  for (size_t i = 0; i < samples_to_be_copied; i++)
107  for (size_t j = 0; j < this->m_audiorecorder_cfg.numChannels; j++)
108  {
109  int16_t s = (int16_t)(m_inputBuffer->read());
110  sound.set(s, i, j);
111  }
112 
113  auto debug_p = sound.getInterleavedAudioRawData();
114 #if DEBUG_TIME_SPENT
115  double ct2 = yarp::os::Time::now();
116  yCDebug(AUDIORECORDER_BASE) << ct2 - ct1;
117 #endif
118  return true;
119 }
120 
121 bool AudioRecorderDeviceBase::getRecordingAudioBufferMaxSize(yarp::dev::AudioBufferSize& size)
122 {
123  //no lock guard is needed here
124  size = this->m_inputBuffer->getMaxSize();
125  return true;
126 }
127 
128 
129 bool AudioRecorderDeviceBase::getRecordingAudioBufferCurrentSize(yarp::dev::AudioBufferSize& size)
130 {
131  //no lock guard is needed here
132  size = this->m_inputBuffer->size();
133  return true;
134 }
135 
136 
137 bool AudioRecorderDeviceBase::resetRecordingAudioBuffer()
138 {
139  std::lock_guard<std::mutex> lock(m_mutex);
140  m_inputBuffer->clear();
141  yCDebug(AUDIORECORDER_BASE) << "resetRecordingAudioBuffer";
142  return true;
143 }
144 
145 bool AudioRecorderDeviceBase::startRecording()
146 {
147  std::lock_guard<std::mutex> lock(m_mutex);
148  m_isRecording = true;
149 #if BUFFER_AUTOCLEAR
150  this->m_recDataBuffer->clear();
151 #endif
152  yCInfo(AUDIORECORDER_BASE) << "Recording started";
153  return true;
154 }
155 
156 
157 bool AudioRecorderDeviceBase::stopRecording()
158 {
159  std::lock_guard<std::mutex> lock(m_mutex);
160  m_isRecording = false;
161 #if BUFFER_AUTOCLEAR
162  this->m_recDataBuffer->clear();
163 #endif
164  yCInfo(AUDIORECORDER_BASE) << "Recording stopped";
165  return true;
166 }
167 
168 AudioRecorderDeviceBase::~AudioRecorderDeviceBase()
169 {
170  delete m_inputBuffer;
171 }
LogStream.h
yarp::sig::Sound::setFrequency
void setFrequency(int freq)
Set the frequency of the sound (i.e.
Definition: Sound.cpp:226
yCWarning
#define yCWarning(component,...)
Definition: LogComponent.h:146
yarp::sig::Sound::getSamples
size_t getSamples() const
Get the number of samples contained in the sound.
Definition: Sound.cpp:404
yarp::dev::AudioBufferSize
Definition: AudioBufferSize.h:26
YARP_LOG_COMPONENT
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:80
yarp::sig::Sound::getChannels
size_t getChannels() const
Get the number of channels of the sound.
Definition: Sound.cpp:409
yarp::os::Time::now
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition: Time.cpp:124
yarp::dev
An interface for the device drivers.
Definition: audioBufferSizeData.cpp:17
yarp::os::SystemClock::delaySystem
static void delaySystem(double seconds)
Definition: SystemClock.cpp:32
yarp::sig::Sound::set
void set(audio_sample value, size_t sample, size_t channel=0)
Definition: Sound.cpp:206
yCError
#define yCError(component,...)
Definition: LogComponent.h:157
c_sleep_time
constexpr double c_sleep_time
Definition: AudioRecorderDeviceBase.cpp:26
yCInfo
#define yCInfo(component,...)
Definition: LogComponent.h:135
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yCDebug
#define yCDebug(component,...)
Definition: LogComponent.h:112
yarp::sig::Sound
Class for storing sounds.
Definition: Sound.h:28
AUDIORECORDER_BASE
const yarp::os::LogComponent & AUDIORECORDER_BASE()
Definition: AudioRecorderDeviceBase.cpp:28
yarp::sig::Sound::resize
void resize(size_t samples, size_t channels=1)
Set the sound size.
Definition: Sound.cpp:167
yarp::sig::Sound::getInterleavedAudioRawData
std::vector< std::reference_wrapper< audio_sample > > getInterleavedAudioRawData() const
Returns a serialized version of the sound, in interleaved format, e.g.
Definition: Sound.cpp:343
AudioRecorderDeviceBase.h