#include <stdint.h>
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_t * | plc_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. |
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.
|
|
|
The length over which the AMDF function looks for similarity (20 ms) Definition at line 107 of file plc.h. Referenced by plc_fillin(). |
|
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(). |
|
Maximum allowed pitch (200 Hz) Definition at line 103 of file plc.h. Referenced by plc_fillin(). |
|
Minimum allowed pitch (66 Hz) Definition at line 101 of file plc.h. Referenced by plc_fillin(). |
|
Maximum pitch OLA window |
|
|
|
Fill-in a block of missing audio samples. Fill-in a block of missing audio samples.
Definition at line 173 of file plc.c. References amdf_pitch(), CORRELATION_SPAN, fsaturate(), plc_state_t::history, plc_state_t::missing_samples, normalise_history(), plc_state_t::pitch, plc_state_t::pitch_offset, plc_state_t::pitchbuf, PLC_HISTORY_LEN, PLC_PITCH_MAX, PLC_PITCH_MIN, s, and save_history(). 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 }
|
|
Process a block of received V.29 modem audio samples. Process a block of received V.29 modem audio samples.
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 }
|
|
Process a block of received audio samples. Process a block of received audio samples.
Definition at line 130 of file plc.c. References fsaturate(), plc_state_t::missing_samples, plc_state_t::pitch, plc_state_t::pitch_offset, plc_state_t::pitchbuf, s, and save_history(). Referenced by adpcmtolin_framein(), alawtolin_framein(), g726tolin_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 }
|