Sat Mar 24 23:30:02 2007

Asterisk developer's documentation


plc.h File Reference

SpanDSP - a series of DSP components for telephony. More...

#include <stdint.h>

Include dependency graph for plc.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  plc_state_t

Defines

#define _PLC_H_
#define CORRELATION_SPAN   160
#define PLC_HISTORY_LEN   (CORRELATION_SPAN + PLC_PITCH_MIN)
#define PLC_PITCH_MAX   40
#define PLC_PITCH_MIN   120
#define PLC_PITCH_OVERLAP_MAX   (PLC_PITCH_MIN >> 2)
#define SAMPLE_RATE   8000

Functions

int plc_fillin (plc_state_t *s, int16_t amp[], int len)
 Fill-in a block of missing audio samples.
plc_state_tplc_init (plc_state_t *s)
 Process a block of received V.29 modem audio samples.
int plc_rx (plc_state_t *s, int16_t amp[], int len)
 Process a block of received audio samples.


Detailed Description

SpanDSP - a series of DSP components for telephony.

plc.h

Author:
Steve Underwood <steveu@coppice.org>
Copyright (C) 2004 Steve Underwood

All rights reserved.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

This version may be optionally licenced under the GNU LGPL licence. This version is disclaimed to DIGIUM for inclusion in the Asterisk project.

Definition in file plc.h.


Define Documentation

#define _PLC_H_
 

Definition at line 32 of file plc.h.

#define CORRELATION_SPAN   160
 

The length over which the AMDF function looks for similarity (20 ms)

Definition at line 107 of file plc.h.

Referenced by plc_fillin().

#define PLC_HISTORY_LEN   (CORRELATION_SPAN + PLC_PITCH_MIN)
 

History buffer length. The buffer much also be at leat 1.25 times PLC_PITCH_MIN, but that is much smaller than the buffer needs to be for the pitch assessment.

Definition at line 111 of file plc.h.

Referenced by normalise_history(), plc_fillin(), and save_history().

#define PLC_PITCH_MAX   40
 

Maximum allowed pitch (200 Hz)

Definition at line 103 of file plc.h.

Referenced by plc_fillin().

#define PLC_PITCH_MIN   120
 

Minimum allowed pitch (66 Hz)

Definition at line 101 of file plc.h.

Referenced by plc_fillin().

#define PLC_PITCH_OVERLAP_MAX   (PLC_PITCH_MIN >> 2)
 

Maximum pitch OLA window

Definition at line 105 of file plc.h.

#define SAMPLE_RATE   8000
 

Definition at line 98 of file plc.h.


Function Documentation

int plc_fillin plc_state_t s,
int16_t  amp[],
int  len
 

Fill-in a block of missing audio samples.

Fill-in a block of missing audio samples.

Parameters:
s The packet loss concealer context.
amp The audio sample buffer.
len The number of samples to be synthesised.
Returns:
The number of samples synthesized.

Definition at line 173 of file plc.c.

References amdf_pitch(), CORRELATION_SPAN, fsaturate(), normalise_history(), PLC_HISTORY_LEN, PLC_PITCH_MAX, PLC_PITCH_MIN, and s.

Referenced by adpcmtolin_framein(), alawtolin_framein(), g726tolin_framein(), gsmtolin_framein(), lpc10tolin_framein(), and ulawtolin_framein().

