/*
 mediastreamer2 library - modular sound and video processing and streaming
 Copyright (C) 2015 Belledonne Communications, Grenoble

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef genericplc_h
#define genericplc_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_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 */
