YARP
Yet Another Robot Platform
fakeMicrophone.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#include "fakeMicrophone.h"
7
8#include <yarp/os/Thread.h>
9#include <yarp/os/Time.h>
10#include <yarp/os/Semaphore.h>
11#include <yarp/os/Stamp.h>
13#include <yarp/os/LogStream.h>
14
15#include <mutex>
16#define _USE_MATH_DEFINES
17#include <math.h>
18#include <string>
19
20
21using namespace yarp::os;
22using namespace yarp::dev;
23using namespace yarp::sig;
24
25constexpr double c_DEFAULT_PERIOD=0.01; //s
26
27namespace {
28YARP_LOG_COMPONENT(FAKEMICROPHONE, "yarp.device.fakeMicrophone")
29}
30
31typedef unsigned short int audio_sample_16t;
32
35{
36}
37
39{
40 close();
41}
42
44{
45 if (config.check("help"))
46 {
47 yCInfo(FAKEMICROPHONE, "Some examples:");
48 yCInfo(FAKEMICROPHONE, "yarpdev --device fakeMicrophone --help");
49 yCInfo(FAKEMICROPHONE, "yarpdev --device AudioRecorderWrapper --subdevice fakeMicrophone --start");
50 yCInfo(FAKEMICROPHONE, "yarpdev --device AudioRecorderWrapper --subdevice fakeMicrophone --start --signal_frequency 400 --waveform sine");
51 yCInfo(FAKEMICROPHONE, "yarpdev --device AudioRecorderWrapper --subdevice fakeMicrophone --start --signal_frequency 400 --waveform sawtooth");
52 yCInfo(FAKEMICROPHONE, "yarpdev --device AudioRecorderWrapper --subdevice fakeMicrophone --start --signal_frequency 400 --waveform square");
53 yCInfo(FAKEMICROPHONE, "yarpdev --device AudioRecorderWrapper --subdevice fakeMicrophone --start --waveform constant");
54 return false;
55 }
56
57 bool b = configureRecorderAudioDevice(config.findGroup("AUDIO_BASE"), "fakeMicrophone");
58 if (!b) { return false; }
59
60 //sets the thread period
61 if(config.check("period"))
62 {
63 double period = config.find("period").asFloat64();
64 setPeriod(period);
65 yCInfo(FAKEMICROPHONE) << "Using chosen period of " << period << " s";
66 }
67 else
68 {
69 yCInfo(FAKEMICROPHONE) << "Using default period of " << c_DEFAULT_PERIOD << " s";
70 }
71
72 if (config.check("signal_frequency"))
73 {
74 m_sig_freq = config.find("signal_frequency").asInt32();
75 }
76
77 if (config.check("amplitude"))
78 {
79 m_wave_amplitude = config.find("amplitude").asInt32();
80 }
81
82 //sets the number of samples processed atomically every thread iteration
83 if (config.check("driver_frame_size"))
84 {
85 m_samples_to_be_copied = config.find("driver_frame_size").asFloat64();
86 }
87 yCDebug(FAKEMICROPHONE) << m_samples_to_be_copied << " will be processed every iteration";
88
89 if (config.check("waveform"))
90 {
91 std::string waveform = config.find("waveform").asString();
92 if (config.find("waveform").toString() == "sine") { m_waveform = waveform_t::sine; }
93 else if (config.find("waveform").toString() == "sawtooth") { m_waveform = waveform_t::sawtooth; }
94 else if (config.find("waveform").toString() == "square") { m_waveform = waveform_t::square; }
95 else if (config.find("waveform").toString() == "constant") { m_waveform = waveform_t::constant; }
96 else if (config.check("waveform")) { yError() << "Unsupported value for waveform parameter"; return false; }
97
98 if (m_waveform == waveform_t::sine) { yCInfo(FAKEMICROPHONE) << "Using sine waveform, signal amplitude=" << m_wave_amplitude << ", signal frequency=" << m_sig_freq; }
99 else if (m_waveform == waveform_t::sawtooth) { yCInfo(FAKEMICROPHONE) << "Using sawtooth waveform, signal amplitude=" << m_wave_amplitude << ", signal frequency=" << m_sig_freq; }
100 else if (m_waveform == waveform_t::square) { yCInfo(FAKEMICROPHONE) << "Using square waveform, signal amplitude=" << m_wave_amplitude << ", signal frequency=" << m_sig_freq; }
101 else if (m_waveform == waveform_t::constant) { yCInfo(FAKEMICROPHONE) << "Using constant waveform, signal amplitude="<< m_wave_amplitude << ", signal frequency=" << m_sig_freq; }
102 }
103
104 //data structure initialization
105 //m_audiorecorder_cfg.numSamples = tmp_freq * 5; //5sec
106 //const size_t EXTRA_SPACE = 2;
107 //AudioBufferSize buffer_size(m_audiorecorder_cfg.numSamples*EXTRA_SPACE, m_audiorecorder_cfg.numChannels, m_audiorecorder_cfg.bytesPerSample);
108 //m_inputBuffer = new yarp::dev::CircularAudioBuffer_16t("fake_mic_buffer", buffer_size);
109
110 m_max_count.resize(m_audiorecorder_cfg.numChannels);
111 m_counter.resize(m_audiorecorder_cfg.numChannels);
112
113 //start the capture thread
114 start();
115 return true;
116}
117
119{
121
122 //wait until the thread is stopped...
123
124 return true;
125}
126
128{
129 std::lock_guard<std::mutex> lock(m_mutex);
130 if (gain > 0)
131 {
132 m_hw_gain = gain;
133 return true;
134 }
135 return false;
136}
137
138bool fakeMicrophone::threadInit()
139{
140 return true;
141}
142
143
144void fakeMicrophone::run()
145{
146 // when not recording, do nothing
148 {
149 return;
150 }
151
152 //fill the buffer with a generated tone.
153 //each iteration, which occurs every xxx ms (thread period), I copy a fixed amount of
154 //samples (m_samples_to_be_copied) in the buffer. This operation cannot be interrupted by stopping the device
155 //with m_recording_enabled=false.
156 for (size_t i = 0; i < m_samples_to_be_copied; i++)
157 {
158 // Default values:
159 // this signal has amplitude (-32000,32000)
160 // the first channel has frequency 440Hz (A4 note)
161 // the second channel has frequency 220Hz etc.
162 // and so on..
163 if (m_waveform == waveform_t::sine)
164 {
165 for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++)
166 {
167 m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_sig_freq / double(i + 1);
168 double elem1 = double(m_wave_amplitude * sin(double(m_counter[i]) / m_max_count[i] * 2 * M_PI));
169 m_inputBuffer->write(elem1 * m_hw_gain);
170 m_counter[i]++;
171 if (m_counter[i] >= m_max_count[i]) {
172 m_counter[i] = 0;
173 }
174 }
175 }
176 else if(m_waveform == waveform_t::sawtooth)
177 {
178 for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++)
179 {
180 m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_sig_freq / double(i + 1);
181 double elem1 = m_wave_amplitude * 2 * (double(m_counter[i])/ m_max_count[i]) - m_wave_amplitude;
182 m_inputBuffer->write(elem1 * m_hw_gain);
183 m_counter[i]++;
184 if (m_counter[i] >= m_max_count[i]) {
185 m_counter[i] = 0;
186 }
187 }
188 }
189 else if (m_waveform == waveform_t::square)
190 {
191 for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++)
192 {
193 m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_sig_freq / double(i + 1);
194 double elem1 = m_counter[i] < m_max_count[i]/2 ? m_wave_amplitude : 0;
195 m_inputBuffer->write(elem1 * m_hw_gain);
196 m_counter[i]++;
197 if (m_counter[i] >= m_max_count[i]) {
198 m_counter[i] = 0;
199 }
200 }
201 }
202 else if (m_waveform == waveform_t::constant)
203 {
204 for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++)
205 {
206 m_inputBuffer->write(m_wave_amplitude * m_hw_gain / double(i + 1));
207 m_counter[i]++;
208 if (m_counter[i] >= m_max_count[i]) {
209 m_counter[i] = 0;
210 }
211 }
212 }
213 else
214 {
215 yCInfo(FAKEMICROPHONE) << "Not implemented/unreachable code";
216 }
217 }
218}
#define yError(...)
Definition: Log.h:356
bool setHWGain(double gain) override
Sets the hardware gain of the grabbing device (if supported by the hardware)
bool close() override
Close the DeviceDriver.
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
~fakeMicrophone() override
yarp::dev::CircularAudioBuffer_16t * m_inputBuffer
bool configureRecorderAudioDevice(yarp::os::Searchable &config, std::string device_name)
AudioDeviceDriverSettings m_audiorecorder_cfg
An abstraction for a periodic thread.
bool setPeriod(double period)
Set the (new) period of the thread.
bool start()
Call this to start the thread.
void stop()
Call this to stop the thread, this call blocks until the thread is terminated (and releaseThread() ca...
A base class for nested structures that can be searched.
Definition: Searchable.h:63
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
Definition: Value.cpp:222
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:204
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
#define M_PI
constexpr double c_DEFAULT_PERIOD
unsigned short int audio_sample_16t
#define yCInfo(component,...)
Definition: LogComponent.h:171
#define yCDebug(component,...)
Definition: LogComponent.h:128
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:76
For streams capable of holding different kinds of content, check what they actually have.
An interface to the operating system, including Port based communication.