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 /* Initialize AEC object. 64 * This must be called when the audio device is opened. 65 * ALSA device mutex must be held before calling this API. 66 * Returns -EINVAL if AEC object fails to initialize, else returns 0. */ 67 int init_aec (int sampling_rate, int num_reference_channels, 68 int num_microphone_channels, struct aec_t **); 69 70 /* Release AEC object. 71 * This must be called when the audio device is closed. */ 72 void release_aec(struct aec_t* aec); 73 74 /* Initialize reference configuration for AEC. 75 * Must be called when a new output stream is opened. 76 * Returns -EINVAL if any processing block fails to initialize, 77 * else returns 0. */ 78 int init_aec_reference_config (struct aec_t *aec, struct alsa_stream_out *out); 79 80 /* Clear reference configuration for AEC. 81 * Must be called when the output stream is closed. */ 82 void destroy_aec_reference_config (struct aec_t *aec); 83 84 /* Initialize microphone configuration for AEC. 85 * Must be called when a new input stream is opened. 86 * Returns -EINVAL if any processing block fails to initialize, 87 * else returns 0. */ 88 int init_aec_mic_config(struct aec_t* aec, struct alsa_stream_in* in); 89 90 /* Clear microphone configuration for AEC. 91 * Must be called when the input stream is closed. */ 92 void destroy_aec_mic_config (struct aec_t *aec); 93 94 /* Used to communicate playback state (running or not) to AEC interface. 95 * This is used by process_aec() to determine if AEC processing is to be run. */ 96 void aec_set_spk_running (struct aec_t *aec, bool state); 97 98 /* Used to communicate playback state (running or not) to the caller. */ 99 bool aec_get_spk_running(struct aec_t* aec); 100 101 /* Write audio samples to AEC reference FIFO for use in AEC. 102 * Both audio samples and timestamps are added in FIFO fashion. 103 * Must be called after every write to PCM. 104 * Returns -ENOMEM if the write fails, else returns 0. */ 105 int write_to_reference_fifo(struct aec_t* aec, void* buffer, struct aec_info* info); 106 107 /* Get reference audio samples + timestamp, in the format expected by AEC, 108 * i.e. same sample rate and bit rate as microphone audio. 109 * Timestamp is updated in field 'timestamp_usec', and not in 'timestamp'. 110 * Returns: 111 * -EINVAL if the AEC object is invalid. 112 * -ENOMEM if the reference FIFO overflows or is corrupted. 113 * -ETIMEDOUT if we timed out waiting for the requested number of bytes 114 * 0 otherwise */ 115 int get_reference_samples(struct aec_t* aec, void* buffer, struct aec_info* info); 116 117 #ifdef AEC_HAL 118 119 /* Processing function call for AEC. 120 * AEC output is updated at location pointed to by 'buffer'. 121 * This function does not run AEC when there is no playback - 122 * as communicated to this AEC interface using aec_set_spk_running(). 123 * Returns -EINVAL if processing fails, else returns 0. */ 124 int process_aec(struct aec_t* aec, void* buffer, struct aec_info* info); 125 126 #else /* #ifdef AEC_HAL */ 127 128 #define process_aec(...) ((int)0) 129 130 #endif /* #ifdef AEC_HAL */ 131 132 #endif /* _AUDIO_AEC_H_ */ 133