130 lines
4.0 KiB
C
130 lines
4.0 KiB
C
|
|
#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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|