YARP
Yet Another Robot Platform
fakeMicrophone.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 #include "fakeMicrophone.h"
10 
11 #include <yarp/os/Thread.h>
12 #include <yarp/os/Time.h>
13 #include <yarp/os/Semaphore.h>
14 #include <yarp/os/Stamp.h>
15 #include <yarp/os/LogComponent.h>
16 #include <yarp/os/LogStream.h>
17 
18 #include <mutex>
19 #define _USE_MATH_DEFINES
20 #include <math.h>
21 #include <string>
22 
23 
24 using namespace yarp::os;
25 using namespace yarp::dev;
26 using namespace yarp::sig;
27 
28 constexpr size_t c_SAMPLES_TO_BE_COPIED=512; //samples
29 constexpr size_t c_bytes_form = 2; //16bit
30 
31 namespace {
32 YARP_LOG_COMPONENT(FAKEMICROPHONE, "yarp.device.fakeMicrophone")
33 }
34 
35 typedef unsigned short int audio_sample_16t;
36 
39 {
40 }
41 
43 {
44  close();
45 }
46 
48 {
49  //sets the thread period
50  if(config.check("period"))
51  {
52  double period = config.find("period").asFloat64();
53  setPeriod(period);
54  yCInfo(FAKEMICROPHONE) << "Using chosen period of " << period << " s";
55  }
56  else
57  {
58  yCInfo(FAKEMICROPHONE) << "Using default period of " << DEFAULT_PERIOD << " s";
59  }
60 
61  size_t tmp_freq = 44100; //Hz
62  size_t tmp_channels = 2;
63  if (config.check("channels"))
64  {
65  tmp_channels = config.find("channels").asInt32();
66  }
67 
68  if (config.check("sampling_frequency"))
69  {
70  tmp_freq = config.find("frequency").asInt32();
71  }
72 
73  if (config.check("signal_frequency"))
74  {
75  m_sig_freq = config.find("signal_frequency").asInt32();
76  }
77 
78  if (config.check("waveform"))
79  {
80  std::string waveform = config.find("waveform").asString();
81  if (config.find("waveform").toString() == "sine") { m_waveform = waveform_t::sine; }
82  else if (config.find("waveform").toString() == "sawtooth") { m_waveform = waveform_t::sawtooth; }
83  else if (config.find("waveform").toString() == "square") { m_waveform = waveform_t::square; }
84  else if (config.find("waveform").toString() == "constant") { m_waveform = waveform_t::constant; }
85  else if (config.check("waveform")) { yError() << "Unsupported value for waveform parameter"; return false; }
86 
87  if (m_waveform == waveform_t::sine) { yCInfo(FAKEMICROPHONE) << "Using sine waveform, signal amplitude=" << m_wave_amplitude << ", signal frequency=" << m_sig_freq; }
88  else if (m_waveform == waveform_t::sawtooth) { yCInfo(FAKEMICROPHONE) << "Using sawtooth waveform, signal amplitude=" << m_wave_amplitude << ", signal frequency=" << m_sig_freq; }
89  else if (m_waveform == waveform_t::square) { yCInfo(FAKEMICROPHONE) << "Using square waveform, signal amplitude=" << m_wave_amplitude << ", signal frequency=" << m_sig_freq; }
90  else if (m_waveform == waveform_t::constant) { yCInfo(FAKEMICROPHONE) << "Using constant waveform, signal amplitude="<< m_wave_amplitude << ", signal frequency=" << m_sig_freq; }
91  }
92 
93  //data structure initialization
94  m_audiorecorder_cfg.numSamples = tmp_freq * 5; //5sec
95  m_audiorecorder_cfg.numChannels = tmp_channels;
96  m_audiorecorder_cfg.frequency = tmp_freq;
98 
99  const size_t EXTRA_SPACE = 2;
101  m_inputBuffer = new yarp::dev::CircularAudioBuffer_16t("fake_mic_buffer", buffer_size);
102 
103  m_max_count.resize(m_audiorecorder_cfg.numChannels);
104  m_counter.resize(m_audiorecorder_cfg.numChannels);
105  //start the capture thread
106  start();
107  return true;
108 }
109 
111 {
113 
114  //wait until the thread is stopped
115 
116  if (m_inputBuffer)
117  {
118  delete m_inputBuffer;
119  m_inputBuffer = 0;
120  }
121  return true;
122 }
123 
124 
125 bool fakeMicrophone::threadInit()
126 {
127  return true;
128 }
129 
130 
131 void fakeMicrophone::run()
132 {
133  // when not recording, do nothing
134  if (!m_isRecording)
135  {
136  return;
137  }
138 
139  //fill the buffer with a sine tone
140  //each iteration, which occurs every xxx ms, I copy a bunch of samples in the buffer.
141  for (size_t i = 0; i < c_SAMPLES_TO_BE_COPIED; i++)
142  {
143  // Default values:
144  // this signal has amplitude (-32000,32000)
145  // the first channel has frequency 440Hz (A4 note)
146  // the second channel has frequency 220Hz etc.
147  // and so on..
148  if (m_waveform == waveform_t::sine)
149  {
150  for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++)
151  {
152  m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_sig_freq / double(i + 1);
153  unsigned short elem1 = double(m_wave_amplitude * sin(double(m_counter[i]) / m_max_count[i] * 2 * M_PI));
154  m_inputBuffer->write(elem1);
155  m_counter[i]++;
156  if (m_counter[i] >= m_max_count[i]) m_counter[i] = 0;
157  }
158  }
159  else if(m_waveform == waveform_t::sawtooth)
160  {
161  for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++)
162  {
163  m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_sig_freq / double(i + 1);
164  unsigned short elem1 = m_wave_amplitude * 2 * (double(m_counter[i])/ m_max_count[i]) - m_wave_amplitude;
165  m_inputBuffer->write(elem1);
166  m_counter[i]++;
167  if (m_counter[i] >= m_max_count[i]) m_counter[i] = 0;
168  }
169  }
170  else if (m_waveform == waveform_t::square)
171  {
172  for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++)
173  {
174  m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_sig_freq / double(i + 1);
175  unsigned short elem1 = m_counter[i] < m_max_count[i]/2 ? m_wave_amplitude : 0;
176  m_inputBuffer->write(elem1);
177  m_counter[i]++;
178  if (m_counter[i] >= m_max_count[i]) m_counter[i] = 0;
179  }
180  }
181  else if (m_waveform == waveform_t::constant)
182  {
183  for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++)
184  {
185  m_inputBuffer->write(m_wave_amplitude / double(i + 1));
186  m_counter[i]++;
187  if (m_counter[i] >= m_max_count[i]) m_counter[i] = 0;
188  }
189  }
190  else
191  {
192  yCInfo(FAKEMICROPHONE) << "Not implemented/unreachable code";
193  }
194  }
195 }
LogStream.h
yarp::dev::CircularAudioBuffer::write
void write(SAMPLE elem)
Definition: CircularAudioBuffer.h:48
yarp::dev::AudioDeviceDriverSettings::bytesPerSample
size_t bytesPerSample
Definition: AudioRecorderDeviceBase.h:30
yarp::os::Searchable
A base class for nested structures that can be searched.
Definition: Searchable.h:69
yarp::sig
Signal processing.
Definition: Image.h:25
M_PI
#define M_PI
Definition: fakeLocalizerDev.cpp:44
yarp::dev::AudioBufferSize
Definition: AudioBufferSize.h:26
yarp::dev::AudioDeviceDriverSettings::numChannels
size_t numChannels
Definition: AudioRecorderDeviceBase.h:28
YARP_LOG_COMPONENT
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:80
yarp::dev::AudioDeviceDriverSettings::numSamples
size_t numSamples
Definition: AudioRecorderDeviceBase.h:27
fakeMicrophone.h
fakeMicrophone::open
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
Definition: fakeMicrophone.cpp:47
yarp::dev::AudioRecorderDeviceBase::m_isRecording
bool m_isRecording
Definition: AudioRecorderDeviceBase.h:36
yError
#define yError(...)
Definition: Log.h:282
DEFAULT_PERIOD
#define DEFAULT_PERIOD
Definition: fakeMicrophone.h:19
yarp::dev
An interface for the device drivers.
Definition: audioBufferSizeData.cpp:17
yarp::dev::AudioDeviceDriverSettings::frequency
size_t frequency
Definition: AudioRecorderDeviceBase.h:29
fakeMicrophone::fakeMicrophone
fakeMicrophone()
Definition: fakeMicrophone.cpp:37
yarp::dev::AudioRecorderDeviceBase::m_audiorecorder_cfg
AudioDeviceDriverSettings m_audiorecorder_cfg
Definition: AudioRecorderDeviceBase.h:40
Stamp.h
yarp::os::Value::asString
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
yarp::os::PeriodicThread::start
bool start()
Call this to start the thread.
Definition: PeriodicThread.cpp:311
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::PeriodicThread::setPeriod
bool setPeriod(double period)
Set the (new) period of the thread.
Definition: PeriodicThread.cpp:281
Thread.h
yarp::os::Searchable::find
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
Semaphore.h
yarp::os::PeriodicThread
An abstraction for a periodic thread.
Definition: PeriodicThread.h:25
LogComponent.h
c_SAMPLES_TO_BE_COPIED
constexpr size_t c_SAMPLES_TO_BE_COPIED
Definition: fakeMicrophone.cpp:28
yarp::os::Value::asInt32
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:207
yCInfo
#define yCInfo(component,...)
Definition: LogComponent.h:135
yarp::dev::AudioRecorderDeviceBase::m_inputBuffer
yarp::dev::CircularAudioBuffer_16t * m_inputBuffer
Definition: AudioRecorderDeviceBase.h:38
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
c_bytes_form
constexpr size_t c_bytes_form
Definition: fakeMicrophone.cpp:29
yarp::dev::CircularAudioBuffer_16t
yarp::dev::CircularAudioBuffer< unsigned short int > CircularAudioBuffer_16t
Definition: CircularAudioBuffer.h:118
yarp::os::PeriodicThread::stop
void stop()
Call this to stop the thread, this call blocks until the thread is terminated (and releaseThread() ca...
Definition: PeriodicThread.cpp:296
Time.h
fakeMicrophone::~fakeMicrophone
~fakeMicrophone() override
Definition: fakeMicrophone.cpp:42
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::asFloat64
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
Definition: Value.cpp:225
fakeMicrophone::close
bool close() override
Close the DeviceDriver.
Definition: fakeMicrophone.cpp:110
audio_sample_16t
unsigned short int audio_sample_16t
Definition: fakeMicrophone.cpp:35