Changeset 1171 for pjproject/branches/split-3rd-party
- Timestamp:
- Apr 7, 2007 4:01:41 PM (18 years ago)
- Location:
- pjproject/branches/split-3rd-party
- Files:
-
- 2 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/split-3rd-party/pjmedia/build/pjmedia.dsp
r1168 r1171 430 430 # End Source File 431 431 # End Group 432 # Begin Group "Resample Files"433 434 # PROP Default_Filter ""435 # Begin Source File436 437 SOURCE=..\src\pjmedia\largefilter.h438 # End Source File439 # Begin Source File440 441 SOURCE=..\src\pjmedia\smallfilter.h442 # End Source File443 # End Group444 432 # End Target 445 433 # End Project -
pjproject/branches/split-3rd-party/pjmedia/include/pjmedia/resample.h
r974 r1171 67 67 * because temporary buffer needs to be created. 68 68 * @param large_filter If true, large filter size will be used. 69 * @param channel_count Number of channels. 69 70 * @param rate_in Clock rate of the input samples. 70 71 * @param rate_out Clock rate of the output samples. … … 77 78 pj_bool_t high_quality, 78 79 pj_bool_t large_filter, 80 unsigned channel_count, 79 81 unsigned rate_in, 80 82 unsigned rate_out, … … 106 108 PJ_DECL(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample); 107 109 110 111 /** 112 * Destroy the resample. 113 * 114 * @param resample The resample session. 115 */ 116 PJ_DECL(void) pjmedia_resample_destroy(pjmedia_resample *resample); 108 117 109 118 /** -
pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/conference.c
r974 r1171 299 299 high_quality, 300 300 large_filter, 301 conf->channel_count, 301 302 conf_port->clock_rate,/* Rate in */ 302 303 conf->clock_rate, /* Rate out */ … … 313 314 high_quality, 314 315 large_filter, 316 conf->channel_count, 315 317 conf->clock_rate, /* Rate in */ 316 318 conf_port->clock_rate, /* Rate out */ -
pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/resample.c
r1170 r1171 24 24 #include <pj/pool.h> 25 25 26 #include "../../third_party/build/resample/resamplesubs.h"26 #include <speex/speex_resampler.h> 27 27 28 28 #define THIS_FILE "resample.c" … … 31 31 struct pjmedia_resample 32 32 { 33 double factor; /* Conversion factor = rate_out / rate_in. */ 34 pj_bool_t large_filter; /* Large filter? */ 35 pj_bool_t high_quality; /* Not fast? */ 36 unsigned xoff; /* History and lookahead size, in samples */ 37 unsigned frame_size; /* Samples per frame. */ 38 pj_int16_t *buffer; /* Input buffer. */ 33 SpeexResamplerState *state; 34 #if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT != 0 35 float *in_buffer; 36 float *out_buffer; 37 #endif 38 unsigned in_samples_per_frame; 39 unsigned out_samples_per_frame; 39 40 }; 40 41 42 #ifndef MAX43 # define MAX(a,b) ((a) >= (b) ? (a) : (b))44 #endif45 41 46 42 … … 48 44 pj_bool_t high_quality, 49 45 pj_bool_t large_filter, 46 unsigned channel_count, 50 47 unsigned rate_in, 51 48 unsigned rate_out, … … 54 51 { 55 52 pjmedia_resample *resample; 53 int quality; 54 int err; 56 55 57 56 PJ_ASSERT_RETURN(pool && p_resample && rate_in && 58 57 rate_out && samples_per_frame, PJ_EINVAL); 59 58 60 resample = pj_pool_alloc(pool, sizeof(pjmedia_resample));59 resample = PJ_POOL_ZALLOC_T(pool, pjmedia_resample); 61 60 PJ_ASSERT_RETURN(resample, PJ_ENOMEM); 62 61 63 /* 64 * If we're downsampling, always use the fast algorithm since it seems 65 * to yield the same quality. 66 */ 67 if (rate_out < rate_in) { 68 //no this is not a good idea. It sounds pretty good with speech, 69 //but very poor with background noise etc. 70 //high_quality = 0; 62 if (high_quality) { 63 if (large_filter) 64 quality = 8; 65 else 66 quality = 7; 67 } else { 68 quality = 3; 71 69 } 72 70 73 #if !defined(PJMEDIA_HAS_LARGE_FILTER) || PJMEDIA_HAS_LARGE_FILTER==0 74 /* 75 * If large filter is excluded in the build, then prevent application 76 * from using it. 77 */ 78 if (high_quality && large_filter) { 79 large_filter = PJ_FALSE; 80 PJ_LOG(5,(THIS_FILE, 81 "Resample uses small filter because large filter is " 82 "disabled")); 83 } 71 resample->in_samples_per_frame = samples_per_frame; 72 resample->out_samples_per_frame = rate_out / (rate_in / samples_per_frame); 73 resample->state = speex_resampler_init(channel_count, rate_in, rate_out, 74 quality, &err); 75 if (resample->state == NULL || err != RESAMPLER_ERR_SUCCESS) 76 return PJ_ENOMEM; 77 78 #if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT != 0 79 resample->in_buffer = pj_pool_calloc(pool, resample->in_samples_per_frame, 80 sizeof(float)); 81 resample->out_buffer=pj_pool_calloc(pool, resample->out_samples_per_frame, 82 sizeof(float)); 84 83 #endif 85 86 #if !defined(PJMEDIA_HAS_SMALL_FILTER) || PJMEDIA_HAS_SMALL_FILTER==087 /*88 * If small filter is excluded in the build and application wants to89 * use it, then drop to linear conversion.90 */91 if (high_quality && large_filter == 0) {92 high_quality = PJ_FALSE;93 PJ_LOG(4,(THIS_FILE,94 "Resample uses linear because small filter is disabled"));95 }96 #endif97 98 resample->factor = rate_out * 1.0 / rate_in;99 resample->large_filter = large_filter;100 resample->high_quality = high_quality;101 resample->frame_size = samples_per_frame;102 103 if (high_quality) {104 unsigned size;105 106 /* This is a bug in xoff calculation, thanks Stephane Lussier107 * of Macadamian dot com.108 * resample->xoff = large_filter ? 32 : 6;109 */110 if (large_filter)111 resample->xoff = (unsigned)112 ((resample_LARGE_FILTER_NMULT + 1) / 2.0 *113 MAX(1.0, 1.0/resample->factor));114 else115 resample->xoff = (unsigned)116 ((resample_SMALL_FILTER_NMULT + 1) / 2.0 *117 MAX(1.0, 1.0/resample->factor));118 119 120 size = (samples_per_frame + 2*resample->xoff) * sizeof(pj_int16_t);121 resample->buffer = pj_pool_alloc(pool, size);122 PJ_ASSERT_RETURN(resample->buffer, PJ_ENOMEM);123 124 pjmedia_zero_samples(resample->buffer, resample->xoff*2);125 126 127 } else {128 resample->xoff = 0;129 }130 84 131 85 *p_resample = resample; 132 86 133 PJ_LOG(5,(THIS_FILE, "resample created: %s qualiy, %s filter, in/out " 134 "rate=%d/%d", 135 (high_quality?"high":"low"), 136 (large_filter?"large":"small"), 137 rate_in, rate_out)); 87 PJ_LOG(5,(THIS_FILE, 88 "resample created: quality=%d, ch=%d, in/out rate=%d/%d", 89 quality, channel_count, rate_in, rate_out)); 138 90 return PJ_SUCCESS; 139 91 } 140 141 92 142 93 … … 145 96 pj_int16_t *output ) 146 97 { 98 spx_uint32_t in_length, out_length; 99 float *fp; 100 unsigned i; 101 147 102 PJ_ASSERT_ON_FAIL(resample, return); 148 103 149 if (resample->high_quality) { 150 pj_int16_t *dst_buf; 151 const pj_int16_t *src_buf; 104 in_length = resample->in_samples_per_frame; 105 out_length = resample->out_samples_per_frame; 152 106 153 /* Okay chaps, here's how we do resampling. 154 * 155 * The original resample algorithm requires xoff samples *before* the 156 * input buffer as history, and another xoff samples *after* the 157 * end of the input buffer as lookahead. Since application can only 158 * supply framesize buffer on each run, PJMEDIA needs to arrange the 159 * buffer to meet these requirements. 160 * 161 * So here comes the trick. 162 * 163 * First of all, because of the history and lookahead requirement, 164 * resample->buffer need to accomodate framesize+2*xoff samples in its 165 * buffer. This is done when the buffer is created. 166 * 167 * On the first run, the input frame (supplied by application) is 168 * copied to resample->buffer at 2*xoff position. The first 2*xoff 169 * samples are initially zeroed (in the initialization). The resample 170 * algorithm then invoked at resample->buffer+xoff ONLY, thus giving 171 * it one xoff at the beginning as zero, and one xoff at the end 172 * as the end of the original input. The resample algorithm will see 173 * that the first xoff samples in the input as zero. 174 * 175 * So here's the layout of resample->buffer on the first run. 176 * 177 * run 0 178 * +------+------+--------------+ 179 * | 0000 | 0000 | frame0... | 180 * +------+------+--------------+ 181 * ^ ^ ^ ^ 182 * 0 xoff 2*xoff size+2*xoff 183 * 184 * (Note again: resample algorithm is called at resample->buffer+xoff) 185 * 186 * At the end of the run, 2*xoff samples from the end of 187 * resample->buffer are copied to the beginning of resample->buffer. 188 * The first xoff part of this will be used as history for the next 189 * run, and the second xoff part of this is actually the start of 190 * resampling for the next run. 191 * 192 * And the first run completes, the function returns. 193 * 194 * 195 * On the next run, the input frame supplied by application is again 196 * copied at 2*xoff position in the resample->buffer, and the 197 * resample algorithm is again invoked at resample->buffer+xoff 198 * position. So effectively, the resample algorithm will start its 199 * operation on the last xoff from the previous frame, and gets the 200 * history from the last 2*xoff of the previous frame, and the look- 201 * ahead from the last xoff of current frame. 202 * 203 * So on this run, the buffer layout is: 204 * 205 * run 1 206 * +------+------+--------------+ 207 * | frm0 | frm0 | frame1... | 208 * +------+------+--------------+ 209 * ^ ^ ^ ^ 210 * 0 xoff 2*xoff size+2*xoff 211 * 212 * As you can see from above diagram, the resampling algorithm is 213 * actually called from the last xoff part of previous frame (frm0). 214 * 215 * And so on the process continues for the next frame, and the next, 216 * and the next, ... 217 * 218 */ 219 dst_buf = resample->buffer + resample->xoff*2; 220 pjmedia_copy_samples(dst_buf, input, resample->frame_size); 221 222 if (resample->factor >= 1) { 107 #if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT != 0 108 fp = resample->in_buffer; 109 for (i=0; i<in_length; ++i) { 110 fp[i] = input[i]; 111 } 112 speex_resampler_process_interleaved_float(resample->state, 113 resample->in_buffer, &in_length, 114 resample->out_buffer, &out_length); 115 fp = resample->out_buffer; 116 for (i=0; i<out_length; ++i) { 117 output[i] = (pj_int16_t)fp[i]; 118 } 119 #else 120 PJ_UNUSED_ARG(dst); 121 PJ_UNUSED_ARG(i); 122 speex_resampler_process_interleaved_int(resample->state, 123 (const __int16 *)input, &in_length, 124 (__int16 *)output, &out_length); 125 #endif 223 126 224 if (resample->large_filter) { 225 SrcUp(resample->buffer + resample->xoff, output, 226 resample->factor, resample->frame_size, 227 resample_LARGE_FILTER_NWING, resample_LARGE_FILTER_SCALE, 228 resample_LARGE_FILTER_IMP, resample_LARGE_FILTER_IMPD, 229 PJ_TRUE); 230 } else { 231 SrcUp(resample->buffer + resample->xoff, output, 232 resample->factor, resample->frame_size, 233 resample_SMALL_FILTER_NWING, resample_SMALL_FILTER_SCALE, 234 resample_SMALL_FILTER_IMP, resample_SMALL_FILTER_IMPD, 235 PJ_TRUE); 236 } 127 pj_assert(in_length == resample->in_samples_per_frame); 128 pj_assert(out_length == resample->out_samples_per_frame); 129 } 237 130 238 } else {239 240 if (resample->large_filter) {241 242 SrcUD( resample->buffer + resample->xoff, output,243 resample->factor, resample->frame_size,244 resample_LARGE_FILTER_NWING,245 resample_LARGE_FILTER_SCALE * resample->factor + 0.5,246 resample_LARGE_FILTER_IMP, resample_LARGE_FILTER_IMPD,247 PJ_TRUE);248 249 } else {250 251 SrcUD( resample->buffer + resample->xoff, output,252 resample->factor, resample->frame_size,253 resample_SMALL_FILTER_NWING,254 resample_SMALL_FILTER_SCALE * resample->factor + 0.5,255 resample_SMALL_FILTER_IMP, resample_SMALL_FILTER_IMPD,256 PJ_TRUE);257 258 }259 260 }261 262 dst_buf = resample->buffer;263 src_buf = input + resample->frame_size - resample->xoff*2;264 pjmedia_copy_samples(dst_buf, src_buf, resample->xoff * 2);265 266 } else {267 SrcLinear( input, output, resample->factor, resample->frame_size);268 }269 }270 131 271 132 PJ_DEF(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample) 272 133 { 273 134 PJ_ASSERT_RETURN(resample != NULL, 0); 274 return resample-> frame_size;135 return resample->in_samples_per_frame; 275 136 } 276 137 138 139 PJ_DEF(void) pjmedia_resample_destroy(pjmedia_resample *resample) 140 { 141 PJ_ASSERT_ON_FAIL(resample, return); 142 if (resample->state) { 143 speex_resampler_destroy(resample->state); 144 resample->state = NULL; 145 } 146 } 147 -
pjproject/branches/split-3rd-party/pjmedia/src/pjmedia/resample_port.c
r974 r1171 96 96 (opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0, 97 97 (opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0, 98 dn_port->info.channel_count, 98 99 dn_port->info.clock_rate, 99 100 rport->base.info.clock_rate, … … 107 108 (opt&PJMEDIA_RESAMPLE_USE_LINEAR)==0, 108 109 (opt&PJMEDIA_RESAMPLE_USE_SMALL_FILTER)==0, 110 dn_port->info.channel_count, 109 111 rport->base.info.clock_rate, 110 112 dn_port->info.clock_rate, … … 205 207 } 206 208 207 /* Nothing else to do */ 209 if (rport->resample_get) { 210 pjmedia_resample_destroy(rport->resample_get); 211 rport->resample_get = NULL; 212 } 213 214 if (rport->resample_put) { 215 pjmedia_resample_destroy(rport->resample_put); 216 rport->resample_put = NULL; 217 } 208 218 209 219 return PJ_SUCCESS; -
pjproject/branches/split-3rd-party/pjproject.dsw
r1170 r1171 40 40 ############################################################################### 41 41 42 Project: "libresample"=".\THIRD_PARTY\BUILD\RESAMPLE\libresample.dsp" - Package Owner=<4>43 44 Package=<5>45 {{{46 }}}47 48 Package=<4>49 {{{50 }}}51 52 ###############################################################################53 54 42 Project: "libspeex"=".\third_party\build\speex\libspeex.dsp" - Package Owner=<4> 55 43 -
pjproject/branches/split-3rd-party/third_party/build/speex/libspeex.dsp
r1168 r1171 67 67 F90=df.exe 68 68 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c 69 # ADD CPP /nologo /MTd /W3 /GX / Ox /Ot /Og /Oi /Ob2/I "." /I "../../speex/include" /I "../../../pjlib/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c69 # ADD CPP /nologo /MTd /W3 /GX /ZI /Od /Ob0 /I "." /I "../../speex/include" /I "../../../pjlib/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c 70 70 # ADD BASE RSC /l 0x809 /d "_DEBUG" 71 71 # ADD RSC /l 0x809 /d "_DEBUG"
Note: See TracChangeset
for help on using the changeset viewer.