Exemplo n.º 1
0
Arquivo: af_hrtf.c Projeto: 0x0all/mpv
static inline void update_ch(af_hrtf_t *s, short *in, const int k)
{
    const int fwr_pos = (k + FWRDURATION) % s->dlbuflen;
    /* Update the full wave rectified total amplitude */
    /* Input matrix decoder */
    if(s->decode_mode == HRTF_MIX_MATRIX2CH) {
       s->l_fwr += abs(in[0]) - fabs(s->fwrbuf_l[fwr_pos]);
       s->r_fwr += abs(in[1]) - fabs(s->fwrbuf_r[fwr_pos]);
       s->lpr_fwr += abs(in[0] + in[1]) -
          fabs(s->fwrbuf_l[fwr_pos] + s->fwrbuf_r[fwr_pos]);
       s->lmr_fwr += abs(in[0] - in[1]) -
          fabs(s->fwrbuf_l[fwr_pos] - s->fwrbuf_r[fwr_pos]);
    }
    /* Rear matrix decoder */
    if(s->matrix_mode) {
       s->lr_fwr += abs(in[2]) - fabs(s->fwrbuf_lr[fwr_pos]);
       s->rr_fwr += abs(in[3]) - fabs(s->fwrbuf_rr[fwr_pos]);
       s->lrprr_fwr += abs(in[2] + in[3]) -
          fabs(s->fwrbuf_lr[fwr_pos] + s->fwrbuf_rr[fwr_pos]);
       s->lrmrr_fwr += abs(in[2] - in[3]) -
          fabs(s->fwrbuf_lr[fwr_pos] - s->fwrbuf_rr[fwr_pos]);
    }

    switch (s->decode_mode) {
    case HRTF_MIX_51:
       /* 5/5+1 channel sources */
       s->lf[k] = in[0];
       s->cf[k] = in[4];
       s->rf[k] = in[1];
       s->fwrbuf_lr[k] = s->lr[k] = in[2];
       s->fwrbuf_rr[k] = s->rr[k] = in[3];
       break;
    case HRTF_MIX_MATRIX2CH:
       /* Matrix encoded 2 channel sources */
       s->fwrbuf_l[k] = in[0];
       s->fwrbuf_r[k] = in[1];
       matrix_decode(in, k, 0, 1, 1, s->dlbuflen,
                     s->l_fwr, s->r_fwr,
                     s->lpr_fwr, s->lmr_fwr,
                     &(s->adapt_l_gain), &(s->adapt_r_gain),
                     &(s->adapt_lpr_gain), &(s->adapt_lmr_gain),
                     s->lf, s->rf, s->lr, s->rr, s->cf);
       break;
    case HRTF_MIX_STEREO:
       /* Stereo sources */
       s->lf[k] = in[0];
       s->rf[k] = in[1];
       s->cf[k] = s->lr[k] = s->rr[k] = 0;
       break;
    }

    /* We need to update the bass compensation delay line, too. */
    // TODO: should this use lf/cf/rf etc. instead?
    s->ba_l[k] = in[0];
    s->ba_r[k] = in[1];
    if (s->decode_mode == HRTF_MIX_51) {
        s->ba_l[k] += in[4] + in[2];
        s->ba_r[k] += in[4] + in[3];
    }
}
Exemplo n.º 2
0
/* Filter data through filter

Two "tricks" are used to compensate the "color" of the KEMAR data:

1. The KEMAR data is refiltered to ensure that the front L, R channels
on the same side of the ear are equalized (especially in the high
frequencies).

2. A bass compensation is introduced to ensure that 0-200 Hz are not
damped (without any real 3D acoustical image, however).
*/
static struct mp_audio* play(struct af_instance *af, struct mp_audio *data)
{
    af_hrtf_t *s = af->setup;
    short *in = data->planes[0]; // Input audio data
    short *out = NULL; // Output audio data
    short *end = in + data->samples * data->nch; // Loop end
    float common, left, right, diff, left_b, right_b;
    const int dblen = s->dlbuflen, hlen = s->hrflen, blen = s->basslen;

    mp_audio_realloc_min(af->data, data->samples);

