/*
 * Copyright (c) 2010-2022 Belledonne Communications SARL.
 *
 * This file is part of mediastreamer2
 * (see https://gitlab.linphone.org/BC/public/mediastreamer2).
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef genericplc_h
#define genericplc_h

#include <stddef.h>
#include <stdint.h>

/* define transition duration in ms when starting/ending a comfort noise period - it introduces an equivalent delay */
#define TRANSITION_DELAY 5

/* 2/<min frequency we want to be able to reproduce> gives then length in seconds */
#define PLC_BUFFER_LEN 2 / 40

/* define in ms the maximum duration of PLC(after wich the output will be 0), and after how long we start decreasing the
 * output volume to reach 0 at MAX_PLC_LEN */
#define PLC_DECREASE_START 100
#define MAX_PLC_LEN 150

/* length in ms of the incoming signal used to adjust energy of PLC generated signal */
#define ENERGY_ADJUSTMENT_WINDOW 10

#define ENERGY_ATTENUATION 0.85f

typedef struct {
	unsigned char *continuity_buffer; /**< buffer used to store a small set of future samples */
	uint16_t plc_buffer_samples_nb;   /**< The buffer len in samples */
	uint16_t plc_buffer_len;          /**< The buffer len in bytes*/
	unsigned char *plc_buffer;        /**< buffer to store the previous frames used to generate plc */
	float *hamming_window;            /**< store the hamming window to apply to signal before fft */
	int16_t *plc_out_buffer; /**< buffer to store the frames generated by plc, same length than previous frames one  */
	uint16_t plc_index;      /**< index of plc_out_buffer to the next samples */
	uint16_t plc_samples_used;      /**< number of plc frames already used */
	void *fft_to_frequency_context; /**< context for the FFT */
	void *fft_to_time_context;      /**< context for the inverse FFT */
	int sample_rate;                /**< sample rate of the audio signal */
} plc_context_t;

plc_context_t *generic_plc_create_context(int sample_rate);
void generic_plc_destroy_context(plc_context_t *context);
void generic_plc_transition_mix(int16_t *inout_buffer, int16_t *continuity_buffer, uint16_t fading_sample_nbr);
void generic_plc_fftbf(plc_context_t *context, int16_t *input_buffer, int16_t *output_buffer, size_t input_buffer_len);
void generic_plc_generate_samples(plc_context_t *context, int16_t *data, uint16_t sample_nbr);
void generic_plc_update_plc_buffer(plc_context_t *context, unsigned char *data, size_t data_len);
void generic_plc_update_continuity_buffer(plc_context_t *context, unsigned char *data, size_t data_len);

#endif /* genericplc_h */
