2 * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <speex/speex.h>
19 #include <speex/speex_preprocess.h>
20 #include <speex/speex_echo.h>
21 #include "algo_speex.h"
31 static int fdrec, fdref, fdout;
34 static int speex_init(int nframes, int rate, int channels);
35 static int speex_process(unsigned char *rec, unsigned char *ref, unsigned char *out);
36 static int speex_deinit();
38 static struct ec_speex {
39 SpeexEchoState *echo_state;
40 SpeexPreprocessState *preprocess;
47 static ec_operation_t op = {
49 .process = speex_process,
50 .deinit = speex_deinit,
53 ec_operation_t *get_speex_instance()
58 static int speex_init(int nframes, int rate, int channels)
61 sp.filter_frames = nframes; /* TODO:It takes much time when 10 times of nframe */
62 sp.channels = channels;
65 LOGI("nframes(%d), filter_frames(%d) rate(%d), channels(%d)",
66 sp.nframes, sp.filter_frames, sp.rate, sp.channels);
68 sp.echo_state = speex_echo_state_init_mc(sp.nframes, sp.filter_frames,
69 sp.channels, sp.channels);
71 LOGE("speex_echo_state_init_mc failed\n");
75 sp.preprocess = speex_preprocess_state_init(sp.nframes, sp.rate);
77 LOGE("speex_echo_state_init_mc failed\n");
81 if (speex_echo_ctl(sp.echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &sp.rate)) {
82 LOGE("speex_echo_ctl SET_SAMPLING_RATE failed\n");
86 if (speex_preprocess_ctl(sp.preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, sp.echo_state)) {
87 LOGE("speex_echo_ctl SET_ECHO_STATE failed\n");
92 unlink("/tmp/rec.raw");
93 unlink("/tmp/ref.raw");
94 unlink("/tmp/out.raw");
96 fdrec = open("/tmp/rec.raw", O_RDWR | O_CREAT | O_TRUNC, 777);
97 fdref = open("/tmp/ref.raw", O_RDWR | O_CREAT | O_TRUNC, 777);
98 fdout = open("/tmp/out.raw", O_RDWR | O_CREAT | O_TRUNC, 777);
104 static int speex_process(unsigned char *rec, unsigned char *ref, unsigned char *out)
107 struct timeval before,after;
108 write(fdrec, rec, sp.nframes * 4);
109 write(fdref, ref, sp.nframes * 4);
110 gettimeofday(&before,NULL);
113 speex_echo_cancellation(sp.echo_state,
114 (const spx_int16_t *)rec,
115 (const spx_int16_t *)ref,
117 speex_preprocess_run(sp.preprocess, (spx_int16_t *)out);
119 rec += sp.nframes * sp.channels;
120 ref += sp.nframes * sp.channels;
121 out += sp.nframes * sp.channels;
123 speex_echo_cancellation(sp.echo_state,
124 (const spx_int16_t *)rec,
125 (const spx_int16_t *)ref,
127 speex_preprocess_run(sp.preprocess, (spx_int16_t *)out);
130 gettimeofday(&after,NULL);
131 LOGE("It takes time(%ld)",
132 1000*(after.tv_sec-before.tv_sec) + (after.tv_usec-before.tv_usec)/1000);
133 write(fdout, out, sp.nframes * 4);
139 static int speex_deinit()
142 speex_echo_state_destroy(sp.echo_state);
144 speex_preprocess_state_destroy(sp.preprocess);