KT25-1014_AC695x_BTE_SDK310/cpu/br23/audio_mic/effect_linein.c
2025-10-14 16:57:01 +08:00

130 lines
4.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "effect_linein.h"
#include "stream_entry.h"
#include "application/audio_dig_vol.h"
#include "system/includes.h"
#include "audio_config.h"
#include "audio_enc.h"
#include "audio_dec.h"
#include "audio_adc.h"
#include "audio_config.h"
#include "media/includes.h"
struct __effect_linein {
struct audio_adc_ch ch;
struct audio_adc_output_hdl output;
s16 *adc_buf;
u16 adc_buf_len;
void *dvol;
struct __stream_entry *stream;
};
//adc出数顺序 lineinL lineinR mic
//mic通路数据源是单声道用reverb会变双声道用echo声道数不变
int effect_linein_mix_callback(void *priv, struct audio_data_frame *in)
{
struct __effect_linein *linein = (struct __effect_linein *)priv;
s16 *data = in->data;
u32 len = in->data_len;
if (linein && linein->adc_buf) {
#if SYS_DIGVOL_GROUP_EN
if (linein->dvol) {
audio_dig_vol_run(linein->dvol, linein->adc_buf, len);
}
#endif/*SYS_DIGVOL_GROUP_EN*/
int i, j;
int points = len >> 1;
if (in->channel == 2) {
for (i = 0; i < points; i++) {
data[i] = data_sat_s16(data[i] + linein->adc_buf[i]);//声道数一致时lineinLR与过了reverb后混响通路数据点数一致
}
} else {
//混响通路是单声道时lineinLR声道点数是mic通路数据的两倍
s16 *tmp = linein->adc_buf;
for (i = 0, j = 0; i < points * 2; i += 2, j++) {
tmp[j] = data_sat_s16(tmp[i] + tmp[i + 1]); //将linein LR合成 单声道
}
for (i = 0; i < points; i++) {
data[i] = data_sat_s16(data[i] + linein->adc_buf[i]);//将合成单声道后的linein数据叠加到混响通路
}
}
}
return len;
}
static void linein_adc_irq_output(void *priv, s16 *data, int len)
{
struct __effect_linein *linein = (struct __effect_linein *)priv;
if (linein) {
linein->adc_buf = data;
linein->adc_buf_len = len;
}
}
struct __effect_linein *effect_linein_open(void)
{
struct __effect_linein *linein = zalloc(sizeof(struct __effect_linein));
if (linein) {
linein->stream = stream_entry_open(linein, effect_linein_mix_callback, 0);
if (linein->stream) {
if (audio_linein_open(&linein->ch, MIC_EFFECT_SAMPLERATE, 3) == 0) {
#if SYS_DIGVOL_GROUP_EN
audio_dig_vol_param linein_digvol_param = {
.vol_start = 0,
.vol_max = 100,
.ch_total = 2,
.fade_en = 1,
.fade_points_step = 5,
.fade_gain_step = 10,
.vol_list = NULL,
};
linein->dvol = audio_dig_vol_open(&linein_digvol_param);
if (linein->dvol) {
audio_dig_vol_group_add(sys_digvol_group, linein->dvol, "music_linein");
}
#endif/*SYS_DIGVOL_GROUP_EN*/
linein->output.handler = linein_adc_irq_output;
linein->output.priv = linein;
audio_linein_add_output(&linein->output);
audio_linein_start(&linein->ch);
printf("audio_linein_open ok!!!\n ");
return linein;
}
} else {
effect_linein_close(&linein);
return NULL;
}
}
return NULL;
}
void effect_linein_close(struct __effect_linein **hdl)
{
if (hdl && (*hdl)) {
struct __effect_linein *linein = *hdl;
#if SYS_DIGVOL_GROUP_EN
sys_digvol_group_ch_close("music_linein");
#endif/*SYS_DIGVOL_GROUP_EN*/
audio_linein_close(&linein->ch, &linein->output);
stream_entry_close(&linein->stream);
local_irq_disable();
free(linein);
*hdl = NULL;
local_irq_enable();
}
}
struct audio_stream_entry *effect_linein_get_stream_entry(struct __effect_linein *hdl)
{
if (hdl && hdl->stream) {
return &(hdl->stream->entry);
}
return NULL;
}