00174 {
00175    int i;
00176    int pitch_overlap;
00177    float old_step;
00178    float new_step;
00179    float old_weight;
00180    float new_weight;
00181    float gain;
00182    int16_t *orig_amp;
00183    int orig_len;
00184 
00185    orig_amp = amp;
00186    orig_len = len;
00187    if (s->missing_samples == 0) {
00188       /* As the gap in real speech starts we need to assess the last known pitch,
00189          and prepare the synthetic data we will use for fill-in */
00190       normalise_history(s);
00191       s->pitch = amdf_pitch(PLC_PITCH_MIN, PLC_PITCH_MAX, s->history + PLC_HISTORY_LEN - CORRELATION_SPAN - PLC_PITCH_MIN, CORRELATION_SPAN);
00192       /* We overlap a 1/4 wavelength */
00193       pitch_overlap = s->pitch >> 2;
00194       /* Cook up a single cycle of pitch, using a single of the real signal with 1/4
00195          cycle OLA'ed to make the ends join up nicely */
00196       /* The first 3/4 of the cycle is a simple copy */
00197       for (i = 0;  i < s->pitch - pitch_overlap;  i++)
00198          s->pitchbuf[i] = s->history[PLC_HISTORY_LEN - s->pitch + i];
00199       /* The last 1/4 of the cycle is overlapped with the end of the previous cycle */
00200       new_step = 1.0/pitch_overlap;
00201       new_weight = new_step;
00202       for (  ;  i < s->pitch;  i++) {
00203          s->pitchbuf[i] = s->history[PLC_HISTORY_LEN - s->pitch + i]*(1.0 - new_weight) + s->history[PLC_HISTORY_LEN - 2*s->pitch + i]*new_weight;
00204          new_weight += new_step;
00205       }
00206       /* We should now be ready to fill in the gap with repeated, decaying cycles
00207          of what is in pitchbuf */
00208 
00209       /* We need to OLA the first 1/4 wavelength of the synthetic data, to smooth
00210          it into the previous real data. To avoid the need to introduce a delay
00211          in the stream, reverse the last 1/4 wavelength, and OLA with that. */
00212       gain = 1.0;
00213       new_step = 1.0/pitch_overlap;
00214       old_step = new_step;
00215       new_weight = new_step;
00216       old_weight = 1.0 - new_step;
00217       for (i = 0;  i < pitch_overlap;  i++) {
00218          amp[i] = fsaturate(old_weight*s->history[PLC_HISTORY_LEN - 1 - i] + new_weight*s->pitchbuf[i]);
00219          new_weight += new_step;
00220          old_weight -= old_step;
00221          if (old_weight < 0.0)
00222             old_weight = 0.0;
00223       }
00224       s->pitch_offset = i;
00225    } else {
00226       gain = 1.0 - s->missing_samples*ATTENUATION_INCREMENT;
00227       i = 0;
00228    }
00229    for (  ;  gain > 0.0  &&  i < len;  i++) {
00230       amp[i] = s->pitchbuf[s->pitch_offset]*gain;
00231       gain -= ATTENUATION_INCREMENT;
00232       if (++s->pitch_offset >= s->pitch)
00233          s->pitch_offset = 0;
00234    }
00235    for (  ;  i < len;  i++)
00236       amp[i] = 0;
00237    s->missing_samples += orig_len;
00238    save_history(s, amp, len);
00239    return len;
00240 }

plc_state_t* plc_init plc_state_t s  ) 
 

Process a block of received V.29 modem audio samples.

Process a block of received V.29 modem audio samples.

Parameters:
s The packet loss concealer context.
Returns:
A pointer to the he packet loss concealer context.

Definition at line 244 of file plc.c.

References s.

Referenced by adpcmtolin_new(), alawtolin_new(), g726tolin_new(), gsm_new(), lpc10_dec_new(), and ulawtolin_new().

00245 {
00246    memset(s, 0, sizeof(*s));
00247    return s;
00248 }

int plc_rx plc_state_t s,
int16_t  amp[],
int  len
 

Process a block of received audio samples.

Process a block of received audio samples.

Parameters:
s The packet loss concealer context.
amp The audio sample buffer.
len The number of samples in the buffer.
Returns:
The number of samples in the buffer.

Definition at line 130 of file plc.c.

References ATTENUATION_INCREMENT, fsaturate(), and s.

Referenced by alawtolin_framein(), gsmtolin_framein(), lpc10tolin_framein(), and ulawtolin_framein().

00131 {
00132    int i;
00133    int pitch_overlap;
00134    float old_step;
00135    float new_step;
00136    float old_weight;
00137    float new_weight;
00138    float gain;
00139    
00140    if (s->missing_samples) {
00141       /* Although we have a real signal, we need to smooth it to fit well
00142       with the synthetic signal we used for the previous block */
00143 
00144       /* The start of the real data is overlapped with the next 1/4 cycle
00145          of the synthetic data. */
00146       pitch_overlap = s->pitch >> 2;
00147       if (pitch_overlap > len)
00148          pitch_overlap = len;
00149       gain = 1.0 - s->missing_samples*ATTENUATION_INCREMENT;
00150       if (gain < 0.0)
00151          gain = 0.0;
00152       new_step = 1.0/pitch_overlap;
00153       old_step = new_step*gain;
00154       new_weight = new_step;
00155       old_weight = (1.0 - new_step)*gain;
00156       for (i = 0;  i < pitch_overlap;  i++) {
00157          amp[i] = fsaturate(old_weight*s->pitchbuf[s->pitch_offset] + new_weight*amp[i]);
00158          if (++s->pitch_offset >= s->pitch)
00159             s->pitch_offset = 0;
00160          new_weight += new_step;
00161          old_weight -= old_step;
00162          if (old_weight < 0.0)
00163             old_weight = 0.0;
00164       }
00165       s->missing_samples = 0;
00166    }
00167    save_history(s, amp, len);
00168    return len;
00169 }


Generated on Sat Mar 24 23:30:03 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6