⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 af_hrtf.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 2 页
字号:
	if(s->lf)	    free(s->lf);	if(s->rf)	    free(s->rf);	if(s->lr)	    free(s->lr);	if(s->rr)	    free(s->rr);	if(s->cf)	    free(s->cf);	if(s->cr)	    free(s->cr);	if(s->ba_l)	    free(s->ba_l);	if(s->ba_r)	    free(s->ba_r);	if(s->ba_ir)	    free(s->ba_ir);	if(s->fwrbuf_l)	   free(s->fwrbuf_l);	if(s->fwrbuf_r)	   free(s->fwrbuf_r);	if(s->fwrbuf_lr)	   free(s->fwrbuf_lr);	if(s->fwrbuf_rr)	   free(s->fwrbuf_rr);	free(af->setup);    }    if(af->data)	free(af->data->audio);    free(af->data);}/* Filter data through filterTwo "tricks" are used to compensate the "color" of the KEMAR data:1. The KEMAR data is refiltered to ensure that the front L, R channelson the same side of the ear are equalized (especially in the highfrequencies).2. A bass compensation is introduced to ensure that 0-200 Hz are notdamped (without any real 3D acoustical image, however).*/static af_data_t* play(struct af_instance_s *af, af_data_t *data){    af_hrtf_t *s = af->setup;    short *in = data->audio; // Input audio data    short *out = NULL; // Output audio data    short *end = in + data->len / sizeof(short); // Loop end    float common, left, right, diff, left_b, right_b;    const int dblen = s->dlbuflen, hlen = s->hrflen, blen = s->basslen;    if(AF_OK != RESIZE_LOCAL_BUFFER(af, data))	return NULL;    if(s->print_flag) {	s->print_flag = 0;	switch (s->decode_mode) {	case HRTF_MIX_51:	  af_msg(AF_MSG_INFO,		 "[hrtf] Using HRTF to mix %s discrete surround into "		 "L, R channels\n", s->matrix_mode ? "5+1" : "5");	  break;	case HRTF_MIX_STEREO:	  af_msg(AF_MSG_INFO,		 "[hrtf] Using HRTF to mix stereo into "		 "L, R channels\n");	  break;	case HRTF_MIX_MATRIX2CH:	  af_msg(AF_MSG_INFO,		 "[hrtf] Using active matrix to decode 2 channel "		 "input, HRTF to mix %s matrix surround into "		 "L, R channels\n", "3/2");	  break;	default:	  af_msg(AF_MSG_WARN,		 "[hrtf] bogus decode_mode: %d\n", s->decode_mode);	  break;	}	       if(s->matrix_mode)	  af_msg(AF_MSG_INFO,		 "[hrtf] Using active matrix to decode rear center "		 "channel\n");    }    out = af->data->audio;    /* MPlayer's 5 channel layout (notation for the variable):     *      * 0: L (LF), 1: R (RF), 2: Ls (LR), 3: Rs (RR), 4: C (CF), matrix     * encoded: Cs (CR)     *      * or: L = left, C = center, R = right, F = front, R = rear     *      * Filter notation:     *      *      CF     * OF        AF     *      Ear->     * OR        AR     *      CR     *      * or: C = center, A = same side, O = opposite, F = front, R = rear     */    while(in < end) {	const int k = s->cyc_pos;	update_ch(s, in, k);	/* Simulate a 7.5 ms -20 dB echo of the center channel in the	   front channels (like reflection from a room wall) - a kind of	   psycho-acoustically "cheating" to focus the center front	   channel, which is normally hard to be perceived as front */	s->lf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen];	s->rf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen];	switch (s->decode_mode) {	case HRTF_MIX_51:	case HRTF_MIX_MATRIX2CH:	   /* Mixer filter matrix */	   common = conv(dblen, hlen, s->cf, s->cf_ir, k + s->cf_o);	   if(s->matrix_mode) {	      /* In matrix decoding mode, the rear channel gain must be		 renormalized, as there is an additional channel. */	      matrix_decode(in, k, 2, 3, 0, s->dlbuflen,			    s->lr_fwr, s->rr_fwr,			    s->lrprr_fwr, s->lrmrr_fwr,			    &(s->adapt_lr_gain), &(s->adapt_rr_gain),			    &(s->adapt_lrprr_gain), &(s->adapt_lrmrr_gain),			    s->lr, s->rr, NULL, NULL, s->cr);	      common +=		 conv(dblen, hlen, s->cr, s->cr_ir, k + s->cr_o) *		 M1_76DB;	      left    =		 ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +		   conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o) +		   (conv(dblen, hlen, s->lr, s->ar_ir, k + s->ar_o) +		    conv(dblen, hlen, s->rr, s->or_ir, k + s->or_o)) *		   M1_76DB + common);	      right   =		 ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +		   conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o) +		   (conv(dblen, hlen, s->rr, s->ar_ir, k + s->ar_o) +		    conv(dblen, hlen, s->lr, s->or_ir, k + s->or_o)) *		   M1_76DB + common);	   } else {	      left    =		 ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +		   conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o) +		   conv(dblen, hlen, s->lr, s->ar_ir, k + s->ar_o) +		   conv(dblen, hlen, s->rr, s->or_ir, k + s->or_o) +		   common);	      right   =		 ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +		   conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o) +		   conv(dblen, hlen, s->rr, s->ar_ir, k + s->ar_o) +		   conv(dblen, hlen, s->lr, s->or_ir, k + s->or_o) +		   common);	   }	   break;	case HRTF_MIX_STEREO:	   left    =	      ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +		conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o));	   right   =	      ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +		conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o));	   break;	default:	    /* make gcc happy */	    left = 0.0;	    right = 0.0;	    break;	}	/* Bass compensation for the lower frequency cut of the HRTF.  A	   cross talk of the left and right channel is introduced to	   match the directional characteristics of higher frequencies.	   The bass will not have any real 3D perception, but that is	   OK (note at 180 Hz, the wavelength is about 2 m, and any	   spatial perception is impossible). */	left_b  = conv(dblen, blen, s->ba_l, s->ba_ir, k);	right_b = conv(dblen, blen, s->ba_r, s->ba_ir, k);	left  += (1 - BASSCROSS) * left_b  + BASSCROSS * right_b;	right += (1 - BASSCROSS) * right_b + BASSCROSS * left_b;	/* Also mix the LFE channel (if available) */	if(data->nch >= 6) {	    left  += in[5] * M3_01DB;	    right += in[5] * M3_01DB;	}	/* Amplitude renormalization. */	left  *= AMPLNORM;	right *= AMPLNORM;	switch (s->decode_mode) {	case HRTF_MIX_51:	case HRTF_MIX_STEREO:	   /* "Cheating": linear stereo expansion to amplify the 3D	      perception.  Note: Too much will destroy the acoustic space	      and may even result in headaches. */	   diff = STEXPAND2 * (left - right);	   out[0] = (int16_t)(left  + diff);	   out[1] = (int16_t)(right - diff);	   break;	case HRTF_MIX_MATRIX2CH:	   /* Do attempt any stereo expansion with matrix encoded	      sources.  The L, R channels are already stereo expanded	      by the steering, any further stereo expansion will sound	      very unnatural. */	   out[0] = (int16_t)left;	   out[1] = (int16_t)right;	   break;	}	/* Next sample... */	in = &in[data->nch];	out = &out[af->data->nch];	(s->cyc_pos)--;	if(s->cyc_pos < 0)	    s->cyc_pos += dblen;    }    /* Set output data */    data->audio = af->data->audio;    data->len   = (data->len * af->mul.n) / af->mul.d;    data->nch   = 2;    return data;}static int allocate(af_hrtf_t *s){    if ((s->lf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    if ((s->rf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    if ((s->lr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    if ((s->rr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    if ((s->cf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    if ((s->cr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    if ((s->ba_l = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    if ((s->ba_r = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    if ((s->fwrbuf_l =	 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    if ((s->fwrbuf_r =	 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    if ((s->fwrbuf_lr =	 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    if ((s->fwrbuf_rr =	 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;    return 0;}/* Allocate memory and set function pointers */static int af_open(af_instance_t* af){    int i;    af_hrtf_t *s;    float fc;    af->control = control;    af->uninit = uninit;    af->play = play;    af->mul.n = 1;    af->mul.d = 1;    af->data = calloc(1, sizeof(af_data_t));    af->setup = calloc(1, sizeof(af_hrtf_t));    if((af->data == NULL) || (af->setup == NULL))	return AF_ERROR;    s = af->setup;    s->dlbuflen = DELAYBUFLEN;    s->hrflen = HRTFFILTLEN;    s->basslen = BASSFILTLEN;    s->cyc_pos = s->dlbuflen - 1;    /* With a full (two axis) steering matrix decoder, s->matrix_mode       should not be enabled lightly (it will also steer the Ls, Rs       channels). */    s->matrix_mode = 0;    s->decode_mode = HRTF_MIX_51;    s->print_flag = 1;    if (allocate(s) != 0) { 	af_msg(AF_MSG_ERROR, "[hrtf] Memory allocation error.\n");	return AF_ERROR;    }    for(i = 0; i < s->dlbuflen; i++)	s->lf[i] = s->rf[i] = s->lr[i] = s->rr[i] = s->cf[i] =	    s->cr[i] = 0;    s->lr_fwr =	s->rr_fwr = 0;    s->cf_ir = cf_filt + (s->cf_o = pulse_detect(cf_filt));    s->af_ir = af_filt + (s->af_o = pulse_detect(af_filt));    s->of_ir = of_filt + (s->of_o = pulse_detect(of_filt));    s->ar_ir = ar_filt + (s->ar_o = pulse_detect(ar_filt));    s->or_ir = or_filt + (s->or_o = pulse_detect(or_filt));    s->cr_ir = cr_filt + (s->cr_o = pulse_detect(cr_filt));    if((s->ba_ir = malloc(s->basslen * sizeof(float))) == NULL) { 	af_msg(AF_MSG_ERROR, "[hrtf] Memory allocation error.\n");	return AF_ERROR;    }    fc = 2.0 * BASSFILTFREQ / (float)af->data->rate;    if(af_filter_design_fir(s->basslen, s->ba_ir, &fc, LP | KAISER, 4 * M_PI) ==       -1) {	af_msg(AF_MSG_ERROR, "[hrtf] Unable to design low-pass "	       "filter.\n");	return AF_ERROR;    }    for(i = 0; i < s->basslen; i++)	s->ba_ir[i] *= BASSGAIN;        return AF_OK;}/* Description of this filter */af_info_t af_info_hrtf = {    "HRTF Headphone",    "hrtf",    "ylai",    "",    AF_FLAGS_REENTRANT,    af_open};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -