10 #include <sound_manager.h>
11 #include <sound_manager_internal.h>
13 #ifndef TIZEN_FEATURE_TV_PROD
24 virtual void execute() const = 0;
30 EchoCanceller() = default;
31 virtual ~EchoCanceller() = default;
34 int ret = sound_manager_start_aec();
36 std::cerr << "failed to start echo cancellation, " << ret << std::endl;
38 std::cout << "[ON] Echo Canceller" << std::endl;
41 int ret = sound_manager_stop_aec();
43 std::cerr << "failed to stop echo cancellation, " << ret << std::endl;
45 std::cout << "[OFF] Echo Canceller" << std::endl;
52 NoiseGenerator() = default;
53 virtual ~NoiseGenerator() = default;
56 std::cout << "[ON] Noise Generator" << std::endl;
60 std::cout << "[OFF] Noise Generator" << std::endl;
65 void playWhiteNoise();
66 void stopWhiteNoise();
68 static void _streamWriteCb(audio_out_h handle, size_t nbytes, void *user_data);
69 static double _getRandDoubleRange(double min, double max);
74 void NoiseGenerator::playWhiteNoise()
76 audio_out_h _output = nullptr;
80 int ret = audio_out_create_new(48000, AUDIO_CHANNEL_STEREO, AUDIO_SAMPLE_TYPE_S16_LE, &_output);
81 if (ret != AUDIO_IO_ERROR_NONE) {
82 std::cerr << "failed to create audio out" << std::endl;
86 ret = audio_out_set_stream_cb(_output, _streamWriteCb, NULL);
87 if (ret != AUDIO_IO_ERROR_NONE) {
88 std::cerr << "failed to set stream callback" << std::endl;
89 audio_out_destroy(_output);
93 ret = audio_out_prepare(_output);
94 if (ret != AUDIO_IO_ERROR_NONE) {
95 std::cerr << "failed to prepare " << std::endl;
96 audio_out_destroy(_output);
103 void NoiseGenerator::stopWhiteNoise()
108 int ret = audio_out_unprepare(output);
109 if (ret != AUDIO_IO_ERROR_NONE)
110 std::cerr << "failed to prepare" << std::endl;
112 ret = audio_out_destroy(output);
113 if (ret != AUDIO_IO_ERROR_NONE)
114 std::cerr << "failed to destroy output" << std::endl;
119 double NoiseGenerator::_getRandDoubleRange(double min, double max)
121 static unsigned int seedp;
122 int r = rand_r(&seedp);
123 return (max / RAND_MAX) * r * (r & 0x1 ? 1 : -1);
126 void NoiseGenerator::_streamWriteCb(audio_out_h handle, size_t nbytes, void *user_data)
128 constexpr double amp = 0.3 * 32767.0;
130 auto buffer = static_cast<short *>(malloc(nbytes));
135 for (size_t i = 0; i < nbytes; i += 2, ptr++)
136 ptr[0] = (short)(amp * _getRandDoubleRange(-1.0, 1.0));
138 audio_out_write(handle, static_cast<void*>(buffer), nbytes);
143 class EchoCancellerOnCommand : public Command
146 explicit EchoCancellerOnCommand(std::shared_ptr<EchoCanceller>& ec) : ec(ec) {}
147 virtual ~EchoCancellerOnCommand() = default;
148 void execute() const override { ec->on(); }
151 std::shared_ptr<EchoCanceller> ec;
154 class EchoCancellerOffCommand : public Command
157 explicit EchoCancellerOffCommand(std::shared_ptr<EchoCanceller>& ec) : ec(ec) {}
158 virtual ~EchoCancellerOffCommand() = default;
159 void execute() const override { ec->off(); }
162 std::shared_ptr<EchoCanceller> ec;
165 class NoiseGeneratorOnCommand : public Command
168 explicit NoiseGeneratorOnCommand(std::shared_ptr<NoiseGenerator>& ng) : ng(ng) {}
169 virtual ~NoiseGeneratorOnCommand() = default;
170 void execute() const override { ng->on(); }
173 std::shared_ptr<NoiseGenerator> ng;
176 class NoiseGeneratorOffCommand : public Command
179 explicit NoiseGeneratorOffCommand(std::shared_ptr<NoiseGenerator>& ng) : ng(ng) {}
180 virtual ~NoiseGeneratorOffCommand() = default;
181 void execute() const override { ng->off(); }
184 std::shared_ptr<NoiseGenerator> ng;
191 RemoteControl() = default;
193 void addCommand(Receiver id, std::pair<std::shared_ptr<Command>, std::shared_ptr<Command>> Commands) {
194 commands.insert({id, Commands});
197 void onButtonPressed(Receiver id) {
198 if (commands.find(id) != commands.end())
199 commands[id].first->execute();
202 void offButtonPressed(Receiver id) {
203 if (commands.find(id) != commands.end())
204 commands[id].second->execute();
208 std::map<Receiver, std::pair<std::shared_ptr<Command>, std::shared_ptr<Command>>> commands{};
211 int capture_sound(char **buffer, int *length, int sec)
214 char *_buffer = NULL;
215 audio_in_h input = NULL;
216 int _length = 16000 * 1 * 2 * sec; // 16Khz, mono, S16LE
219 std::cout << "buffer is null" << std::endl;
223 ret = audio_in_create(16000, AUDIO_CHANNEL_MONO, AUDIO_SAMPLE_TYPE_S16_LE, &input);
224 if (ret != AUDIO_IO_ERROR_NONE) {
225 std::cerr << "failed to create audio_input" << std::endl;
229 ret = audio_in_prepare(input);
230 if (ret != AUDIO_IO_ERROR_NONE) {
231 std::cerr << "failed to prepare, " << ret << std::endl;
235 _buffer = static_cast<char *>(malloc(_length));
237 std::cerr << "_buffer is null" << std::endl;
241 ret = audio_in_read(input, _buffer, _length);
243 std::cerr << "failed to read, " << ret << ", " << _length << std::endl;
246 ret = audio_in_unprepare(input);
247 if (ret != AUDIO_IO_ERROR_NONE) {
248 std::cerr << "failed to unprepare, " << ret << std::endl;
259 audio_in_destroy(input);
266 int test_echo_cancellation(char **buffer, bool enable_ec, bool enable_ref, int time_sec)
269 char *_buffer = NULL;
272 auto ec = std::make_shared<EchoCanceller>();
273 auto ng = std::make_shared<NoiseGenerator>();
275 RemoteControl control;
276 control.addCommand(Receiver::ECHO_CANCELLER,
277 { std::make_shared<EchoCancellerOnCommand>(ec),
278 std::make_shared<EchoCancellerOffCommand>(ec) });
279 control.addCommand(Receiver::NOISE_GENERATOR,
280 { std::make_shared<NoiseGeneratorOnCommand>(ng),
281 std::make_shared<NoiseGeneratorOffCommand>(ng) });
284 control.onButtonPressed(Receiver::ECHO_CANCELLER);
286 control.onButtonPressed(Receiver::NOISE_GENERATOR);
288 std::cout << "Say something for " << time_sec << " seconds.. ec " << enable_ec << ", ref " << enable_ref << std::endl;
290 ret = capture_sound(&_buffer, &length, time_sec);
293 control.offButtonPressed(Receiver::NOISE_GENERATOR);
295 control.offButtonPressed(Receiver::ECHO_CANCELLER);
305 int dump_to_file(const char *filename, char *buffer, int length)
307 int fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0644);
309 std::cerr << "failed to open file" << std::endl;
313 ssize_t ret = write(fd, buffer, length);
315 std::cerr << "failed to write" << std::endl;
323 int main(int argc, char **argv)
325 #ifndef TIZEN_FEATURE_TV_PROD
335 std::cout << "- Usages :" << std::endl;
336 std::cout << "- # audio_io_test_ec [filename] [on/off 0:1] [noise 0:1] [seconds]" << std::endl;
341 enable_ec = !!atoi(argv[2]);
342 enable_ref = !!atoi(argv[3]);
343 time_sec = atoi(argv[4]);
345 size = test_echo_cancellation(&buffer, enable_ec, enable_ref, time_sec);
347 std::cerr << "failed to test aec" << std::endl;
351 if (dump_to_file(filename, buffer, size))
352 std::cerr << "failed to save file, " << filename << std::endl;
356 std::cout << "not supported yet" << std::endl;