1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17 /* 18 * Definitions and interface related to HAL implementations of Acoustic Echo Canceller (AEC). 19 * 20 * AEC cleans the microphone signal by removing from it audio data corresponding to loudspeaker 21 * playback. Note that this process can be nonlinear. 22 * 23 */ 24 25 #ifndef _AUDIO_AEC_H_ 26 #define _AUDIO_AEC_H_ 27 28 #include <stdint.h> 29 #include <pthread.h> 30 #include <sys/time.h> 31 #include <hardware/audio.h> 32 #include <audio_utils/resampler.h> 33 #include "audio_hw.h" 34 #include "fifo_wrapper.h" 35 36 struct aec_t { 37 pthread_mutex_t lock; 38 size_t num_reference_channels; 39 bool mic_initialized; 40 int32_t *mic_buf; 41 size_t mic_num_channels; 42 size_t mic_buf_size_bytes; 43 size_t mic_frame_size_bytes; 44 uint32_t mic_sampling_rate; 45 struct aec_info last_mic_info; 46 bool spk_initialized; 47 int32_t *spk_buf; 48 size_t spk_num_channels; 49 size_t spk_buf_size_bytes; 50 size_t spk_frame_size_bytes; 51 uint32_t spk_sampling_rate; 52 struct aec_info last_spk_info; 53 int16_t *spk_buf_playback_format; 54 int16_t *spk_buf_resampler_out; 55 void *spk_fifo; 56 void *ts_fifo; 57 ssize_t read_write_diff_bytes; 58 struct resampler_itfe *spk_resampler; 59 bool spk_running; 60 bool prev_spk_running; 61 }; 62 63 struct aec_params { 64 int num_mic_channels; 65 int num_reference_channels; 66 int num_playback_channels; 67 int mic_sampling_rate_hz; 68 int playback_sampling_rate_hz; 69 }; 70 71 /* Initialize AEC object. 72 * This must be called when the audio device is opened. 73 * ALSA device mutex must be held before calling this API. 74 * Returns -EINVAL if AEC object fails to initialize, else returns 0. */ 75 int init_aec(struct aec_params* params, struct aec_t** aec_ptr); 76 77 /* Release AEC object. 78 * This must be called when the audio device is closed. */ 79 void release_aec(struct aec_t* aec); 80 81 /* Initialize reference configuration for AEC. 82 * Must be called when a new output stream is opened. 83 * Returns -EINVAL if any processing block fails to initialize, 84 * else returns 0. */ 85 int init_aec_reference_config (struct aec_t *aec, struct alsa_stream_out *out); 86 87 /* Clear reference configuration for AEC. 88 * Must be called when the output stream is closed. */ 89 void destroy_aec_reference_config (struct aec_t *aec); 90 91 /* Initialize microphone configuration for AEC. 92 * Must be called when a new input stream is opened. 93 * Returns -EINVAL if any processing block fails to initialize, 94 * else returns 0. */ 95 int init_aec_mic_config(struct aec_t* aec, struct alsa_stream_in* in); 96 97 /* Clear microphone configuration for AEC. 98 * Must be called when the input stream is closed. */ 99 void destroy_aec_mic_config (struct aec_t *aec); 100 101 /* Used to communicate playback state (running or not) to AEC interface. 102 * This is used by process_aec() to determine if AEC processing is to be run. */ 103 void aec_set_spk_running (struct aec_t *aec, bool state); 104 105 /* Used to communicate playback state (running or not) to the caller. */ 106 bool aec_get_spk_running(struct aec_t* aec); 107 108 /* Write audio samples to AEC reference FIFO for use in AEC. 109 * Both audio samples and timestamps are added in FIFO fashion. 110 * Must be called after every write to PCM. 111 * Returns -ENOMEM if the write fails, else returns 0. */ 112 int write_to_reference_fifo(struct aec_t* aec, void* buffer, struct aec_info* info); 113 114 /* Get reference audio samples + timestamp, in the format expected by AEC, 115 * i.e. same sample rate and bit rate as microphone audio. 116 * Timestamp is updated in field 'timestamp_usec', and not in 'timestamp'. 117 * Returns: 118 * -EINVAL if the AEC object is invalid. 119 * -ENOMEM if the reference FIFO overflows or is corrupted. 120 * -ETIMEDOUT if we timed out waiting for the requested number of bytes 121 * 0 otherwise */ 122 int get_reference_samples(struct aec_t* aec, void* buffer, struct aec_info* info); 123 124 #ifdef AEC_HAL 125 126 /* Processing function call for AEC. 127 * AEC output is updated at location pointed to by 'buffer'. 128 * This function does not run AEC when there is no playback - 129 * as communicated to this AEC interface using aec_set_spk_running(). 130 * Returns -EINVAL if processing fails, else returns 0. */ 131 int process_aec(struct aec_t* aec, void* buffer, struct aec_info* info); 132 133 #else /* #ifdef AEC_HAL */ 134 135 #define process_aec(...) ((int)0) 136 137 #endif /* #ifdef AEC_HAL */ 138 139 #endif /* _AUDIO_AEC_H_ */ 140