/* Copyright 2018 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <syslog.h>

#include "buffer_share.h"
#include "cras_audio_area.h"
#include "cras_dsp_pipeline.h"
#include "cras_mix.h"
#include "cras_rstream.h"
#include "cras_system_state.h"
#include "dsp_util.h"
#include "input_data.h"
#include "utlist.h"

void input_data_run(struct ext_dsp_module *ext, unsigned int nframes)
{
	struct input_data *data = (struct input_data *)ext;
	float *const *wp;
	int i;
	unsigned int writable;
	unsigned int offset = 0;

	while (nframes) {
		writable = float_buffer_writable(data->fbuffer);
		writable = MIN(nframes, writable);
		if (!writable) {
			syslog(LOG_ERR,
			       "Not enough space to process input data");
			break;
		}
		wp = float_buffer_write_pointer(data->fbuffer);
		for (i = 0; i < data->fbuffer->num_channels; i++)
			memcpy(wp[i], ext->ports[i] + offset,
			       writable * sizeof(float));

		float_buffer_written(data->fbuffer, writable);
		nframes -= writable;
		offset += writable;
	}
}

void input_data_configure(struct ext_dsp_module *ext, unsigned int buffer_size,
			  unsigned int num_channels, unsigned int rate)
{
	struct input_data *data = (struct input_data *)ext;

	if (data->fbuffer)
		float_buffer_destroy(&data->fbuffer);
	data->fbuffer = float_buffer_create(buffer_size, num_channels);
}

struct input_data *input_data_create(void *dev_ptr)
{
	struct input_data *data = (struct input_data *)calloc(1, sizeof(*data));

	data->dev_ptr = dev_ptr;

	data->ext.run = input_data_run;
	data->ext.configure = input_data_configure;

	return data;
}

void input_data_destroy(struct input_data **data)
{
	if ((*data)->fbuffer)
		float_buffer_destroy(&(*data)->fbuffer);
	free(*data);
	*data = NULL;
}

void input_data_set_all_streams_read(struct input_data *data,
				     unsigned int nframes)
{
	if (!data->fbuffer)
		return;

	if (float_buffer_level(data->fbuffer) < nframes) {
		syslog(LOG_ERR,
		       "All streams read %u frames exceeds %u"
		       " in input_data's buffer",
		       nframes, float_buffer_level(data->fbuffer));
		float_buffer_reset(data->fbuffer);
		return;
	}
	float_buffer_read(data->fbuffer, nframes);
}

/*
 * The logic is not trivial to return the cras_audio_area and offset for
 * a input stream to read. The buffer position and length of a bunch of
 * input member variables are described below.
 *
 *                          hw_ptr                 appl_ptr
 * a. buffer of input device: |------------------------|
 * b. fbuffer of input data:         |<--------------->|
 * c. stream offset of input data:         |<--------->|
 *    stream offset of input data:                |<-->|
 *    stream offset of input data:     |<------------->|
 * d. audio area of input data:          |<----------->|
 *
 * One thing to keep in mind is, the offset could exceed the size of
 * buffer to read. It's not intuitive though why the stream offset would
 * exceed buffer size. Check this example:
 *
 * Idev gets input buffer 500 frames. One stream read 400, while the other
 * stream read 100. We track stream offset [0, 300] after both stream
 * consumes 100 frames. In the next wake up, audio thread asks idev to
 * get 250 frames. Now the input data holds audio area containing 250 frames
 * of audio as queried, while its float buffer contains 400 frames of audio
 * deinterleaved from last wake up.
 *
 * Wake up at T0:
 *                        hw_ptr                        appl_ptr
 * Input audio area         |-------------------------------|
 * deinterleave float       |-------------------------------|
 * Stream 1 read                                     |------|
 * Stream 2 read                    |-----------------------|
 *
 * Wake up at T1:
                          hw_ptr                 appl_ptr
 * Input audio area                     |------------|
 * deinterleave float       |------------------------|
 * Stream 1 offset                                   |
 * Stream 2 offset                  |----------------|
 *
 * Case 1:
 * A normal input stream, of read offset 0, about to read from device.
 * We shall return the exact audio area from idev, and set read offset to 0.
 *
 * Case 2:
 * A normal input stream, of read offset 300, about to read from device.
 * We shall return the exact audio area from idev but clip read offset to 250.
 *
 * Case 3:
 * An APM Stream of read offset 300, would like to read the deinterleaved
 * float buffer. We shall let APM process the float buffer from offset 300.
 * Don't bother clip read offset in this case, because fbuffer contains
 * the deepest deinterleaved audio data ever read from idev.
 */
int input_data_get_for_stream(struct input_data *data,
			      struct cras_rstream *stream,
			      struct buffer_share *offsets,
			      struct cras_audio_area **area,
			      unsigned int *offset)
{
	int apm_processed;
	struct cras_apm *apm;
	int stream_offset = buffer_share_id_offset(offsets, stream->stream_id);

	apm = cras_apm_list_get_active_apm(stream, data->dev_ptr);
	if (apm == NULL) {
		/*
		 * Case 1 and 2 from above example.
		 */
		*area = data->area;
		*offset = MIN(stream_offset, data->area->frames);
	} else {
		/*
		 * Case 3 from above example.
		 */
		apm_processed = cras_apm_list_process(apm, data->fbuffer,
						      stream_offset);
		if (apm_processed < 0) {
			cras_apm_list_remove_apm(stream->apm_list, apm);
			return 0;
		}
		buffer_share_offset_update(offsets, stream->stream_id,
					   apm_processed);
		*area = cras_apm_list_get_processed(apm);
		*offset = 0;
	}

	return 0;
}

int input_data_put_for_stream(struct input_data *data,
			      struct cras_rstream *stream,
			      struct buffer_share *offsets, unsigned int frames)
{
	struct cras_apm *apm =
		cras_apm_list_get_active_apm(stream, data->dev_ptr);

	if (apm)
		cras_apm_list_put_processed(apm, frames);
	else
		buffer_share_offset_update(offsets, stream->stream_id, frames);

	return 0;
}

float input_data_get_software_gain_scaler(struct input_data *data,
					  float idev_sw_gain_scaler,
					  struct cras_rstream *stream)
{
	struct cras_apm *apm;
	/*
	 * APM has more advanced gain control mechanism. If it is using tuned
	 * settings, give APM total control of the captured samples without
	 * additional gain scaler at all.
	 */
	apm = cras_apm_list_get_active_apm(stream, data->dev_ptr);
	if (apm && cras_apm_list_get_use_tuned_settings(apm))
		return 1.0f;

	return idev_sw_gain_scaler * cras_rstream_get_volume_scaler(stream);
}