    if(s->print_flag) {
	s->print_flag = 0;
	switch (s->decode_mode) {
	case HRTF_MIX_51:
	  mp_msg(MSGT_AFILTER, MSGL_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:
	  mp_msg(MSGT_AFILTER, MSGL_INFO,
		 "[hrtf] Using HRTF to mix stereo into "
		 "L, R channels\n");
	  break;
	case HRTF_MIX_MATRIX2CH:
	  mp_msg(MSGT_AFILTER, MSGL_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:
	  mp_msg(MSGT_AFILTER, MSGL_WARN,
		 "[hrtf] bogus decode_mode: %d\n", s->decode_mode);
	  break;
	}

       if(s->matrix_mode)
	  mp_msg(MSGT_AFILTER, MSGL_INFO,
		 "[hrtf] Using active matrix to decode rear center "
		 "channel\n");
    }

    out = af->data->planes[0];

    /* 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] = av_clip_int16(left  + diff);
	   out[1] = av_clip_int16(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] = av_clip_int16(left);
	   out[1] = av_clip_int16(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->planes[0] = af->data->planes[0];
    mp_audio_set_num_channels(data, 2);

    return data;
}
Exemplo n.º 3
0
void dpl2decode(float *samples, int numsamples, float *out)
{
    static const unsigned int FWRDURATION = 240; // FWR average duration (samples)
    static const int cfg_delay = 0;
    static const unsigned int fmt_freq = 48000;
    static const unsigned int fmt_nchannels = 2; // input channels

    int cur = 0;

    if (olddelay != cfg_delay || oldfreq != fmt_freq)
    {
        done();
        olddelay = cfg_delay;
        oldfreq = fmt_freq;
        dlbuflen = std::max(FWRDURATION, (fmt_freq * cfg_delay / 1000)); //+(len7000-1);
        cyc_pos = dlbuflen - 1;
        fwrbuf_l.resize(dlbuflen);
        fwrbuf_r.resize(dlbuflen);
        lf.resize(dlbuflen);
        rf.resize(dlbuflen);
        lr.resize(dlbuflen);
        rr.resize(dlbuflen);
        cf.resize(dlbuflen);
        cr.resize(dlbuflen);
        filter_coefs_lfe = calc_coefficients_125Hz_lowpass(fmt_freq);
        lfe_pos = 0;
        memset(LFE_buf, 0, sizeof(LFE_buf));
    }

    float *in = samples; // Input audio data
    float *end = in + numsamples * fmt_nchannels; // Loop end

    while (in < end)
    {
        const int k = cyc_pos;

        const int fwr_pos = (k + FWRDURATION) % dlbuflen;
        /* Update the full wave rectified total amplitude */
        /* Input matrix decoder */
        l_fwr += fabs(in[0]) - fabs(fwrbuf_l[fwr_pos]);
        r_fwr += fabs(in[1]) - fabs(fwrbuf_r[fwr_pos]);
        lpr_fwr += fabs(in[0] + in[1]) - fabs(fwrbuf_l[fwr_pos] + fwrbuf_r[fwr_pos]);
        lmr_fwr += fabs(in[0] - in[1]) - fabs(fwrbuf_l[fwr_pos] - fwrbuf_r[fwr_pos]);

        /* Matrix encoded 2 channel sources */
        fwrbuf_l[k] = in[0];
        fwrbuf_r[k] = in[1];
        matrix_decode(in, k, 0, 1, true, dlbuflen,
                      l_fwr, r_fwr,
                      lpr_fwr, lmr_fwr,
                      &adapt_l_gain, &adapt_r_gain,
                      &adapt_lpr_gain, &adapt_lmr_gain,
                      &lf[0], &rf[0], &lr[0], &rr[0], &cf[0]);

        out[cur + 0] = lf[k];
        out[cur + 1] = rf[k];
        out[cur + 2] = cf[k];
        LFE_buf[lfe_pos] = (out[0] + out[1]) / 2;
        out[cur + 3] = firfilter(LFE_buf, lfe_pos, len125, len125, filter_coefs_lfe);
        lfe_pos++;
        if (lfe_pos == len125)
        {
            lfe_pos = 0;
        }
        out[cur + 4] = lr[k];
        out[cur + 5] = rr[k];
        // Next sample...
        in += 2;
        cur += 6;
        cyc_pos--;
        if (cyc_pos < 0)
        {
            cyc_pos += dlbuflen;
        }
    }
}